Evening,
I have the following shader:
#include "Lights.fx"
// Light properties.
int LightType;
float4 LightDiffuseColour;
float4 LightSpecularColour;
float4 LightAmbientColour;
float3 LightPosition;
float3 LightDirection;
float LightRange;
float LightFalloff;
float LightAttenuation0;
float LightAttenuation1;
float LightAttenuation2;
float LightTheta;
float LightPhi;
float3 CameraPosition;
float4 ClearColor = float4( 0,0,0,0 );
texture PosMapTexture;
texture NormalMapTexture;
sampler PosMapSampler =
sampler_state
{
Texture = PosMapTexture;
};
sampler NormalMapSampler =
sampler_state
{
Texture = NormalMapTexture;
};
struct VS_INPUT
{
float3 Pos: POSITION;
float3 Normal: NORMAL;
};
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 TexCoord: TEXCOORD0;
};
struct PS_INPUT
{
float2 TexCoord: TEXCOORD0;
};
struct PS_OUTPUT
{
float4 Color : COLOR0;
};
VS_OUTPUT vs_main( VS_INPUT In )
{
VS_OUTPUT Out;
Out.Pos = float4(sign(In.Pos.xy),0.0,1.0);
Out.TexCoord.x = (Out.Pos.x+1.0) * 0.5;
Out.TexCoord.y = 1.0 - ((Out.Pos.y-1.0) * 0.5);
return Out;
}
PS_OUTPUT ps_main( PS_INPUT In )
{
PS_OUTPUT Out;
float4 Pos = tex2D(PosMapSampler,In.TexCoord);
if (Pos.w==0.0) // If nothing is drawn at this pixel, just output clear color
{
Out.Color = ClearColor;
} // End if
else
{
if ( LightType == 0 ) //Ambient
{
Out.Color = LightAmbientColour;
}
else if ( LightType == 1 )
{
float3 Normal = normalize( tex2D( NormalMapSampler, In.TexCoord ).xyz );
Out.Color = Directional( Normal, normalize(LightPosition), LightAmbientColour, LightDiffuseColour );
}
else if ( LightType == 2 ) // Point
{
float3 Normal = normalize( tex2D( NormalMapSampler, In.TexCoord ).xyz );
float4 FinalColour = Phong(Pos,
Normal,
LightPosition,
CameraPosition,
LightAmbientColour,
LightDiffuseColour,
LightSpecularColour );
float Dist = length( LightPosition - Pos );
float Attenuation = 1 / ( LightAttenuation0 + LightAttenuation1 * Dist + LightAttenuation2 * pow(Dist, 2) );
if ( Dist > LightRange )
{
Attenuation = 0;
}
Out.Color = FinalColour * Attenuation;
}
else if ( LightType == 3 )
{
float3 Normal = normalize( tex2D( NormalMapSampler, In.TexCoord ).xyz );
float4 FinalColour = Spot( Pos,
Normal,
LightPosition,
normalize(LightDirection),
CameraPosition,
LightAmbientColour,
LightDiffuseColour,
LightSpecularColour,
LightTheta,
LightPhi );
Out.Color = FinalColour;
}
}
return Out;
}
technique DefaultTechnique
{
pass P0
{
VertexShader = compile vs_4_0 vs_main();
PixelShader = compile ps_4_0 ps_main();
}
}
that includes:
float4 Phong( float3 Position,
float3 Normal,
float3 LightPosition,
float3 CameraPosition,
float4 AmbientColour,
float4 DiffuseColour,
float4 SpecularColour )
{
float3 ToLight = normalize( LightPosition - Position );
float3 Reflect = normalize( 2.0f * Normal * saturate(dot( Normal, ToLight )) - ToLight );
float3 View = normalize( CameraPosition - Position );
float Dot = saturate(dot( Normal, ToLight ));
float4 Ambient = AmbientColour;
float4 Diffuse = DiffuseColour * Dot;
float SpecMod = saturate(pow(dot( Reflect, View ),8));
float4 Specular = mul(SpecMod, SpecularColour );
return Ambient + Diffuse + Specular * Dot;
}
float4 Directional(float3 Normal,
float3 DirectionToLight,
float4 AmbientColour,
float4 DiffuseColour )
{
return AmbientColour + saturate(dot( Normal, DirectionToLight )) * DiffuseColour;
}
float4 Spot( float3 Position,
float3 Normal,
float3 LightPosition,
float3 LightDirection,
float3 CameraPosition,
float4 AmbientColour,
float4 DiffuseColour,
float4 SpecularColour,
float Theta,
float Phi )
{
float3 ToLight = normalize( LightPosition - Position );
float3 Reflect = normalize( 2.0f * Normal * saturate(dot( Normal, ToLight )) - ToLight );
float3 View = normalize( CameraPosition - Position );
float4 Ambient = AmbientColour;
float4 Diffuse = DiffuseColour * saturate(dot( Normal, ToLight ));
float4 Specular = SpecularColour * saturate(pow(dot( Reflect, View ),8));
float4 Phong = Ambient + Diffuse + Specular;
float3 LightToFragment = normalize( Position - LightPosition );
float Dot = dot( LightDirection, LightToFragment );
float Intensity = 0;
if ( Dot <= Phi )
{
Intensity = 0;
}
else if ( Dot > Theta )
{
Intensity = lerp(0,1, (Dot-Theta)/(1-Theta) );
}
else
{
//Intensity = 0.5;//((cos(Dot) - cos(Phi/2))/(cos(Theta/2) - cos(Phi/2)));
}
return Phong * Intensity;
}
When i compile it with:
HRESULT result = D3DXCreateEffectFromFileA( m_Device, rPath.GetFullPath().c_str(), NULL, NULL, D3DXSHADER_DEBUG | D3DXSHADER_NO_PRESHADER |
D3DXSHADER_OPTIMIZATION_LEVEL0 | D3DXSHADER_SKIPOPTIMIZATION | D3DXSHADER_SKIPVALIDATION, 0, &NewEffect, &pErrorBuffer );
It compiles with no errors and runs as expected visually. No warnings other than redundant render states are given by D3D with full debugging on.
If i compile it with:
HRESULT result = D3DXCreateEffectFromFileA( m_Device, rPath.GetFullPath
().c_str(), NULL, NULL, 0, 0, &NewEffect, &pErrorBuffer );
it fails compile with the following error:
../DeferredShadingPass.fx(140,21): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression.
ID3DXEffectCompiler: Compilation Failed.
What's more, when running the application i get warnings like the following:
Direct3D9: (WARN) :Can not render to a render target that is also used
as a texture. A render target was detected as bound, but couldn't detect if texture was actually used in rendering.
Which dont appear when the effect builds nor have they done for some time and my pipeline hasn't changed at all.
EDIT: Please note it also fails if i make it PS & VS 3.0.
EDIT2: I just tried dropping it back to PS & VS 2.0 and it compiled and ran fine.
Any suggestions are welcome, thanks.
[Edited by - Dave on July 22, 2009 4:51:08 PM]