dimanche 1 mars 2015

Calculate per-fragment normals for light in modern OpenGL


I want to know how to calculate per-fragment normals to be able to add light to the scene!


I read in a texture generated from libnoise library - http://ift.tt/1dqeala and create a terrain by calculating stuff in geometry-shader as seen below


The terrain looks fine but not the lightning..


Want to calculate normals for light


My code looks like this:



const int TOTAL = (TERRAIN_WIDTH*TERRAIN_DEPTH);
const int TOTAL_INDICES = TOTAL*3*3;
glm::vec3 vertices[TOTAL];
GLuint indices[TOTAL_INDICES];

//...

int count = 0;
GLuint* id=&indices[0];
// Set up Geometry for terrain
for(int j = 0; j < TERRAIN_DEPTH; j++) {
for(int i = 0; i < TERRAIN_WIDTH; i++) {

//So I want to calculate position and normal here <-----
vertices[count] = glm::vec3((float(i)/(TERRAIN_WIDTH-1)), 1.0,(float(j)/(TERRAIN_DEPTH-1)));
count++;
}
}

for (int i = 0; i < TERRAIN_DEPTH-1; i++) {
for (int j = 0; j < TERRAIN_WIDTH-1; j++) {
int i0 = j+ i*TERRAIN_WIDTH;
int i1 = i0+1;
int i2 = i0+TERRAIN_WIDTH;
int i3 = i2+1;

*id++ = i0;
*id++ = i2;
*id++ = i1;
*id++ = i1;
*id++ = i2;
*id++ = i3;
}
}

...

GLubyte *pData = SOIL_load_image(filename, &textureWidth,
&textureHeight, &channels, SOIL_LOAD_L);

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) , &vertices[0], GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW);

glGenTextures(1, &heightMapTextureID);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, heightMapTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, textureWidth, textureHeight, 0, GL_RED, GL_UNSIGNED_BYTE, pData);


Geometry shader:



layout (triangles) in;
layout (triangle_strip, max_vertices=9) out;

uniform sampler2D heightMapTexture;
uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;


void main()
{
for(int i=0;i<gl_in.length(); i++) {
vec4 position = gl_in[i].gl_Position;

float height = texture(heightMapTexture, position.xz).r;
vec2 xz = (position.xz*50); // the multiplication will decide how big the terrain will be
gl_Position = (projection * view * model) * vec4(xz.x,height*5,xz.y , 1.0);
EmitVertex();
}
EndPrimitive();
}


And my vertex and fragment shader are as basic as it can get.



#version 330 core
layout(location = 0) out vec4 finalColor;

void main()
{
finalColor = vec4(vec3(1,1,1), 1.0f);
}


Vertex:



#version 330 core
//inputs
layout(location = 0)in vec3 position;

void main()
{
gl_Position = vec4(position, 1.0f);
}


Can someone help me?




Aucun commentaire:

Enregistrer un commentaire