像素级光照在许多OpenGL应用程序中都是一个常见的问题,因为标准的OpenGL光照质量非常差。
我想使用GLSL程序,将我的OpenGL程序从顶点级别的光照改为像素级别的光照。至少需要有漫反射光照、雾、纹理和纹理透明度。
我从这个着色器开始:
texture.vert:
varying vec3 position;
varying vec3 normal;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
normal = normalize(gl_NormalMatrix * gl_Normal);
position = vec3(gl_ModelViewMatrix * gl_Vertex);
}
texture.frag:
uniform sampler2D Texture0;
uniform int ActiveLights;
varying vec3 position;
varying vec3 normal;
void main(void)
{
vec3 lightDir;
float attenFactor;
vec3 eyeDir = normalize(-position); // camera is at (0,0,0) in ModelView space
vec4 lightAmbientDiffuse = vec4(0.0,0.0,0.0,0.0);
vec4 lightSpecular = vec4(0.0,0.0,0.0,0.0);
// iterate all lights
for (int i=0; i<ActiveLights; ++i)
{
// attenuation and light direction
if (gl_LightSource[i].position.w != 0.0)
{
// positional light source
float dist = distance(gl_LightSource[i].position.xyz, position);
attenFactor = 1.0/( gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * dist +
gl_LightSource[i].quadraticAttenuation * dist * dist );
lightDir = normalize(gl_LightSource[i].position.xyz - position);
}
else
{
// directional light source
attenFactor = 1.0;
lightDir = gl_LightSource[i].position.xyz;
}
// ambient + diffuse
lightAmbientDiffuse += gl_FrontLightProduct[i].ambient*attenFactor;
lightAmbientDiffuse += gl_FrontLightProduct[i].diffuse * max(dot(normal, lightDir), 0.0) * attenFactor;
// specular
vec3 r = normalize(reflect(-lightDir, normal));
lightSpecular += gl_FrontLightProduct[i].specular *
pow(max(dot(r, eyeDir), 0.0), gl_FrontMaterial.shininess) *
attenFactor;
}
// compute final color
vec4 texColor = gl_Color * texture2D(Texture0, gl_TexCoord[0].xy);
gl_FragColor = texColor * (gl_FrontLightModelProduct.sceneColor + lightAmbientDiffuse) + lightSpecular;
float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; // Intensität berechnen
fog = clamp(fog, 0.0, 1.0); // Beschneiden
gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); // Nebelfarbe einmischen
}
很抱歉,由于这段代码是发布在德国网站上的,所以注释是德语。
但是这个着色器只是让所有东西变得非常暗。没有任何光照效果-然而,着色器代码确实被编译了。如果我只在片段着色器中使用GL_LIGHT0,那么它似乎可以工作,但只对面向相机的多边形合理,我的地板多边形只是非常暗。另外,带有RGBA纹理的四边形没有透明度的迹象。 我使用标准的glRotate / Translate来进行模型视图矩阵,并使用glVertex / Normal来绘制多边形。OpenGL光照效果除了在非常大的表面上看起来很丑陋之外,都运行良好。我三次检查了我的法线,它们没问题。
以上代码是否有问题? 或者说,告诉我为什么没有通用的光照着色器来完成这个任务(基于点的光源并具有距离衰减:就像蜡烛一样)-难道不应该只有一种正确的方法吗?我不想要凸起/法线/视差/卡通/模糊/任何效果。我只想让我的光照在较大的多边形上表现更好。
我找到的所有教程只对在相机位于0,0,0,面向物体的正交方向时照明单个对象有用。以上是唯一一个看起来像我想做的事情的东西。