|
|
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// Use samplers 9+
// Use constanst registers 29+
#ifndef USEPATTERN
#define USEPATTERN 0
#endif
#ifndef GENERATEBASETEXTURE
#define GENERATEBASETEXTURE 0
#endif
#ifndef GENERATENORMAL
#define GENERATENORMAL 0
#endif
#ifndef GENERATEMASKS1
#define GENERATEMASKS1 0
#endif
#ifndef BASEALPHAPHONGMASK
#define BASEALPHAPHONGMASK 0
#endif
#ifndef BASEALPHAENVMASK
#define BASEALPHAENVMASK 0
#endif
#ifndef BUMPALPHAENVMASK
#define BUMPALPHAENVMASK 0
#endif
#ifndef CHEAPFILTERING
#define CHEAPFILTERING 0
#endif
#if ( GENERATENORMAL && ( ( BASEALPHAPHONGMASK == 1 ) && ( BUMPALPHAENVMASK == 1 ) || ( BASEALPHAPHONGMASK == 0 ) ) )
#define NORMALALPHAUSED 1
#else
#define NORMALALPHAUSED 0
#endif
sampler MaterialMaskSampler : register( s9 ); sampler AOSampler : register( s10 ); sampler3D GrungeSampler : register( s11 ); sampler3D DetailSampler : register( s12 ); sampler3D DetailNormalSampler : register( s13 );
#if ( USEPATTERN > 0 )
sampler PatternSampler : register( s14 ); #endif
sampler NoiseSampler : register( s15 );
const float4 g_vDetailScale : register( c108 ); const float4 g_vDetailSpecBoost : register( c32 ); const float4 g_vDamageDetailSpecBoost : register( c100 ); const float4 g_vDetailEnvBoost : register( c34 ); const float4 g_vDamageDetailEnvBoost : register( c35 ); const float4 g_vDetailPhongAlbedoTint : register( c36 ); const float4 g_vDetailWarpIndex : register( c37 ); const float4 g_vDetailMetalness : register( c38 ); const float4 g_vDetailNormalDepth : register( c39 ); const float4 g_vDamageNormalEdgeDepth : register( c40 ); const float4 g_vDamageLevels0_1 : register( c41 ); #define g_vDamageLevels0 g_vDamageLevels0_1.xy
#define g_vDamageLevels1 g_vDamageLevels0_1.zw
const float4 g_vDamageLevels2_3 : register( c42 ); #define g_vDamageLevels2 g_vDamageLevels2_3.xy
#define g_vDamageLevels3 g_vDamageLevels2_3.zw
const float4 g_vPatternTexcoordTransform[2] : register( c43 ); // c43 & c44
const int4 g_vPatternColorIndices : register( c45 ); const float4 g_vWearProgress_PatternParams : register( c46 ); #define g_fWearProgress g_vWearProgress_PatternParams.x
#define g_fPatternDetailInfluence g_vWearProgress_PatternParams.y
#define g_nPatternReplaceIndex int( g_vWearProgress_PatternParams.z )
#define g_fTexelSize g_vWearProgress_PatternParams.w
const float4 g_paletteColor0_paletteColor3r : register( c47 ); #define g_cPaletteColor0 g_paletteColor0_paletteColor3r.rgb
const float4 g_paletteColor1_paletteColor3g : register( c48 ); #define g_cPaletteColor1 g_paletteColor1_paletteColor3g.rgb
const float4 g_paletteColor2_paletteColor3b : register( c49 ); #define g_cPaletteColor2 g_paletteColor2_paletteColor3b.rgb
#define g_cPaletteColor3 float3( g_paletteColor0_paletteColor3r.w, g_paletteColor1_paletteColor3g.w, g_paletteColor2_paletteColor3b.w )
const float4 g_paletteColor4_paletteColor7r : register( c50 ); #define g_cPaletteColor4 g_paletteColor4_paletteColor7r.rgb
const float4 g_paletteColor5_paletteColor7g : register( c51 ); #define g_cPaletteColor5 g_paletteColor5_paletteColor7g.rgb
const float4 g_paletteColor6_paletteColor7b : register( c52 ); #define g_cPaletteColor6 g_paletteColor6_paletteColor7b.rgb
#define g_cPaletteColor7 float3( g_paletteColor4_paletteColor7r.w, g_paletteColor5_paletteColor7g.w, g_paletteColor6_paletteColor7b.w )
const float4 g_vGrungeTexcoordTransform[2] : register( c53 ); // c53 & c54
const float4 g_vWearBleaching : register( c55 ); const float4 g_vWearDetailPhongBoost : register( c56 ); const float4 g_vWearDetailEnvBoost : register( c57 ); const float4 g_vDamageEdgePhongBoost : register( c58 ); const float4 g_vDamageEdgeEnvBoost : register( c59 ); const float4 g_vCurvatureWearBoost : register( c60 ); const float4 g_vCurvatureWearPower : register( c61 ); const float4 g_vDamageDetailSaturation : register( c62 ); const float4 g_vDamageBleaching : register( c63 ); const float4 g_vDetailGrungeFactor : register( c90 ); //64
const float4 g_vPatternParams : register( c91 ); //65
#define g_fPatternPhongFactor g_vPatternParams.x
#define g_fPatternPaintThickness g_vPatternParams.y
#define g_fFlipFixup g_vPatternParams.z
//#define UNUSED g_vPatternParams.zw
const float4 g_vDamageBrightness : register( c92 ); //66
const float4 g_vGrungeMax : register( c93 ); //67
const float4 g_vGrimeSaturation : register( c94 ); //70
const float4 g_vGrimeBrightness : register( c95 ); //72
const float4 g_vGrungeTexcoordRotation[2] : register( c96 ); const float4 g_vPatternTexcoordRotation[2] : register( c98 );
#define g_lum float3( 0.299, 0.587, 0.114 )
#define g_unitVec float3( 0.577f, 0.577f, 0.577f )
// todo: convert to param
#define g_sampleSliceZ float4( 0.0f, 0.375f, 0.625f, 1.0f )
float3 colorize( float3 cVal, float3 cColor, float fBrightness, float fSaturation ) { if ( fSaturation > 0 ) { float fLocalSaturation = fSaturation; float3 cRetVal = normalize(cColor * dot(cColor, g_lum));
fLocalSaturation *= pow(abs(dot(cRetVal - g_unitVec, g_unitVec)), 0.2f); fLocalSaturation = saturate(fLocalSaturation);
float3 cDiff = normalize(cRetVal - float3(0.577f, 0.577f, 0.577f)); cRetVal = saturate(cDiff * 2.0f + 1.0f);
float3 temp = cRetVal * g_lum; float fSaturatedBrightness = fBrightness / (temp.r + temp.g + temp.b);
cRetVal = lerp(cVal, cRetVal * fSaturatedBrightness, fLocalSaturation);
return cRetVal; } else { return lerp( cVal, dot( cVal, g_lum ), -fSaturation ); } }
float fourWayLerp( float4 fvVal, float3 fvMask ) { float fVal = lerp( fvVal.x, fvVal.y, fvMask.r ); fVal = lerp( fVal, fvVal.z, fvMask.g ); fVal = lerp( fVal, fvVal.w, fvMask.b ); return fVal; }
float2 fourWayLerp( float2 fvVal[4], float3 fvMask ) { float2 fvRetVal = lerp( fvVal[0], fvVal[1], fvMask.r ); fvRetVal = lerp( fvRetVal, fvVal[2], fvMask.g ); fvRetVal = lerp( fvRetVal, fvVal[3], fvMask.b ); return fvRetVal; }
float3 fourWayLerp( float3 fvVal[4], float3 fvMask ) { float3 fvRetVal = lerp( fvVal[0], fvVal[1], fvMask.r ); fvRetVal = lerp( fvRetVal, fvVal[2], fvMask.g ); fvRetVal = lerp( fvRetVal, fvVal[3], fvMask.b ); return fvRetVal; }
float4 fourWayLerp( float4 fvVal[4], float3 fvMask ) { float4 fvRetVal = lerp( fvVal[0], fvVal[1], fvMask.r ); fvRetVal = lerp( fvRetVal, fvVal[2], fvMask.g ); fvRetVal = lerp( fvRetVal, fvVal[3], fvMask.b ); return fvRetVal; }
void customizeCharacter( const float2 vTexcoord, inout float4 vBaseTextureSample, inout float4 vNormalSample, inout float4 vMasks1Params ) { //GENERATEBASETEXTURE
//GENERATENORMAL
//GENERATEMASKS1
#if ( ( GENERATEBASETEXTURE == 0 ) && ( GENERATENORMAL == 0 ) && ( GENERATEMASKS1 == 0 ) )
return; #endif
float4 vMaterialMaskSample = tex2D( MaterialMaskSampler, vTexcoord );
#if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
#if ( CHEAPFILTERING == 0 )
float4 fvSampleOffset[9] = { float4( 0.0f, 0.0f, 0.319727891, 0.0f ), float4( -1.0f, -1.0f, 0.051020408, 0.075f ), float4( -1.0f, 0.0f, 0.119047619, 0.175f ), float4( -1.0f, 1.0f, 0.051020408, 0.075f ), float4( 0.0f, -1.0f, 0.119047619, 0.175f ), float4( 0.0f, 1.0f, 0.119047619, 0.175f ), float4( 1.0f, -1.0f, 0.051020408, 0.075f ), float4( 1.0f, 0.0f, 0.119047619, 0.175f ), float4( 1.0f, 1.0f, 0.051020408, 0.075f ) }; #endif
float4 vAOSample = tex2D( AOSampler, vTexcoord ); float fAO = vAOSample.g; float fWear = vAOSample.b; float fCurvatureWearPower = fourWayLerp( g_vCurvatureWearPower, vMaterialMaskSample.rgb ); float fCurvature = pow( vAOSample.r, fCurvatureWearPower ); float fDurability = vAOSample.a;
// Grunge
float2 fvGrungeTexcoord = float2( dot( vTexcoord, g_vGrungeTexcoordTransform[0].xy ) + g_vGrungeTexcoordTransform[0].w, dot( vTexcoord, g_vGrungeTexcoordTransform[1].xy ) + g_vGrungeTexcoordTransform[1].w ); float4 vGrungeSamples[4] = { tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.x ) ), tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.y ) ), tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.z ) ), tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.w ) ) }; float4 cGrunge = fourWayLerp( vGrungeSamples, vMaterialMaskSample.rgb );
// Damage
float2 fvDamageLevelArray[4] = { g_vDamageLevels0, g_vDamageLevels1, g_vDamageLevels2, g_vDamageLevels3 }; float2 fvDamageLevels = fourWayLerp( fvDamageLevelArray, vMaterialMaskSample.rgb ); float fWearInfluence = fCurvature * fDurability;
// Detail
float4 vDetailSamples[4] = { tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.x, g_sampleSliceZ.x ) ), tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.y, g_sampleSliceZ.y ) ), tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.z, g_sampleSliceZ.z ) ), tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.w, g_sampleSliceZ.w ) ) };
float4 fvFinalDetails = fourWayLerp( vDetailSamples, vMaterialMaskSample.rgb );
float fCurvatureWearBoost = fourWayLerp( g_vCurvatureWearBoost, vMaterialMaskSample.rgb );
float fDamageAmount = fWearInfluence * cGrunge.a; fDamageAmount = saturate( fDamageAmount + fCurvatureWearBoost * fCurvature ); float fWearAmount = fDamageAmount; fDamageAmount *= g_fWearProgress; fWearAmount *= g_fWearProgress * 4.0f; fDamageAmount = smoothstep( fvDamageLevels.x, fvDamageLevels.y, fDamageAmount ); // wear is a halo around the damage
fWearAmount = smoothstep( fvDamageLevels.x, fvDamageLevels.y, fWearAmount ); fWearAmount = saturate( fWearAmount ) * ( 1.0f - fDamageAmount ) * fvFinalDetails.b; float fDamageAndWearAmount = saturate( fDamageAmount + fWearAmount );
float fDetail = lerp( fvFinalDetails.g, fvFinalDetails.r, fDamageAndWearAmount ); #endif
#if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
float4 cPattern = float4( 0.0f, 0.0f, 0.0f, 1.0f ); float4 cSubColor = float4( 0.0f, 0.0f, 0.0f, 1.0f ); float3 cvPaletteColorsOrig[8] = { g_cPaletteColor0, g_cPaletteColor1, g_cPaletteColor2, g_cPaletteColor3, g_cPaletteColor4, g_cPaletteColor5, g_cPaletteColor6, g_cPaletteColor7 };
#if ( USEPATTERN > 0 )
float2 vPatternTexcoord = float2( dot( vTexcoord, g_vPatternTexcoordTransform[0].xy ) + g_vPatternTexcoordTransform[0].w, dot( vTexcoord, g_vPatternTexcoordTransform[1].xy ) + g_vPatternTexcoordTransform[1].w ); vPatternTexcoord += ( fDetail * 2.0f - 1.0f ) * g_fTexelSize * g_fPatternDetailInfluence; vPatternTexcoord.x *= ( vTexcoord.x < 0 ) ? -1.0 : 1.0; float4 vPatternSample = tex2D( PatternSampler, vPatternTexcoord );
#if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
float3 cvPatternPalette[4] = { cvPaletteColorsOrig[ g_vPatternColorIndices[ 0 ] ], cvPaletteColorsOrig[ g_vPatternColorIndices[ 1 ] ], cvPaletteColorsOrig[ g_vPatternColorIndices[ 2 ] ], cvPaletteColorsOrig[ g_vPatternColorIndices[ 3 ] ] };
cPattern.rgb = fourWayLerp( cvPatternPalette, vPatternSample.rgb ); #else
cPattern.rgb = vPatternSample.rgb; #endif
cPattern.a = lerp( 1.0f, ( vPatternSample.a - 0.5f ) * 2.0f * g_fPatternPhongFactor + 1.0f, g_fPatternPhongFactor ); #endif
float4 cvPaletteColors[8]; #endif
#if ( GENERATEBASETEXTURE == 1 )
cvPaletteColors[0] = float4( g_cPaletteColor0, 1.0f ); cvPaletteColors[1] = float4( g_cPaletteColor1, 1.0f ); cvPaletteColors[2] = float4( g_cPaletteColor2, 1.0f ); cvPaletteColors[3] = float4( g_cPaletteColor3, 1.0f ); cvPaletteColors[4] = float4( g_cPaletteColor4, 1.0f ); cvPaletteColors[5] = float4( g_cPaletteColor5, 1.0f ); cvPaletteColors[6] = float4( g_cPaletteColor6, 1.0f ); cvPaletteColors[7] = float4( g_cPaletteColor7, 1.0f ); #if ( USEPATTERN > 2 )
cvPaletteColors[0] = lerp( cPattern, float4( g_cPaletteColor0, cPattern.a ), fDamageAmount ); cvPaletteColors[1] = lerp( cPattern, float4( g_cPaletteColor1, cPattern.a ), fDamageAmount ); cvPaletteColors[2] = lerp( cPattern, float4( g_cPaletteColor2, cPattern.a ), fDamageAmount ); cvPaletteColors[3] = lerp( cPattern, float4( g_cPaletteColor3, cPattern.a ), fDamageAmount ); cvPaletteColors[4] = lerp( cPattern, float4( g_cPaletteColor4, cPattern.a ), fDamageAmount ); cvPaletteColors[5] = lerp( cPattern, float4( g_cPaletteColor5, cPattern.a ), fDamageAmount ); cvPaletteColors[6] = lerp( cPattern, float4( g_cPaletteColor6, cPattern.a ), fDamageAmount ); cvPaletteColors[7] = lerp( cPattern, float4( g_cPaletteColor7, cPattern.a ), fDamageAmount ); #else
cvPaletteColors[0] = lerp( cPattern, float4( g_cPaletteColor0, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 0 ) ) ); cvPaletteColors[1] = lerp( cPattern, float4( g_cPaletteColor1, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 1 ) ) ); cvPaletteColors[2] = lerp( cPattern, float4( g_cPaletteColor2, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 2 ) ) ); cvPaletteColors[3] = lerp( cPattern, float4( g_cPaletteColor3, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 3 ) ) ); cvPaletteColors[4] = lerp( cPattern, float4( g_cPaletteColor4, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 4 ) ) ); cvPaletteColors[5] = lerp( cPattern, float4( g_cPaletteColor5, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 5 ) ) ); cvPaletteColors[6] = lerp( cPattern, float4( g_cPaletteColor6, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 6 ) ) ); cvPaletteColors[7] = lerp( cPattern, float4( g_cPaletteColor7, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 7 ) ) ); #endif
#endif
#if ( ( GENERATEBASETEXTURE == 0 ) && ( GENERATENORMAL == 1 ) )
cvPaletteColors[0] = float4( 1.0f, 1.0f, 1.0f, 1.0f ); cvPaletteColors[1] = float4( 1.0f, 1.0f, 1.0f, 1.0f ); cvPaletteColors[2] = float4(1.0f, 1.0f, 1.0f, 1.0f); cvPaletteColors[3] = float4(1.0f, 1.0f, 1.0f, 1.0f); cvPaletteColors[4] = float4(1.0f, 1.0f, 1.0f, 1.0f); cvPaletteColors[5] = float4(1.0f, 1.0f, 1.0f, 1.0f); cvPaletteColors[6] = float4(1.0f, 1.0f, 1.0f, 1.0f); cvPaletteColors[7] = float4(1.0f, 1.0f, 1.0f, 1.0f);
#if ( USEPATTERN > 2 )
cvPaletteColors[0].a = cPattern.a; cvPaletteColors[1].a = cPattern.a; cvPaletteColors[2].a = cPattern.a; cvPaletteColors[3].a = cPattern.a; cvPaletteColors[4].a = cPattern.a; cvPaletteColors[5].a = cPattern.a; cvPaletteColors[6].a = cPattern.a; cvPaletteColors[7].a = cPattern.a; #else
cvPaletteColors[0].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 0 ) ) ); cvPaletteColors[1].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 1 ) ) ); cvPaletteColors[2].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 2 ) ) ); cvPaletteColors[3].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 3 ) ) ); cvPaletteColors[4].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 4 ) ) ); cvPaletteColors[5].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 5 ) ) ); cvPaletteColors[6].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 6 ) ) ); cvPaletteColors[7].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 7 ) ) ); #endif
#endif
#if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
//switching to float4[2] to save on temp registers
//float fvSubColorMask[7] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
float4 fvSubColorMask[2] = { float4( 0, 0, 0, 0 ), float4( 0, 0, 0, 0 ) }; #if ( CHEAPFILTERING == 0 )
for ( int i = 0; i < 9; i++ ) { float fSubColorMask = tex2D( MaterialMaskSampler, vTexcoord + fvSampleOffset[i].xy * g_fTexelSize ).a; for ( int j = 0; j < 2; j++ ) for ( int k = 0; k < 4; k++ ) { if ( ( j * 4 + k ) == ( floor( fSubColorMask * 8 ) - 1 ) ) fvSubColorMask[j][k] += fvSampleOffset[i].z; } }
// fill in under the blurred mask
for ( i = 0; i < 2; i++ ) for ( int j = 0; j < 4; j++ ) for ( int k = 0; k <= i; k++ ) { int maxl = ( i == k ) ? j : 4; for ( int l = 0; l < maxl; l++ ) fvSubColorMask[k][l] = saturate( fvSubColorMask[k][l] + ( fvSubColorMask[k][l] > 0 ) * ( fvSubColorMask[i][j] > 0 ) );
} #else
float fSubColorMask = tex2D( MaterialMaskSampler, vTexcoord ).a;
for ( int i = 0; i < 2; i++ ) for ( int j = 0; j < 4; j++ ) { fvSubColorMask[i][j] = ( ( i * 4 + j ) == ( floor( fSubColorMask * 8 ) - 1 ) ); } #endif
#endif
#if ( GENERATEBASETEXTURE == 1)
cSubColor = lerp( cvPaletteColors[0], cvPaletteColors[1], fvSubColorMask[0][0] ); cSubColor = lerp( cSubColor, cvPaletteColors[2], fvSubColorMask[0][1] ); cSubColor = lerp( cSubColor, cvPaletteColors[3], fvSubColorMask[0][2] ); cSubColor = lerp( cSubColor, cvPaletteColors[4], fvSubColorMask[0][3] ); cSubColor = lerp( cSubColor, cvPaletteColors[5], fvSubColorMask[1][0] ); cSubColor = lerp( cSubColor, cvPaletteColors[6], fvSubColorMask[1][1] ); cSubColor = lerp( cSubColor, cvPaletteColors[7], fvSubColorMask[1][2] ); #endif
#if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
float fPatternMask = ( 1.0f - fDamageAmount );
#if ( USEPATTERN == 1 )
if ( g_nPatternReplaceIndex == 0 ) { fPatternMask *= 1.0f - fvSubColorMask[0][0]; fPatternMask *= 1.0f - fvSubColorMask[0][1]; fPatternMask *= 1.0f - fvSubColorMask[0][2]; fPatternMask *= 1.0f - fvSubColorMask[0][3]; fPatternMask *= 1.0f - fvSubColorMask[1][0]; fPatternMask *= 1.0f - fvSubColorMask[1][1]; fPatternMask *= 1.0f - fvSubColorMask[1][2]; } else { fPatternMask *= fvSubColorMask[ g_nPatternReplaceIndex > 4 ][ g_nPatternReplaceIndex > 4 ? g_nPatternReplaceIndex - 5 : g_nPatternReplaceIndex - 1 ]; } #endif
float fPaintThickness = 0.0f;
#if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
fPaintThickness = ( vPatternSample.r + vPatternSample.g + vPatternSample.b ) * g_fPatternPaintThickness;
if ( g_fPatternPaintThickness > 0 ) { float4 vPatternShadowSample = tex2Dbias( PatternSampler, float4( vPatternTexcoord, 0.0f, 0.5f + 0.1f * g_fPatternPaintThickness ) ); float fPaintShadowPower = g_fPatternPaintThickness; float fPaintShadow = lerp( pow( 1.0f - vPatternShadowSample.r, fPaintShadowPower ), 1.0f, vPatternSample.r ); fPaintShadow *= lerp( pow( 1.0f - vPatternShadowSample.g, fPaintShadowPower ), 1.0f, vPatternSample.g ); fPaintShadow *= lerp( pow( 1.0f - vPatternShadowSample.b, fPaintShadowPower ), 1.0f, vPatternSample.b ); fAO *= lerp( 1.0f, fPaintShadow, fPatternMask ); }
fPatternMask *= saturate( fPaintThickness ); fvFinalDetails.rgb = lerp( fvFinalDetails.rgb, float3( 0.5f, 0.5f, 0.0f ), saturate( fPaintThickness ) * fPatternMask ); fDetail = lerp( fDetail, 1.0f, saturate( fPaintThickness ) * fPatternMask ); #endif
#endif
#if ( GENERATEBASETEXTURE == 1 )
float3 cFinalColor = cSubColor.rgb; float fDamageDetailSaturation = fourWayLerp( g_vDamageDetailSaturation, vMaterialMaskSample.rgb );
float fSubColorLum = dot( g_lum, cSubColor.rgb );
// Apply Curvature
float fDetailCurvatureClean = ( 1.0f - abs( ddx( fvFinalDetails.g * fCurvature ) ) ) * ( 1.0f - abs( ddy( fvFinalDetails.g * fCurvature ) ) ); fDetailCurvatureClean *= saturate( abs( ddx( fvFinalDetails.g * fCurvature ) ) + abs( ddy ( fvFinalDetails.g * fCurvature ) ) );
float fDetailCurvatureDamaged = ( 1.0f - abs( ddx( fvFinalDetails.r * fCurvature ) ) ) * ( 1.0f - abs( ddy( fvFinalDetails.r * fCurvature ) ) ); fDetailCurvatureDamaged *= saturate( abs( ddx( fvFinalDetails.r * fCurvature ) ) + abs( ddy ( fvFinalDetails.r * fCurvature ) ) );
float fDetailCurvature = lerp( fDetailCurvatureClean, fDetailCurvatureDamaged, fDamageAmount );
fDetailCurvature *= 1.0f - saturate( abs( ddx( vMaterialMaskSample.r + vMaterialMaskSample.g + vMaterialMaskSample.b ) ) ); fDetailCurvature *= 1.0f - saturate( abs( ddy( vMaterialMaskSample.r + vMaterialMaskSample.g + vMaterialMaskSample.b ) ) );
// use a little curvature to exaggerate form
cFinalColor = lerp( cFinalColor, cFinalColor * fCurvature * 2.0f, 0.5f ); // lighten sharp edges a little to highlight them
cFinalColor = lerp( cFinalColor, cFinalColor + cFinalColor * fDetailCurvature, 0.5f ); // Bleaching
float fWearBleaching = fourWayLerp( g_vWearBleaching, vMaterialMaskSample.rgb ); float fDamageBleaching = fourWayLerp( g_vDamageBleaching, vMaterialMaskSample.rgb );
// Grime
float fGrimeBrightnessAdjustment = fourWayLerp( g_vGrimeBrightness, vMaterialMaskSample.rgb ); float fGrimeBrightness = dot( cGrunge.rgb, g_lum ); float fGrimeDetailSaturation = fourWayLerp( g_vGrimeSaturation, vMaterialMaskSample.rgb ); float3 cGrime = colorize( cGrunge.rgb, cGrunge.rgb, fGrimeBrightness, fGrimeDetailSaturation ); cGrime *= ( 1.0f + fGrimeBrightnessAdjustment );
float fBleaching = lerp( g_fWearProgress * fWear * fWearBleaching, fDamageBleaching, fDamageAndWearAmount );
// Add some grunge even to pristine materials
float fDetailGrungeFactor = fourWayLerp( g_vDetailGrungeFactor, vMaterialMaskSample.rgb ); fDetailGrungeFactor = fDetailGrungeFactor * ( 1.0f + g_fWearProgress * fDetailGrungeFactor ); // Desaturate grunge somewhat at low opacities
float3 fColorVariation = lerp( cFinalColor, dot( cFinalColor, g_lum ), saturate( 1.0f - fDetailGrungeFactor ) ); float3 cColorVariation = lerp( cFinalColor, cFinalColor * cGrunge.rgb * 4.0f, fDetailGrungeFactor * ( 1.0f - fDamageAndWearAmount ) );
cFinalColor = lerp( cColorVariation, cGrime * fDetail, fBleaching );
float fBrightnessAdjustment = fourWayLerp( g_vDamageBrightness, vMaterialMaskSample.rgb ); float fBrightness = dot( cFinalColor, g_lum ); float3 cFinalSaturation = colorize( cFinalColor, cSubColor.rgb, fBrightness, fDamageDetailSaturation ); cFinalColor = lerp( cFinalColor, cFinalSaturation * ( 1.0f + fBrightnessAdjustment ), fDamageAndWearAmount );
// Grunge
float fGrungeAmount = smoothstep( 0.45f, 0.75f, ( 1.0f - vAOSample.r * vAOSample.g * vAOSample.g ) * g_fWearProgress ) * ( 1.0f - fSubColorLum * 0.5f ); float fGrungeMax = fourWayLerp( g_vGrungeMax, vMaterialMaskSample.rgb ); fGrungeAmount *= fGrungeMax; cFinalColor = lerp( cFinalColor, cGrunge.rgb * cFinalColor, fGrungeAmount );
// AO
cFinalColor = lerp( cFinalColor * cFinalColor * fAO, cFinalColor, fAO ); cFinalColor = lerp( cFinalColor * cFinalColor * fDetail * 2.0f, cFinalColor, fDetail );
fBrightness = dot( cFinalColor, g_lum ); float3 cMottleColor1 = float3( 0.6f, 1.0f, 0.0f ); float3 cMottleColor2 = float3( 0.2f, 0.6f, 1.0f ); if ( ( cFinalColor.r > cFinalColor.g ) && ( cFinalColor.r > cFinalColor.b ) ) { cMottleColor1 += cFinalColor.brg; cMottleColor2 += cFinalColor.bgr; } else if ( ( cFinalColor.g > cFinalColor.r ) && ( cFinalColor.g > cFinalColor.b ) ) { cMottleColor1 += cFinalColor.brg; cMottleColor2 += cFinalColor.gbr; } float fSaturation = pow( ( 1.0f - fSubColorLum ), 3.5f ) * 0.3f; fSaturation += length( cFinalColor - fBrightness.xxx ) * 0.15f + 0.05f; float3 fvMottle = tex2D( NoiseSampler, vTexcoord * 2.0f ).rgb; float fAOMottle = pow( vAOSample.g, 8.0f ); fvMottle.r = saturate( fAOMottle * fvMottle.r ); fvMottle.b = saturate( fvMottle.b * ( 0.5f + fAOMottle * 0.5f ) );
cFinalColor = lerp( lerp( colorize( cFinalColor, cMottleColor2, fBrightness, fSaturation ), colorize( cFinalColor, cMottleColor1, fBrightness, fSaturation ), fvMottle.r ), cFinalColor, fvMottle.b ); cFinalColor = saturate( cFinalColor );
vBaseTextureSample.rgb = cFinalColor;
#endif
#if ( ( GENERATENORMAL == 1 ) || ( ( GENERATEBASETEXTURE == 1 ) && ( ( BASEALPHAPHONGMASK == 1) || ( BASEALPHAENVMASK == 1 ) ) ) )
float fDamageNormalEdgeDepth = fourWayLerp( g_vDamageNormalEdgeDepth, vMaterialMaskSample.rgb );
float2 fvDamageEdgeNormal = float2( 0.0f, 0.0f ); float2 fPaintModifier = 1.0f;
#if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
fPaintModifier = 1.0f + fPatternMask * g_fPatternPaintThickness; #endif
float fDamageEdgeMask = 0.0f;
for ( int o = 0; o < 2; o++ ) { for ( int n = 0; n < 2; n++ ) { float4 fvGrungeSamples = 0; float2 fvSampleOffset = float2( o * 2 - 1, n * 2 - 1 );
float fGrungeSample = 0;
float2 vSampleTexcoord = fvGrungeTexcoord + fvSampleOffset.xy * g_fTexelSize * fDamageNormalEdgeDepth * fPaintModifier; fvGrungeSamples.x = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.x ) ).a; fvGrungeSamples.y = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.y ) ).a; fvGrungeSamples.z = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.z ) ).a; fvGrungeSamples.w = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.w ) ).a;
fGrungeSample = fourWayLerp( fvGrungeSamples, vMaterialMaskSample.rgb );
fGrungeSample *= fWearInfluence; fGrungeSample = saturate( fGrungeSample + fCurvatureWearBoost * fCurvature ); fGrungeSample *= g_fWearProgress; fGrungeSample = smoothstep( fvDamageLevels.x, fvDamageLevels.y, fGrungeSample );
fvDamageEdgeNormal.xy -= ( fDamageAmount - fGrungeSample ) * fvSampleOffset; fDamageEdgeMask += abs( fDamageAmount - fGrungeSample ); } }
fDamageEdgeMask = fDamageEdgeMask * 0.25f;
#endif
#if ( GENERATENORMAL == 1 )
fvDamageEdgeNormal = float2( dot( fvDamageEdgeNormal, g_vGrungeTexcoordRotation[0].xy ), dot( fvDamageEdgeNormal, g_vGrungeTexcoordRotation[1].xy ) );
float3 fvFinalNormal = vNormalSample * 2.0f - 1.0f;
// Detail normals
float4 vNormalSamples[4] = { tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.x, g_sampleSliceZ.x ) ), tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.y, g_sampleSliceZ.y ) ), tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.z, g_sampleSliceZ.z ) ), tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.w, g_sampleSliceZ.w ) ) };
float4 fvDetailNormal = fourWayLerp( vNormalSamples, vMaterialMaskSample.rgb );
float2 fvDetailNormalDamage = fvDetailNormal.zw * 2.0f - 1.0f; float2 fvDetailNormalClean = fvDetailNormal.xy * 2.0f - 1.0f;
float fDetailNormalDepth = fourWayLerp( g_vDetailNormalDepth, vMaterialMaskSample.rgb );
fvDetailNormal.xy = lerp( fvDetailNormalClean, fvDetailNormalDamage, fDamageAmount ); fvDetailNormal.xy *= fDetailNormalDepth;
float2 fvPaintEdgeNormal = float2( 0.0f, 0.0f );
#if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
for ( int m = 0; m < 2; m++ ) { for ( int n = 0; n < 2; n++ ) { float2 fvSampleOffset = float2( m * 2 - 1, n * 2 - 1 ); float3 fvPaintSample = tex2D( PatternSampler, vPatternTexcoord + fvSampleOffset.xy * g_fTexelSize * g_fPatternPaintThickness * 2.0f ).rgb; float fPaintSample = ( fvPaintSample.r + fvPaintSample.g + fvPaintSample.b );// * ( 1.0f - fDamageAmount );
fvPaintEdgeNormal += ( fPaintThickness - fPaintSample ) * fvSampleOffset; } }
fvPaintEdgeNormal = float2( dot( fvPaintEdgeNormal, g_vPatternTexcoordRotation[0].xy ), dot( fvPaintEdgeNormal, g_vPatternTexcoordRotation[1].xy ) );
fvPaintEdgeNormal.x *= g_fFlipFixup; if ( vTexcoord.x < 0 ) { fvPaintEdgeNormal.x *= -1; } fvDetailNormal.xy = lerp( fvDetailNormal.xy, float2( 0, 0 ), min( pow( saturate( fPatternMask * g_fPatternPaintThickness ), 0.5f ), 0.9f ) ); fvPaintEdgeNormal *= fPatternMask * g_fPatternPaintThickness; fDamageNormalEdgeDepth += fPatternMask * g_fPatternPaintThickness;
#endif
// Detail normal edges
fvDamageEdgeNormal.xy *= fDamageNormalEdgeDepth /** ( 1.0f - fDamageAmount * fDamageAmount )*/;
float2 fvEdgeNormals = lerp( fvPaintEdgeNormal.xy, fvDamageEdgeNormal.xy, fDamageAmount ); vNormalSample.xyz = fvFinalNormal.xyz; vNormalSample.xy += fvDetailNormal; vNormalSample.xy += fvEdgeNormals; vNormalSample.xyz = normalize( vNormalSample.xyz ) * 0.5f + 0.5f;
#endif
#if ( ( ( GENERATEBASETEXTURE == 1 ) && ( ( BASEALPHAPHONGMASK == 1 ) || ( BASEALPHAENVMASK == 1 ) ) ) || ( ( GENERATENORMAL == 1 ) && ( ( BASEALPHAPHONGMASK == 0 ) || ( BUMPALPHAENVMASK == 1 ) ) ) )
float fDetailGrungePhongFactor = fourWayLerp( g_vDetailGrungeFactor, vMaterialMaskSample.rgb ); fDetailGrungePhongFactor = saturate( g_fWearProgress + fDetailGrungePhongFactor ); fDetailGrungePhongFactor = lerp( 1.0f, dot( cGrunge.rgb, g_lum ), fDetailGrungePhongFactor ); #endif
#if ( ( ( GENERATEBASETEXTURE == 1 ) && ( BASEALPHAPHONGMASK == 1 ) ) || ( ( GENERATENORMAL == 1 ) && ( BASEALPHAPHONGMASK == 0 ) ) )
float fWearDetailPhongBoost = fourWayLerp( g_vWearDetailPhongBoost, vMaterialMaskSample.rgb ); float fDamageEdgePhongBoost = fourWayLerp( g_vDamageEdgePhongBoost, vMaterialMaskSample.rgb );
float fDetailSpec = fourWayLerp( g_vDetailSpecBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.a; float fDamageDetailSpec = fourWayLerp( g_vDamageDetailSpecBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.r; fDetailSpec = lerp( fDetailSpec, fDamageDetailSpec, fDamageAmount );
fDetailSpec *= fDetailGrungePhongFactor;
fDetailSpec = lerp( fDetailSpec, fDetailSpec * fWearDetailPhongBoost, fWearAmount ); fDetailSpec = lerp( fDetailSpec, fDetailSpec * fDamageEdgePhongBoost, fDamageEdgeMask );
fDetailSpec *= cSubColor.a;
fDetailSpec = saturate( fDetailSpec );
#if ( ( GENERATEBASETEXTURE == 1) && ( BASEALPHAPHONGMASK == 1 ) )
vBaseTextureSample.a = fAO * fAO * fDetailSpec; #else
vNormalSample.a = fAO * fAO * fDetailSpec; #endif
#endif
#if ( ( ( GENERATEBASETEXTURE == 1 ) && ( BASEALPHAENVMASK == 1) && ( BASEALPHAPHONGMASK == 0 ) ) || ( ( GENERATENORMAL == 1 ) && ( BASEALPHAPHONGMASK == 1 ) && ( BUMPALPHAENVMASK == 1 ) ) )
float fWearDetailEnvBoost = fourWayLerp( g_vWearDetailEnvBoost, vMaterialMaskSample.rgb ); float fDamageEdgeEnvBoost = fourWayLerp( g_vDamageEdgeEnvBoost, vMaterialMaskSample.rgb ); fWearDetailEnvBoost = abs( fWearDetailEnvBoost ) * ( fWearDetailEnvBoost < 0 ? 1.0f - fWear * fvFinalDetails.b : fWear * fvFinalDetails.b );
float fDetailEnv = fourWayLerp( g_vDetailEnvBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.a; float fDamageDetailEnv = fourWayLerp( g_vDamageDetailEnvBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.r; fDetailEnv = lerp( fDetailEnv, fDamageDetailEnv, fDamageAmount );
fDetailEnv *= fDetailGrungePhongFactor;
fDetailEnv = lerp( fDetailEnv, fDetailEnv * fWearDetailEnvBoost, fWearAmount ); fDetailEnv = lerp( fDetailEnv, fDetailEnv * fDamageEdgeEnvBoost, fDamageEdgeMask );
fDetailEnv *= cSubColor.a;
fDetailEnv = saturate( fDetailEnv );
#if ( ( GENERATEBASETEXTURE == 1) && ( BASEALPHAENVMASK == 1) )
vBaseTextureSample.a = fAO * fAO * fDetailEnv; #else
vNormalSample.a = fAO * fAO * fDetailEnv; #endif
#endif
#if ( GENERATEMASKS1 == 1 )
//Phong Albedo Tint
float fPhongAlbedoTint = fourWayLerp( g_vDetailPhongAlbedoTint, vMaterialMaskSample.rgb ); // Material ID
float fWarpIndex = fourWayLerp( g_vDetailWarpIndex, vMaterialMaskSample.rgb ); // Metalness
float fMetalness = fourWayLerp( g_vDetailMetalness, vMaterialMaskSample.rgb ); // Masks 1
vMasks1Params.gba = float3( fPhongAlbedoTint, fMetalness, fWarpIndex ); #endif
}
|