Code:
void LightingVSNormal( float3 posL : POSITION0,
float3 tangentL : TANGENT0,
float3 binormalL : BINORMAL0,
float3 normalL : NORMAL0,
float2 texCoord : TEXCOORD0,
out float4 oPosH : POSITION0,
out float3 oEyeVec : TEXCOORD0,
out float3 oLightVec : TEXCOORD1,
out float2 oTexCoord : TEXCOORD2,
out float3x3 oTBN : TEXCOORD3,
out float3 oToCamObjectSpace : TEXCOORD6)
{
float3x3 TBN;
TBN[0] = tangentL;
TBN[1] = binormalL;
TBN[2] = normalL;
oTBN = TBN;
float3 camPosL = mul( float4(g_camPos, 1.0f), g_matWorldInv );
oToCamObjectSpace = (camPosL - posL);
oEyeVec = mul( TBN, oToCamObjectSpace );
float3 lightDir = mul( float4(g_lightDir, 0.0f), g_matWorldInv );
oLightVec = mul(TBN, lightDir);
oPosH = mul( float4( posL, 1.0f ), g_matWVP );
oTexCoord = texCoord;
}
float4 LightingPSNormal( float3 camVec : TEXCOORD0,
float3 lightVec : TEXCOORD1,
float2 texCoord : TEXCOORD2,
float3x3 TBN : TEXCOORD3,
float3 toCamObjectSpace : TEXCOORD6) : COLOR0
{
camVec = normalize(camVec);
lightVec = normalize(lightVec);
float3 normalT = tex2D(g_samNormal, texCoord);
normalT = 2.0f*normalT - 1.0f;
normalT = normalize(normalT);
float spec = calculateSpecularFactor( lightVec, normalT, camVec );
float diff = calculateDiffuseFactor( -lightVec, normalT );
// reflection
// transformisemo normalu u object space
float3 normalObject = normalize(mul(normalT, TBN));
float3 reflectedColor = 0;
if(g_bReflecting)
{
// racunamo refleksiju u object space
float3 envMapTex = reflect(-normalize(toCamObjectSpace), normalObject);
reflectedColor = texCUBE(g_samEnv, envMapTex);
}
float4 diffuseColor = diff*tex2D(g_samDiffuse, texCoord);
if(g_bReflecting)
{
diffuseColor = float4(g_fReflectivity*reflectedColor, 1.0f) + (1.0f - g_fReflectivity)*diffuseColor;
}
float4 specularColor = diff == 0.0f ? 0.0f : spec*float4(1, 1, 1, 1);
float4 ambientColor = 0.1f*tex2D(g_samDiffuse, texCoord);
float4 glowColor = tex2D(g_samGlow, texCoord);
float4 finalColor = ambientColor + glowColor + diffuseColor + specularColor;
if(g_bSelected == true)
finalColor*=float4(1.0f, 0.1f, 0.1f, 1.0f) + float4(0.5f, 0, 0, 1);
return finalColor;
}
technique techLightingNormal
{
pass p0
{
vertexshader = compile VS_PROFILE LightingVSNormal();
pixelshader = compile PS_PROFILE LightingPSNormal();
}
}
void LightingVSNormal( float3 posL : POSITION0,
float3 tangentL : TANGENT0,
float3 binormalL : BINORMAL0,
float3 normalL : NORMAL0,
float2 texCoord : TEXCOORD0,
out float4 oPosH : POSITION0,
out float3 oEyeVec : TEXCOORD0,
out float3 oLightVec : TEXCOORD1,
out float2 oTexCoord : TEXCOORD2,
out float3x3 oTBN : TEXCOORD3,
out float3 oToCamObjectSpace : TEXCOORD6)
{
float3x3 TBN;
TBN[0] = tangentL;
TBN[1] = binormalL;
TBN[2] = normalL;
oTBN = TBN;
float3 camPosL = mul( float4(g_camPos, 1.0f), g_matWorldInv );
oToCamObjectSpace = (camPosL - posL);
oEyeVec = mul( TBN, oToCamObjectSpace );
float3 lightDir = mul( float4(g_lightDir, 0.0f), g_matWorldInv );
oLightVec = mul(TBN, lightDir);
oPosH = mul( float4( posL, 1.0f ), g_matWVP );
oTexCoord = texCoord;
}
float4 LightingPSNormal( float3 camVec : TEXCOORD0,
float3 lightVec : TEXCOORD1,
float2 texCoord : TEXCOORD2,
float3x3 TBN : TEXCOORD3,
float3 toCamObjectSpace : TEXCOORD6) : COLOR0
{
camVec = normalize(camVec);
lightVec = normalize(lightVec);
float3 normalT = tex2D(g_samNormal, texCoord);
normalT = 2.0f*normalT - 1.0f;
normalT = normalize(normalT);
float spec = calculateSpecularFactor( lightVec, normalT, camVec );
float diff = calculateDiffuseFactor( -lightVec, normalT );
// reflection
// transformisemo normalu u object space
float3 normalObject = normalize(mul(normalT, TBN));
float3 reflectedColor = 0;
if(g_bReflecting)
{
// racunamo refleksiju u object space
float3 envMapTex = reflect(-normalize(toCamObjectSpace), normalObject);
reflectedColor = texCUBE(g_samEnv, envMapTex);
}
float4 diffuseColor = diff*tex2D(g_samDiffuse, texCoord);
if(g_bReflecting)
{
diffuseColor = float4(g_fReflectivity*reflectedColor, 1.0f) + (1.0f - g_fReflectivity)*diffuseColor;
}
float4 specularColor = diff == 0.0f ? 0.0f : spec*float4(1, 1, 1, 1);
float4 ambientColor = 0.1f*tex2D(g_samDiffuse, texCoord);
float4 glowColor = tex2D(g_samGlow, texCoord);
float4 finalColor = ambientColor + glowColor + diffuseColor + specularColor;
if(g_bSelected == true)
finalColor*=float4(1.0f, 0.1f, 0.1f, 1.0f) + float4(0.5f, 0, 0, 1);
return finalColor;
}
technique techLightingNormal
{
pass p0
{
vertexshader = compile VS_PROFILE LightingVSNormal();
pixelshader = compile PS_PROFILE LightingPSNormal();
}
}
Posmatracu sledeci deo koda koji je zaduzen za refleksiju:
Code:
float3 normalObject = normalize(mul(normalT, TBN));
float3 reflectedColor = 0;
if(g_bReflecting)
{
// racunamo refleksiju u object space
float3 envMapTex = reflect(-normalize(toCamObjectSpace), normalObject);
reflectedColor = texCUBE(g_samEnv, envMapTex);
}
float3 normalObject = normalize(mul(normalT, TBN));
float3 reflectedColor = 0;
if(g_bReflecting)
{
// racunamo refleksiju u object space
float3 envMapTex = reflect(-normalize(toCamObjectSpace), normalObject);
reflectedColor = texCUBE(g_samEnv, envMapTex);
}
normalT se racuna u tangent (texture) space. Ona je priblizna pravcu Z ose ( ili je paralelena sa Z osom ako je flat surface ), tako da je uvek pozitivna tako da se envMapTex ne moze racunati u tangent space.
float3 normalObject = normalize(mul(normalT, TBN));
Mnozenjem sa TBN prevodim normalT u object space. Camera vektor je isto u object space tako da sada mogu da proracunam reflection vektor.
Problem je sto nigde nisam video da se ovo radi na ovaj nacin :) Meni se cini da je proracun korektan posto se normala rotira iz tangent space u object space tako da se dovodi u isti koordinatni sistem u kojem je i kamera.
[url= http://i44.tinypic.com/w0hnpg.jpg ]Evo [/url]kako sve to izgleda u mom Mesh Editoru.
Na netu sam nasao nacin rekalkulisanja Z komponente:
Primer koda:
half3 N=normalize( half3( Nxy * bumpCoeff,sqrt( 1 - Nxy.x * Nxy.x - Nxy.y * Nxy.y)) );
Mozda je to bolje resenje... Mene zanima kako to, u stvari, treba pravilno uraditi. :)
[Ovu poruku je menjao glorius dana 31.03.2010. u 21:46 GMT+1]
EOF