Lighting shader

There is my simple lighting shader working with directional light. And i have a problem, that from any point of view 3d objects so bright, as when camera viewing in the direction close to light vector.



Vertex shader

[java]uniform mat4 g_WorldViewProjectionMatrix;

uniform mat4 g_WorldViewMatrix;

uniform mat4 g_ViewMatrix;

uniform mat3 g_NormalMatrix;

uniform vec4 g_LightPosition;



varying vec2 texCoord;

varying vec3 tbnDirToLight;

varying vec3 tbnHalfVector;



attribute vec3 inPosition;

attribute vec3 inNormal;

attribute vec3 inTangent;

attribute vec2 inTexCoord;



void main(void)

{

vec4 pos = vec4(inPosition, 1.0);

gl_Position = g_WorldViewProjectionMatrix * pos;

texCoord = inTexCoord;



vec3 wvPosition = (g_WorldViewMatrix * pos).xyz;

vec3 wvNormal = normalize(g_NormalMatrix * inNormal);

vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);

vec3 wvBinormal = cross(wvNormal, wvTangent);



vec3 wvDirToEye = -wvPosition;

vec3 wvDirToLight = (g_ViewMatrix * vec4(g_LightPosition.xyz, 0)).xyz;

wvDirToLight *= -1;



vec3 tbnDirToEye;

tbnDirToEye.x = dot(wvDirToEye, wvTangent);

tbnDirToEye.y = dot(wvDirToEye, wvBinormal);

tbnDirToEye.z = dot(wvDirToEye, wvNormal);



tbnDirToLight.x = dot(wvDirToLight, wvTangent);

tbnDirToLight.y = dot(wvDirToLight, wvBinormal);

tbnDirToLight.z = dot(wvDirToLight, wvNormal);



tbnHalfVector = normalize(tbnDirToEye + tbnDirToLight);

}[/java]



Fragment shader

[java]uniform vec4 m_MetalColor;

uniform float m_SpecularPower;

uniform float m_CorrectionPower;



uniform sampler2D m_NormalMap;



varying vec2 texCoord;

varying vec3 tbnHalfVector;



void main(void)

{

vec4 baseColor = m_MetalColor;

vec3 normal = normalize((texture2D(m_NormalMap, texCoord).xyz * 2.0) - 1.0);



vec4 ambient = vec4(0, 0, 0, 0);



vec3 tbnNormHalfVector = normalize(tbnHalfVector);

float diffuseIntensity = max(dot(tbnNormHalfVector, normal), 0.0);

diffuseIntensity = pow(diffuseIntensity, m_CorrectionPower * 2);

vec4 diffuse = diffuseIntensity * baseColor;



gl_FragColor = ambient + diffuse;

}[/java]

No one can help? Ok, that’s another example. I’ve tried to implement simple lighting in RenderMonkey. The core problem is the same (object is bright from any point of view).



Vertex

[java]uniform vec3 fvLightPosition;

uniform vec3 fvEyePosition;

uniform float fSpecularPower;

uniform vec4 fvAmbient, fvDiffuse, fvSpecular;



varying vec4 color;



void main(void)

{

gl_Position = ftransform();

vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz;

vec3 normal = gl_NormalMatrix * gl_Normal;

normal = normalize(normal);

vec3 toEye = normalize(-pos);

vec3 lightDir = normalize(pos - fvLightPosition);

vec3 r = reflect(lightDir, normal);

float t = pow(max(dot(r, toEye), 0.0f), fSpecularPower);

float s = max(dot(-lightDir, normal), 0.0f);

vec3 spec = t*(fvSpecular).rgb;

vec3 diffuse = s*(fvDiffuse).rgb;

vec3 ambient = fvAmbient.rgb;

color.rgb = ambient + diffuse + spec;

}[/java]



Fragment

[java]varying vec4 color;



void main(void)

{

gl_FragColor = color;

}[/java]



Result (in RenderMonkey)

gl_FragColor = ambient * diffuse + diffuse * LIGHTVECTOR;



possibly something like this?



Edited:

Also don’t forget about specular Shininess (the size of specular).





Edited2:

ambient = 0.0; - by default to get only light shading.

with changes to fragment shader

[java]varying vec3 toEye;

varying vec3 lightDir;

varying vec4 color;



void main(void)

{

gl_FragColor = color * max(dot(normalize(toEye), normalize(-lightDir)),0.0);

}[/java]

Result is the same (bright from any direction, but now overall light intensity is little lower)

Have a look at the default Lighting shader. Generally, you will need for basic lighting without specularity:





light = max(0.0, dot(normal, vLightDir));



gl_FragColor = diffuseColor * light.x;





But this is very roughly. Without any light attenuation. :stuck_out_tongue:

Ok, man from GameDev helped me. Silly mistake was in that i forgot to convert light direction vector to view space and normalize toEye and toLight vectors before calculating half vector.

Cool. Sorry, i’m not good in shader language.

1 Like

By the way if you are interested in improved lighting shader:



Guys, I finished material improvements. I hope you will like it.

