WebGl聚光灯着色器

WebGl聚光灯着色器,webgl,shader,Webgl,Shader,我一直在尝试编写一个基本的webgl聚光灯着色器,但无论我如何努力,我都无法使聚光灯的位置与世界相对。我目前使用的代码如下,我几乎尝试了我能使用的所有坐标系,以使其正常工作,但无论我做什么,我只能得到部分正确的结果。 例如,如果切换到世界坐标,聚光灯的位置将是正确的,但它将仅反射一个对象,或者如果使用视图空间,灯光将工作,但其位置相对于相机。 在其当前状态下,聚光灯似乎相对于每个对象帧。不知道为什么。非常感谢您为解决此问题提供的任何帮助 顶点着色器: 片段着色器: 当前输出:我最近已经完成了这个

我一直在尝试编写一个基本的webgl聚光灯着色器,但无论我如何努力,我都无法使聚光灯的位置与世界相对。我目前使用的代码如下,我几乎尝试了我能使用的所有坐标系,以使其正常工作,但无论我做什么,我只能得到部分正确的结果。 例如,如果切换到世界坐标,聚光灯的位置将是正确的,但它将仅反射一个对象,或者如果使用视图空间,灯光将工作,但其位置相对于相机。 在其当前状态下,聚光灯似乎相对于每个对象帧。不知道为什么。非常感谢您为解决此问题提供的任何帮助

顶点着色器:

片段着色器:


当前输出:

我最近已经完成了这个练习,一个有用的调试技术是将gl_FragColor设置为您要传递的不同均匀/变化,以查明哪个是不正确的。例如,假设您的Vnormal位于视图空间中,则面向您的每个网格应为蓝色0、0、1;再看看您的代码,shouldnt D=lightDirection.xyz//光线方向是否也在视图空间/眼睛坐标中?这似乎起了作用,或者看起来是这样。在第二次检查中,这仅部分起作用…:
attribute vec4 vPosition;
attribute vec4 vNormal;
attribute vec2 vTexCoord;

varying vec3 L, E, N,D;
varying vec2 fTexCoord;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 NormalMatrix;
uniform mat4 View;

uniform vec4 lightPosition;
uniform vec4 lightDirection;
uniform vec3 Eye;

void main(){
    L= (modelViewMatrix * lightPosition).xyz; //Light position in eye coordinates
    E = (modelViewMatrix * vPosition).xyz;    //Vertex position in eye coordinates.
    //Normal position in eye coordinate. Transpose(Inverse(modelViewMatrix) * vNormal.
    N=(NormalMatrix * vNormal).xyz;
    D=lightDirection.xyz;//Light direction
    fTexCoord=vTexCoord;
    gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
precision mediump float;
uniform vec4 lDiffuseColor;
uniform vec4 lSpecular;
uniform vec4 lAmbientColor;
uniform float lShininess;

varying vec3 L,E,N,D;
const float lExponent=2.0;
const float lCutoff=0.867;
vec3 lWeight=vec3(0,0,0);

void main(){

    vec3 vtoLS=normalize(L - E);//Vector to light source from vertex.
    float Ks=pow(max(dot(normalize(N),vtoLS),0.0),lShininess);
    vec3 specular=Ks* lSpecular.xyz;
    float diffuseWeight=max(dot(normalize(N), -vtoLS),0.0);
    vec3 diffuse=diffuseWeight * lDiffuseColor.xyz;

    if(diffuseWeight >0.0){
        float lEffect= dot(normalize(D),normalize(-vtoLS));
        if(lEffect > lCutoff){
            lEffect= pow(lEffect,Ks);
            vec3 reflection= normalize(reflect(-vtoLS,normalize(N)));
            vec3 vEye=-normalize(E);
            float rdotv=max(dot(reflection,vEye),0.0);
            float specularWeight=pow(rdotv,lShininess);
            lWeight= (lEffect * diffuse.xyz  + lEffect * specular.xyz) + vec3(0.5,0,0);
        }   
    }
    lWeight+=lAmbientColor.xyz;
    gl_FragColor=vec4(lWeight.rgb,1);

}