// STATIC: "BASETEXTURE" "0..1"
// STATIC: "DETAILTEXTURE" "0..1"
// STATIC: "CUBEMAP" "0..1"
// STATIC: "DIFFUSELIGHTING" "0..1"
// STATIC: "ENVMAPMASK" "0..1"
// STATIC: "BASEALPHAENVMAPMASK" "0..1"
// STATIC: "SELFILLUM" "0..1"
// STATIC: "VERTEXCOLOR" "0..1"
// STATIC: "VERTEXALPHA" "0..1"
// STATIC: "FLASHLIGHT" "0..1"
// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1"
// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1"
// DYNAMIC: "FOGTYPE" "0..2"
// DYNAMIC: "LIGHTING_PREVIEW" "0..2"
// DYNAMIC: "FLASHLIGHTDEPTH" "0..0"
// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK
// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM
// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA
// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK)
// SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTDEPTH)
#include "common_vertexlitgeneric_dx9.h"
const HALF4 g_EnvmapTint : register( c0 );
const HALF4 g_DiffuseModulation : register( c1 );
#if !FLASHLIGHT
// we don't use these with HDR.
const HALF3 g_EnvmapContrast : register( c2 );
const HALF3 g_EnvmapSaturation : register( c3 );
#endif
const HALF4 g_SelfIllumTint : register( c4 );
const HALF4 g_WaterFogColor : register( c19 );
const HALF3 g_EyePos : register( c20 );
const HALF4 g_FogParams : register( c21 );
#define g_WaterZ g_FogParams.y
#define g_FogOORange g_FogParams.w
const float4 g_FlashlightAttenuationFactors : register( c22 );
const HALF3 g_FlashlightPos : register( c23 );
const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27
sampler BaseTextureSampler : register( s0 );
sampler EnvmapSampler : register( s1 );
sampler DetailSampler : register( s2 );
sampler EnvmapMaskSampler : register( s4 );
sampler FlashlightSampler : register( s7 );
struct PS_INPUT
{
HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate
HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate
float4 color : TEXCOORD2; // Vertex color (from lighting or unlit)
float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection
float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps
float4 worldPos_projPosZ : TEXCOORD7; // Necessary for water fog dest alpha
float4 fogFactorW : COLOR1;
};
#if LIGHTING_PREVIEW == 2
struct LPREVIEW_PS_OUT
{
float4 color : COLOR0;
float4 normal : COLOR1;
float4 position : COLOR2;
float4 flags : COLOR3;
};
LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR
#else
HDR_PS_OUTPUT main( PS_INPUT i ) : COLOR
#endif
{
bool bBaseTexture = BASETEXTURE ? true : false;
bool bDetailTexture = DETAILTEXTURE ? true : false;
bool bCubemap = CUBEMAP ? true : false;
bool bDiffuseLighting = DIFFUSELIGHTING ? true : false;
bool bEnvmapMask = ENVMAPMASK ? true : false;
bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false;
bool bSelfIllum = SELFILLUM ? true : false;
bool bVertexColor = VERTEXCOLOR ? true : false;
bool bVertexAlpha = VERTEXALPHA ? true : false;
bool bFlashlight = FLASHLIGHT ? true : false;
HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f );
if( bBaseTexture )
{
baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy );
}
HALF3 detailColor = HALF3( 1.0f, 1.0f, 1.0f );
if( bDetailTexture )
{
detailColor = 2.0 * tex2D( DetailSampler, i.detailTexCoord.xy );
}
HALF3 specularFactor = 1.0f;
HALF4 envmapMaskTexel;
if( bEnvmapMask )
{
envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy );
specularFactor *= envmapMaskTexel.xyz;
}
if( bBaseAlphaEnvmapMask )
{
specularFactor *= 1.0 - baseColor.a; // this blows!
}
HALF3 diffuseLighting = HALF3( 1.0f, 1.0f, 1.0f );
if( bDiffuseLighting )
{
diffuseLighting = i.color.rgb;
}
HALF3 albedo = HALF3( 1.0f, 1.0f, 1.0f );
HALF alpha = 1.0f;
if( bBaseTexture )
{
albedo *= baseColor;
if( !bBaseAlphaEnvmapMask && !bSelfIllum )
{
alpha *= baseColor.a;
}
}
// If we only have specularity, assume that we want a black diffuse component, and
// get alpha from the envmapmask
if( !bBaseTexture && bCubemap )
{
if( bEnvmapMask )
{
alpha *= envmapMaskTexel.a;
}
}
#if FLASHLIGHT
if( bFlashlight )
{
bool bDoShadow = (FLASHLIGHTDEPTH==1)?1:0;
diffuseLighting = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, i.worldSpaceNormal,
g_FlashlightWorldToTexture, g_FlashlightAttenuationFactors.xyz,
g_FlashlightAttenuationFactors.w, FlashlightSampler, EnvmapMaskSampler, bDoShadow );
}
#endif
// FIXME: This could be done per vertex!
diffuseLighting *= g_DiffuseModulation.rgb;
alpha *= g_DiffuseModulation.a;
if( bVertexColor )
{
albedo *= i.color.rgb;
}
if( bVertexAlpha )
{
alpha *= i.color.a;
}
if( bDetailTexture )
{
albedo *= detailColor;
}
HALF3 diffuseComponent = albedo * diffuseLighting;
#if SELFILLUM_ENVMAPMASK_ALPHA
// range of alpha:
// 0 - 0.125 = lerp(diffuse,selfillum,alpha*8)
// 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows)
HALF3 selfIllumComponent = g_SelfIllumTint * albedo;
half Adj_Alpha=8*envmapMaskTexel.a;
diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent;
#else
if( bSelfIllum )
{
HALF3 selfIllumComponent = g_SelfIllumTint * albedo;
diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a );
}
#endif
HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f );
#if !FLASHLIGHT
if( bCubemap )
{
// If we've *only* specified a cubemap, blow off the diffuse component
if ( !bBaseTexture && !bVertexColor && !bVertexAlpha && !bDetailTexture && !bDiffuseLighting && !bSelfIllum && !bFlashlight )
{
diffuseComponent = HALF3( 0.0f, 0.0f, 0.0f );
}
HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz );
specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect );
specularLighting *= specularFactor;
specularLighting *= g_EnvmapTint;
HALF3 specularLightingSquared = specularLighting * specularLighting;
specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) );
specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
}
#endif
HALF3 result = diffuseComponent + specularLighting;
#if FOGTYPE == 2
float fogFactor = CalcWaterFogAlpha( g_WaterZ, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w, g_FogOORange );
result = lerp( result, g_WaterFogColor.xyz, fogFactor );
#if WRITEWATERFOGTODESTALPHA
alpha = fogFactor;
#endif
#endif
#if LIGHTING_PREVIEW
# if LIGHTING_PREVIEW == 1
float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5)));
return LinearColorToHDROutput( float4( dotprod*albedo.xyz, alpha ), 0 );
# else
LPREVIEW_PS_OUT ret;
ret.flags=float4(1,1,1,1);
ret.color=float4( albedo.xyz, alpha );
ret.normal=float4(i.worldSpaceNormal,alpha);
ret.position=float4(i.worldPos_projPosZ.xyz,alpha);
return ret;
# endif
#else
return LinearColorToHDROutput( float4( result.xyz, alpha ), i.fogFactorW);
#endif
}