Advertisement

Simulating shader computation to cpp file?

Started by November 04, 2015 04:15 PM
0 comments, last by Alundra 9 years, 1 month ago

This is just a follow up question to my previous question on debugging shader. Apparently, there is just no way I could see the value inside of the variable of the fragment shader. Some say to use debugger, tried it but I still cant see the value of for example a uniform variable on my vertex or fragment shader. Right now Im still stuck on spot light computation on this site.

I dont understand is, why when the outer cut off angle is lower than the inner cutoff angle, the inner cutoff angle color will just be black. It really bugs me.

The Fragmet shader


     vec3 lightDir = normalize(light.position - FragPos);
   
    float theta = dot(lightDir, normalize(-light.direction)); 

     // Ambient
        vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)) ;
        
        // Diffuse
        vec3 norm = normalize(Normal);        
        //vec3 lightDir = normalize(light.position - FragPos);
        float diff = max(dot(norm, lightDir), 0.0);
        vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)) * objectColor2;  

         // Specular
        vec3 viewDir = normalize(viewPos - FragPos);
        vec3 reflectDir = reflect(-lightDir, norm);  
        float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
        vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));

    

   
        float epsilon = (light.cutOff - light.outerCutOff);
        
        // Use the the formula to get the Intensity stated above. DO NOTE: we use clamp here to make sure the intensity values won't end up outside the [0, 1] interval.
        float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);    


        // Multiply the intesity to diffuse and specular to get the proper interpolation.
        diffuse  *= intensity;
        specular *= intensity;
        


        // Attenuation
         // Attenuation
        float distance    = length(light.position - FragPos);
        float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance));    
        ambient  *= attenuation;
        diffuse  *= attenuation;
        specular *= attenuation;   
        
    

        color = vec4(ambient + diffuse + specular , 1.0f)  ;  

The vertex shader


   gl_Position = projection * view *  model * vec4(position, 1.0f);
    FragPos = vec3(model * vec4(position, 1.0f));
    Normal = mat3(transpose(inverse(model))) * normal;  
    TexCoords = texCoords;

and this is the simulated computation on cpp file. I dont know if this is right



        glm::vec4  ff = model * (glm::vec4(0.5f, -0.5f, -0.5f, 1.0f));                  // the Fragpos  computation in vertex shader
        float lightcutoff = glm::cos(glm::radians(4.5f));                                    // outer cutoff
        float cutoff = glm::cos(glm::radians(5.5f));                                          // inner cutoff
        float epsi = glm::cos(cutoff - lightcutoff);                                            // epsilon
        glm::vec3 ll = glm::normalize(camera.Position - glm::vec3(ff));         // the  vec3 lightDir computation in fragment shader
        float thetaa = glm::dot(ll, glm::normalize(camera.Front));                  // the theta
        float intensit = (thetaa - lightcutoff) / epsi;                                          // intensity
        cout << glm::normalize(intensit) << endl;                                           // ouputing the value

Does GLSL do some computations inside the shader that is kind of hidden? cause even if I change the lightoutercutoff to make it bigger, let say 10.5f, than the inner cutoff, I just keep getting -1 as a result. meaning it will always be black. and that's confusing because it should have been the lit part and should be between 0 and 1 but not totally 0. could be 0.something.

is there something missingon my simulated computation? or is it all wrong?

This is when outer cutoff is bigger than inner cutoff

problem_2.jpg

and this is when outer cutoff is lower inner cutoff

problem1.jpg

I use a different way, simpler for the artist, here the shader code :


struct SPOT_LIGHT
{
  float3 Position;
  float Cutoff;
  float3 Direction;
  float Exponent;
  float3 Color;
  float Intensity;
  float StartAttenuation;
  float EndAttenuation;
};

void Spot( in SURFACE_DATA SurfaceData, in SPOT_LIGHT Light, inout float3 Result )
{
  float3 LightDirection = Light.Position - SurfaceData.Position;
  float d = length( LightDirection );
  LightDirection /= d;
  float SdotL = dot( -LightDirection, Light.Direction );
  if( SdotL > cos( Light.Cutoff ) )
  {
    float NdotL = max( 0.0f, dot( SurfaceData.Normal, LightDirection ) );
    if( NdotL > 0.0f )
    {
      // Compute the specular factor.
      float3 SpecFactor = ComputeSpecFactor( SurfaceData, LightDirection, NdotL );
      
      // Compute the attenuation factor.
      float Attenuation = smoothstep( Light.EndAttenuation, Light.StartAttenuation, d );
      Attenuation *= pow( abs( SdotL ), Light.Exponent );
      
      // Accumulate the light results.
      Result += Light.Intensity * Light.Color * (SurfaceData.DiffuseColor * NdotL + SpecFactor) * Attenuation;
    }
  }
}

You can send cos( Light.Cutoff ) directly to avoid to compute it for each pixel.

Cutoff is the angle and Exponent is used for the radial attenuation.

This topic is closed to new replies.

Advertisement