我一直在尝试编写一个基本的webgl聚光灯着色器,但无论我怎么努力,我都无法让聚光灯的位置与世界相关。
我目前的代码使用在下面,我已经尝试了几乎每个坐标框架,我可以使这工作,但无论我做什么,我只得到部分正确的结果。
例如,如果我切换到世界坐标,聚光灯位置将是正确的,但它只会反射一个物体,或者如果我使用视图空间,灯光将起作用,但它的位置是相对于相机。
/>
在它的当前状态下,聚光灯似乎与每个物体框架相关。 (不知道为什么。)。非常感谢帮助解决这个问题的任何帮助。
顶点着色器:
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);
}