我使用OpenGL不推荐使用的功能和我的光计算在片段着色器完成。 所以,我做平滑阴影。
我的问题是,当我画一个立方体,我需要平法线。 由扁平法线我的意思是在一个面生成的每个片段具有相同的正常。
我对这个解决方案到目前为止是产生每个面不同的顶点。 这样,代替具有8个顶点,我现在有24(6×4)的顶点。
但是,这似乎是我错了,复制的顶点。 有没有更好的方式来获得平坦的法线?
更新:我使用的OpenGL版本3.3.0,我没有对OpenGL 4支持呢。
我使用OpenGL不推荐使用的功能和我的光计算在片段着色器完成。 所以,我做平滑阴影。
我的问题是,当我画一个立方体,我需要平法线。 由扁平法线我的意思是在一个面生成的每个片段具有相同的正常。
我对这个解决方案到目前为止是产生每个面不同的顶点。 这样,代替具有8个顶点,我现在有24(6×4)的顶点。
但是,这似乎是我错了,复制的顶点。 有没有更好的方式来获得平坦的法线?
更新:我使用的OpenGL版本3.3.0,我没有对OpenGL 4支持呢。
如果您在摄像机空间做照明,可以使用dFdx / dFdy来计算正常的脸从顶点的摄像机空间位置。
所以片段着色器看起来有点像这样。
varying vec3 v_PositionCS; // Position of the vertex in camera/eye-space (passed in from the vertex shader)
void main()
{
// Calculate the face normal in camera space
vec3 normalCs = normalize(cross(dFdx(v_PositionCS), dFdy(v_PositionCS)));
// Perform lighting
...
...
}
由于几何着色器可以“看到”一个三角形的三个顶点的同时,您可以使用几何着色器来计算法线并将它们发送到您的片段着色器。 这样,您就不必重复顶点。
// Geometry Shader
#version 330
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
out vec3 gNormal;
// You will need to pass your untransformed positions in from the vertex shader
in vec3 vPosition[];
uniform mat3 normalMatrix;
void main()
{
vec3 side2 = vPosition[2] - vPosition[0];
vec3 side0 = vPosition[1] - vPosition[0];
vec3 facetNormal = normalize(normalMatrix * cross(side0, side2));
gNormal = facetNormal;
gl_Position = gl_in[0].gl_Position;
EmitVertex();
gNormal = facetNormal;
gl_Position = gl_in[1].gl_Position;
EmitVertex();
gNormal = facetNormal;
gl_Position = gl_in[2].gl_Position;
EmitVertex();
EndPrimitive();
}
另一种选择是通过MV-矩阵和未旋转AxisAligned坐标到片段着色器:
attribute aCoord;
varying vCoord;
void main() {
vCoord = aCoord;
glPosition = aCoord * MVP;
}
在片段着色器可以通过计算vCoord的主导轴,该设定为1.0(或-1.0),另一个坐标为零识别正常 - 这是正常的,其具有由所述MV - 矩阵旋转。