Files
2026-01-08 20:43:08 +05:00

128 lines
4.9 KiB
HLSL

#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