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

仅使用Shader如何让指定Shader获取应用另一Shader的所有GameObject世界坐标

仅Shader层面实现坐标获取的可行方案

方案1:全局结构化缓冲区传递

  • 首先在Shader X和Shader Y中声明相同绑定槽位的全局缓冲区:
    着色器中统一声明:Shader X用可写缓冲区RWStructuredBuffer<float3> _ObjWorldPosBuffer : register(u10);,Shader Y用只读缓冲区StructuredBuffer<float3> _ObjWorldPosBuffer : register(t10);,保持槽位一致即可
  • 修改Shader X的顶点着色器逻辑,取当前对象的世界空间原点坐标写入缓冲区,使用SV_InstanceID作为写入索引避免不同对象数据覆盖:
    v2f vert (appdata v, uint instanceID : SV_InstanceID) {
        _ObjWorldPosBuffer[instanceID] = float3(unity_ObjectToWorld[0][3], unity_ObjectToWorld[1][3], unity_ObjectToWorld[2][3]);
        // 原有顶点变换逻辑保持不变
    }
    
  • Shader Y中直接遍历_ObjWorldPosBuffer所有元素,即可拿到所有使用Shader X的GameObject的世界坐标,过滤掉预设的无效值(比如提前写入的float3(-9999, -9999, -9999))即可排除未使用的槽位
  • 注意:缓冲区容量需要在你项目的渲染管线资源配置中提前固定分配,容量设置为场景中最多同时存在的Shader X对象数量即可,无需MonoBehaviour动态调整

方案2:全局纹理传递(适用于不支持结构化缓冲区的平台)

  • 在渲染管线配置中提前创建一张1D RGBAFloat格式的全局纹理,绑定到固定采样槽位,长度匹配最大Shader X对象数量
  • Shader X渲染时将自身世界坐标编码为RGBA值,写入纹理对应instanceID位置的像素
  • Shader Y采样这张全局纹理,逐像素解码出坐标值即可

通用注意事项

  • 必须保证Shader X的渲染队列早于Shader Y,可在Shader的SubShader标签中设置Queue = "Geometry-100"(Shader X)和Queue = "Geometry"(Shader Y)确保写入操作先于读取操作执行
  • 如果存在视锥体剔除导致Shader X对象不渲染、没有写入数据的情况,可在Shader X中添加强制渲染的Pass,或者在管线配置中关闭对应层的视锥体剔除即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:45:04