Author Topic: [TUTO] Phong Shading - Spot Light (english)  (Read 6192 times)

0 Members and 1 Guest are viewing this topic.

JeGX

  • Global Moderator
  • Capo Crimine
  • *****
  • Posts: 2343
    • oZone3D.Net
[TUTO] Phong Shading - Spot Light (english)
« on: February 19, 2006, 10:36:49 PM »
Here is a little tutorial that shows in detail the Phong shading model implementation using the GLSL. The spot light is described (finally!) and the double cones model (penumbra area) too.
The tutor is available here: Phong Tutorial.

The spot model with two cones comes from Direct3D. In this tutor, I've used a simple linear function to go from the lit area to the shadowed one.
Other functions (exp, quadratic, ...) could certainly improve the rendering.

Do not hesitate to do some tests and tuning and post your results!
« Last Edit: March 13, 2007, 04:54:42 PM by JeGX »

Vyacheslav

  • Associate
  • Posts: 1
[TUTO] Phong Shading - Spot Light
« Reply #1 on: March 02, 2006, 04:34:32 PM »
Here is optimised pixel shader for spot light(with two cones)
Code: [Select]

[Pixel_Shader]

varying vec3 normal, lightDir, eyeVec;

const float cos_outer_cone_angle = 0.8; // 36 degrees

void main (void)
{
    vec4 final_color =
        (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
        (gl_LightSource[0].ambient * gl_FrontMaterial.ambient);

    vec3 L = normalize(lightDir);
    vec3 D = normalize(gl_LightSource[0].spotDirection);

    float cos_cur_angle = dot(-L, D);

    float cos_inner_cone_angle = gl_LightSource[0].spotCosCutoff;

    float cos_inner_minus_outer_angle =
        cos_inner_cone_angle - cos_outer_cone_angle;
    //Don't need dynamic branching, precompute falloff(i will call it spot)
    float spot = 0.0;
    if(cos_cur_angle > cos_outer_cone_angle)
        spot = clamp((cos_cur_angle - cos_outer_cone_angle) /
            cos_inner_minus_outer_angle, 0.0, 1.0);
    //
    vec3 N = normalize(normal);

    float lambertTerm = max( dot(N,L), 0.0);
    if(lambertTerm > 0.0)
    {
        final_color += gl_LightSource[0].diffuse *
            gl_FrontMaterial.diffuse *
            lambertTerm * spot;

        vec3 E = normalize(eyeVec);
        vec3 R = reflect(-L, N);

        float specular = pow( max(dot(R, E), 0.0),
            gl_FrontMaterial.shininess );

        final_color += gl_LightSource[0].specular *
            gl_FrontMaterial.specular *
            specular * spot;
    }
    gl_FragColor = final_color;
}

JeGX

  • Global Moderator
  • Capo Crimine
  • *****
  • Posts: 2343
    • oZone3D.Net
[TUTO] Phong Shading - Spot Light
« Reply #2 on: March 03, 2006, 12:38:15 AM »
Yeah nice optimization !
But we can do better by removing the if(cos_cur_angle > cos_outer_cone_angle) test. That works still fine without it.

I've done some tests with the original shader (s0), your shader (s1) and the improved version of your shader (s2). Here are the results on my 7800GT:

s0: 363 FPS
s1: 448 FPS
s2: 463 FPS

Conclusion: dynamic branching is still gpu-cycle-eater even on high-end graphics controller.

Good work Vyacheslav!

vexator

  • Associate
  • Posts: 2
[TUTO] Phong Shading - Spot Light
« Reply #3 on: August 09, 2006, 05:04:14 PM »
hi! very good tutorial, i'm just adapting it for my renderer. but i don't want to use gl's internal uniform variables, so i'd like to replace gl_LightSource[0].spotDirection, gl_LightSource[0].spotCosCutoff etc with my own uniforms.

however, i don't understand how to define the spot radii then.. i thought that gl_LightSource[0].spotCosCutoff = cos(gl_LightSource[0].spotCutoff), but that does not seem to be the case.. i'd like to pass values in degrees for the radii, like 45° for the inner radius and 60° for the outer radius - how? (yep, i suck at maths)

thanks in advance! :D

JeGX

  • Global Moderator
  • Capo Crimine
  • *****
  • Posts: 2343
    • oZone3D.Net
[TUTO] Phong Shading - Spot Light
« Reply #4 on: August 10, 2006, 07:03:56 PM »
hi man,
try to use your angles in radian rather than in degrees. I think that'll work better.

vexator

  • Associate
  • Posts: 2
[TUTO] Phong Shading - Spot Light
« Reply #5 on: August 10, 2006, 07:22:53 PM »
d'oh! thank you, i'll give it a try! :D