250 lines
6.6 KiB
HLSL
250 lines
6.6 KiB
HLSL
|
//-----------------------------------------------------------------------------
|
||
|
// 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]]);
|
||
|
}
|
||
|
}
|