All features:

  • Improved lighting calculations.
  • Improved reflection calculations.
  • Reflection map implementation with normal map alpha.
  • Improved Minnaert calculations.
  • Image Based Lighting with Albedo.
  • Emissive map implementation with diffuse alpha.
  • normalization of normals by default.
  • Specular map implementation with normal map alpha.
  • Specular intensity implementation.
  • Switching -x/-y/-z normals for different normal maps (3dmax, blender, xnormal have different approaches).
  • Clamping diffuseColor and specularColor by default (to get only (0.0, 1.0) intensity).
  • Hemispherical lighting.
  • “Specular Color” now can be used for specular maps too.
  • “No attenuation” switches off att parameter. Increase fps a bit,
  • AphaMap is renamed to Alpha_A_Dif. it uses diffuse alpha channel.
  • USE_REFLECTION is renamed to REFLECTION.



    My little video introduction to the features:

    http://www.youtube.com/watch?v=knROh_3o2uo



I'll write full description soon..

The code is downloadable from:
http://code.google.com/p/jme-glsl-shaders/downloads/list - entire JMP project.

If someone wants to change something or share with his thoughts, so you are welcome.

Future features which i did not make:
- Using Emissive map as Glow Map (for glow shader).
- make static Image Based Lighting. Dynamic IBL works like reflection.
- Fog Color based on IBL Map. It was made in Lugaru project and looks cool.

Discussion is here:
http://hub.jmonkeyengine.org/groups/contribution-depot-jme3/forum/topic/lighting-material-improvements-01-specular/?topic_page=3&num=15

hi here check this shader*******
Can this is work or not???
reply please


VERTEX SHADER

[java]//vert
uniform mat4 g_WorldViewProjectionMatrix;

attribute vec3 inPosition;
attribute vec4 inTexCoord;
uniform mat3 g_NormalMatrix;
attribute vec3 inNormal;

varying vec3 normal,halfVector;

void main(){
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
vec3 n = normalize(g_NormalMatrix * inNormal);
normal=n;

halfVector = gl_LightSource[0].halfVector.xyz;

}
[/java]

FRAGMENT SHADER
[java]
/*

  • fragment shader template
    */

varying vec3 normal;
varying vec3 halfVector;

vec4 DirectionalLightOperation( in int i,
in vec3 normal,
vec4 ambient,
vec4 diffuse,
vec4 specular
)
{
float ndotpv;
float ndothv;
float pf;
ndotpv=max(0.0f,dot(normal,normalize(vec3(gl_LightSource[i].position))));
ndothv=max(0.0f,dot(normal,vec3(gl_LightSource[i].halfVector)));
if(ndotpv=0.0f)
pf=0.0f;
else
pf=pow(ndothv,gl_FrontMaterial.shininess);
ambient+=gl_LightSource[i].ambient;
diffuse+=gl_LightSource[i].diffusendotpv;
specular+=gl_LightSource[i].specular
pf;
vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;
return color;
}

/*
As gl_FrontLightModelProduct.sceneColor
Al gl_LightSource[0].ambient
Am gl_FrontMaterial.ambient
Dl gl_LightSource[0].diffuse
Dm gl_FrontMaterial.diffuse
Sl gl_LightSource[0].specular
Sm gl_FrontMaterial.specular
f gl_FrontMaterial.shininess
*/
void main() {
// Set the fragment color for example to gray, alpha 1.0
vec4 ambient = gl_FrontMaterial.ambient ;
vec4 diffuse = gl_FrontMaterial.diffuse ;
vec4 specular= gl_FrontMaterial.specular ;

gl_FragColor = DirectionalLightOperation(0,normal,ambient,diffuse,specular);  

}

[/java]

Can this is work or not please reply???
Directional Light shader

This looks like decaprated api useage. opengl3 does not reall yuse any of the gl_ stuff anymore -> see wiki for materials ans shader infos

Hi friends here , i give a directional lightshader which is run fine…


Vertex Shader
[java]
uniform mat4 g_WorldViewProjectionMatrix;

attribute vec3 inPosition;
attribute vec4 inTexCoord;
uniform mat3 g_NormalMatrix;
attribute vec3 inNormal;

varying vec4 color;
vec4 DirectionalLightOperation( in int i,
in vec3 normal,
vec4 ambient,
vec4 diffuse,
vec4 specular
)
{
float ndotpv;
float ndothv;
float pf;
ndotpv=max(0.0,dot(normal,normalize(vec3(gl_LightSource[i].position))));
ndothv=max(0.0,dot(normal,vec3(gl_LightSource[i].halfVector)));
if(ndotpv==0.0)
pf=0.0;
else
pf=pow(ndothv,gl_FrontMaterial.shininess);
ambient+=gl_LightSource[i].ambient;
diffuse+=gl_LightSource[i].diffusendotpv;
specular+=gl_LightSource[i].specular
pf;
vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;
return color;
}
void main(){
vec3 normal,halfVector;
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
vec3 n = normalize(g_NormalMatrix * inNormal);
normal=n;

halfVector = gl_LightSource[0].halfVector.xyz;
vec4 ambient = gl_FrontMaterial.ambient ;
vec4 diffuse = gl_FrontMaterial.diffuse ;
vec4 specular= gl_FrontMaterial.specular ;

color=DirectionalLightOperation(0,normal,ambient,diffuse,specular);

}
[/java]

Fragment shader
[java]
/*

  • fragment shader template
    */
    varying vec4 color;

/*
As gl_FrontLightModelProduct.sceneColor
Al gl_LightSource[0].ambient
Am gl_FrontMaterial.ambient
Dl gl_LightSource[0].diffuse
Dm gl_FrontMaterial.diffuse
Sl gl_LightSource[0].specular
Sm gl_FrontMaterial.specular
f gl_FrontMaterial.shininess
*/
void main() {
// Set the fragment color for example to gray, alpha 1.0

gl_FragColor = color;

}[/java]

1 Like