views:

96

answers:

4

Hiya.

I have an opengl application that loads a dxf and draws it on the screen, each time i need to calculate normals. is there a way to calculate normals in GPU instead of CPU ? if so how ?

+4  A: 

Yes, it's possible. You will want to learn about Pixel Shaders in Cg.

Official book.

karlphillip
The normals should be calculated in a geometry shader, not fragment.
ext
+1  A: 

Have a look at glEnable(GL_AUTO_NORMAL).

Ben Voigt
+1  A: 

You can calculate "flat-shaded" (one normal per face) normals from within geometry shader. One for each triangle, "on the fly", using cross-products. You cannot generate "smooth" normals that way, because GS doesn't have info about neighbors.

If mesh is parametric (say, metaballs), normal can be calculated by sampling few nearby function values. This can also be done on GPU.

You can also calculate normals in shader if mesh is based on heightmap or something similar.

IF GPU supports CUDA, OpenCL or something similar, AND if it can process arbitrary arrays of data, then you can probably also compute normals on the GPU, using traditional tehcniques.

Also, I think that 5 years ago (or so) I saw a paper titled something like "normal smoothing on GPU" or "normal generation on GPU". It had a flat-shaded reflective polygonal heart on the first page. Unfortunately, I cannot locate that paper, and I'm not exactly sure if it existed (or where I saw it). You may be able to find it(if it exists) in GDC papers, SIGGRAPH papers, ATI SDK or NVidia SDK.

SigTerm
+1  A: 

You'll have to use shaders.

You can use a GLSL geometry shader. Here's the GLSL version for face normals. Vertices normals require more work since they have to take neighboring vertices into account.

  • Make sure your graphic card support geometry shaders ! Use for instance GPU Caps Viewer.
  • Cut and paste any tutorial to incorporate a geometry shader in your app.
  • The shader should look like this (how do I get rid of this formatting ?) :

    // glsl shader

    version 120

    extension GL_EXT_geometry_shader4 : enable

    void main(void) { // Compute per-face normal vec4 d1 = gl_PositionIn[1] - gl_PositionIn[0]; vec4 d2 = gl_PositionIn[2] - gl_PositionIn[0]; gl_Normal = cross(d1,d2);

    // Emit all input vertices for(i=0; i< gl_VerticesIn; i++){ gl_Position = gl_PositionIn[i]; EmitVertex(); } EndPrimitive(); }

Calvin1602