// STATIC: "MASKEDBLENDING" "0..1" // STATIC: "BASETEXTURE2" "0..1" // STATIC: "DETAILTEXTURE" "0..1" // STATIC: "BUMPMAP" "0..1" // STATIC: "BUMPMAP2" "0..1" // STATIC: "CUBEMAP" "0..1" // STATIC: "ENVMAPMASK" "0..1" // STATIC: "BASEALPHAENVMAPMASK" "0..1" // STATIC: "SELFILLUM" "0..1" // STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" // STATIC: "DIFFUSEBUMPMAP" "0..1" // STATIC: "BASETEXTURENOENVMAP" "0..1" // STATIC: "BASETEXTURE2NOENVMAP" "0..1" // STATIC: "WARPLIGHTING" "0..1" // STATIC: "FANCY_BLENDING" "0..1" // DYNAMIC: "FASTPATHENVMAPTINT" "0..1" // DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1" // DYNAMIC: "FASTPATH" "0..1" // DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" // DYNAMIC: "FOGTYPE" "0..2" // DYNAMIC: "LIGHTING_PREVIEW" "0..2" #define NORMALIZE_WITHOUT_CUBEMAP (WARPLIGHTING) // SKIP: $BUMPMAP2 && $WARPLIGHTING // SKIP: $WARPLIGHTING && $DETAILTEXTURE // SKIP: $ENVMAPMASK && $BUMPMAP // SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK // SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK // SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK // SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM // SKIP: !$FASTPATH && $FASTPATHENVMAPCONTRAST // SKIP: !$FASTPATH && $FASTPATHENVMAPTINT // SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP // SKIP: !$BUMPMAP && $BUMPMAP2 // SKIP: $ENVMAPMASK && $BUMPMAP2 // SKIP: $BASETEXTURENOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) // SKIP: $BASETEXTURE2NOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) // SKIP: $BASEALPHAENVMAPMASK && $BUMPMAP // SKIP: $FANCY_BLENDING && $DETAILTEXTURE // NOSKIP: $FANCY_BLENDING && (! $FASTPATH) // debug crap: // NOSKIP: $DETAILTEXTURE // NOSKIP: $CUBEMAP // NOSKIP: $ENVMAPMASK // NOSKIP: $BASEALPHAENVMAPMASK // NOSKIP: $SELFILLUM #include "common_ps_fxc.h" #if FASTPATH == 1 # if FASTPATHENVMAPTINT == 0 static const HALF4 g_EnvmapTint = { 1.0f, 1.0f, 1.0f, 1.0f }; # else const HALF4 g_EnvmapTint : register( c0 ); # endif # if FASTPATHENVMAPCONTRAST == 0 static const HALF3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f }; # else static const HALF3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f }; # endif static const HALF3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f }; static const HALF g_FresnelReflection = 1.0f; static const HALF g_OneMinusFresnelReflection = 0.0f; static const HALF4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f }; #else const HALF4 g_EnvmapTint : register( c0 ); const HALF3 g_EnvmapContrast : register( c2 ); const HALF3 g_EnvmapSaturation : register( c3 ); const HALF4 g_FresnelReflectionReg : register( c4 ); #define g_FresnelReflection g_FresnelReflectionReg.a #define g_OneMinusFresnelReflection g_FresnelReflectionReg.b const HALF4 g_SelfIllumTint : register( c7 ); #endif const HALF3 g_EyePos : register( c10 ); const HALF4 g_FogParams : register( c11 ); #define g_FogEndOverRange g_FogParams.x #define g_WaterZ g_FogParams.y #define g_FogOORange g_FogParams.w const HALF4 g_WaterFogColor : register( c14 ); sampler BaseTextureSampler : register( s0 ); sampler LightmapSampler : register( s1 ); sampler EnvmapSampler : register( s2 ); #if FANCY_BLENDING sampler BlendModulationSampler : register( s3 ); #endif #if DETAILTEXTURE sampler DetailSampler : register( s3 ); #endif sampler BumpmapSampler : register( s4 ); #if BUMPMAP2 == 1 sampler BumpmapSampler2 : register( s5 ); #else sampler EnvmapMaskSampler : register( s5 ); #endif #if NORMALIZE_WITHOUT_CUBEMAP == 0 sampler NormalizeSampler : register( s6 ); #endif #if WARPLIGHTING sampler WarpLightingSampler : register( s6 ); #endif sampler BaseTextureSampler2 : register( s7 ); struct PS_INPUT { HALF2 baseTexCoord : TEXCOORD0; // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. HALF4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // CENTROID: TEXCOORD2 HALF4 lightmapTexCoord1And2 : TEXCOORD2; // CENTROID: TEXCOORD3 HALF4 lightmapTexCoord3 : TEXCOORD3; HALF4 worldPos_projPosZ : TEXCOORD4; HALF3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7 HALF4 vertexColor : COLOR; float4 vertexBlendX_fogFactorW : COLOR1; }; #if LIGHTING_PREVIEW # 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 HALF4 main( PS_INPUT i ) : COLOR # endif #else HDR_PS_OUTPUT main( PS_INPUT i ) : COLOR #endif { bool bBaseTexture2 = BASETEXTURE2 ? true : false; bool bDetailTexture = DETAILTEXTURE ? true : false; bool bBumpmap = BUMPMAP ? true : false; bool bBumpmap2 = BUMPMAP2 ? true : false; bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; bool bCubemap = CUBEMAP ? true : false; bool bEnvmapMask = ENVMAPMASK ? true : false; bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; bool bSelfIllum = SELFILLUM ? true : false; bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; bool bBaseTextureNoEnvmap = BASETEXTURENOENVMAP ? true : false; bool bBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP ? true : false; HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); #if LIGHTING_PREVIEW == 0 if( bBumpmap && bDiffuseBumpmap ) { HALF2 bumpCoord1; HALF2 bumpCoord2; HALF2 bumpCoord3; ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, bumpCoord1, bumpCoord2, bumpCoord3 ); HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); lightmapColor1 = lightmapSample1.rgb; lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); } else { HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); lightmapColor1 = lightmapSample1.rgb; } #endif #if DETAILTEXTURE == 1 HALF2 detailTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; HALF2 bumpmapTexCoord = i.baseTexCoord.xy; #else HALF2 detailTexCoord = 0.0f; HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; #endif HALF2 envmapMaskTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); #if DETAILTEXTURE detailColor = 2.0f * tex2D( DetailSampler, detailTexCoord ); #endif HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); #if LIGHTING_PREVIEW == 2 baseColor.xyz=GammaToLinear(baseColor.xyz); #endif float blendedAlpha = baseColor.a; if( bBaseTexture2 ) { HALF4 baseColor2 = tex2D( BaseTextureSampler2, i.baseTexCoord.xy ); #if MASKEDBLENDING float blendfactor=0.5; #else float blendfactor=i.vertexBlendX_fogFactorW.r; #endif #if (SELFILLUM == 0) && (NORMALMAPALPHAENVMAPMASK==0) && (FOGTYPE != 2) && (FANCY_BLENDING) float4 modt=tex2D(BlendModulationSampler,i.lightmapTexCoord3.zw); #if MASKEDBLENDING float minb=modt.g-modt.r; float maxb=modt.g+modt.r; #else float minb=max(0,modt.g-modt.r); float maxb=min(1,modt.g+modt.r); #endif blendfactor=smoothstep(minb,maxb,blendfactor); #endif baseColor.rgb = lerp( baseColor, baseColor2.rgb, blendfactor ); blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor ); } HALF3 specularFactor = 1.0f; HALF3 normal = HALF3( 0.0f, 0.0f, 1.0f ); if( bBumpmap ) { HALF4 normalTexel; normalTexel = tex2D( BumpmapSampler, bumpmapTexCoord.xy ); if( bBaseTextureNoEnvmap ) { normalTexel.a = 0.0f; } #if BUMPMAP2 == 1 { HALF4 normalTexel2 = tex2D( BumpmapSampler2, bumpmapTexCoord.xy ); if( bBaseTexture2NoEnvmap ) { normalTexel2.a = 0.0f; } normalTexel = lerp( normalTexel, normalTexel2, i.vertexBlendX_fogFactorW.r ); } #endif if( bNormalMapAlphaEnvmapMask ) { specularFactor *= normalTexel.a; } normal = 2.0 * normalTexel - 1.0; } #if BUMPMAP2 == 0 if( bEnvmapMask ) { specularFactor *= tex2D( EnvmapMaskSampler, envmapMaskTexCoord ).xyz; } #endif if( bBaseAlphaEnvmapMask ) { specularFactor *= 1.0 - blendedAlpha; // Reversing alpha blows! } HALF3 albedo = HALF3( 1.0f, 1.0f, 1.0f ); HALF alpha = 1.0f; albedo *= baseColor; if( !bBaseAlphaEnvmapMask && !bSelfIllum ) { alpha *= baseColor.a; } if( bDetailTexture ) { albedo *= detailColor; } // The vertex color contains the modulation color + vertex color combined albedo *= i.vertexColor; alpha *= i.vertexColor.a; // not sure about this one HALF3 diffuseLighting; if( bBumpmap && bDiffuseBumpmap ) { float3 dp; dp.x = saturate( dot( normal, bumpBasis[0] ) ); dp.y = saturate( dot( normal, bumpBasis[1] ) ); dp.z = saturate( dot( normal, bumpBasis[2] ) ); dp *= dp; diffuseLighting = dp.x * lightmapColor1 + dp.y * lightmapColor2 + dp.z * lightmapColor3; float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); diffuseLighting *= LIGHT_MAP_SCALE / sum; } else { diffuseLighting = lightmapColor1 * LIGHT_MAP_SCALE; } #if WARPLIGHTING float len=0.5*length(diffuseLighting); diffuseLighting *= 2.0*tex2D(WarpLightingSampler,float2(len,0)); #endif HALF3 diffuseComponent = albedo * diffuseLighting; if( bSelfIllum ) { HALF3 selfIllumComponent = g_SelfIllumTint * albedo; diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); } HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); if( bCubemap ) { float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz; float3 worldSpaceNormal = mul( normal, i.tangentSpaceTranspose ); float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector ); // Calc Fresnel factor #if NORMALIZE_WITHOUT_CUBEMAP half3 eyeVect = normalize(worldVertToEyeVector); #else HALF3 eyeVect = NormalizeWithCubemap( NormalizeSampler, worldVertToEyeVector ); #endif HALF fresnel = 1.0 - dot( worldSpaceNormal, eyeVect ); fresnel = pow( fresnel, 5.0 ); fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection; specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); specularLighting *= specularFactor; #if FANCY_BLENDING == 0 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 specularLighting *= fresnel; } 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 float3 worldSpaceNormal = mul( normal, i.tangentSpaceTranspose ); # if LIGHTING_PREVIEW == 1 float dotprod=0.7+0.25*dot(worldSpaceNormal,normalize(float3(1,2,-.5))); return HALF4( dotprod*albedo.xyz, alpha ); # else LPREVIEW_PS_OUT ret; ret.color=float4( albedo.xyz,alpha); ret.normal=float4( worldSpaceNormal,alpha); ret.position=float4(i.worldPos_projPosZ.xyz,alpha); ret.flags=float4(1,1,1,alpha); return ret; # endif #else return LinearColorToHDROutput( float4( result.xyz, alpha ), i.vertexBlendX_fogFactorW.w ); #endif }