shader PerPixel Lighting2: Unterschied zwischen den Versionen
Aus DGL Wiki
Olee (Diskussion | Beiträge) (→Besondere Vorraussetzungen) |
(→Code) |
||
(10 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt) | |||
Zeile 13: | Zeile 13: | ||
==Bilder== | ==Bilder== | ||
{| | {| | ||
− | |[[Bild: | + | |[[Bild:PPLShader.jpg|framed|400px|400px|Beispiel (Es handelt sich hierbei um EIN EINZIGES großes Quad)]] |
|- | |- | ||
− | |||
|} | |} | ||
Zeile 26: | Zeile 25: | ||
==Besondere Vorraussetzungen== | ==Besondere Vorraussetzungen== | ||
Es muss eine Textur gebunden sein, sonst ist das ergebnis immer Schwarz aufgrund des Folgenden Codes: | Es muss eine Textur gebunden sein, sonst ist das ergebnis immer Schwarz aufgrund des Folgenden Codes: | ||
− | <cpp> | + | <source lang="cpp"> |
− | vec4 texColor | + | vec4 texColor = gl_Color * texture2D(Texture0, gl_TexCoord[0].xy); |
− | gl_FragColor | + | gl_FragColor = texColor * (gl_FrontLightModelProduct.sceneColor + lightAmbientDiffuse) + lightSpecular; |
− | </ | + | </source> |
Entweder man entfernt den eintrag '''*texture2D(Texture0, gl_TexCoord[0].xy)''' oder bindet vorher eine | Entweder man entfernt den eintrag '''*texture2D(Texture0, gl_TexCoord[0].xy)''' oder bindet vorher eine | ||
weiße-1D-Textur. | weiße-1D-Textur. | ||
Zeile 37: | Zeile 36: | ||
==Code== | ==Code== | ||
Vertexshader: | Vertexshader: | ||
− | < | + | <source lang="glsl"> |
varying vec3 position; | varying vec3 position; | ||
varying vec3 normal; | varying vec3 normal; | ||
Zeile 49: | Zeile 48: | ||
position = vec3(gl_ModelViewMatrix * gl_Vertex); | position = vec3(gl_ModelViewMatrix * gl_Vertex); | ||
} | } | ||
− | </ | + | </source> |
Fragmentshader: | Fragmentshader: | ||
− | < | + | <source lang="glsl"> |
uniform sampler2D Texture0; | uniform sampler2D Texture0; | ||
uniform int ActiveLights; | uniform int ActiveLights; | ||
Zeile 88: | Zeile 87: | ||
// ambient + diffuse | // ambient + diffuse | ||
lightAmbientDiffuse += gl_FrontLightProduct[i].ambient*attenFactor; | lightAmbientDiffuse += gl_FrontLightProduct[i].ambient*attenFactor; | ||
− | lightAmbientDiffuse += gl_FrontLightProduct[i].diffuse * max(dot(normal, lightDir), 0.0) * attenFactor; | + | lightAmbientDiffuse += gl_FrontLightProduct[i].diffuse * max(dot(normalize(normal), lightDir), 0.0) * attenFactor; |
// specular | // specular | ||
vec3 r = normalize(reflect(-lightDir, normal)); | vec3 r = normalize(reflect(-lightDir, normal)); | ||
Zeile 103: | Zeile 102: | ||
gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); // Nebelfarbe einmischen | gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); // Nebelfarbe einmischen | ||
} | } | ||
− | </ | + | </source> |
Aktuelle Version vom 7. Juni 2012, 13:20 Uhr
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(normalize(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
}