我一直在使用OpenGL的Superbible(第5版)点光源示例。glsl 1.3+中的点光源/聚光灯衰减?
我发现它们缺少集成到旧照明模型中的恒定,线性和二次衰减值,所以我写了一个基于此ogre guide的衰减值的点光源着色器。
结果已经完全离奇了。 如何才能在新的glsl上获得合理的光线衰减?是否有衰减常量的glsl表格?
照片管理
衰减在距离99 -sphere是黑色的,光在距离蓝光
衰减50 -sphere是黑的,光被蓝光
衰减在距离16 -sphere是黑的,光被发射蓝色
衰减在距离2 -sphere是黑的,光被发射蓝色
样品顶点和片段程序:
顶点程序:
//point light per pixel vertex program
#version 130
// Incoming per vertex... position and normal
in vec4 vVertex;
in vec3 vNormal;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
// Color to fragment program
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;
out float dist;
out float constantAttenuation;
out float linearAttenuation;
out float quadraticAttenuation;
void main(void)
{
// Get surface normal in eye coordinates
vVaryingNormal = normalMatrix * vNormal;
// Get vertex position in eye coordinates
vec4 vPosition4 = mvMatrix * vVertex;
vec3 vPosition3 = vPosition4.xyz/vPosition4.w;
//get distance to light source
dist=length(vLightPosition-vPosition3);
//write proper attenuation values
if (dist<7.0){
constantAttenuation=1.0;
linearAttenuation=0.7;
quadraticAttenuation=1.8;
}
else if (dist<13.0){
constantAttenuation=1.0;
linearAttenuation=0.35;
quadraticAttenuation=0.44;
}
else if (dist<20.0){
constantAttenuation=1.0;
linearAttenuation=0.22;
quadraticAttenuation=0.20;
}
if (dist<32.0){
constantAttenuation=1.0;
linearAttenuation=0.14;
quadraticAttenuation=0.07;
}
if (dist<50.0){
constantAttenuation=1.0;
linearAttenuation=0.09;
quadraticAttenuation=0.32;
}
if (dist<65.0){
constantAttenuation=1.0;
linearAttenuation=0.07;
quadraticAttenuation=0.017;
}
if (dist<100.0){
constantAttenuation=1.0;
linearAttenuation=0.045;
quadraticAttenuation=0.0075;
}
// Get vector to light source
vVaryingLightDir = normalize(vLightPosition - vPosition3);
// Don't forget to transform the geometry!
gl_Position = mvpMatrix * vVertex;
}
片断程序:
//point light per pixel fragment program
#version 130
out vec4 vFragColor;
uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
smooth in vec3 vVaryingNormal;
smooth in vec3 vVaryingLightDir;
in float dist;
in float constantAttenuation;
in float linearAttenuation;
in float quadraticAttenuation;
void main(void){
float att;
att = 1.0/constantAttenuation + linearAttenuation*dist +quadraticAttenuation*dist*dist;
// Dot product gives us diffuse intensity
float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
// Multiply intensity by diffuse color, force alpha to 1.0
vFragColor = att*(diff * diffuseColor +ambientColor); // attenuation affects the diffuse component
// Specular Light
vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal)));
float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));
if(diff != 0) {
float fSpec = pow(spec, 128.0);
vFragColor.rgb += (att*vec3 (fSpec, fSpec, fSpec)); // attenuation affects the specular component
}
}
任何图像的机会,以澄清“奇怪”? – ssube 2011-04-03 01:50:31
@peachykeen:当然,朋友。 – andandandand 2011-04-03 02:04:51