shader PerPixelLighting

Aus DGL Wiki
Wechseln zu: Navigation, Suche

Per Pixel-Beleuchtung

Zurück zur Shadersammlung

Beschreibung Autor Version
Beleuchtet Primitiven per Pixel anstatt per Vertex, wie es OpenGLs Standardbeleuchtung macht Ireyon 1.0

Bilder

Deutlich sichtbarer Reflexionspunkt

Beschreibung

Dieser Shader berechnet im Gegensatz zur Standard-OpenGL-Beleuchtung, die per Vertex berechnet, die Fragmentfarbe per Pixel. Anders als der im zweiten GLSL-Tutorial veröffentlichte Per-Pixel-Beleuchtungsshader berücksichtigt dieser allerdings auch Texturen und Materialien. Die Rendergeschwindigkeit könnte bei älteren Grafikkarten stark sinken.

Besondere Vorraussetzungen

Licht- und Materialinformationen werden wie beim normale OpenGL-Licht übergeben, vor der Verwendung dieses Shaders sollte es aber mit glDisable(GL_LIGHTING); ausgeschaltet werden.

Code

Vertexshader:

varying vec3 v;
varying vec3 lightvec;
varying vec3 normal;
varying vec4 FrontColor;

void main(void) {
  normal         = normalize(gl_NormalMatrix * gl_Normal);
  v              = vec3(gl_ModelViewMatrix * gl_Vertex);
  lightvec       = normalize(gl_LightSource[0].position.xyz - v);

  gl_TexCoord[0] = gl_MultiTexCoord0;
  FrontColor     = gl_Color;

  gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragmentshader:

varying vec3 v;
varying vec3 lightvec;
varying vec3 normal;
varying vec4 FrontColor;

uniform sampler2D Texture0;

void main(void) {
  vec3 Eye       = normalize(-v);
  vec3 Reflected = normalize(reflect( -lightvec, normal)); 

  vec4 IAmbient  = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
  vec4 IDiffuse  = gl_LightSource[0].diffuse * max(dot(normal, lightvec), 0.0) * gl_FrontMaterial.diffuse;
  vec4 ISpecular = gl_LightSource[0].specular * pow(max(dot(Reflected, Eye), 0.0), gl_FrontMaterial.shininess) * gl_FrontMaterial.specular;
  
  gl_FragColor   = vec4((gl_FrontLightModelProduct.sceneColor + IAmbient + IDiffuse) * texture2D(Texture0, vec2(gl_TexCoord[0])) + ISpecular);
}