Hello,
since several days i try to develop an cg fragment and vertex shader for dot3 based bumpmapping. The shaders looks like working, i got my bumpmapped object, but i’ve problems with the light and shadowing …
Because an Image tells more than thousand words, here is the one:
http://img.photobucket.com/albums/v211/Hellhound_01/shadow.jpg
What you see is a simple object, the object looks like a dot3 bumpmapped object, but the shadows are too sharpen at the edges and when i move the light arround the object often the shadows gets translucent.
The other problem is a lighting problem. When i move a light source arround the object, you can see a “switch” of the texture to the side where the light comes from. I’ve tested the shaders again and again and figured out, that only two states of light are computed. When i place the position of the light on the right side of the object i got the correct lighting of the object from the right side.
When i now move the light position near to the object, normaly the reflection must be more intensive but there is no approximation computed. On the other hand, when i move the light more far a way the object must be lighted darker, but nothing happends …
When i move the light position through the object on the other side, the lighting switches hardly at the “zero” point to the other side.
I’ve no idea what could be wrong. The Light position looks like correct computed in the shader. Has anyone an idea what could be wrong?
I’ve added some additional pictures which shows the lighting failure in more detail (The purple sphere represents the position of the light):
- http://img.photobucket.com/albums/v211/Hellhound_01/rightLight.jpg
- http://img.photobucket.com/albums/v211/Hellhound_01/leftLight.jpg
- http://img.photobucket.com/albums/v211/Hellhound_01/FailureLight.jpg
The last image shows the failure of lighting in detail. I’ve marked the edge of the “texture switch” with red elipses. The lower part shows the texture by lighting from left, the upper part shows the texture by lighting from right…
I think there could be a problem in my calculations, perhaps someone of you could help me …
Here is my vertex shader:
// input structure
struct appl2vert
{
float3 Position : POSITION;
float3 Normal : NORMAL;
float2 TextureCoords : TEXCOORD0;
float3 Tangents : TEXCOORD1;
};
// output structure
struct vert2frag
{
float4 Position : POSITION;
float2 TextureCoords :TEXCOORD0;
float3 TangentSpaceLightPos :TEXCOORD1;
};
void main(const appl2vert IN, out vert2frag OUT,
const uniform float4x4 ModelViewProj,
const uniform float4x4 InvModelViewMatrix,
const uniform float4 LightPos,
)
{
// calculations for rasterizer
OUT.Position = mul(ModelViewProj, float4(IN.Position, 1) );
// get Light form world space to eye space
float4 lightPosOS = mul(InvModelViewMatrix, LightPos);
float3 surface2light = normalize(lightPosOS.xyz - IN.Position.xyz);
// calculate the TangentSpaceMatrix (TBN)
float3 binormal = cross( IN.Normal, IN.Tangents );
float3x3 tbn_matrix = float3x3( IN.Tangents, binormal, IN.Normal );
// get light direction L
OUT.TangentSpaceLightPos = mul(tbn_matrix, surface2light.xyz);
// transfer coords
OUT.TextureCoords = IN.TextureCoords;
}
And here my fragment shader:
// input structure
struct vert2frag
{
float2 TextureCoords:TEXCOORD0;
float3 TangentSpaceLightPos:TEXCOORD1;
};
void main(const vert2frag IN, out float3 oColor:COLOR,
const uniform sampler2D NormalMap,
const uniform sampler2D DecalMap )
{
// normalize Light
float3 normTangentSpaceLightPos = normalize(IN.TangentSpaceLightPos);
// Do Dot3 calculation (N.L) (multiplication for more reflection)
float3 nmap= 2*(tex2D(NormalMap,IN.TextureCoords)-0.5).rgb;
//adding decal color (multiplication for better color results)
oColor = dot(nmap.xyz, normTangentSpaceLightPos)*tex2D(DecalMap,IN.TextureCoords);
}
And here is my openGL code fragment:
// Bind the programs
cgGLBindProgram(m_pCgDot3VertexShader);
cgGLBindProgram(m_pCgDot3FragmentShader);
// Update matrix
cgGLSetStateMatrixParameter(m_cgpMdlViewProjMatrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
cgGLSetStateMatrixParameter(m_cgpInvModelViewMatrix, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE);
// Update Light Pos
cgGLSetParameter4fv(m_cgpLightPos, m_pLightSource->m_pvLightPosition);
// Enable the profiles
cgGLEnableProfile(m_pCgVertexProfile);
cgGLEnableProfile(m_pCgFragmentProfile);
// Set Decal Texture (Param1 TEXCOORDS0 as TextureCoords)
texIter = pDmgLvTexturesToMap->find(CTextureSetElement::TYPE_DECAL);
//Aktivate array for VBOs
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glBindBufferARB( GL_ARRAY_BUFFER_ARB, getGPUTextureOffsetID());
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );
glEnable(GL_TEXTURE_2D);
//Aktivate and bind decaltexture
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, getTextureOffsetID());
// bind texture to fragment-shader
cgGLSetTextureParameter(m_cgpBaseTexture, getTextureOffsetID());
cgGLEnableTextureParameter(m_cgpBaseTexture);
// bind tangents to vertex-shader (Param2 TEXTURECOORDS1)
for (int i=0; i<m_pMeshesToRender->getVertexCount(); i++) {
glMultiTexCoord3fARB(GL_TEXTURE1_ARB, m_pMeshesToRender->m_pvTangents[i].m_fX, m_pMeshesToRender->m_pvTangents[i].m_fY, m_pMeshesToRender->m_pvTangents[i].m_fZ);
}
// bind normal texture to fragment-shader
cgGLSetTextureParameter(m_cgpNormalMapTexture, getNormalTextureOffsetID());
cgGLEnableTextureParameter(m_cgpNormalMapTexture);
I’ve figured out, that my sytem hardly crashes when i use the following sniplet in the OpenGl code instad of the loop with glMultiTexCoord.
m_pIRenderer->glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Tangents
glTexCoordPointer(3, GL_FLOAT, 0, m_pMeshesToRender->m_pvTangents);
Thanks for any help,
Christian