【Unity Shader 中Pass相关介绍_第三篇】

简介: 【Unity Shader 中Pass相关介绍_第三篇】

1.1.在CG中调用属性变量


Shader通过Properties代码块声明开放出来的属性,如果想访问这些属性,需要在CG代码块中再次进行声明,它的语法格式为:

    type name;
    //type为变量的类型,name为属性变量的名称。


提示:

必须在函数调用属性之前对其进行声明,否则编译会失败。

下面是在这一篇中介绍到的属性,在CG中全部在声明一遍,代码块如下:

Shader "Unlit/在CG中调用属性变量"
{
    Properties
    {
        //下面是可能会出现的 Properties 的结构
        _2D("2D", 2D) = "" {}                     //2D贴图类型
        _Color("Color",Color) = (1,1,1,1)               //颜色类型
        _Value("Value",Range(0,10)) = 2.5               //范围类型
        _Float("Float",Float) = 0                   //浮点类型
        _Vector("Vector",Vector) = (0,0,0,0)              //向量类型
        _Cube("Cube",Cube) = "" {}                    //立方体贴图类型
        _3D("3D",3D) = "" {}                      //3D贴图类型
        //_name("display name" , type) = "defaulttexture"       //_属性名CG代码块方便调用(“在面板中显示的” , 属性类型) = 初始化默认值

    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            //在CG中声明属性变量
      sampler2D _2D                       //2D贴图类型
      float4 _Color                       //颜色类型
      float _Value                        //范围类型
      float _Float                        //浮点类型
      float4 _Vector                        //向量类型
      samplerCUBE _Cube                     //立方体贴图类型
      sampler3D _3D                       //3D贴图类型

            void vert()
            {
            }

            void frag()
            {
            }
            
    ENDCG
        }
    }
}

下面是开放属性与CG属性变量的对应关系:

语义 描述
float,Range 浮点和范围类型的属性,根据精度可以使用float,half或者fixed
Color,Vector 颜色和向量类的属性,可以使用float4,half4或fixed4声明,其中颜色使用低精度的fixed4声明可以减少性能消耗
2D 2D纹理贴图属性,使用sampler2D声明
cube 立方体贴图属性,使用samplerCUBE声明
3D 3D纹理贴图属性,使用sampler3D声明

1.2.实现更改颜色


先小试一下,其他的大多都差不多,需要多练习就熟悉了。下面对颜色属性,在CG中重新声明属性变量,实现更改颜色功能。

Shader "Unlit/实现更改颜色"
{
    Properties
    {
        //开放颜色属性
        _Color("Color",Color) = (1,1,1,1) //颜色类型,默认值为(1,1,1,1)=白色
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

      float4 _Color;    //在CG中以float4类型再次声明
      
            void vert(in float4 vertex : POSITION,
                out float4 position : SV_POSITION)
            {
              position = UnityObjectToClipPos(vertex);
            }

            void frag(out float4 color : SV_TARGET)   //在第一篇中解释了,为啥片段着色器可以直邮输出?
            {
              //调用颜色变量_Color
              Color = _Color;   //在片段着色器中直接使用变量_Color输出颜色,无返回值。
            }
    ENDCG
        }
    }
}

1.3.实现使用贴图(启用纹理的变量的Tiling和Offset的语法细则)


上面通过声明实现自由更改颜色。接下来实现使用纹理贴图。

在Properties代码块别定义之后,还需要在CG代码块中再次声明。但是与其他属性不同的是,CG还需要额外声明一个变量用于储存贴图的其他信息。如下面的图:


下面是Tiling和Offset属性:


平铺(Tiling)和偏移(Offset)属性,额外声明的变量就是为了储存这些信息。

在CG中,声明一个纹理的变量的Tiling和Offset的语法结构如下:

float4{TextureName}_ST;

其中TextureName是纹理属性的名称

ST:Scale和Transform的首字母,表示UV的缩放和平移。

x和y分量分别为Tiling的X值和Y值

z和w分量分别为Offset的Z值和W值

纹理坐标的计算公式为:

texcoord = uv * {TextureName}. xy + {TextureName}.zw

