Files
2026-08-09 04:23:10 -07:00

205 lines
7.4 KiB
C++

/*
==================================================================================
FETCH_UNIQUE
==================================================================================
*/
#template FETCH_UNIQUE( sampleSpecular, sampleYCoCg, sampleNormal )
{
float3 physCoord = UniqueVirtualToPhysical( fragment.texcoord0.xy );
#ifdef USE_VIRTUAL_ANISO_FOOTPRINT
float2 dx = ddx( fragment.texcoord0.xy ) * physCoord.z;
float2 dy = ddy( fragment.texcoord0.xy ) * physCoord.z;
sampleSpecular = texPhys( $physicalUniquePagesMap0, physCoord.xy, dx, dy );
sampleYCoCg = texPhys( $physicalUniquePagesMap1, physCoord.xy, dx, dy );
sampleNormal = texPhys( $physicalUniquePagesMap2, physCoord.xy, dx, dy );
#else
sampleSpecular = h4texPhys( $physicalUniquePagesMap0, physCoord.xy );
sampleYCoCg = h4texPhys( $physicalUniquePagesMap1, physCoord.xy );
sampleNormal = h4texPhys( $physicalUniquePagesMap2, physCoord.xy );
#endif
}
#endtemplate
/*
==================================================================================
FETCH_UNIQUE_BLEND
uses fragment.texcoord0;
out half4 sampleSpecular;
out half4 sampleYCoCg;
out half4 sampleNormal;
out half2 feedbackTexCoord;
out half morphScale;
==================================================================================
*/
#template FETCH_UNIQUE_BLEND( sampleSpecular, sampleYCoCg, sampleNormal, feedbackTexCoord, morphScale )
{
float4 texCoord = fragment.texcoord0;
float3 physCoord = UniqueVirtualToPhysical( texCoord.xy );
#ifdef USE_VIRTUAL_ANISO_FOOTPRINT
float2 dx = ddx( texCoord.xy ) * physCoord.z;
float2 dy = ddy( texCoord.xy ) * physCoord.z;
sampleSpecular = texPhys( $physicalUniquePagesMap0, physCoord.xy, dx, dy );
sampleYCoCg = texPhys( $physicalUniquePagesMap1, physCoord.xy, dx, dy );
sampleNormal = texPhys( $physicalUniquePagesMap2, physCoord.xy, dx, dy );
#else
sampleSpecular = texPhys( $physicalUniquePagesMap0, physCoord.xy );
sampleYCoCg = texPhys( $physicalUniquePagesMap1, physCoord.xy );
sampleNormal = texPhys( $physicalUniquePagesMap2, physCoord.xy );
#endif
feedbackTexCoord = texCoord.xy;
/* blend in another texture based on the morph map */
{
float3 physCoord = UniqueVirtualToPhysical( texCoord.zw );
#ifdef USE_VIRTUAL_ANISO_FOOTPRINT
float2 dx = ddx( texCoord.zw ) * physCoord.z;
float2 dy = ddy( texCoord.zw ) * physCoord.z;
float4 sampleSpecular2 = texPhys( $physicalUniquePagesMap0, physCoord.xy, dx, dy );
float4 sampleYCoCg2 = texPhys( $physicalUniquePagesMap1, physCoord.xy, dx, dy );
float4 sampleNormal2 = texPhys( $physicalUniquePagesMap2, physCoord.xy, dx, dy );
#else
float4 sampleSpecular2 = texPhys( $physicalUniquePagesMap0, physCoord.xy );
float4 sampleYCoCg2 = texPhys( $physicalUniquePagesMap1, physCoord.xy );
float4 sampleNormal2 = texPhys( $physicalUniquePagesMap2, physCoord.xy );
#endif
sampleSpecular = lerp( sampleSpecular, sampleSpecular2, morphScale );
sampleYCoCg = lerp( sampleYCoCg, sampleYCoCg2, morphScale );
sampleNormal = lerp( sampleNormal, sampleNormal2, morphScale );
float2 fp = fragment.position.xy * $positionToFeedback.zw;
float2 xy = frac( fp ) - 0.5;
feedbackTexCoord = ( xy.x * xy.y < 0.0 ) ? texCoord.xy : texCoord.zw;
}
}
#endtemplate
/*
==================================================================================
FETCH_UNIQUE_YCOCG
==================================================================================
*/
#template FETCH_UNIQUE_YCOCG( sampleYCoCg )
{
float3 physCoord = UniqueVirtualToPhysical( fragment.texcoord0.xy );
#ifdef USE_VIRTUAL_ANISO_FOOTPRINT
float2 dx = ddx( fragment.texcoord0.xy ) * physCoord.z;
float2 dy = ddy( fragment.texcoord0.xy ) * physCoord.z;
sampleYCoCg = texPhys( $physicalUniquePagesMap1, physCoord.xy, dx, dy );
#else
sampleYCoCg = texPhys( $physicalUniquePagesMap1, physCoord.xy );
#endif
}
#endtemplate
/*
==================================================================================
FETCH_DIFFUSE_ONLY
==================================================================================
*/
#template FETCH_DIFFUSE_ONLY( sampleYCoCg )
{
float3 physCoord = UniqueDiffuseOnlyVirtualToPhysical( fragment.texcoord0.xy );
#ifdef USE_VIRTUAL_ANISO_FOOTPRINT
float2 dx = ddx( fragment.texcoord0.xy ) * physCoord.z;
float2 dy = ddy( fragment.texcoord0.xy ) * physCoord.z;
sampleYCoCg = texPhys( $physicalUniqueDiffuseOnlyPagesMap1, physCoord.xy, dx, dy );
#else
sampleYCoCg = texPhys( $physicalUniqueDiffuseOnlyPagesMap1, physCoord.xy );
#endif
}
#endtemplate
/*
==================================================================================
FETCH_DIFFUSE_ONLY2
==================================================================================
*/
#template FETCH_DIFFUSE_ONLY2( sampleYCoCg )
{
float3 physCoord = UniqueDiffuseOnly2VirtualToPhysical( fragment.texcoord0.xy );
#ifdef USE_VIRTUAL_ANISO_FOOTPRINT
float2 dx = ddx( fragment.texcoord0.xy ) * physCoord.z;
float2 dy = ddy( fragment.texcoord0.xy ) * physCoord.z;
sampleYCoCg = texPhys( $physicalUniqueDiffuseOnly2PagesMap1, physCoord.xy, dx, dy );
#else
sampleYCoCg = texPhys( $physicalUniqueDiffuseOnly2PagesMap1, physCoord.xy );
#endif
}
#endtemplate
/*
==================================================================================
CALC_DIFFUSE_RGB
==================================================================================
*/
#template CALC_DIFFUSE_RGB( diffuse, sampleYCoCg )
{
sampleYCoCg.z = ( sampleYCoCg.z * 31.875 ) + 1.0; /* z = z * 255.0/8.0 + 1.0 */
sampleYCoCg.z = 1.0 / sampleYCoCg.z;
sampleYCoCg.xy *= sampleYCoCg.z;
diffuse.x = dot4( sampleYCoCg, matrixCoCg1YtoRGB1X );
diffuse.y = dot4( sampleYCoCg, matrixCoCg1YtoRGB1Y );
diffuse.z = dot4( sampleYCoCg, matrixCoCg1YtoRGB1Z );
diffuse.w = 0.5; // how much to accept dim-shadows
diffuse.xyz *= $newDiffuseScale.xyz;
}
#endtemplate
/*
==================================================================================
APPLY_SPECULAR
==================================================================================
*/
#template APPLY_SPECULAR( color, sampleSpecular, sampleNormal, localToGlobalX, localToGlobalY, localToGlobalZ, viewOriginToFragment )
{
/* Note that the optimized derivation of the localNormal below results */
/* in a vector that is half-unit length! */
half3 localNormal;
localNormal.xy = sampleNormal.wy - 0.5;
localNormal.z = sqrt( abs( dot( localNormal.xy, localNormal.xy ) - 0.25 ) );
/* transform the normal into ambient map space */
half3 globalNormal;
globalNormal.x = dot3( localNormal, localToGlobalX );
globalNormal.y = dot3( localNormal, localToGlobalY );
globalNormal.z = dot3( localNormal, localToGlobalZ );
globalNormal = normalize( globalNormal );
/* calculate the specular reflection vector from viewer and globalNormal */
half4 reflection;
reflection.xyz = viewOriginToFragment - ( globalNormal * dot3( viewOriginToFragment, globalNormal ) * 2.0 );
/* Power factor is stored in sampleNormal.x as 0.0 - 1.0 */
/* We want a 0 | 1 | 2 | 3 mip value. */
/* The artists really prefer white to be shiny instead of dull, so invert it here. */
/* We could probably skip the floor, but I am wary of hardware / api rounding. */
reflection.w = floor( ( 1.0 - sampleNormal.x ) * 4.0 + $newPowerScale.x );
half3 envColor = texCUBElod( $dynamicEnvMap, reflection ).xyz;
half3 specular = sampleSpecular.xyz * 8.0 / ( sampleNormal.z * 255.0 + 8.0 );
/* modulate by the environment mask map (specular channel) */
color.xyz += envColor * specular * $newSpecularScale.xyz;
}
#endtemplate