答案 0 :(得分:0)
对我来说,听起来像是无聊的紫外线。您可以尝试搜索“ Unity Matcap着色器”,看看是否有不错的东西出现。这是计算的中心部分(在顶点着色器中):
o.uv = mul((float3x3)UNITY_MATRIX_V, UnityObjectToWorldNormal(v.vertex)).xy * 0.5 + 0.5;
编辑:因此,除了对象作为原点之外,您基本上需要屏幕空间UV。我认为,如果将法线替换为对象空间位置,上述解决方案应该仍然可以使用。
o.uv = mul((float3x3)UNITY_MATRIX_V, v.vertex).xy * 0.5 + 0.5;
这将使用模型的对象空间位置,并旋转到屏幕空间中。只要网格原点在其中心,它就应该起作用。请注意,尽管UV坐标的范围取决于模型的大小(1米= 1 uv瓦片),所以您可能需要将其乘以某个系数。
EDIT2:好的,所以我开始更多地了解您要实现的目标。如果要使屏幕空间UV相对于对象的边界,则需要以某种方式将屏幕空间边界框传递到着色器中。
我建议向材质中添加float4矢量属性,其中XY为边界中心,ZW为框尺寸,然后使用类似GetComponent<MeshRenderer>().material.SetProperty("_ScreenBounds", bounds);
的代码从代码中进行设置。您将必须在脚本的update方法中计算对象的屏幕边界。您可以使用Renderer.bounds获取边界,也可以使用Camera.WorldToScreenPoint()将边界转换为屏幕空间。变换边界框的所有角并获取最小/最大点。
在着色器内部,您可以计算对象的常规屏幕空间UV,然后减去偏移并除以尺寸。
我应该警告您,虽然将数据发送到GPU会有一些延迟,所以在更新边界时可能会遇到一些滞后。