注意:公式先乘以平铺再加偏移值。初中的加减乘除运算规则是先乘除再加减,这样记住就可以了。有兴趣的可以看一下背后推导的过程,这里不扩充。


直接上代码,注释里会说的很清楚。

Shader "Unlit/实现使用贴图"
{
    Properties
    {
        //开放颜色属性
        _MainTex("MainTex", 2D) = "white" {}              //2D贴图类型
        _MainColor("MainColor",Color) = (1,1,1,1)           //颜色类型
        //Properties开放的名称为_MainTex的纹理属性,默认值为白色。
                      //当然这里也可以写成这样,比较灵活,他们要声明的属性是一个类型。
                      //_2D("2D", 2D) = "white" {}//2D贴图类型
                      //_Color("Color",Color) = (1,1,1,1) //颜色类型

    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag//这三行在第一篇里有详细说明。

      float4 _MainColor;    //在CG中以float4类型再次声明
      //声明纹理属性变量以及ST变量
      sampler2D _MainTex;
      float4 _MainColor_ST;
      
            void vert(in float4 vertex : POSITION,in float2 uv : TEXCOORD0,
                out float4 position : SV_POSITION,out float2 texcoord : TEXCOORD0)
            {
        //下面这个“UnityObjectToClipPos”是unity5.6以后的写法,unity5.6以前的写法是“UNITY_MATRIX_MVP”
              position = UnityObjectToClipPos(vertex);
              //使用公式计算纹理坐标
              texcoord = uv * _MainColor_ST.xy + _MainColor_ST.zw;
              //如果用不到平铺(Tiling)和偏移(Offset)属性效果,那么可以省略对纹理资源ST变量的声明,同时不再计算其纹理坐标。
              //则公式可以写成这样:
              //        texcoord = uv;
              //也就是UV坐标输入到顶点函数之后无需计算平铺和偏移,而是直接输出。
              //片段函数void frag()获取到UV坐标之后直接对纹理进行采样。
            }
      //来到了片段着色器
            void frag(in float4 position : SV_POSITION,in float2 texcoord : TEXCOORD0,
                out float4 color : SV_TARGET)
            {
              Color = tex2D(_MainTex,texcoord) * _MainColor;
            }
    ENDCG
        }
    }
}

Pass介绍的第三篇了,是时候介绍 具体的 多一点的 结构体,着色器通常需要输入和输出参数,为了使代码编写更加方便,并且看起了整洁,所以有了这样的一个数据类型——结构体

相关文章
|
图形学 Android开发 iOS开发
|
4天前
|
图形学
【实现100个unity特效】shader实现3D物品闪光和描边效果
【实现100个unity特效】shader实现3D物品闪光和描边效果
8 0
|
4天前
|
开发工具 图形学
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
6 0
|
4天前
|
图形学
【实现100个unity特效之2】使用shader和shader Graph实现2d图片描边效果(附源码)
【实现100个unity特效之2】使用shader和shader Graph实现2d图片描边效果(附源码)
8 0
|
5天前
|
图形学 开发者
【实现100个unity特效之1】使用Shader Graph实现动物森友会的世界弯曲效果(带源码)
【实现100个unity特效之1】使用Shader Graph实现动物森友会的世界弯曲效果(带源码)
8 0
|
2月前
|
图形学 异构计算
【Unity Shader 中Pass相关介绍_第四篇】
【Unity Shader 中Pass相关介绍_第四篇】
|
2月前
|
缓存 图形学 异构计算
【#Unity Shader#Amplify Shader Editor(ASE)_第二篇】
【#Unity Shader#Amplify Shader Editor(ASE)_第二篇】
|
2月前
|
图形学 异构计算
【Unity Shader 中Pass相关介绍_第二篇】
【Unity Shader 中Pass相关介绍_第二篇】
|
2月前
|
存储 图形学
【Unity Shader 中Pass相关介绍_第一篇】
【Unity Shader 中Pass相关介绍_第一篇】
|
2月前
|
图形学
【Unity Shader 中SubShader相关介绍】
【Unity Shader 中SubShader相关介绍】