我目前正在尝试使用glsl和使用Phong模型在球体上制作镜面光照。
这就是我的片段着色器的样子:
#version 120
uniform vec4 color;
uniform vec3 sunPosition;
uniform mat4 normalMatrix;
uniform mat4 modelViewMatrix;
uniform float shininess;
// uniform vec4 lightSpecular;
// uniform vec4 materialSpecular;
varying vec3 viewSpaceNormal;
varying vec3 viewSpacePosition;
vec4 calculateSpecular(vec3 l, vec3 n, vec3 v, vec4 specularLight, vec4 materialSpecular) {
vec3 r = -l+2*(n*l)*n;
return specularLight * materialSpecular * pow(max(0,dot(r, v)), shininess);
}
void main(){
vec3 normal = normalize(viewSpaceNormal);
vec3 viewSpacePosition = (modelViewMatrix * vec4(gl_FragCoord.x, gl_FragCoord.y, gl_FragCoord.z, 1.0)).xyz;
vec4 specular = calculateSpecular(sunPosition, normal, viewSpacePosition, vec4(0.3,0.3,0.3,0.3), vec4(0.3,0.3,0.3,0.3));
gl_FragColor = color+specular;
}
sunPosition没有移动,并设置为值(2.0f,3.0f,-1.0f)。
问题在于图像看起来没什么,因为如果镜面反射计算是正确的,那么图像就可以了。
这是它的样子: http://i.imgur.com/Na2C6.png
我在此代码中没有任何环境 - /发射 - /散光 - 照明的原因是因为我想让镜面光部件首先工作。
感谢任何帮助!
编辑: @Darcy Rayner 那个indead帮助它变得难以接近,这仍然是不正确的......
目前的代码如下:
顶点着色器:
viewSpacePosition = (modelViewMatrix*gl_Vertex).xyz;
viewSpaceSunPosition = (modelViewMatrix*vec4(sunPosition,1)).xyz;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
viewSpaceNormal = (normalMatrix * vec4(gl_Position.xyz, 0.0)).xyz;
Fragment Shader:
vec4 calculateSpecular(vec3 l, vec3 n, vec3 v, vec4 specularLight, vec4 materialSpecular) {
vec3 r = -l+2*(n*l)*n;
return specularLight * materialSpecular * pow(max(0,dot(r, v)), shininess);
}
void main(){
vec3 normal = normalize(viewSpaceNormal);
vec3 viewSpacePosition = normalize(viewSpacePosition);
vec3 viewSpaceSunPosition = normalize(viewSpaceSunPosition);
vec4 specular = calculateSpecular(viewSpaceSunPosition, normal, viewSpacePosition, vec4(0.7,0.7,0.7,1.0), vec4(0.6,0.6,0.6,1.0));
gl_FragColor = color+specular;
}
球体看起来像这样:
太阳位置:sunPosition = new Vector(12.0f,15.0f,-1.0f);
答案 0 :(得分:0)
尝试不使用gl_FragCoord,因为它存储在屏幕坐标中(我不认为通过modelViewMatrix将其转换回视图坐标)。最简单的事情是,在顶点着色器中将viewSpacePosition设置为:
// Change gl_Vertex to whatever attribute you are using.
viewSpacePosition = (modelViewMatrix * gl_Vertex).xyz;
这应该让你在视图坐标中看到viewSpacePosition(即在应用投影之前)。然后,您可以继续并在片段着色器中规范化viewSpacePosition。不确定您是否将太阳矢量存储在世界坐标中,但您可能希望将其转换为视图空间,然后将其标准化。试一试,看看会发生什么,这些事情往往非常容易出错。