#ifndef XPBR_LIT_BASE #define XPBR_LIT_BASE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" CBUFFER_START(UnityPerMaterial) float4 _MainTex_ST; half4 _BaseColor; half _Cutoff; half _Metallic; half _Roughness; half _AO; CBUFFER_END half _XRuntimeAmbientEnabled; half4 _XRuntimeAmbientSky; half4 _XRuntimeAmbientEquator; half4 _XRuntimeAmbientGround; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); TEXTURE2D(_MixTex); SAMPLER(sampler_MixTex); struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float2 texcoord : TEXCOORD0; float2 staticLightmapUV : TEXCOORD1; #ifdef DYNAMICLIGHTMAP_ON float2 dynamicLightmapUV : TEXCOORD2; #endif UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 1); float3 positionWS : TEXCOORD2; half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z #ifdef _ADDITIONAL_LIGHTS_VERTEX half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light #else half fogFactor : TEXCOORD6; #endif #ifdef DYNAMICLIGHTMAP_ON float2 dynamicLightmapUV : TEXCOORD7; #endif float4 positionCS : SV_POSITION; #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) float4 shadowCoord : TEXCOORD8; #endif UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; //解码 RG 两通道球面映射压缩法线(有符号,ModelTranslator 工具编码:enc = n.xy/sqrt(2*(1+n.z)) * 0.5 + 0.5) float3 DecodeSphereMap(float2 encoded) { encoded = encoded * 2.0 - 1.0; //rg 无符号存储,重映射回有符号 float4 nn = float4(encoded, 1, -1); float l = dot(nn.xyz, -nn.xyw); nn.z = l; nn.xy *= sqrt(l); return nn.xyz * 2 + float3(0, 0, -1); } half3 SampleXRuntimeAmbient(half3 normalWS) { half y = normalize(normalWS).y; half useGlobal = step(0.5h, _XRuntimeAmbientEnabled); half3 sky = lerp(half3(1.353h, 1.452h, 1.568h), _XRuntimeAmbientSky.rgb, useGlobal); half3 equator = lerp(half3(1.023h, 1.122h, 1.254h), _XRuntimeAmbientEquator.rgb, useGlobal); half3 ground = lerp(half3(0.561h, 0.528h, 0.462h), _XRuntimeAmbientGround.rgb, useGlobal); half3 upper = lerp(equator, sky, saturate(y)); half3 lower = lerp(equator, ground, saturate(-y)); return lerp(lower, upper, step(0.0h, y)); } void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData) { inputData = (InputData)0; inputData.positionWS = input.positionWS; half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS); // 法线已在 frag 中经 TBN 转换到世界空间后写回 input.normalWS inputData.normalWS = input.normalWS.xyz; inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); inputData.viewDirectionWS = viewDirWS; #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 #ifdef _ADDITIONAL_LIGHTS_VERTEX inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.fogFactorAndVertexLight.x); inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; #else inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.fogFactor); #endif #if defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); #elif defined(LIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS); #else inputData.bakedGI = SampleSH(inputData.normalWS); #endif inputData.bakedGI = SampleXRuntimeAmbient(inputData.normalWS); inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); #if defined(DEBUG_DISPLAY) #if defined(DYNAMICLIGHTMAP_ON) inputData.dynamicLightmapUV = input.dynamicLightmapUV; #endif #if defined(LIGHTMAP_ON) inputData.staticLightmapUV = input.staticLightmapUV; #else inputData.vertexSH = input.vertexSH; #endif #endif } #endif