2014-12-27 79 views
-2

有一些场景与一些物体和地形。当我尝试旋转对象时,法线保持不变。意味着对象的黑暗面保持对象的黑暗面。 我的镜面闪电正在工作。GLSL:旋转正常

顶点着色器:

uniform vec3 lightPos; 
uniform sampler2D Texture; 
varying vec2 TexCoord; 

varying vec3 position; 
varying vec3 vertex; 
varying mat3 nMat; 
varying mat3 vMatrix; 
varying vec3 normal; 
varying vec3 oneNormal; 
varying vec3 lightPos2; 

void main() 
{ 
     gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex; 
     position=vec3(gl_ModelViewMatrix*gl_Vertex); 
     vMatrix = mat3(gl_ModelViewMatrix); 
     lightPos2 = vec3(gl_ModelViewMatrix*vec4(lightPos,1.0)); 
     vertex = vec3(gl_Vertex); 
     nMat = gl_NormalMatrix; 
     normal=gl_NormalMatrix*gl_Normal; 
     oneNormal = gl_Normal; 
     TexCoord=gl_MultiTexCoord0.xy; 
} 

片段着色器:

varying vec3 position; 
varying vec3 normal; 

uniform sampler2D Texture; 
varying vec2 TexCoord; 

uniform vec3 lightPos; 
varying vec3 vertex; 
uniform vec3 lambient; 
uniform vec3 ldiffuse; 
uniform vec3 lspecular; 
uniform float shininess; 
varying mat3 nMat; 
varying mat3 vMatrix; 
varying vec3 oneNormal; 
varying vec3 lightPos2; 


void main() 
{ 
     float dist=length(vertex-lightPos); 
     float att=1.0/(1.0+0.1*dist+0.01*dist*dist); 
     vec4 TexColor = texture2D(Texture, TexCoord); 
     vec3 ambient=TexColor.rgb*lambient; //the ambient light 

    //=== Diffuse ===// 
     vec3 surf2light=normalize(position-lightPos2); 
     float dcont=max(0.0, 
        dot(normalize(nMat*(-normal)), nMat*surf2light)); 
     vec3 diffuse=dcont*(TexColor.rgb*ldiffuse); 

    //=== Specular ===// 
     vec3 surf2view = normalize(lightPos-position); 
     surf2light=nMat*normalize(-vertex); 
     vec3 reflection=reflect(-surf2view,normalize(normal)); 

     float scont=pow(max(0.0,dot(surf2light,reflection)),shininess); 
     vec3 specular=scont*lspecular; 

     gl_FragColor=vec4((ambient+diffuse+specular)*att,1.0); 
} 
+0

最后你有问题吗? – 2014-12-27 20:13:55

+0

我该如何解决这个问题:D – 2014-12-27 20:14:26

+0

修复**究竟是什么**? – 2014-12-27 20:15:17

回答

0

您正在改变法线。但至少对于照明计算的一部分,您使用的光源位置也转换为相同的坐标空间。如果您同时转换光源的法线,法线相对于光源的方向将再次相同。

提取从顶点着色器的关键行:

position=vec3(gl_ModelViewMatrix*gl_Vertex); 
    lightPos2 = vec3(gl_ModelViewMatrix*vec4(lightPos,1.0)); 
    normal=gl_NormalMatrix*gl_Normal; 

gl_NormalMatrix对应于gl_ModelViewMatrix,与必要的调整,变换方向矢量,而不是点。因此,modelview转换已应用于所有positionlightPos2normal

然后,所有这三个值(用插值应用)被传递到片段着色器,在这里你有这个计算的漫反射照明术语:

vec3 surf2light=normalize(position-lightPos2); 
    float dcont=max(0.0, 
       dot(normalize(nMat*(-normal)), nMat*surf2light)); 
    vec3 diffuse=dcont*(TexColor.rgb*ldiffuse); 

现在,有几个问题在这里:

  • 即使它们已经被转换,您也正在向这两个向量应用nMat,这是正常矩阵。这并没有什么坏处,因为如果将相同的旋转应用于两个矢量,点积不会改变,但它没有任何意义。
  • 所有使用的值(positionlightPos2,normal)都被模型视图矩阵转换。所以他们的相对位置和方向与原来的完全相同。计算结果将与应用于相应未转换的载体时的结果相同。

您需要决定要用于照明计算的坐标系。至少有几个选项。最容易的一个可能是使用眼睛坐标空间。为此,您可以在将视图转换为光照位置之前应用视图转换,然后在着色器代码中直接使用此光照位置,而无需进行任何其他转换。

由于您认为镜面照明可以按照需要工作,并且您在那里使用统一的lightPos,所以在漫反射计算中使用该变量代替lightPos2可能非常简单。