4 light normalmapping for animated meshes [C++/GLSL]
-
- Posts: 219
- Joined: Fri Feb 19, 2010 4:03 pm
- Location: Estonia
Try this.
vertex program
pixel program
vertex program
Code: Select all
float4x4 matWorldInverse;
float4x4 ModelViewMatrix;
float4x4 ModelViewProjectionMatrix;
float3 fvLightPosition1;
float3 fvLightPosition2;
float3 fvLightPosition3;
float3 fvLightPosition4;
float fLightStrength1;
float fLightStrength2;
float fLightStrength3;
float fLightStrength4;
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection1 : TEXCOORD2;
float3 LightDirection2 : TEXCOORD3;
float3 LightDirection3 : TEXCOORD4;
float3 LightDirection4 : TEXCOORD5;
float4 LightDistMultiplier : TEXCOORD6;
};
float getLengthSQR (float3 vec)
{
return(vec.x*vec.x+vec.y*vec.y+vec.z*vec.z);
}
struct VS_INPUT
{
float3 Position : POSITION0;
float3 Normal : NORMAL;
float2 Texcoord : TEXCOORD0;
};
VS_OUTPUT vertexMain( in VS_INPUT IN )
{
VS_OUTPUT OUT = (VS_OUTPUT)0;
// common output
OUT.Position = mul(float4(IN.Position,1.0), ModelViewProjectionMatrix);
OUT.Texcoord = IN.Texcoord;
float4x4 LightTransform= ModelViewMatrix;
LightTransform= mul(matWorldInverse, LightTransform);
float4 fvObjectPosition = mul(float4(IN.Position,1.0), ModelViewProjectionMatrix);
float4 fvLightPos1 = mul(float4(fvLightPosition1,1.0), LightTransform);
float4 fvLightPos2 = mul(float4(fvLightPosition2,1.0), LightTransform);
float4 fvLightPos3 = mul(float4(fvLightPosition3,1.0), LightTransform);
float4 fvLightPos4 = mul(float4(fvLightPosition4,1.0), LightTransform);
float3 fvViewDirection = - fvObjectPosition.xyz;
float3 fvLightDirection1 = (fvLightPos1.xyz - fvObjectPosition.xyz);
float3 fvLightDirection2 = (fvLightPos2.xyz - fvObjectPosition.xyz);
float3 fvLightDirection3 = (fvLightPos3.xyz - fvObjectPosition.xyz);
float3 fvLightDirection4 = (fvLightPos4.xyz - fvObjectPosition.xyz);
OUT.LightDistMultiplier[0]=1.0/(getLengthSQR (fvLightDirection1)/(fLightStrength1*10000.0));
OUT.LightDistMultiplier[1]=1.0/(getLengthSQR (fvLightDirection2)/(fLightStrength2*10000.0));
OUT.LightDistMultiplier[2]=1.0/(getLengthSQR (fvLightDirection3)/(fLightStrength3*10000.0));
OUT.LightDistMultiplier[3]=1.0/(getLengthSQR (fvLightDirection4)/(fLightStrength4*10000.0));
float3 fvTangent = -float3(abs(IN.Normal.y) + abs(IN.Normal.z), abs(IN.Normal.x), 0);
float3 fvBinormal = cross(fvTangent,IN.Normal);
float3 fvNormal = mul(IN.Normal, ModelViewMatrix);
fvTangent = mul( cross(fvBinormal, IN.Normal), ModelViewMatrix );
fvBinormal = mul( fvBinormal, ModelViewMatrix );
OUT.ViewDirection.x = dot( fvTangent, fvViewDirection );
OUT.ViewDirection.y = dot( fvBinormal, fvViewDirection );
OUT.ViewDirection.z = dot( fvNormal, fvViewDirection );
OUT.LightDirection1.x = dot( fvTangent, fvLightDirection1.xyz );
OUT.LightDirection1.y = dot( fvBinormal, fvLightDirection1.xyz );
OUT.LightDirection1.z = dot( fvNormal, fvLightDirection1.xyz );
OUT.LightDirection2.x = dot( fvTangent, fvLightDirection2.xyz );
OUT.LightDirection2.y = dot( fvBinormal, fvLightDirection2.xyz );
OUT.LightDirection2.z = dot( fvNormal, fvLightDirection2.xyz );
OUT.LightDirection3.x = dot( fvTangent, fvLightDirection3.xyz );
OUT.LightDirection3.y = dot( fvBinormal, fvLightDirection3.xyz );
OUT.LightDirection3.z = dot( fvNormal, fvLightDirection3.xyz );
OUT.LightDirection4.x = dot( fvTangent, fvLightDirection4.xyz );
OUT.LightDirection4.y = dot( fvBinormal, fvLightDirection4.xyz );
OUT.LightDirection4.z = dot( fvNormal, fvLightDirection4.xyz );
return OUT;
}
Code: Select all
float4 fvAmbient;
float4 fvLight1Color;
float4 fvLight2Color;
float4 fvLight3Color;
float4 fvLight4Color;
float fSpecularPower;
float fSpecularStrength;
float fBumpStrength;
sampler2D baseMap : register(s0);
sampler2D bumpMap : register(s1);
struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection1 : TEXCOORD2;
float3 LightDirection2 : TEXCOORD3;
float3 LightDirection3 : TEXCOORD4;
float3 LightDirection4 : TEXCOORD5;
float4 LightDistMultiplier : TEXCOORD6;
};
float4 pixelMain( in PS_INPUT IN ) : COLOR
{
float4 color = float4(0,0,0,0);
float3 fvLightDirection1 = normalize( IN.LightDirection1 );
float3 fvLightDirection2 = normalize( IN.LightDirection2 );
float3 fvLightDirection3 = normalize( IN.LightDirection3 );
float3 fvLightDirection4 = normalize( IN.LightDirection4 );
float3 fvNormal = tex2D( bumpMap, IN.Texcoord ).yxz;
fvNormal.xy*=2.0;
fvNormal.xy-=1.0;
fvNormal=(float3(0.0,0.0,1.0)-fvNormal)*fBumpStrength+fvNormal;
fvNormal=normalize(fvNormal);
float fNDotL1 = max(dot(fvNormal, fvLightDirection1),0.0)-0.1;
float fNDotL2 = max(dot(fvNormal, fvLightDirection2),0.0)-0.1;
float fNDotL3 = max(dot(fvNormal, fvLightDirection3),0.0)-0.1;
float fNDotL4 = max(dot(fvNormal, fvLightDirection4),0.0)-0.1;
float3 fvReflection1 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection1 );
float3 fvReflection2 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection2 );
float3 fvReflection3 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection3 );
float3 fvReflection4 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection4 );
float3 fvViewDirection = normalize( IN.ViewDirection );
float fRDotV1 = max( 0.0, dot( fvReflection1, fvViewDirection ) );
float fRDotV2 = max( 0.0, dot( fvReflection2, fvViewDirection ) );
float fRDotV3 = max( 0.0, dot( fvReflection3, fvViewDirection ) );
float fRDotV4 = max( 0.0, dot( fvReflection4, fvViewDirection ) );
float4 fvBaseColor = tex2D( baseMap, IN.Texcoord );
float4 fvTotalAmbient = fvAmbient * fvBaseColor;
float4 fvTotalDiffuse = fvLight1Color * fNDotL1* fvBaseColor*IN.LightDistMultiplier[0];
float4 fvTotalSpecular = fNDotL1*fvLight1Color * ( pow( fRDotV1, fSpecularPower ) )*IN.LightDistMultiplier[0];
fvTotalDiffuse += fvLight2Color * fNDotL2* fvBaseColor*IN.LightDistMultiplier[1];
fvTotalSpecular += fNDotL2*fvLight2Color * ( pow( fRDotV2, fSpecularPower ) )*IN.LightDistMultiplier[1];
fvTotalDiffuse += fvLight3Color * fNDotL3* fvBaseColor*IN.LightDistMultiplier[2];
fvTotalSpecular += fNDotL3*fvLight3Color * ( pow( fRDotV3, fSpecularPower ) )*IN.LightDistMultiplier[2];
fvTotalDiffuse += fvLight4Color * fNDotL4* fvBaseColor*IN.LightDistMultiplier[3];
fvTotalSpecular += fNDotL4*fvLight4Color * ( pow( fRDotV4, fSpecularPower ) )*IN.LightDistMultiplier[3];
color=( fvTotalAmbient + fvTotalDiffuse+ (fvTotalSpecular*fSpecularStrength));
if(color.r>1.0){color.gb+=color.r-1.0;}
if(color.g>1.0){color.rb+=color.g-1.0;}
if(color.b>1.0){color.rg+=color.b-1.0;}
return color;
}
hello, please help me with the directx version callback
here is my code :
i dont know how to set the "ModelViewMatrix" and the "ModelViewProjectionMatrix" variable.
here is my code :
Code: Select all
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
//int var0=0;
// services->setPixelShaderConstant("baseMap", (float*)(&var0), 1); //the colormap
// int var1=1;
// services->setPixelShaderConstant("bumpMap", (float*)(&var1), 1); //the normalmap
core::matrix4 invWorld = services->getVideoDriver()->getTransform(video::ETS_WORLD);
invWorld.makeInverse();
services->setVertexShaderConstant("matWorldInverse", (float*)(&invWorld), 16);
core::matrix4 ModelViewMatrix = services->getVideoDriver()->getTransform(video::ETS_VIEW);
ModelViewMatrix.makeInverse();
services->setVertexShaderConstant("ModelViewMatrix", (float*)(&ModelViewMatrix), 16);
core::matrix4 worldViewProj;
worldViewProj = services->getVideoDriver()->getTransform(video::ETS_PROJECTION);
worldViewProj *= services->getVideoDriver()->getTransform(video::ETS_VIEW);
worldViewProj *= services->getVideoDriver()->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("ModelViewProjectionMatrix", (float*)(&worldViewProj), 16);
services->setVertexShaderConstant("fLightStrength1", (float*)(&fLightStrength[0]), 1);
services->setVertexShaderConstant("fLightStrength2", (float*)(&fLightStrength[1]), 1);
services->setVertexShaderConstant("fLightStrength3", (float*)(&fLightStrength[2]), 1);
services->setVertexShaderConstant("fLightStrength4", (float*)(&fLightStrength[3]), 1);
services->setVertexShaderConstant("fvLightPosition1", (float*)(&fvLightPosition[0]), 3);
services->setVertexShaderConstant("fvLightPosition2", (float*)(&fvLightPosition[1]), 3);
services->setVertexShaderConstant("fvLightPosition3", (float*)(&fvLightPosition[2]), 3);
services->setVertexShaderConstant("fvLightPosition4", (float*)(&fvLightPosition[3]), 3);
services->setPixelShaderConstant("fvAmbient", (float*)(&fvAmbient), 4);
services->setPixelShaderConstant("fvLight1Color", (float*)(&fvLightColor[0]), 4);
services->setPixelShaderConstant("fvLight2Color", (float*)(&fvLightColor[1]), 4);
services->setPixelShaderConstant("fvLight3Color", (float*)(&fvLightColor[2]), 4);
services->setPixelShaderConstant("fvLight4Color", (float*)(&fvLightColor[3]), 4);
services->setPixelShaderConstant("fSpecularPower", (float*)(&fSpecularPower), 1);
services->setPixelShaderConstant("fSpecularStrength", (float*)(&fSpecularStrength), 1);
services->setPixelShaderConstant("fBumpStrength", (float*)(&fBumpStrength), 1);
}
};
Code: Select all
matrix4 ModelViewProjectionMatrix;
ModelViewProjectionMatrix = driver->getTransform(ETS_PROJECTION);
ModelViewProjectionMatrix *= driver->getTransform(ETS_VIEW);
ModelViewProjectionMatrix *= driver->getTransform(ETS_WORLD);
services->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16);
matrix4 ModelViewMatrix;
ModelViewMatrix = driver->getTransform(ETS_VIEW);
ModelViewMatrix *= driver->getTransform(ETS_WORLD);
services->setVertexShaderConstant("ModelViewMatrix", ModelViewMatrix.pointer(), 16);
The shader in the first page should be marked as "deprecated"
The tangents and binormals are currently passed to the shaders, even in the animated meshes, and they are correctly calculated inside the engine.
They are passed in TEXCOORD1 (the tangent) and TEXCOORD2 (the binormal), instead of the expected semantics TANGENT0 and BINORMAL0, and they are also passed to animated meshes (though their processing isn't correct ATM, the tangents and binormals should be animated too, and they aren't)
IN HLSL, in the vertex definition the tangents and binormals are there:
So, this 4 lights shader would look like this in the vertex shader:
And the pixel shader remains the same.
The tangents and binormals are currently passed to the shaders, even in the animated meshes, and they are correctly calculated inside the engine.
They are passed in TEXCOORD1 (the tangent) and TEXCOORD2 (the binormal), instead of the expected semantics TANGENT0 and BINORMAL0, and they are also passed to animated meshes (though their processing isn't correct ATM, the tangents and binormals should be animated too, and they aren't)
IN HLSL, in the vertex definition the tangents and binormals are there:
Code: Select all
...
float3 tangent :TEXCOORD1;
float3 binormal :TEXCOORD2;
...
Code: Select all
float4x4 matWorldInverse;
float4x4 ModelViewMatrix;
float4x4 ModelViewProjectionMatrix;
float3 fvLightPosition1;
float3 fvLightPosition2;
float3 fvLightPosition3;
float3 fvLightPosition4;
float fLightStrength1;
float fLightStrength2;
float fLightStrength3;
float fLightStrength4;
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection1 : TEXCOORD2;
float3 LightDirection2 : TEXCOORD3;
float3 LightDirection3 : TEXCOORD4;
float3 LightDirection4 : TEXCOORD5;
float4 LightDistMultiplier : TEXCOORD6;
};
float getLengthSQR (float3 vec)
{
return(vec.x*vec.x+vec.y*vec.y+vec.z*vec.z);
}
struct VS_INPUT
{
float3 Position : POSITION0;
float3 Normal : NORMAL;
float2 Texcoord : TEXCOORD0;
float3 Tangent :TEXCOORD1;
float3 Binormal :TEXCOORD2;
};
VS_OUTPUT vertexMain( in VS_INPUT IN )
{
VS_OUTPUT OUT = (VS_OUTPUT)0;
// common output
OUT.Position = mul(float4(IN.Position,1.0), ModelViewProjectionMatrix);
OUT.Texcoord = IN.Texcoord;
float4x4 LightTransform= ModelViewMatrix;
LightTransform= mul(matWorldInverse, LightTransform);
float4 fvObjectPosition = mul(float4(IN.Position,1.0), ModelViewProjectionMatrix);
float4 fvLightPos1 = mul(float4(fvLightPosition1,1.0), LightTransform);
float4 fvLightPos2 = mul(float4(fvLightPosition2,1.0), LightTransform);
float4 fvLightPos3 = mul(float4(fvLightPosition3,1.0), LightTransform);
float4 fvLightPos4 = mul(float4(fvLightPosition4,1.0), LightTransform);
float3 fvViewDirection = - fvObjectPosition.xyz;
float3 fvLightDirection1 = (fvLightPos1.xyz - fvObjectPosition.xyz);
float3 fvLightDirection2 = (fvLightPos2.xyz - fvObjectPosition.xyz);
float3 fvLightDirection3 = (fvLightPos3.xyz - fvObjectPosition.xyz);
float3 fvLightDirection4 = (fvLightPos4.xyz - fvObjectPosition.xyz);
OUT.LightDistMultiplier[0]=1.0/(getLengthSQR (fvLightDirection1)/(fLightStrength1*10000.0));
OUT.LightDistMultiplier[1]=1.0/(getLengthSQR (fvLightDirection2)/(fLightStrength2*10000.0));
OUT.LightDistMultiplier[2]=1.0/(getLengthSQR (fvLightDirection3)/(fLightStrength3*10000.0));
OUT.LightDistMultiplier[3]=1.0/(getLengthSQR (fvLightDirection4)/(fLightStrength4*10000.0));
float3 fvTangent = mul(IN.tangent,ModelViewMatrix);
float3 fvBinormal = mul(IN.binormal,ModelViewMatrix);
float3 fvNormal = mul(IN.Normal, ModelViewMatrix);
OUT.ViewDirection.x = dot( fvTangent, fvViewDirection );
OUT.ViewDirection.y = dot( fvBinormal, fvViewDirection );
OUT.ViewDirection.z = dot( fvNormal, fvViewDirection );
OUT.LightDirection1.x = dot( fvTangent, fvLightDirection1.xyz );
OUT.LightDirection1.y = dot( fvBinormal, fvLightDirection1.xyz );
OUT.LightDirection1.z = dot( fvNormal, fvLightDirection1.xyz );
OUT.LightDirection2.x = dot( fvTangent, fvLightDirection2.xyz );
OUT.LightDirection2.y = dot( fvBinormal, fvLightDirection2.xyz );
OUT.LightDirection2.z = dot( fvNormal, fvLightDirection2.xyz );
OUT.LightDirection3.x = dot( fvTangent, fvLightDirection3.xyz );
OUT.LightDirection3.y = dot( fvBinormal, fvLightDirection3.xyz );
OUT.LightDirection3.z = dot( fvNormal, fvLightDirection3.xyz );
OUT.LightDirection4.x = dot( fvTangent, fvLightDirection4.xyz );
OUT.LightDirection4.y = dot( fvBinormal, fvLightDirection4.xyz );
OUT.LightDirection4.z = dot( fvNormal, fvLightDirection4.xyz );
return OUT;
}
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
-
- Posts: 758
- Joined: Mon Mar 31, 2008 3:32 pm
- Location: Bulgaria
Since you have:
should be:
Code: Select all
struct VS_INPUT
{
(...)
float3 Tangent :TEXCOORD1;
float3 Binormal :TEXCOORD2;
};
Code: Select all
float3 fvTangent = mul(IN.tangent,ModelViewMatrix);
float3 fvBinormal = mul(IN.binormal,ModelViewMatrix);
Code: Select all
float3 fvTangent = mul(IN.Tangent,ModelViewMatrix);
float3 fvBinormal = mul(IN.Binormal,ModelViewMatrix);
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
-
- Posts: 758
- Joined: Mon Mar 31, 2008 3:32 pm
- Location: Bulgaria
Either name is correct at any case, it is a complementary vector to the tangent and the normal vectors to create the tangent space, so, it really doesn't matter how you name it. In spanish, for instance, the name is binormal, not bitangent.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Is it really correct? Consider a plane; It consists of one normal and two tangents. Two normals for a plane just doesn't make any sense.
If we were to consider a line instead, there's one tangent and two normals. The name binormal makes sense then, but a bitangent would make no sense at all.
(I suppose there might be more normals for a surface in higher dimensions, don't know anything about that)
If we were to consider a line instead, there's one tangent and two normals. The name binormal makes sense then, but a bitangent would make no sense at all.
(I suppose there might be more normals for a surface in higher dimensions, don't know anything about that)
According to wikipedia, this is a "bitangent"
http://en.wikipedia.org/wiki/Bitangent
But then, you find things like this:
http://mathworld.wolfram.com/BitangentVector.html
So i am really confused now...
http://en.wikipedia.org/wiki/Bitangent
But then, you find things like this:
http://mathworld.wolfram.com/BitangentVector.html
So i am really confused now...
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt