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

Unity中HLSL几何着色器硬编码三角形无法显示的问题求助

问题分析与解决方案

嘿,我一眼就瞅出几个关键问题,这就是你的几何着色器输出全黑的原因:

  • 顶点没转成裁剪空间坐标:你在几何着色器里直接写的是局部空间的数值,但Unity的GPU需要的是经过MVP变换后的裁剪空间坐标,不然它根本不知道该把这些点画在屏幕的哪个位置。
  • 顶点的w分量设错了:你写的float4(0.1, 0.1, 0, 0)里w是0,GPU会把这个当成方向向量,而不是实际的位置点,正确的位置点w分量得是1.0才行。

另外,你现在只输出了3个顶点(一个三角形),如果要画四边形的话得输出6个顶点(两个三角形),不过先把显示问题解决再说~

修改后的完整Shader

Shader "foo/bar" {
    SubShader{
        Cull Off
        Lighting Off
        ZWrite Off
        Pass{
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom
            // 引入Unity内置的工具函数和矩阵
            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex : POSITION;
            };
            struct v2g {
                float4 vertex : POSITION;
            };
            struct g2f {
                float4 vertex : SV_POSITION; // 这里必须用SV_POSITION,这是GPU识别裁剪空间位置的标准语义
            };

            v2g vert(appdata v) {
                v2g o = (v2g)0;
                o.vertex = v.vertex;
                return o;
            }

            [maxvertexcount(4)]
            void geom(point v2g p[1], inout TriangleStream<g2f> tristream) {
                g2f o = (g2f)0;

                // 定义四边形的四个局部空间顶点,w分量设为1.0
                float4 quadVerts[4] = {
                    float4(0.1, 0.1, 0, 1.0),
                    float4(0.1, 0.9, 0, 1.0),
                    float4(0.9, 0.9, 0, 1.0),
                    float4(0.9, 0.1, 0, 1.0)
                };

                // 把每个顶点从局部空间转换到裁剪空间
                for (int i = 0; i < 4; i++) {
                    o.vertex = UnityObjectToClipPos(quadVerts[i]);
                    tristream.Append(o);
                }
                // 重启三角带,让四个顶点组成一个四边形(两个三角形)
                tristream.RestartStrip();
            }

            fixed4 frag(g2f i) : COLOR {
                return fixed4(1,1,1,1);
            }
            ENDCG
        }
    }
}

关键修改点说明

  1. 引入UnityCG.cginc:这个内置文件帮我们封装了常用的变换函数,比如UnityObjectToClipPos,不用自己手动写复杂的矩阵乘法。
  2. g2f的顶点语义改成SV_POSITION:原来的POSITION在顶点着色器里是局部空间坐标,但几何着色器输出给片元着色器的必须是裁剪空间坐标,SV_POSITION是GPU认可的标准语义。
  3. 把顶点w分量改成1.0:确保这些坐标被GPU当成实际的位置点,而不是方向向量。
  4. 添加裁剪空间变换:用UnityObjectToClipPos()把我们定义的局部空间顶点转换成GPU能识别的裁剪空间坐标,这样才能正确渲染到屏幕上。
  5. 补全第四个顶点并调用RestartStrip():这样四个顶点就能组成一个完整的四边形,符合你最初想用几何着色器把点转成四边形的需求。

额外要检查的点

  • 确认你的GameObject用的是点网格(Point Mesh):因为你的几何着色器声明的是point输入类型,只有当Mesh的拓扑是Points时,几何着色器才会接收到输入。如果你的Mesh是三角形或者其他拓扑,几何着色器根本不会触发哦。
  • 检查相机的视锥体范围:确保你定义的四边形坐标在相机能看到的范围内,比如如果是正交相机,要和相机的Size参数匹配,不然可能会被裁切掉。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:08:21