如何在表面着色器中获取纹理坐标?

时间:2019-04-20 16:52:02

标签: unity3d shader

要求我使用表面着色器在两个给定点之间绘制一条线。该点以纹理坐标给出(0到1之间),并直接进入Unity中的表面着色器。我想通过计算像素位置并查看它是否在该行上来做到这一点。因此,我要么尝试将corcordate的纹理转换为世界位置,要么获得相对于该纹理坐标的像素位置。

但是我只在unity shader手册中找到worldPos和screenPos。有什么方法可以获取纹理坐标中的位置(或至少获取世界pos中纹理对象的大小?)

1 个答案:

答案 0 :(得分:1)

这是一个简单的例子:

Shader "Line" {
    Properties {
        // Easiest way to get access of UVs in surface shaders is to define a texture
        _MainTex("Texture", 2D) = "white"{}
        // We can pack both points into one vector
        _Line("Start Pos (xy), End Pos (zw)", Vector) = (0, 0, 1, 1) 

    }

    SubShader {

        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert
        sampler2D _MainTex;
        float4 _Line;

        struct Input {
            // This UV value will now represent the pixel coordinate in UV space
            float2 uv_MainTex;
        };
        void surf (Input IN, inout SurfaceOutput o) {
            float2 start = _Line.xy;
            float2 end = _Line.zw;
            float2 pos = IN.uv_MainTex.xy;

            // Do some calculations

            return fixed4(1, 1, 1, 1);
        }
        ENDCG
    }
}

有关如何计算点是否在直线上的文章不错:

How to check if a point lies on a line between 2 other points

假设您使用以下签名从中定义一个函数:

inline bool IsPointOnLine(float2 p, float2 l1, float2 l2)

然后输入返回值:

return IsPointOnLine(pos, start, end) ? _LineColor : _BackgroundColor

如果要在不使用纹理的情况下进行UV坐标处理,我建议改用顶点片段着色器,并在appdata / VertexInput结构中定义float2 uv : TEXCOORD0。然后,您可以将其传递给顶点函数内的片段着色器。