C++ 在现代OpenGL中计算灯光的每片段法线
我想知道如何计算每个片段的法线,以便能够为场景添加灯光 我读入了从libnoise库生成的纹理,并通过计算几何体着色器中的内容创建了一个地形,如下所示 地形看起来很好,但闪电却没有 我的代码如下所示:C++ 在现代OpenGL中计算灯光的每片段法线,c++,opengl,fragment-shader,geometry-shader,C++,Opengl,Fragment Shader,Geometry Shader,我想知道如何计算每个片段的法线,以便能够为场景添加灯光 我读入了从libnoise库生成的纹理,并通过计算几何体着色器中的内容创建了一个地形,如下所示 地形看起来很好,但闪电却没有 我的代码如下所示: const int TOTAL = (TERRAIN_WIDTH*TERRAIN_DEPTH); const int TOTAL_INDICES = TOTAL*3*3; glm::vec3 vertices[TOTAL]; GLuint indices[TOTAL_INDICES]; //.
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);
顶点:
#version 330 core
//inputs
layout(location = 0)in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0f);
}
有人能帮我吗 在将几何体传递到地形之前,应计算几何体上的法线。我想说它现在更努力了,但最好是为您的terrain CPU端生成所有数据,然后将其传递给图形卡。问题是一个片段没有关于下一个片段或上一个片段的信息 您应该传递法线顶点数据以及法线和颜色(或纹理,或两者都不传递),然后使用这些数据在GPU上进行计算 问题是,可以在GeometryShader中生成几何体,但无法获得平滑照明,因为只能为一个面计算一条法线 总而言之: 1.)在CPU上生成几何图形,并将其存储在CPU上 2.)迭代每个顶点并计算其法线。要计算其法线,将取所有相邻面或向量的法线,然后求和并取平均值 3.)将此数据传递到着色器管道 4.)根据所有输入计算照明模型(可能是phong)
这也意味着您不必在每帧生成几何体,如果地形或世界变得更大,这可能会变得非常昂贵。计算每片段法线的最简单方法是在片段着色器中取
gl\u FragCoord
的偏导数的叉积。这将使您获得屏幕空间法线。对此进行了讨论。这些法线将是平坦的,所以我不知道这是否是你想要的?这就是使用视图空间法线,这需要插入额外的逐顶点属性。我不确定应用程序需要哪个坐标空间法线。
#version 330 core
layout(location = 0) out vec4 finalColor;
void main()
{
finalColor = vec4(vec3(1,1,1), 1.0f);
}
#version 330 core
//inputs
layout(location = 0)in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0f);
}