Unity3D Shader教程二 基础颜色

今天讲解下最基本的如何通过一个shader来渲染一个物体,教程结束的时候将会看到一个纯色的立方体。如果代码部分有不清楚的地方,建议看一下上一篇讲解HLSL的教程。

Unity3D Shader教程二 基础颜色_第1张图片
result.png

Shaderlab 的结构

在开始写shader之前,我们先要搞清楚shaderlab的结构。Shader文件第一行 以Shader开头,后面跟着的是shader文件的路径和名字,后面会在Inspector中选择shader的时候显示出来。接下来是Subshader.。一个shader可以包含多个Subshader,可以针对不同的情况使用不同的Subshader。

Shader "Tutorial/02_Simple"{
    Subshader{

    }
}

在subshader里面是 Pass, 同样可以有多个。当Subshader被渲染的时候,将会依次渲染里面的每个pass,这里我们只用了一个pass。在Pass里面我们通过Tag告诉unity如果去处理当前的Pass。比如下面的,我们希望物体被渲染为不透明,并且和其他不透明物体一起渲染。

Shader "Tutorial/02_Simple"{
    Subshader{
        Pass{
            Tags{
                "RenderType"="Opaque"
                "Queue"="Geometry"
            }

        }
    }
}

HLSL Code

上面的都准备好之后,我们可以开始写HLSL代码部分了。我们来看一下Shader中的数据流程是怎样的。首先 3D模型的数据信息给到vertex shader, 变换为相对于屏幕的一些信息。然后通过光栅化,把顶点及三角面转化为像素信息给到fragment shader,fragment shader通过一系列的差值及其他操作,讲最终颜色输出到屏幕上。

Unity3D Shader教程二 基础颜色_第2张图片
Shader Pipeline

通过CGPROGRAM 开始 和 ENDCG 结束 告诉unity我们使用HLSL来书写代码。为了使用unity提供的一些工具函数,我们引入 “UnityCG.cginc“ 文件.

Shader "Tutorial/02_Simple"{
    Subshader{
        Pass{
            Tags{
                "RenderType"="Opaque"
                "Queue"="Geometry"
            }

            CGPROGRAM
            #include "unityCG.cginc"

            ENDCG
        }
    }
}

通过一个结构体来引入输入数据,一般命名为appdata ,这里我们只获取物体的顶点位置,通过POSITION属性来标明为物体的局部空间位置信息。

struct appdata{
    float4 vertex : POSITION;
}

我们再声明一个结构体,这个结构体是vertex shader的输出值。现在我们只需要顶点的屏幕坐标,我们通过SV_POSITION属性来标明。

struct v2f{
    float4 position : SV_POSITION;
}

接下来是vertex shader,它接受appdata中的物体信息,输出v2f的结构体给到fragment shader。首先我们生成一个v2f的新实例,然后把顶点的屏幕坐标赋值给它。UnityObjectToClipPos函数定义在UnityCG.cginc 文件中,将顶点从局部空间坐标变化到屏幕坐标,我们直接使用就行了。

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

最后我们来写一下fragment shader。这里我们仅仅返回一个红色,在后续的教程里将会对它做更多其他的操作。我们将函数标明为SV_TARGET,这样unity就知道函数的返回值将被渲染到屏幕上。

fixed4 frag(v2f i) : SV_TARGET{
    return fixed4(0.5, 0, 0, 1);
}

完成上面这些之后,我们还需要告诉unity,vertex shader对应的函数 以及 fragment shader 对应的函数。通过 #pragma vertex 函数名 #pragma fragment 函数名 来实现。

Shader "Tutorial/01_Basic"{
    SubShader{
        Tags{
                "RenderType"="Opaque" 
                "Queue"="Geometry"
            }
        Pass{

            CGPROGRAM
            #include "UnityCG.cginc"

            #pragma vertex vert
            #pragma fragment frag

            struct appdata{
                float4 vertex : POSITION;
            };

            struct v2f{
                float4 position : SV_POSITION;
            };

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

            fixed4 frag(v2f i) : SV_TARGET{
                return fixed4(0.5, 0, 0, 1);
            }

            ENDCG
        }
    }
}

现在我们可以把新创建的这个Shader赋给一个材质,将会看到立方体显示fragment shader返回的颜色。


Unity3D Shader教程二 基础颜色_第3张图片
Apply

from:https://www.ronja-tutorials.com/2018/03/21/simple-color.html

Unity技术交流 微信公众号 UnityAsk,QQ群:891920228


你可能感兴趣的:(Unity3D Shader教程二 基础颜色)