PDA

View Full Version : Passing Normals to Shader

joatmon
11-05-2013, 06:29 PM
I'm trying to draw a cube. I have a data structure that keeps all of the relevant vertex data on the cube (position, texture mapping, normals, color) that looks like this:

typedef struct {
GLKVector3 positionCoordinates;
GLKVector2 textureCoordinates;
GLKVector3 normalCoordinates;
GLKVector4 colorCoordinates;
} VertexData;

I define a unit cube centered at the origin with this data:

VertexData modelViewVertices[] = {
//{ {position x, position y, position z}, {texture}, {normalX, normalY, normalZ}, { red, blue, green, alpha} }
{ { 0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}, // rightward facing (+X)
{ { 0.5f, 0.5f, -0.5f}, {1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f, 0.5f}, {0.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f, 0.5f}, {0.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, 0.5f, -0.5f}, {1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, 0.5f, 0.5f}, {1.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },

{ { 0.5f, 0.5f, -0.5f}, {0.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} }, // upward facing (+Y)
{ {-0.5f, 0.5f, -0.5f}, {1.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, 0.5f, 0.5f}, {0.0f, 1.0f}, { 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, 0.5f, 0.5f}, {0.0f, 1.0f}, { 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, 0.5f, -0.5f}, {1.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f}, { 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },

{ {-0.5f, 0.5f, -0.5f}, {0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} }, // leftward facing (-X)
{ {-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, 0.5f, 0.5f}, {0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, 0.5f, 0.5f}, {0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, -0.5f, 0.5f}, {1.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },

{ {-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} }, // downward facing (-Y)
{ { 0.5f, -0.5f, -0.5f}, {1.0f, 0.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, -0.5f, 0.5f}, {0.0f, 1.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, -0.5f, 0.5f}, {0.0f, 1.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f, -0.5f}, {1.0f, 0.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f, 0.5f}, {1.0f, 1.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },

{ { 0.5f, 0.5f, 0.5f}, {0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} }, // forward facing (+Z)
{ {-0.5f, 0.5f, 0.5f}, {1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f, 0.5f}, {0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f, 0.5f}, {0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, 0.5f, 0.5f}, {1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, -0.5f, 0.5f}, {1.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },

{ { 0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} }, // rear facing (-Z)
{ {-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, 0.5f, -0.5f}, {0.0f, 1.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ { 0.5f, 0.5f, -0.5f}, {0.0f, 1.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
{ {-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f, 0.0f} },
};

Then, I go to draw the cube with this code:

- (void)drawCube
{
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(modelViewVertices), modelViewVertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition) ;
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLubyte *)0 + offsetof(VertexData, positionCoordinates));
glEnableVertexAttribArray(GLKVertexAttribNormal);
// glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLubyte *)0 + offsetof(VertexData, normalCoordinates));
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*)(5*sizeof(GLfloat)));

glBindVertexArrayOES(0);
}

The cube draws, but the normals seem to not be working. My guess is that my glVertexAttribPointer command is wrong, but I don't know how to fix it. Can anyone help me to get this to draw correctly. Thanks!

If it helps, here is the vertex shader code:

attribute vec4 position;
attribute vec3 normal;

varying lowp vec4 colorVarying;

uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

void main()
{
vec3 eyeNormal = normalize(normalMatrix * normal);
vec3 lightPosition = vec3(0.0, 0.0, 1.0);
vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0);

float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));

colorVarying = diffuseColor; //* nDotVP;

gl_Position = modelViewProjectionMatrix * position;
}

carsten neumann
11-06-2013, 01:16 AM
The cube draws, but the normals seem to not be working.

What do you mean by that? Are you checking for OpenGL errors (glGetError)? FWIW on a quick reading I did not see anything obviously wrong in the code you posted, but without a better description of the problem you are running into it's difficult to know where to look.

joatmon
11-06-2013, 09:06 PM
The cube displays on the screen, but it is all one single color, with no shading so you cannot see any depth. I can rotate it, etc., but without any shading it looks like a flat image.

Here's a screen shot:

1178

carsten neumann
11-07-2013, 12:08 AM
Did you take that screenshot with the multiplication with nDotVP enabled in: colorVarying = diffuseColor; //* nDotVP; ? What happens when you just map the value nDotVP to the surface, i.e. colorVarying = vec4(nDotVP, nDotVP, nDotVP, 1); ?

joatmon
11-07-2013, 08:12 AM
Aaaagh! In all my obsession over the code in drawCube and my data structure, I overlooked the obvious fact that somewhere along the way I had commented out half that line of code. Now it renders in it's 3d glory. Thank you!