PDA

View Full Version : CG texturing problem



enmaniac
11-05-2005, 10:30 AM
Hi! I wrote vertex and fragment shader to texture a planet in the way that bright side is of another texture than dark one. The light is at the same position all the time.
The planet rotates around its axis. Everything is fine except that bright side rotates with the planet!!!! I am not sure where is the problem.

Here is a screen shot to illustrate the problem:

http://www.republika.pl/enmaniac/images/textureproblem0.JPG

The shaders are:


// VERTEX SHADER

struct VertexIn
{
float4 position : POSITION;
float4 color : COLOR;
float3 vNormal : NORMAL;

float2 texCoord : TEXCOORD0;

const uniform float4x4 modelViewProjMatrix;
const uniform float3 vLightPosition;
};

struct VertexOut
{
float4 position : POSITION;
float4 color : COLOR;
float2 texCoord : TEXCOORD0;

float3 vLightVector : TEXCOORD1;
float3 vNormalVector : TEXCOORD2;
};

VertexOut main(VertexIn In)
{
VertexOut Out;

Out.position = mul( In.modelViewProjMatrix, In.position );
Out.color = In.color;
Out.texCoord = In.texCoord;

Out.vLightVector = normalize( In.vLightPosition-Out.position.xyz );

Out.vNormalVector = In.vNormal;

return Out;
}

// PIXEL SHADER
struct FragmentIn
{
float4 color : COLOR;

float3 vLightVector : TEXCOORD1;
float3 vNormalVector : TEXCOORD2;

float2 texCoord : TEXCOORD0;

uniform sampler2D textureLight : TEXUNIT0;
uniform sampler2D textureDark : TEXUNIT1;
};

struct FragmentOut
{
float4 color : COLOR;
};

FragmentOut main(FragmentIn In)
{
FragmentOut Out;

float lightCoeff = dot( In.vNormalVector, In.vLightVector );

float4 brightSample = tex2D( In.textureLight, In.texCoord );
float4 darkSample = tex2D( In.textureDark, In.texCoord );

Out.color = lerp (darkSample, brightSample * max(lightCoeff, 0), lightCoeff * 0.5 + 0.5);

return Out;
}

enmaniac
11-06-2005, 04:21 AM
OK it seems I forgot about rotating the normals in vertex shader. But still I cannot fix the prob. When I rotate the normals the light side of the planet dissapears at all :-(

My new vertext program looks this:

struct VertexIn
{
float4 position : POSITION;
float4 color : COLOR;
float3 vNormal : NORMAL;

float2 texCoord : TEXCOORD0;

const uniform float4x4 rotationMatrix;
const uniform float4x4 modelViewProjMatrix;
const uniform float3 vLightPosition;
};


struct VertexOut
{
float4 position : POSITION;
float4 color : COLOR;
float2 texCoord : TEXCOORD0;

float3 vLightVector : TEXCOORD1;
float3 vNormalVector : TEXCOORD2;
};


VertexOut main(VertexIn In)
{
VertexOut Out;

Out.position = mul( In.modelViewProjMatrix, In.position );
Out.color = In.color;
Out.texCoord = In.texCoord;

Out.vLightVector = normalize( In.vLightPosition-In.position.xyz );

float4 norm = float4( In.vNormal.x, In.vNormal.y, In.vNormal.z, 1 );

// Out.vNormalVector = In.vNormal;
Out.vNormalVector = normalize( mul( In.rotationMatrix, norm ) ).xyz;

return Out;
} Anyone can help ?
Thx in advance

rgpc
11-06-2005, 04:27 AM
The "obvious" solution would be to apply the inverse rotation of the planet around it's axis to the modelview matrix before you draw the "glow". Either apply the same rotation (with the angle negated) or pop the rotation off the matrix (if you do the axis rotation on it's own when drawing the planet).

The other solution is to transform the Normal vector. IIRC (no doubt someone will correct me if I'm wrong) you have to multiply the Normal Vector by the inverse of the modelView matrix.

The reason you are getting the problem you are getting is you are rotating the vertex - but still using the original Normal. So point A - which in it's home location has a normal that points directly at the Sun is then rotated around the "dark side" - but it's normal still points directly at the sun - so it will be bright.

enmaniac
11-06-2005, 05:05 AM
I have tried multiplying normal vector by inverse of modelview matrix but it didnt work. I also tried to multiply the vector by rotation matrix (which holds only the rotation along main axis). I use this matrix to rotate the globe too. Unfortunately it didnt work either :-/ grrrrr...

Where is the catch ? Am I missing sth ?