Shaders problems

Hello !

I’m new here, I discovered panda a few weeks ago and so far I like it. I’m trying to do some shader coding but it’s kinda hard :frowning:

I’ve read the entire nvidia cg tutorial and so far the simple vertex and fragment lighting shaders are working, here the fragm. light. :

//Cg

/// VERTEX SHADER ///
void vshader(
            float4 vtx_position : POSITION,
            float3 vtx_normal : NORMAL,
            uniform float4x4 mat_modelproj,
            out float4 l_position : POSITION,
            out float3 l_screenpos : TEXCOORD0,
            out float3 l_normal : TEXCOORD1
            )


{
  l_position = mul(mat_modelproj, vtx_position);
  l_screenpos = vtx_position.xyz;
  l_normal = vtx_normal.xyz;

}


/// FRAGMENT SHADER ///
void fshader(
             float4 l_position  : TEXCOORD0,
             float4 l_normal    : TEXCOORD1,
             out float4 o_color     : COLOR,
             uniform float3 globalAmbient,
             uniform float3 lightColor,
             uniform float3 lightPosition,
             uniform float3 eyePosition,
             uniform float3 Ke,
             uniform float3 Ka,
             uniform float3 Kd,
             uniform float3 Ks)
{
 
  // -- CALCULATE LIGHTING -- //
  float3 P = l_position.xyz;

  float3 N = normalize(l_normal);

  // Compute the emissive term
  float3 emissive = Ke;

  // Compute the ambient term
  float3 ambient = Ka * globalAmbient;

  // Compute the diffuse term
  float3 L = normalize(lightPosition - P);
  float diffuseLight = max(dot(N, L), 0);
  float3 diffuse = Kd * lightColor * diffuseLight;

  // Compute the specular term
  float3 V = normalize(eyePosition - P);
  float3 H = normalize(L + V);

  float specularLight = pow(max(dot(N, H), 0), 90);

  if (diffuseLight <= 0) specularLight = 0;
  float3 specular = Ks * lightColor * specularLight;

  o_color.xyz =  diffuse + specular + ambient ;
  o_color.w = 1;
}

However, my attempts to get deferred point light system is not working, the light looks wrong :

//Cg

void vshader(
             float4 vtx_position : POSITION,
             float3 vtx_normal : NORMAL,
             out float4 l_position : POSITION,
             out float4 l_pos : TEXCOORD0,
             uniform float4x4 trans_model_to_clip,
             out float3 l_normal : TEXCOORD1,
             uniform float4x4 mat_modelproj)
{
    l_position = mul(mat_modelproj, vtx_position);
    l_pos = l_position;
    l_normal = vtx_normal.xyz;
}

void fshader(
             float4 l_position : TEXCOORD0,
             float4 l_normal    : TEXCOORD1,
             uniform sampler2D k_albedo : TEXUNIT0,
             uniform sampler2D k_depth : TEXUNIT1,
             uniform sampler2D k_normal : TEXUNIT2,
             uniform float4 texpad_albedo,
             uniform float4 texpad_depth,
             uniform float4 attr_color,
             uniform float4 vspos_world,
             uniform float3 lightPosition,
             
             uniform float3 lightRadius,
             uniform float4 vspos_camera,
             uniform float3 Kd,
             uniform float3 Ks,
             uniform float4 wspos_light,
             uniform float4x4 vstrans_clip,
             uniform float4x4 trans_model_to_view,
             uniform float4x4 trans_world_to_view,
             uniform float4x4 trans_clip_to_view,
             uniform float4 vspos_light,
             uniform float4 vspos_model,
             uniform float3 test,

             uniform float4 clipplane_0,
             uniform float4 clipplane_1,
             uniform float4 row0_model_to_view,
             out float4 o_aux: COLOR1,
             out float4 o_color0 : COLOR0)
{

    l_position.xy /= l_position.w; //Perspective Division
    
    float2 texcoords = float2(l_position.xy) * texpad_albedo.xy + texpad_albedo.xy;

    float4 albedo = tex2D(k_albedo, texcoords);
    float4 normal = tex2D(k_normal, texcoords);
    float depth = tex2D(k_depth, texcoords).r;
    
    float4 P;
    P.xy = l_position.xy;
    P.z = depth ;
    P.w = 1;
    P = mul(trans_clip_to_view, P);
    P /= P.w * 2;
   
    float3 N = normalize(float3(normal));

    // Compute the diffuse term

    float3 L = lightPosition - P;

    //Normalize Light Vector
    L = normalize(L);

    float diffuseLight = max(dot(L, N), 0);
    float3 diffuse = diffuseLight ;

    // Compute the specular term
    float3 V = normalize(vspos_camera - P);
    float3 H = normalize(L + V);

    float specularLight = pow(max(dot(N, H), 0), 180);

    if (diffuseLight <= 0) specularLight = 0;
    float3 specular = Ks * attr_color * specularLight* albedo;


    o_color0.xyz =  diffuse ;
    o_color0.w = 1;
 
}

My panda code is very simple, I use a filter manager to render scene into depth, color and normal maps, then I apply the above shader to a volume light (a convex sphere), with Z-test “Less” and Culling “Clockwise”. I send some inputs to the shader :

  • depth map
  • normal map (generated by the panda auto shader gen.)
  • color map
  • position of the light volume

I think the problem comes from :

  • the normal map space (does the autoshader writes normals in world space?)
  • the use of the depth map, I’ve read about z-buffer precision, and I’ve discovered the surface lit by light varies with the near clip setting in panda. How can I use the clipping planes in a .cg shader ?
  • the calculation of the P point (point hit by light ray) is good imo, it comes from cookbook + various sites.
  • the light position not in the good space. With the FIRST shader, I was sending the light position relative to the object using the shader, it was working, here I don’t know, vspos_model instead of lightPosition does the same result.

Finally, when you send an object position to a shader, what is the space ( nodepath.getPos(render) for ex.) ?

Thanks in advance, sorry for the english :angry:

EDIT : ok I found it finally !! I’ve looked at how normal buffers are generated by the autoshader and made the reversed operations :

float4 n;

n = normal;

n.xyz = n.xyz - float3(0.5,0.5,0.5);
n.xyz = 2 * n.xyz;

n = mul(trans_view_to_world, n);

float3 N = normalize(float3(n));