shader PerPixel Lighting2
Aus DGL Wiki
Version vom 23. Februar 2009, 01:21 Uhr von Olee (Diskussion | Beiträge) (→Besondere Vorraussetzungen)
Inhaltsverzeichnis
Per-Pixel-Lighting Shader
Zurück zur Shadersammlung
Beschreibung | Autor | Version |
---|---|---|
Per-Pixel-Lighting Shader | Olee | 1.0 |
Bilder
Beschreibung
Eine Erweiterung des bestehenden PPL-Shaders aus der Shadersammlung. Dabei beachtet dieser im Gegensatz zum bestehenden den Abstand zur Lichtquelle, unendlich weit entfernte Lichtquellen (Positionsvektor.W = 0) und er behandelt im Anschluss an das Licht noch den Fog.
Besondere Vorraussetzungen
Es muss eine Textur gebunden sein, sonst ist das ergebnis immer Schwarz aufgrund des Folgenden Codes:
vec4 texColor = gl_Color * texture2D(Texture0, gl_TexCoord[0].xy); gl_FragColor = texColor * (gl_FrontLightModelProduct.sceneColor + lightAmbientDiffuse) + lightSpecular;
Entweder man entfernt den eintrag *texture2D(Texture0, gl_TexCoord[0].xy) oder bindet vorher eine weiße-1D-Textur.
Über die uniform-Variable ActiveLights kann die Anzahl der Lichtquellen angegeben werden, die für die berechnung des Lichtes verwendet werden sollen. Dabei wird von von der Lichtquelle 0 aus hochgezählt.
Code
Vertexshader:
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); }
Fragmentshader:
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 }