[osg-users] textures and shader
Andreas Goebel
a-goebel at gmx.de
Mon Nov 5 06:51:03 PST 2007
> "Normal" textures display correctly, but the shadow simply does not appear.
>
> Regards,
>
> Andreas
>
Hi,
I have solved this. The textur-coordinates for the shadow-texture are
generated with texGen, so the vertex-shader has to simulate that.
I use the following vertex-shader (which is based on a shader generated
by ShaderGen):
--------------------------------------shader begin
/*******************************************************
* Fixed.vert Fixed Function Equivalent Vertex Shader *
* Automatically Generated by 3Dlabs GLSL ShaderGen *
* http://developer.3dlabs.com *
*******************************************************/
varying vec4 Ambient;
vec4 Diffuse;
vec4 Specular;
varying vec4 Ambient2;
void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)
{
float nDotVP; // normal . light direction
float nDotHV; // normal . light half vector
float pf; // power factor
float attenuation; // computed attenuation factor
float d; // distance from surface to light source
vec3 VP; // direction from surface to light position
vec3 halfVector; // direction of maximum highlights
// Compute vector from surface to light position
VP = vec3 (gl_LightSource[i].position) - ecPosition3;
// Compute distance between surface and light position
d = length(VP);
// Normalize the vector from surface to light position
VP = normalize(VP);
// Compute attenuation
attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * d +
gl_LightSource[i].quadraticAttenuation * d * d);
halfVector = normalize(VP + eye);
nDotVP = max(0.0, dot(normal, VP));
nDotHV = max(0.0, dot(normal, halfVector));
if (nDotVP == 0.0)
{
pf = 0.0;
}
else
{
pf = pow(nDotHV, gl_FrontMaterial.shininess);
}
Ambient += gl_LightSource[i].ambient * attenuation;
Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;
Specular += gl_LightSource[i].specular * pf * attenuation;
}
vec3 fnormal(void)
{
//Compute the normal
vec3 normal = gl_NormalMatrix * gl_Normal;
normal = normalize(normal);
return normal;
}
void ftexgen(in vec3 normal, in vec4 ecPosition)
{
vec4 vertex = gl_ModelViewMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1].s = dot( ecPosition, gl_EyePlaneS[1] );
gl_TexCoord[1].t = dot( ecPosition, gl_EyePlaneT[1] );
gl_TexCoord[1].p = dot( ecPosition, gl_EyePlaneR[1] );
gl_TexCoord[1].q = dot( ecPosition, gl_EyePlaneQ[1] );
}
void flight(in vec3 normal, in vec4 ecPosition, float alphaFade)
{
vec4 color;
vec3 ecPosition3;
vec3 eye;
ecPosition3 = (vec3 (ecPosition)) / ecPosition.w;
eye = vec3 (0.0, 0.0, 1.0);
// Clear the light intensity accumulators
Ambient = vec4 (0.0);
Diffuse = vec4 (0.0);
Specular = vec4 (0.0);
pointLight(0, normal, eye, ecPosition3);
color = gl_FrontLightModelProduct.sceneColor +
Ambient * gl_FrontMaterial.ambient +
Diffuse * gl_FrontMaterial.diffuse;
color += Specular * gl_FrontMaterial.specular;
color = clamp( color, 0.0, 1.0 );
gl_FrontColor = color;
Ambient2 = gl_FrontLightModelProduct.sceneColor +
Ambient * gl_FrontMaterial.ambient;
gl_FrontColor.a *= alphaFade;
}
void main (void)
{
vec3 transformedNormal;
float alphaFade = 1.0;
// Eye-coordinate position of vertex, needed in various calculations
vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
// Do fixed functionality vertex transform
gl_Position = ftransform();
transformedNormal = fnormal();
if (dot(transformedNormal,vec3(0.0, 0.0, 1.0) )<0.0)
transformedNormal = -1.0*transformedNormal;
flight(transformedNormal, ecPosition, alphaFade);
ftexgen(transformedNormal, ecPosition);
}
------------------------------shader end
The relevant part for you is the ftexgen-function.
In the fragment shader I use the ambient2-color for the shadow, which
then fits nicely to the rest of the scene. In the shader I simulate
two-sided lighting by turning the normal towards the user:
if (dot(transformedNormal,vec3(0.0, 0.0, 1.0) )<0.0)
transformedNormal = -1.0*transformedNormal;
This doesn´t give perfect results due to perspective. If someone has a
better idea here, please tell me.
Of course this shader only works if the shadowtexture uses texture-unit 1.
Regards,
Andreas
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
More information about the osg-users
mailing list