#ifndef PLAYER_CAMO_GBUFFER_INCLUDED #define PLAYER_CAMO_GBUFFER_INCLUDED // Camo variant of URP's LitGBufferPassFragment. Include AFTER LitGBufferPass.hlsl (reuses its // Varyings / InitializeInputData / InitializeBakedGIData). // // The project renders FORWARD, so this GBuffer pass has exactly ONE consumer: HTrace WSGI renders // its thin GBuffer through the "UniversalGBuffer" tag and its GI composite multiplies the traced // irradiance by GBuffer0.rgb (diffuse albedo) and GBuffer1.a (occlusion), ADDING the result after // post-processing - i.e. after the forward pass's camo grade already ran. Two camo hooks keep that // injected indirect light consistent with the graded forward look: // 1. ApplyPaintedHeightSurface: forward AO semantics for the painted height (neutral 0.5 -> AO 1) // instead of the raw 0.5-centred height value in GBuffer1.a, + the relief normal. // 2. ApplyCamoBodyGrade on the albedo: brightness/saturation follow into the injected GI, so // desaturated paint stays desaturated in shadows / under indirect light. // Everything else is a faithful copy of URP 17.3 LitGBufferPass.hlsl's fragment. #include "PlayerCamoShared.hlsl" GBufferFragOutput CamoGBufferFragment(Varyings input) { UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); #if defined(_PARALLAXMAP) #if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) half3 viewDirTS = input.viewDirTS; #else half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS); half3 viewDirTS = GetViewDirectionTangentSpace(input.tangentWS, input.normalWS, viewDirWS); #endif ApplyPerPixelDisplacement(viewDirTS, input.uv); #endif SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); // Camo hooks (see header). The albedo grade is clamped: GBuffer0 is UNORM, and HTrace multiplies // its GI by the stored value, so out-of-range brightness would clip there anyway. ApplyPaintedHeightSurface(input.uv, surfaceData); ApplyCamoBodyGrade(surfaceData.albedo); surfaceData.albedo = saturate(surfaceData.albedo); #ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); #endif InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, UNDO_TRANSFORM_TEX(input.uv, _BaseMap)); #if defined(_DBUFFER) ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData); #endif InitializeBakedGIData(input, inputData); BRDFData brdfData; InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); half3 color = GlobalIllumination(brdfData, (BRDFData)0, 0, inputData.bakedGI, surfaceData.occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); return PackGBuffersBRDFData(brdfData, inputData, surfaceData.smoothness, surfaceData.emission + color, surfaceData.occlusion); } #endif