美文网首页
Unity3D Shader教程八 Planar Mapping

Unity3D Shader教程八 Planar Mapping

作者: UnityAsk | 来源:发表于2019-08-06 20:17 被阅读0次

有时候我们的物体上没有uv坐标休息,或者我们可能希望多个物体上的贴图对齐,或者你希望生成自己的uv坐标信息。在今天教程中,我们展示如果用最简单的方式生成uv坐标信息,平面映射。

本节的shader脚本基于 前面的 Simple textured shader,但是你可以使用任何包含surface shaders的脚本。

Result

基础

我们先移除input 结构体中的 uv 坐标相关语句,因为后面我们将生成自己的uv坐标。

struct appdata{
    float vertex : POSITION;
};

因为uv坐标可以像之前讲过的,通过差值的方式在顶点间生成,所以我们在vertex shader中来生成。作为简单的开始,我们首先将顶点位置信息的x 、 z设置为uv坐标,这样就可以让贴图在模型上显示出来了。

v2f vert(appdata v){
    v2f o;
    o.position = UnityObjectToClipPos(v.vertex);
    o.uv = v.vertex.xz;
    return o;
}

调整 Tiling

上面这样没有将缩放考虑进去,我们可能不希望贴图随随着物体旋转和移动。

通过将TRANSFORM_TEX宏添加到uv坐标信息上,我们可以实现单独控制贴图的偏移和缩放。

v2f vert(appdata v){
    v2f o;
    o.position = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.vertex.xz, _MainTex);
    return o;
}

adjust tiling and offset and watch the material react

贴图坐标信息基于世界坐标

我们可以使用顶点的世界坐标 来使得 贴图 不跟随物体,前面我们使用的是顶点相对于物体的局部坐标。为了获得顶点世界坐标,我们通过 unity_ObjectToWorld 矩阵乘上顶点局部坐标来实现。然后将顶点的世界坐标设置为uv坐标。

v2f vert(appdata v){
    v2f o;
    //calculate the position in clip space to render the object
    o.position = UnityObjectToClipPos(v.vertex);
    //calculate world position of vertex
    float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
    //change UVs based on tiling and offset of texture
    o.uv = TRANSFORM_TEX(worldPos.xz, _MainTex);
    return o;
}

create a few spheres with the new material and move them around

你可以看到这种技术有一些不足之处,主要包括它只能针对 tile able(无缝贴图) 的贴图,而且在边缘进行了拉伸。这些可以通过别的技术比如 triplanar(三位映射) 进行减轻,后面的教程中我们将讲解。

Shader "Tutorial/008_Planar_Mapping"{
    //show values to edit in inspector
    Properties{
        _Color ("Tint", Color) = (0, 0, 0, 1)
        _MainTex ("Texture", 2D) = "white" {}
    }

    SubShader{
        //the material is completely non-transparent and is rendered at the same time as the other opaque geometry
        Tags{ "RenderType"="Opaque" "Queue"="Geometry"}

        Pass{
            CGPROGRAM

            #include "UnityCG.cginc"

            #pragma vertex vert
            #pragma fragment frag

            //texture and transforms of the texture
            sampler2D _MainTex;
            float4 _MainTex_ST;

            fixed4 _Color;

            struct appdata{
                float4 vertex : POSITION;
            };

            struct v2f{
                float4 position : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert(appdata v){
                v2f o;
                //calculate the position in clip space to render the object
                o.position = UnityObjectToClipPos(v.vertex);
                //calculate world position of vertex
                float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
                //change UVs based on tiling and offset of texture
                o.uv = TRANSFORM_TEX(worldPos.xz, _MainTex);
                return o;
            }

            fixed4 frag(v2f i) : SV_TARGET{
                //read texture at uv position
                fixed4 col = tex2D(_MainTex, i.uv);
                //multiply texture color with tint color
                col *= _Color;
                return col;
            }

            ENDCG
        }
    }
    FallBack "Standard" //fallback adds a shadow pass so we get shadows on other objects
}

相关文章

网友评论

      本文标题:Unity3D Shader教程八 Planar Mapping

      本文链接:https://www.haomeiwen.com/subject/xdbzrctx.html