I'm using DX9....
I have already gone down this road with posting my code in an earlier thread. It got me nowhere because either the people reading didn't understand my code or didn't care to help. I'm going to post it again:
D3DXMATRIX VP=ActorController.Actors[0].rotMatrix*GE->MyCamera.m_projMatrix;
D3DXMATRIX compVM=ActorController.Actors[0].rotMatrix*ShipController.Ship[0].RotationMatrix;
// D3DXMatrixInverse(&compVM,0,&compVM);
static D3DXHANDLE hTechnique;
static UINT totalPasses;
hTechnique = FXManager.Effect[NormalMappingFX].FX->GetTechniqueByName("NormalMappingPointLighting");
if (FAILED(FXManager.Effect[NormalMappingFX].FX->SetTechnique(hTechnique)))
return;
// Set the camera position.
D3DXVECTOR3 pos=ActorController.Actors[0].ActorLoc.Normalize();
pos*=(float)ActorController.Actors[0].ActorLoc.Length;
FXManager.Effect[NormalMappingFX].FX->SetValue("cameraPos", &pos, sizeof(pos));
// Set the scene global ambient term.
float g_sceneAmbient[4] = {0.1f, 0.1f, 0.1f, 1.0f};
FXManager.Effect[NormalMappingFX].FX->SetValue("globalAmbient", &g_sceneAmbient, sizeof(g_sceneAmbient));
// Set the number of active lights.
int g_numLights=1;
FXManager.Effect[NormalMappingFX].FX->SetValue("numLights", &g_numLights, sizeof(g_numLights));
D3DXHANDLE hLight;
D3DXHANDLE hLightPos;
D3DXHANDLE hLightAmbient;
D3DXHANDLE hLightDiffuse;
D3DXHANDLE hLightSpecular;
D3DXHANDLE hLightRadius;
hLight = FXManager.Effect[NormalMappingFX].FX->GetParameterElement("lights", 0);
hLightPos = FXManager.Effect[NormalMappingFX].FX->GetParameterByName(hLight, "pos");
hLightAmbient = FXManager.Effect[NormalMappingFX].FX->GetParameterByName(hLight, "ambient");
hLightDiffuse = FXManager.Effect[NormalMappingFX].FX->GetParameterByName(hLight, "diffuse");
hLightSpecular = FXManager.Effect[NormalMappingFX].FX->GetParameterByName(hLight, "specular");
hLightRadius = FXManager.Effect[NormalMappingFX].FX->GetParameterByName(hLight, "radius");
//float Lpos[3]={1,2,2};
D3DXVECTOR3 Lpos(0,0,0);
// Lpos-=pos;
float amb[4]={0,0,0,0};
float diff[4]={1,0,1,0};
float spec[4]={0,0,0,0};
FXManager.Effect[NormalMappingFX].FX->SetValue(hLightPos, Lpos, sizeof(Lpos));
FXManager.Effect[NormalMappingFX].FX->SetValue(hLightAmbient, amb, sizeof(amb));
FXManager.Effect[NormalMappingFX].FX->SetValue(hLightDiffuse, diff, sizeof(diff));
FXManager.Effect[NormalMappingFX].FX->SetValue(hLightSpecular, spec, sizeof(spec));
FXManager.Effect[NormalMappingFX].FX->SetFloat(hLightRadius, 3.0f);
Material g_dullMaterial={
0.2f, 0.2f, 0.2f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
100.0f
};
FXManager.Effect[NormalMappingFX].FX->SetValue("material.ambient", g_dullMaterial.ambient, sizeof(g_dullMaterial.ambient));
FXManager.Effect[NormalMappingFX].FX->SetValue("material.diffuse", g_dullMaterial.diffuse, sizeof(g_dullMaterial.diffuse));
FXManager.Effect[NormalMappingFX].FX->SetValue("material.emissive", g_dullMaterial.emissive, sizeof(g_dullMaterial.emissive));
FXManager.Effect[NormalMappingFX].FX->SetValue("material.specular", g_dullMaterial.specular, sizeof(g_dullMaterial.specular));
FXManager.Effect[NormalMappingFX].FX->SetFloat("material.shininess", g_dullMaterial.shininess);
FXManager.Effect[NormalMappingFX].FX->SetTexture("colorMapTexture", TextureList[ShipTexture[1].C].Texture);
FXManager.Effect[NormalMappingFX].FX->SetTexture("normalMapTexture", TextureList[ShipTexture[0].N].Texture);
//do a render sort
numInSort=0;
for (UINT s=0;s<Section.size();s++){
D3DXVECTOR3 v(Section[s].pos.x,Section[s].pos.y,Section[s].pos.z);
v-=pos;
float d=D3DXVec3Length(&v);
SL[numInSort].Sect=s;
SL[numInSort].dist=d;
SO[numInSort]=0;
numInSort++;
}
SO[0]=0;
for (int i=1;i<numInSort;i++){
int q=0;
for (q=0;q<i;q++) if (SL[i].dist>SL[SO[q]].dist) break;
if (q<=i) for (int q2=i;q2>q;q2--) SO[q2]=SO[q2-1];//shift everything else down the list
SO[q]=i;
}
bool ZR=false;
if (ActorController.Actors[0].InMesh==-1) ZR=true;
for (int sl=0;sl<numInSort;sl++){
int s=SL[SO[sl]].Sect;
D3DXVECTOR3 v(Section[s].pos.x,Section[s].pos.y,Section[s].pos.z);
v-=pos;
FXManager.Effect[NormalMappingFX].FX->SetValue(hLightPos, Lpos, sizeof(Lpos));
for (UINT i=0;i<Section[s].Objects.size();i++) {
tmp=Section[s].Objects[i].matrix;
tmp(3,0)+=v.x;
tmp(3,1)+=v.y;
tmp(3,2)+=v.z;
FXManager.Effect[NormalMappingFX].FX->SetMatrix("worldMatrix", &tmp);
D3DXMATRIX wit=tmp;
wit(3,0)=0;
wit(3,1)=0;
wit(3,2)=0;
wit(3,3)=1;;
D3DXMatrixInverse(&wit,0,&wit);
D3DXMatrixTranspose(&wit,&wit);
FXManager.Effect[NormalMappingFX].FX->SetMatrix("worldInverseTransposeMatrix", &wit);
tmp*=VP;
FXManager.Effect[NormalMappingFX].FX->SetMatrix("worldViewProjectionMatrix", &tmp);
if (SUCCEEDED(FXManager.Effect[NormalMappingFX].FX->Begin(&totalPasses, 0)))
{
for (UINT pass = 0; pass < totalPasses; ++pass)
{
if (SUCCEEDED(FXManager.Effect[NormalMappingFX].FX->BeginPass(pass)))
{
MeshObject[mesh].ppMesh->DrawSubset(Section[s].Objects[i].ObjIndex);
FXManager.Effect[NormalMappingFX].FX->EndPass();
}
}
FXManager.Effect[NormalMappingFX].FX->End();
}
}
}
Here is the .fx:
//-----------------------------------------------------------------------------
// Copyright (c) 2008 dhpoware. All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//
// Tangent space normal mapping with multiple point lights in a single pass
// using shader model 3.0. This effect file limits the number of point lights
// to 8.
//
//-----------------------------------------------------------------------------
#define MAX_POINT_LIGHTS 8
struct PointLight
{
float3 pos;
float4 ambient;
float4 diffuse;
float4 specular;
float radius;
};
struct Material
{
float4 ambient;
float4 diffuse;
float4 emissive;
float4 specular;
float shininess;
};
//-----------------------------------------------------------------------------
// Globals.
//-----------------------------------------------------------------------------
float4x4 worldMatrix;
float4x4 worldInverseTransposeMatrix;
float4x4 worldViewProjectionMatrix;
float3 cameraPos;
float4 globalAmbient;
int numLights;
PointLight lights[MAX_POINT_LIGHTS];
Material material;
//-----------------------------------------------------------------------------
// Textures.
//-----------------------------------------------------------------------------
texture colorMapTexture;
texture normalMapTexture;
sampler2D colorMap = sampler_state
{
Texture = <colorMapTexture>;
MagFilter = Linear;
MinFilter = Anisotropic;
MipFilter = Linear;
MaxAnisotropy = 16;
};
sampler2D normalMap = sampler_state
{
Texture = <normalMapTexture>;
MagFilter = Linear;
MinFilter = Anisotropic;
MipFilter = Linear;
MaxAnisotropy = 16;
};
//-----------------------------------------------------------------------------
// Vertex Shaders.
//-----------------------------------------------------------------------------
struct VS_INPUT
{
float3 position : POSITION;
float2 texCoord : TEXCOORD0;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct VS_OUTPUT
{
float4 position : POSITION;
float3 worldPos : TEXCOORD0;
float2 texCoord : TEXCOORD1;
float3 normal : TEXCOORD2;
float3 tangent : TEXCOORD3;
float3 bitangent : TEXCOORD4;
};
VS_OUTPUT VS_PointLighting(VS_INPUT IN)
{
VS_OUTPUT OUT;
OUT.position = mul(float4(IN.position, 1.0f), worldViewProjectionMatrix);
OUT.worldPos = mul(float4(IN.position, 1.0f), worldMatrix).xyz;
OUT.texCoord = IN.texCoord;
OUT.normal = mul(IN.normal, (float3x3)worldInverseTransposeMatrix);
OUT.tangent = mul(IN.tangent.xyz, (float3x3)worldInverseTransposeMatrix);
OUT.bitangent = cross(OUT.normal, OUT.tangent) * IN.tangent.w;
return OUT;
}
//-----------------------------------------------------------------------------
// Pixel Shaders.
//-----------------------------------------------------------------------------
float4 PS_PointLighting(VS_OUTPUT IN) : COLOR
{
float3 t = normalize(IN.tangent);
float3 b = normalize(IN.bitangent);
float3 n = normalize(IN.normal);
float3x3 tbnMatrix = float3x3(t.x, b.x, n.x,
t.y, b.y, n.y,
t.z, b.z, n.z);
float3 v = normalize(mul(cameraPos - IN.worldPos, tbnMatrix));
float3 l = float3(0.0f, 0.0f, 0.0f);
float3 h = float3(0.0f, 0.0f, 0.0f);
float atten = 0.0f;
float nDotL = 0.0f;
float nDotH = 0.0f;
float power = 0.0f;
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
n = normalize(tex2D(normalMap, IN.texCoord).rgb * 2.0f - 1.0f);
for (int i = 0; i < numLights; ++i)
{
l = mul((lights[i].pos - IN.worldPos) / lights[i].radius, tbnMatrix);
atten = saturate(1.0f - dot(l, l));
l = normalize(l);
h = normalize(l + v);
nDotL = saturate(dot(n, l));
nDotH = saturate(dot(n, h));
power = (nDotL == 0.0f) ? 0.0f : pow(nDotH, material.shininess);
color += (material.ambient * (globalAmbient + (atten * lights[i].ambient))) +
(material.diffuse * lights[i].diffuse * nDotL * atten) +
(material.specular * lights[i].specular * power * atten);
}
return color * tex2D(colorMap, IN.texCoord);
}
//-----------------------------------------------------------------------------
// Techniques.
//-----------------------------------------------------------------------------
technique NormalMappingPointLighting
{
pass
{
VertexShader = compile vs_3_0 VS_PointLighting();
PixelShader = compile ps_3_0 PS_PointLighting();
}
}
Here is a video illustrating the outcome:
[media]http:
[/media]
There is supposed to be 1 point light (at the player's head). The surfaces are not rendering properly....
This is how it SHOULD look:
[media]http:
[/media]