美文网首页
Unity3D Shader教程四 Textures

Unity3D Shader教程四 Textures

作者: UnityAsk | 来源:发表于2019-07-30 22:10 被阅读0次

今天我们来讲下Shader中 贴图的使用,通过“texture samplers”,可以快速的获取到贴图信息。

开始本教程前,你需要了解Shader中Properties的使用,我们还是基于之前教程的Shader 进行更改,所以如果你不是很清楚,请先参看本系列教程之前的内容。


Result

Sampler 声明

我们通过声明sampler2d类型的变量来向shader添加贴图信息,然后我们在Properties代码块中添加对应的变量,当没有任何贴图的时候,我们默认为白色。

Shader "Tutorial/03_Properties"{
    Properties{
        _Color("Color", Color) = (0, 0, 0, 1)
        _MainTex ("Texture", 2D) = "white" {}
    }

    // ...

            //texture
            sampler2D _MainTex;
            //tint of the texture
            fixed4 _Color;

Texture 坐标

接下来我们在Input结构体中添加UV坐标信息。UV坐标决定了贴图的哪个部分显示在Mesh网格的哪个地方。它们已经在我们的模型数据里面了,所以我们无需代码创建uv坐标,直接使用就行了。声明一个float2类型数据,并将属性设定为TEXCOORD0。在vertex shader部分,我们从appdata中读取uv信息,并且赋值给v2f,这样后面的frag shader中可以使用uv信息。我们将uv信息设为颜色的 r 和 g。

CGPROGRAM
//include useful shader functions
#include "UnityCG.cginc"

//define vertex and fragment shader
#pragma vertex vert
#pragma fragment frag

//texture
sampler2D _MainTex;
//tint of the texture
fixed4 _Color;

//the object data that's put into the vertex shader
struct appdata{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
};

//the data that's used to generate fragments and can be read by the fragment shader
struct v2f{
    float4 position : SV_POSITION;
    float2 uv : TEXCOORD0;
};

//the vertex shader
v2f vert(appdata v){
    v2f o;
    //convert the vertex positions from object space to clip space so they can be rendered
    o.position = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    return o;
}

//the fragment shader
fixed4 frag(v2f i) : SV_TARGET{
    return fixed4(i.uv.x, i.uv.y, 0, 1);
}
ENDCG

Coordinates

这里我们能看到左下角的uv坐标为(0,0)黑色,右上角为(1,1)黄色。接下来我们使用uv坐标信息,从贴图中读取信息,通过tex2D函数来实现,第一个参数为sampler 第二个参数为uv坐标。然后我们在Inspector中选择一个贴图,来查看效果。

//the fragment shader
fixed4 frag(v2f i) : SV_TARGET{
    fixed4 col = tex2D(_MainTex, i.uv);
    return col;
}

Apply

Tiling

现在Inpspector中Texture的旁边你能看到"tiling"和"offset",但是改变它们的值发现没有任何作用。我们可以通过下面的操作让它们能够移动和缩放网格上的贴图。添加一个float4类型的变量TextureName_ST,TextureName对应的是Properties中的贴图属性名,比如这里我们命名为_MainTex_ST。其中ST代表缩放和移动,分别对应float4 的 前两个值x&y和后两个值z&w。我们可以直接通过Unity提供的 TRANSFORM_TEX命令来使用这些值。
初始的uv坐标和贴图的名字作为传入的参数,然后在vertex Shader中来使用它,将input中的uv坐标拷贝到v2f结构体中。现在再到Inspector中试试,已经可以起作用了。

//the vertex shader
v2f vert(appdata v){
    v2f o;
    //convert the vertex positions from object space to clip space so they can be rendered
    o.position = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    return o;
}

image

Tint

最后,我们添加代码来支持改变贴图的色调。我们使用Color变量作为色调改变的变量,所以我们把它重命名为Tint。然后在fragment Shader中我们将贴图的颜色乘上Tint的值,这意味着Tint为白色时,没有任何作用,当Tint为红色[1,0,0,1] 时,将只有贴图的红色部分起作用。

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

// ...

//the fragment shader
fixed4 frag(v2f i) : SV_TARGET{
    fixed4 col = tex2D(_MainTex, i.uv);
    col *= _Color;
    return col;
}

// ...

image
Shader "Tutorial/004_Textures"{
    //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 useful shader functions
            #include "UnityCG.cginc"

            //define vertex and fragment shader
            #pragma vertex vert
            #pragma fragment frag

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

            //tint of the texture
            fixed4 _Color;

            //the object data that's put into the vertex shader
            struct appdata{
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            //the data that's used to generate fragments and can be read by the fragment shader
            struct v2f{
                float4 position : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            //the vertex shader
            v2f vert(appdata v){
                v2f o;
                //convert the vertex positions from object space to clip space so they can be rendered
                o.position = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            //the fragment shader
            fixed4 frag(v2f i) : SV_TARGET{
                fixed4 col = tex2D(_MainTex, i.uv);
                col *= _Color;
                return col;
            }

            ENDCG
        }
    }
}

至此,我们的Shader和Unity提供的无光照Shader的功能已经基本上一样了,而且理解了每一行Shader代码的作用。Unity中的无光照Shader可以通过New->Shader->Unlit来创建。

相关文章

网友评论

      本文标题:Unity3D Shader教程四 Textures

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