Unity着色器。获取屏幕空间类似四边形的采样

时间:2019-11-10 12:04:11

标签: unity3d shader

想要从对象的四边形中将其包围的(0,0)(1,1)的屏幕空间坐标
尝试不依赖于屏幕位置和摄像机角度来实现此结果
enter image description here
这是从特定角度进行的简单紫外线采样
我需要从另一侧看到相同的结果,但另一侧有uv接缝
enter image description here

1 个答案:

答案 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会有一些延迟,所以在更新边界时可能会遇到一些滞后。