I have gone down a long road with pixil lighting and I was wondering if it would be worth it to try something different.
Currently I have a scene broken into sections so I can omit them when not seen. It uses HLSL lighting with multiple lights:
//-----------------------------------------------------------------------------
// 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.
//
//
//
//*************** THIS HAS BEEN MODIFIED TO SUPPORT 3 TYPES OF LIGHTS WITHIN
// THE SAME EFFECT
//
//
//-----------------------------------------------------------------------------
#define MAX_ALL_LIGHTS 16
struct AllLight
{
int type;//0==directional, 1==point, 2==spot
float3 dir;
float3 pos; // world space position
float4 ambient;
float4 diffuse;
float4 specular;
float spotInnerCone; // spot light inner cone (theta) angle
float spotOuterCone; // spot light outer cone (phi) angle
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;
AllLight lights[MAX_ALL_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_AllLighting(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_AllLighting(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);
float4 ShinnyMap = tex2D(normalMap, IN.texCoord);
for (int i = 0; i < numLights; ++i)
{
float len=length(lights[i].pos - IN.worldPos);
if ((len<lights[i].radius*1.25f)||(lights[i].type==0)){
if (lights[i].type==0){
l=mul(-lights[i].dir,tbnMatrix);
atten = 1.0f;
}
else{
l = mul((lights[i].pos - IN.worldPos) / lights[i].radius, tbnMatrix);
atten = saturate(1.0f - dot(l, l));
}
l = normalize(l);
if (lights[i].type==2) {
float2 cosAngles = cos(float2(lights[i].spotOuterCone, lights[i].spotInnerCone) * 0.5f);
float3 dl=mul(lights[i].dir,tbnMatrix);
float spotDot = dot(-l, normalize(dl));
float spotEffect = smoothstep(cosAngles[0], cosAngles[1], spotDot);
atten *= spotEffect;
}
h = normalize(l + v);
nDotL = saturate(dot(n, l));
nDotH = saturate(dot(n, h));
power = (nDotL == 0.0f) ? 0.0f : pow(nDotH, material.shininess*ShinnyMap.w);
color += ((material.diffuse * lights[i].diffuse )+
(lights[i].specular * power ))* nDotL * atten;
}
}
color += material.ambient * globalAmbient +material.emissive;
return color * tex2D(colorMap, IN.texCoord);
}
//-----------------------------------------------------------------------------
// Techniques.
//-----------------------------------------------------------------------------
technique NormalMappingAllLighting
{
pass
{
VertexShader = compile vs_3_0 VS_AllLighting();
PixelShader = compile ps_3_0 PS_AllLighting();
}
}
It looks great, but there is a problem. On certain surfaces, when I get close to them, the frame rate dramatically fluctuates(30-50fps). When I'm not close to anything the frame rate is 60fps. The only thing that seems to keep it at 60 all the time is when I remove ALL the lights....
There are three parts to this question:
1. Am I doing something wrong in the shader? If so, please help me fix it.
2. Is there any better lighting method for normal mapping?
3. I was thinking about trying cube lighting. Will it work with normal mapping? Is it faster than pixil lighting?
e