You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity HDRP中CGPROGRAM草地Shader光影交互问题解决咨询

Unity HDRP自定义草地Shader光影交互问题

我在Unity高清晰度渲染管线(HDRP)中开发自定义草地Shader,采用CGPROGRAM编写,目前遇到草地无法与场景光影系统交互的问题:草地能正常渲染,但无法响应光源、投射或接收阴影。

我已知HDRP对材质与Shader的光影处理有特定要求,但当前Shader缺失关键实现环节。以下是我使用的Shader代码:

Shader "HDRP/GeometryGrass" {
    Properties {
        _Color ("Color", Color) = (1, 1, 1, 1)

        _Height("Grass Height", float) = 3
        _Width("Grass Width", range(0, 0.1)) = 0.05
        _WindSpeed ("Wind Speed", Range(0, 10)) = 1
        _WindStrength ("Wind Strength", Range(0, 1)) = 0.1
        _TessellationUniform("Tessellation Uniform", Range(1, 64)) = 1
        _OffsetStrength("Offset Strength", Range(0, 1)) = 0.1
    }

    SubShader {
        Cull Off
        ZWrite On
        Tags {
            "RenderPipeline" = "HDRenderPipeline"
            "RenderType" = "Opaque"
            "Queue" = "Geometry"
        }
        

        Pass {
            CGPROGRAM
            #pragma vertex vp
            #pragma geometry gp
            #pragma fragment fp
            #pragma multi_compile_instancing
            #pragma target 4.5
            #pragma hull hull
            #pragma domain domain

            #include "UnityPBSLighting.cginc"
            #include "AutoLight.cginc"

            #include "../Resources/Random.cginc"
            #include "../Resources/Simplex.compute"
            #include "../Resources/CustomTessellation.cginc"

            struct VertexData {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
            };

            struct v2g {
                float4 vertex : SV_POSITION;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
                float2 uv : TEXCOORD0;
            };

            struct g2f {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float4 worldPos : TEXCOORD1;
                float3 normal : NORMAL;
            };


            float4 _Color;
            float _Height, _Width;
            float _WindSpeed, _WindStrength;
            float _OffsetStrength;

            vertexInput vp(VertexData v) {
                vertexInput o;
                o.vertex = v.vertex;
                o.normal = v.normal;
                o.tangent = v.tangent;
                return o;
            }

            float4 RotateAroundYInDegrees(float4 vertex, float degrees) {
                float alpha = degrees * UNITY_PI / 180.0;
                float sina, cosa;
                sincos(alpha, sina, cosa);
                float2x2 m = float2x2(cosa, -sina, sina, cosa);
                return float4(mul(m, vertex.xz), vertex.yw).xzyw;
            }

            [maxvertexcount(24)]
            void gp(point v2g points[1], inout TriangleStream<g2f> triStream) {
                float3 normal = normalize(points[0].normal);
                float slopeAngle = acos(dot(normal, float3(0, 1, 0)));
                if (slopeAngle > 0.5235988) return;

                float4 root = points[0].vertex;
                float idHash = randValue(abs(root.x * 10000 + root.y * 100 + root.z * 0.05f + 2));
                idHash = randValue(idHash * 100000);

                float2 randomOffset = float2(randValue(idHash * 12.345), randValue(idHash * 67.89));
                randomOffset = (randomOffset - 0.5f) * _OffsetStrength;
                root.xz += randomOffset;

                const int vertexCount = 12;
                g2f v[vertexCount];

                for (int i = 0; i < vertexCount; ++i) {
                    float widthMod = 1.0f - float(i) / float(vertexCount);
                    widthMod = pow(widthMod * widthMod, 1.0f / 3.0f);
                    
                    float currentV = (float(i) / (vertexCount - 1));
                    float currentVertexHeight = currentV * _Height * lerp(0.9f, 1.35f, idHash);

                    if (i % 2 == 0) {
                        v[i].vertex = float4(root.x - (_Width * widthMod), root.y + currentVertexHeight, root.z, 1);
                        v[i].uv = float2(0, currentV);
                    } else {
                        v[i].vertex = float4(root.x + (_Width * widthMod), root.y + currentVertexHeight, root.z, 1);
                        v[i].uv = float2(1, currentV);
                    }

                    float sway = snoise(v[i].vertex.xyz * 0.35f + _Time.y * _WindSpeed) 
                                 * v[i].uv.y * _WindStrength;
                    v[i].vertex.xz += sway;

                    v[i].vertex.xyz -= root.xyz;
                    v[i].vertex = RotateAroundYInDegrees(v[i].vertex, idHash * 180.0f);
                    v[i].vertex.xyz += root.xyz;

                    v[i].worldPos = v[i].vertex;
                    v[i].vertex = UnityObjectToClipPos(v[i].vertex);
                    v[i].normal = normal;
                }

                for (int j = 0; j < vertexCount - 2; ++j) {
                    triStream.Append(v[j]);
                    triStream.Append(v[j + 2]);
                    triStream.Append(v[j + 1]);
                }
            }

            float4 fp(g2f i) : SV_Target {
                 return _Color;
            }

            ENDCG
        }
    }    
}

问题详情:该Shader无法与HDRP光影系统交互,草地无光影效果,期望实现草地接收动态光源、环境光,以及投射/接收阴影。

已尝试操作:引入UnityPBSLighting.cginc与AutoLight.cginc,调整Shader属性参数,但问题未解决。


内容的提问来源于stack exchange,提问作者Guillaume Marrec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:29:54