anx.framework/shader/XNA/EnvironmentMapEffect.fx

250 lines
6.6 KiB
HLSL
Raw Permalink Normal View History

//-----------------------------------------------------------------------------
// EnvironmentMapEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
DECLARE_TEXTURE(Texture, 0);
DECLARE_CUBEMAP(EnvironmentMap, 1);
BEGIN_CONSTANTS
float3 EnvironmentMapSpecular _ps(c0) _cb(c0);
float FresnelFactor _vs(c0) _cb(c0.w);
float EnvironmentMapAmount _vs(c1) _cb(c2.w);
float4 DiffuseColor _vs(c2) _cb(c1);
float3 EmissiveColor _vs(c3) _cb(c2);
float3 DirLight0Direction _vs(c4) _cb(c3);
float3 DirLight0DiffuseColor _vs(c5) _cb(c4);
float3 DirLight1Direction _vs(c6) _cb(c5);
float3 DirLight1DiffuseColor _vs(c7) _cb(c6);
float3 DirLight2Direction _vs(c8) _cb(c7);
float3 DirLight2DiffuseColor _vs(c9) _cb(c8);
float3 EyePosition _vs(c10) _cb(c9);
float3 FogColor _ps(c1) _cb(c10);
float4 FogVector _vs(c11) _cb(c11);
float4x4 World _vs(c16) _cb(c12);
float3x3 WorldInverseTranspose _vs(c19) _cb(c16);
MATRIX_CONSTANTS
float4x4 WorldViewProj _vs(c12) _cb(c0);
END_CONSTANTS
// We don't use these parameters, but Lighting.fxh won't compile without them.
#define SpecularPower 0
#define SpecularColor float3(0, 0, 0)
#define DirLight0SpecularColor float3(0, 0, 0)
#define DirLight1SpecularColor float3(0, 0, 0)
#define DirLight2SpecularColor float3(0, 0, 0)
#include "Structures.fxh"
#include "Common.fxh"
#include "Lighting.fxh"
float ComputeFresnelFactor(float3 eyeVector, float3 worldNormal)
{
float viewAngle = dot(eyeVector, worldNormal);
return pow(max(1 - abs(viewAngle), 0), FresnelFactor) * EnvironmentMapAmount;
}
VSOutputTxEnvMap ComputeEnvMapVSOutput(VSInputNmTx vin, uniform bool useFresnel, uniform int numLights)
{
VSOutputTxEnvMap vout;
float4 pos_ws = mul(vin.Position, World);
float3 eyeVector = normalize(EyePosition - pos_ws.xyz);
float3 worldNormal = normalize(mul(vin.Normal, WorldInverseTranspose));
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights);
vout.PositionPS = mul(vin.Position, WorldViewProj);
vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a);
if (useFresnel)
vout.Specular.rgb = ComputeFresnelFactor(eyeVector, worldNormal);
else
vout.Specular.rgb = EnvironmentMapAmount;
vout.Specular.a = ComputeFogFactor(vin.Position);
vout.TexCoord = vin.TexCoord;
vout.EnvCoord = reflect(-eyeVector, worldNormal);
return vout;
}
// Vertex shader: basic.
VSOutputTxEnvMap VSEnvMap(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, false, 3);
}
// Vertex shader: fresnel.
VSOutputTxEnvMap VSEnvMapFresnel(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, true, 3);
}
// Vertex shader: one light.
VSOutputTxEnvMap VSEnvMapOneLight(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, false, 1);
}
// Vertex shader: one light, fresnel.
VSOutputTxEnvMap VSEnvMapOneLightFresnel(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, true, 1);
}
// Pixel shader: basic.
float4 PSEnvMap(PSInputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: no fog.
float4 PSEnvMapNoFog(PSInputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
return color;
}
// Pixel shader: specular.
float4 PSEnvMapSpecular(PSInputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
color.rgb += EnvironmentMapSpecular * envmap.a;
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: specular, no fog.
float4 PSEnvMapSpecularNoFog(PSInputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
color.rgb += EnvironmentMapSpecular * envmap.a;
return color;
}
VertexShader VSArray[4] =
{
compile vs_2_0 VSEnvMap(),
compile vs_2_0 VSEnvMapFresnel(),
compile vs_2_0 VSEnvMapOneLight(),
compile vs_2_0 VSEnvMapOneLightFresnel(),
};
int VSIndices[16] =
{
0, // basic
0, // basic, no fog
1, // fresnel
1, // fresnel, no fog
0, // specular
0, // specular, no fog
1, // fresnel + specular
1, // fresnel + specular, no fog
2, // one light
2, // one light, no fog
3, // one light, fresnel
3, // one light, fresnel, no fog
2, // one light, specular
2, // one light, specular, no fog
3, // one light, fresnel + specular
3, // one light, fresnel + specular, no fog
};
PixelShader PSArray[4] =
{
compile ps_2_0 PSEnvMap(),
compile ps_2_0 PSEnvMapNoFog(),
compile ps_2_0 PSEnvMapSpecular(),
compile ps_2_0 PSEnvMapSpecularNoFog(),
};
int PSIndices[16] =
{
0, // basic
1, // basic, no fog
0, // fresnel
1, // fresnel, no fog
2, // specular
3, // specular, no fog
2, // fresnel + specular
3, // fresnel + specular, no fog
0, // one light
1, // one light, no fog
0, // one light, fresnel
1, // one light, fresnel, no fog
2, // one light, specular
3, // one light, specular, no fog
2, // one light, fresnel + specular
3, // one light, fresnel + specular, no fog
};
int ShaderIndex = 0;
Technique EnvironmentMapEffect
{
Pass
{
VertexShader = (VSArray[VSIndices[ShaderIndex]]);
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
}
}