Shader "Custom/ProceduralGrid_Local_Lit" { Properties { _ColorA ("Color A", Color) = (1,1,1,1) _ColorB ("Color B", Color) = (0,0,0,1) _CellSize ("Cell Size", Float) = 1.0 _Metallic ("Metallic", Range(0,1)) = 0.0 _Smoothness ("Smoothness", Range(0,1)) = 0.5 } SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "Queue" = "Geometry" } Cull Back ZWrite On // ============================================================ // COMMON // ============================================================ HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" CBUFFER_START(UnityPerMaterial) half4 _ColorA; half4 _ColorB; float _CellSize; half _Metallic; half _Smoothness; CBUFFER_END float Checker(float2 uv) { float2 cell = floor(uv); return frac((cell.x + cell.y) * 0.5) * 2.0; } half4 GetCheckerColor( float3 positionOS, float3 normalOS ) { float cellSize = max(_CellSize, 0.0001); float3 n = abs(normalize(normalOS)); float2 uv; // Верх / низ if (n.y >= n.x && n.y >= n.z) { uv = positionOS.xz / cellSize; } // Боковины X else if (n.x >= n.y && n.x >= n.z) { uv = positionOS.zy / cellSize; } // Боковины Z else { uv = positionOS.xy / cellSize; } float checker = Checker(uv); return lerp( _ColorA, _ColorB, checker ); } ENDHLSL // ============================================================ // FORWARD LIT // ============================================================ Pass { Name "ForwardLit" Tags { "LightMode" = "UniversalForward" } HLSLPROGRAM #pragma target 3.0 #pragma vertex Vert #pragma fragment Frag // -------------------------------------------------------- // Main light // -------------------------------------------------------- #pragma multi_compile _ _MAIN_LIGHT_SHADOWS #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_SCREEN // -------------------------------------------------------- // Additional lights // -------------------------------------------------------- #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT // -------------------------------------------------------- // LIGHTMAPS // -------------------------------------------------------- #pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK // Reflection Probes #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION #pragma multi_compile_fog #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; // UV2 модели float2 staticLightmapUV : TEXCOORD1; }; struct Varyings { float4 positionCS : SV_POSITION; float3 positionWS : TEXCOORD0; float3 normalWS : TEXCOORD1; float3 positionOS : TEXCOORD2; float3 normalOS : TEXCOORD3; float4 shadowCoord : TEXCOORD4; half fogFactor : TEXCOORD5; half3 vertexLighting : TEXCOORD6; // Если LIGHTMAP_ON: // float2 lightmapUV // // иначе: // half3 vertexSH DECLARE_LIGHTMAP_OR_SH( lightmapUV, vertexSH, 7 ); }; // ======================================================== // VERTEX // ======================================================== Varyings Vert(Attributes input) { Varyings output = (Varyings)0; VertexPositionInputs positionInputs = GetVertexPositionInputs( input.positionOS.xyz ); VertexNormalInputs normalInputs = GetVertexNormalInputs( input.normalOS ); output.positionCS = positionInputs.positionCS; output.positionWS = positionInputs.positionWS; output.normalWS = normalInputs.normalWS; output.positionOS = input.positionOS.xyz; output.normalOS = input.normalOS; // ---------------------------------------------------- // Lightmap UV // ---------------------------------------------------- OUTPUT_LIGHTMAP_UV( input.staticLightmapUV, unity_LightmapST, output.lightmapUV ); // Если объект lightmap не использует, // Unity возьмет SH / Light Probes OUTPUT_SH( output.normalWS, output.vertexSH ); // ---------------------------------------------------- // Realtime shadows // ---------------------------------------------------- output.shadowCoord = GetShadowCoord( positionInputs ); // ---------------------------------------------------- // Fog // ---------------------------------------------------- output.fogFactor = ComputeFogFactor( positionInputs.positionCS.z ); // ---------------------------------------------------- // Vertex additional lights // ---------------------------------------------------- output.vertexLighting = VertexLighting( positionInputs.positionWS, normalInputs.normalWS ); return output; } // ======================================================== // FRAGMENT // ======================================================== half4 Frag(Varyings input) : SV_Target { half4 baseColor = GetCheckerColor( input.positionOS, input.normalOS ); // ---------------------------------------------------- // URP lighting // ---------------------------------------------------- InputData inputData = (InputData)0; inputData.positionWS = input.positionWS; inputData.normalWS = normalize( input.normalWS ); inputData.viewDirectionWS = GetWorldSpaceNormalizeViewDir( input.positionWS ); inputData.shadowCoord = input.shadowCoord; inputData.fogCoord = input.fogFactor; inputData.vertexLighting = input.vertexLighting; // ---------------------------------------------------- // BAKED GI / LIGHTMAP // ---------------------------------------------------- inputData.bakedGI = SAMPLE_GI( input.lightmapUV, input.vertexSH, inputData.normalWS ); // Mixed Lighting / Shadowmask inputData.shadowMask = SAMPLE_SHADOWMASK( input.lightmapUV ); inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV( input.positionCS ); // ---------------------------------------------------- // PBR // ---------------------------------------------------- half4 color = UniversalFragmentPBR( inputData, // Albedo baseColor.rgb, // Metallic _Metallic, // Specular half3(0,0,0), // Smoothness _Smoothness, // Occlusion 1.0h, // Emission half3(0,0,0), // Alpha baseColor.a ); color.rgb = MixFog( color.rgb, inputData.fogCoord ); return color; } ENDHLSL } // ============================================================ // SHADOW CASTER // ============================================================ Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } ZWrite On ZTest LEqual ColorMask 0 HLSLPROGRAM #pragma vertex ShadowVert #pragma fragment ShadowFrag #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl" struct ShadowAttributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; }; struct ShadowVaryings { float4 positionCS : SV_POSITION; }; float3 _LightDirection; float3 _LightPosition; float4 GetShadowPositionHClip( ShadowAttributes input ) { float3 positionWS = TransformObjectToWorld( input.positionOS.xyz ); float3 normalWS = TransformObjectToWorldNormal( input.normalOS ); #if _CASTING_PUNCTUAL_LIGHT_SHADOW float3 lightDirectionWS = normalize( _LightPosition - positionWS ); #else float3 lightDirectionWS = _LightDirection; #endif float4 positionCS = TransformWorldToHClip( ApplyShadowBias( positionWS, normalWS, lightDirectionWS ) ); #if UNITY_REVERSED_Z positionCS.z = min( positionCS.z, UNITY_NEAR_CLIP_VALUE * positionCS.w ); #else positionCS.z = max( positionCS.z, UNITY_NEAR_CLIP_VALUE * positionCS.w ); #endif return positionCS; } ShadowVaryings ShadowVert( ShadowAttributes input ) { ShadowVaryings output; output.positionCS = GetShadowPositionHClip( input ); return output; } half4 ShadowFrag( ShadowVaryings input ) : SV_Target { return 0; } ENDHLSL } // ============================================================ // META // // Используется Unity при bake lightmap. // Checker участвует в расчете bounced GI. // ============================================================ Pass { Name "Meta" Tags { "LightMode" = "Meta" } Cull Off HLSLPROGRAM #pragma target 3.0 #pragma vertex MetaVert #pragma fragment MetaFrag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl" struct MetaAttributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; // Lightmap UV float2 uv1 : TEXCOORD1; // Dynamic lightmap UV, если есть float2 uv2 : TEXCOORD2; }; struct MetaVaryings { float4 positionCS : SV_POSITION; float3 positionOS : TEXCOORD0; float3 normalOS : TEXCOORD1; }; MetaVaryings MetaVert( MetaAttributes input ) { MetaVaryings output; output.positionCS = UnityMetaVertexPosition( input.positionOS.xyz, input.uv1, input.uv2 ); output.positionOS = input.positionOS.xyz; output.normalOS = input.normalOS; return output; } half4 MetaFrag( MetaVaryings input ) : SV_Target { half4 baseColor = GetCheckerColor( input.positionOS, input.normalOS ); BRDFData brdfData; half alpha = baseColor.a; InitializeBRDFData( baseColor.rgb, _Metallic, half3(0,0,0), _Smoothness, alpha, brdfData ); MetaInput metaInput = (MetaInput)0; // Аналогично стандартному URP Lit metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5h; metaInput.Emission = half3(0,0,0); return UnityMetaFragment( metaInput ); } ENDHLSL } } }