#ifndef SG_TERRAIN_PBRGBUFFERPASS_INC #define SG_TERRAIN_PBRGBUFFERPASS_INC #include "TerrainVert.hlsl" void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, out InputData inputData) { inputData = (InputData)0; inputData.positionWS = input.positionWS; half3 SH = 0.0h; CalculateTerrainNormalWS(input, surfaceDescription, inputData); #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) inputData.shadowCoord = input.shadowCoord; #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); #else inputData.shadowCoord = float4(0, 0, 0, 0); #endif inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.fogFactorAndVertexLight.x); inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; #if defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, SH, inputData.normalWS); #else inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, SH, inputData.normalWS); #endif inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); #if defined(DEBUG_DISPLAY) #if defined(DYNAMICLIGHTMAP_ON) inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; #endif #if defined(LIGHTMAP_ON) inputData.staticLightmapUV = input.staticLightmapUV; #else inputData.vertexSH = input.sh; #endif #endif } GBufferFragOutput frag(PackedVaryings packedInput) { Varyings unpacked = UnpackVaryings(packedInput); UNITY_SETUP_INSTANCE_ID(unpacked); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); #ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL float2 sampleCoords = (unpacked.texCoord0.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy; float3 normalOS = SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb; normalOS = normalize(normalOS * 2.0 - 1.0); unpacked.normalWS = TransformObjectToWorldNormal(normalOS); #ifdef VARYINGS_NEED_TANGENT_WS float4 tangentOS = ConstructTerrainTangent(normalOS, float3(0.0, 0.0, 1.0)); unpacked.tangentWS = float4(TransformObjectToWorldNormal(normalize(tangentOS.xyz)), tangentOS.w); #endif #endif SurfaceDescription surfaceDescription = BuildSurfaceDescription(unpacked); #ifdef _TERRAIN_SG_ALPHA_CLIP half alpha = AlphaDiscard(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold); #else half alpha = 1.0; #endif InputData inputData; InitializeInputData(unpacked, surfaceDescription, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, unpacked.texCoord0); float3 specular = 0; float metallic = surfaceDescription.Metallic; half3 normalTS = half3(0, 0, 0); #if defined(_NORMALMAP) && defined(_NORMAL_DROPOFF_TS) normalTS = surfaceDescription.NormalTS; #endif SurfaceData surface; surface.albedo = surfaceDescription.BaseColor; surface.metallic = saturate(metallic); surface.specular = specular; surface.smoothness = saturate(surfaceDescription.Smoothness), surface.occlusion = surfaceDescription.Occlusion, surface.emission = surfaceDescription.Emission, surface.alpha = 1.0; surface.normalTS = normalTS; surface.clearCoatMask = 0; surface.clearCoatSmoothness = 1; surface.albedo = AlphaModulate(surface.albedo, surface.alpha); #ifdef _DBUFFER ApplyDecalToSurfaceData(unpacked.positionCS, surface, inputData); #endif BRDFData brdfData; InitializeBRDFData(surfaceDescription.BaseColor, metallic, specular, surfaceDescription.Smoothness, alpha, brdfData); // Baked lighting. half4 color; Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); color.rgb = GlobalIllumination(brdfData, inputData.bakedGI, surfaceDescription.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS); color.a = alpha; SplatmapFinalColor(color, inputData.fogCoord); // Dynamic lighting: emulate SplatmapFinalColor() by scaling gbuffer material properties. This will not give the same results // as forward renderer because we apply blending pre-lighting instead of post-lighting. // Blending of smoothness and normals is also not correct but close enough? brdfData.albedo.rgb *= alpha; brdfData.diffuse.rgb *= alpha; brdfData.specular.rgb *= alpha; brdfData.reflectivity *= alpha; inputData.normalWS = inputData.normalWS * alpha; surfaceDescription.Smoothness *= alpha; return PackGBuffersBRDFData(brdfData, inputData, surfaceDescription.Smoothness, color.rgb, surfaceDescription.Occlusion); } #endif