我需要一个简单的聚光灯着色器的帮助。 锥体内的所有顶点应为黄色,锥体外的所有顶点应为黑色。 我无法让它发挥作用。我认为这与从世界到眼睛坐标的转换有关。
顶点着色器:
uniform vec4 lightPositionOC; // in object coordinates
uniform vec3 spotDirectionOC; // in object coordinates
uniform float spotCutoff; // in degrees
void main(void)
{
vec3 lightPosition;
vec3 spotDirection;
vec3 lightDirection;
float angle;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Transforms light position and direction into eye coordinates
lightPosition = (lightPositionOC * gl_ModelViewMatrix).xyz;
spotDirection = normalize(spotDirectionOC * gl_NormalMatrix);
// Calculates the light vector (vector from light position to vertex)
vec4 vertex = gl_ModelViewMatrix * gl_Vertex;
lightDirection = normalize(vertex.xyz - lightPosition.xyz);
// Calculates the angle between the spot light direction vector and the light vector
angle = dot( normalize(spotDirection),
-normalize(lightDirection));
angle = max(angle,0);
// Test whether vertex is located in the cone
if(angle > radians(spotCutoff))
gl_FrontColor = vec4(1,1,0,1); // lit (yellow)
else
gl_FrontColor = vec4(0,0,0,1); // unlit(black)
}
Fragment Shader:
void main(void)
{
gl_FragColor = gl_Color;
}
修改
蒂姆是对的。此
if(angle > radians(spotCutoff))
应该是:
if(acos(angle) < radians(spotCutoff))
新问题:
灯光似乎没有停留在场景中的固定位置,而是当我向前或向后移动时,它似乎相对于我的相机移动,因为锥体变小或变大。
答案 0 :(得分:5)
(让spotDirection为向量A,lightDirection为向量B)
您正在分配;
angle = dot(A,B)
公式不应该是:
cos(angle) = dot(A,B)
或
angle = arccos(dot(A,B))
http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation
答案 1 :(得分:1)
在我的旧着色器中,我使用了该代码:
float spotEffect = dot(normalize(gl_LightSource[0].spotDirection.xyz),
normalize(-light));
if (spotEffect < gl_LightSource[0].spotCosCutoff)
{
spotEffect = smoothstep(gl_LightSource[0].spotCosCutoff-0.002,
gl_LightSource[0].spotCosCutoff, spotEffect);
}
else spotEffect = 1.0;
而不是将Angles发送到着色器,最好发送那些Angles的Cos
答案 2 :(得分:1)
要回答您的新问题,请点击以下链接:GLSL point light shader moving with camera。 解决方案是删除gl_NormalMatrix和gl_ModelViewMatrix。
spotDirection = normalize(spotDirectionOC * gl_NormalMatrix);
会变成:
spotDirection = normalize(spotDirectionOC);
答案 3 :(得分:0)
https://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/graphics/shader.vert?r=1639
if (spotEffect >= cos(radians(uLightOuterCone[index])))
和
//vec3 NSpotDir = (uViewMatrix * vec4(uLightDirection[index],0)).xyz; //must do outside or become flashlight follow
vec3 NSpotDir = normalize(uLightDirection[index]);