【Shader-02】--Unlit/SimplestUnlitShade

本文采用代码和注释分离的形式记录阅读笔记,目的在于阅读的时候可以记思考,在思考之后在继续阅读下文,和注释进行核对,得到前后的立即对比,增加理解能力。所以采用直接先贴出代码,然后给出自己的理解,最后附上效果图;

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unlit/SimplestUnlitShader"
{
    Properties
    {
        //we have removed support for texture tiling/offset,
        //so make them not be displayed in material inspector
        [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            //use "vert" function as the vertex shader
            #pragma vertex vert
            //use "frag" function as the pixel (fragment) shader
            #pragma fragment frag

            //vertex shader inputs
            struct appdata
            {
                float4 vertex : POSITION; // vertex position
                float2 uv : TEXCOORD0; // texture coordinate
            };

            //vertex shader outputs ("vertex to fragment")
            struct v2f
            {
                float2 uv : TEXCOORD0; //texture coordinate
                float4 vertex : SV_POSITION; // clip space position
            };

            //vertex shader
            v2f vert (appdata v)
            {
                v2f o;
                // transform position to clip space
                // (multiply with model*view*projection matrix)
                o.vertex = UnityObjectToClipPos(v.vertex);
                // just pass the texture coordinate
                o.uv = v.uv;
                return o;
            }
            
            //texture we will sample
            sampler2D _MainTex;

            // pixel shader; returns low precision ("fixed4" type)
            // color ("SV_Target" semantic)
            fixed4 frag (v2f i) : SV_Target
            {
                // sample texture and return it
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

基本结构

该着色器由两部分组成Properties(属性)和一个SubShader(子着色器)组成;SubShader中定义了一个Pass(子通道)用于渲染几何对象,上文代码中也包括了或多或少的英文注释,下文将更详细的解释和说明阅读的具体笔记内容。

Properties

在该结构中定义了一2D类型的纹理贴图:

[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}

NoScaleOffset:从英文的字面意思可以看出是没有Scale和Offset,也就是不会在Material中看到tilling/offset;反之是可以看见的

_MainTex:这定义的属性的变量,该变量在本程序中会引用到,如果在需要引用是需要重新定义一次的,下文会提到;

Texture: 该属性在Unity的材质面板上显示的名字,根据自己的实际情况来定义即可。

定义了NoScaleOffset 如图:

     

没有定义NoScaleOffset如图:

     

2D:指当前定义的属性的类型是2D纹理类型,并初始化该属性默认颜色是white(白色),所引用的纹理为空,也就是没有引用纹理,这里是需要用户手动指定的。 

在纹理定义中的属性初始值为white,没有指定对应的纹理,那么默认的模型颜色是白色的,如下图:​​​​

这里的颜色可以设置为white(白色)、black(黑色),如果设置为其它颜色会以灰色的状态来显色,如下图显示,

设置为black:

               

设置为green:

 

一般情况下这里的的默认值都是“white {}",除非有特别的需求才会去修改,这个根据实际情况来处理即可。

 

SubShader

该着色器中,只有一个子着色器,并且子着色器中也只有一个Pass,其余就没有定义其它结构。如果有多个SubShader,在移动设备上系统会根据硬件性能情况,选择一个适合本身硬件的SubShader来进行运行;

Pass

Pass属于SubShader中的通道,可以有多个,根据定义的先后顺序执行。每个Pass通道必须定义vertex(顶点函数)和fragment(片元/像素函数);

CGPROGRAM

.......

ENDCG

在Pass中编写逻辑代码,需要把相关的片元函数/顶点函数以及相关的逻辑都需要放在CGPROGRAM和ENDCG之间。

#pragma vertex vert:通过预处理指令#pragma结合关键字vertex(顶点)定义顶点函数,顶点函数名为vert;当然顶点函数名你可以任意去(不能和关键字重复),不过最好还是采用vert,简单明了,也是官方demo里面所使用,这里就定义了一个顶点着色器。

#pragma fragment frag:通过预处理里指令#pragma结合关键字fragment(片元/像素)定义片元/像素函数,片元函数的名字为frag,同样的在名字的规范上面需要谨慎。

struct appdata:定义了一个结构,该结构作为顶点函数的输入结构,顶点函数中需要用到的参数都需要在这里面定义好,当然也可以采用Unity已经定义好的一些结构,可以在UnityCG.cginc文件中查找到,该文件位于Unity安装目录的CGIncludes中,该文件夹下面包括了许多常用的函数、宏等定义,有需要可以直接找出来查阅即可,该结构中定义了顶点位置和贴图的uv坐标。

struct v2f:定义了一个结构名为v2f的结构,可以把该结构名翻译为vertext to fragment,也就是从顶点着色到片元着色。该结构作为顶点函数的输出,片元函数的输入,结构中定义了贴图的uv坐标和顶点在裁剪空间中的坐标位置。

v2f vert (appdata v)顶点函数的具体实现,该顶点函数的名字必须要和上文中定义的顶点函数的名字是相同的(这个特别重要),该函数实现了2个功能,对顶点位置坐标空间的转换和纹理坐标的赋值,最后返回v2 f类型对象传递给片元函数。

sampler2D _MainTex定义了一个2d采样纹理对象,该对象的名字就是中Propeties中定义的纹理名字,这里的名字必须要和上文一致,这个是规范,必须遵守。

fixed4 frag (v2f i) : SV_Target片元/像素着色器的具体实现,通过从顶点做色器传入的结构对象,根据对象的贴图uv坐标对纹理进行采样,对采样的值进行输出,该像素着色器返回一个颜色值,渲染的目标的目标对象当前只有一个,SV_Target语义等价于SV_TARGET0.

 


总结:

该着色器只是简单的定义了一个纹理属性,在顶点做色器中对顶点的位置进行转换,纹理uv进行获取然后传递给结构对象,作为像素着色器的输入。在像素着色器中通过纹理的uv坐标进行纹理采样,最后对采样的结构值作为像素着色器的颜色进行返回渲染。该着色器包括了基本着色器的框架定义和简单逻辑流程,在后面的文章中不会在记录这种结构说明,会把重点放到没有记录过的内容上面。

 

本文属于个人阅读笔记,若有见解不对之处,万望见谅及指!!!!

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值