20.CG语法函数

20.CG-函数


20.1 知识点

注意

CG语法中的函数声明和使用几乎和C#中一模一样。

无返回值的函数

  • 基本结构:
    • void:以void开头,表示没有返回值
    • name:函数的名称
    • in:表示是输入参数,表示由函数外部传递给函数内部,内部不会修改该参数,只会使用该参数进行计算,允许有多个
    • out:表示是输出参数,表示由函数内部传递给函数的调用者,在函数内部必须对该参数值进行初始化或修改,允许有多个
void name(in 参数类型 参数名, out 参数类型 参数名)
{
    函数体
}
  • 实例
// 无返回值的函数
void test(in fixed inF, out fixed outF)
{
    outF = inF + 10; 
}

// 调用示例
fixed f = 10;
fixed f2;
test(f, f2); // f2的值会变成20
  • 注意:
    • in和out都可以省略,省略后就没有了in和out相关的限制
    • 虽然可以省略,但是建议大家在编写Shader时不要省略in和out,因为他们可以明确参数的传递方式,提高代码的可读性和可维护性,可以让我们更容易的理解函数是如何与参数交互的,减少潜在的误解可能

有返回值的函数

  • 基本结构:
    • type:返回值类型
    • return:返回指定类型的数据
type name(in 参数类型 参数名)
{
      函数体
      return 返回值;
}
  • 实例
// 有返回值的函数
float test2(in float inF, out fixed f)
{
    f = inF + 2;
    return inF * 2;
}

// 调用示例
float f3 = test2(11, f); // f3: 11, f: 13
  • 注意:
    • 虽然可以在有返回值的函数中使用out参数,但这并不是常见做法,除非是一些自定义逻辑函数。对于顶点/片元着色器函数只会使用单返回值的方式进行处理。

总结

CG当中的函数声明和函数使用和C#中基本一致。

区别主要是CG中的in和out关键字:

  1. in表示输入参数,用于外部传给内部,内部只会用,不会改,可以有多个。
  2. out表示输出参数,用于内部传给外部,内部必须初始化或修改,可以有多个。

对于有返回值的函数,要不采用返回值形式,要不采用out。


20.2 知识点代码

Lesson20_CG_函数

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson20_CG_函数 : MonoBehaviour
{
    void Start()
    {
        #region 注意

        //CG语法中的函数声明和使用几乎和C#中一模一样

        #endregion

        #region 知识点一 无返回值的函数

        //基本结构
        //void name(in 参数类型 参数名, out 参数类型 参数名)
        //{
        //      函数体
        //}
        //void:以void开头,表示没有返回值
        //name:函数的名称
        //in:表示是输入参数,表示由函数外部传递给函数内部,内部不会修改该参数,只会使用该参数进行计算,允许有多个
        //out:表示是输出参数,表示由函数内部传递给函数的调用者,在函数内部必须对该参数值进行初始化或修改,允许有多个

        //注意:
        //in和out都可以省略,省略后就没有了in和out相关的限制
        //虽然可以省略,但是建议大家在编写Shader时不要省略in和out
        //因为他们可以明确参数的传递方式,提高代码的可读性和可维护性
        //可以让我们更容易的理解函数是如何与参数交互的,减少潜在的误解可能

        #endregion

        #region 知识点二 有返回值的函数

        //基本结构
        //type name(in 参数类型 参数名)
        //{
        //      函数体
        //      return 返回值;
        //}
        //type:返回值类型
        //return:返回指定类型的数据

        //注意:
        //虽然可以在有返回值的函数中使用out参数
        //但是这并不是常见做法,除非是一些自定义逻辑函数
        //对于顶点/片元着色器函数只会使用单返回值的方式进行处理

        #endregion

        #region 总结

        //CG当中的函数声明和函数使用和C#中基本一致

        //区别主要是CG中的in和out关键字
        //1.in表示输入参数,用于外部传给内部,内部只会用,不会改,可以有多个
        //2.out表示输出参数,用于内部传给外部,内部必须初始化或修改,可以有多个

        //对于有返回值的函数,要不采用返回值形式,要不采用out

        #endregion
    }
}

Lesson20_NewUnlitShader.shader

Shader "ShaderTeach/Lesson20_NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            //无返回值的函数
            void test(in fixed inF, out fixed outF)
            {
                outF = inF + 10; 
            }

            //有返回值的函数
            float test2(in float inF, out fixed f)
            {
                f = inF + 2;
                return inF * 2;
            }

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);

                //无返回值的函数
                fixed f = 10;
                fixed f2;
                test(f, f2);//f2的值会变成20
        
                //有返回值的函数
                float f3 = test2(11, f);//f3:11 f:13

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

20.3 练习题

在CG中申明一个函数,要求可以得到两个返回值,请至少用5种方式完成

除了in、out两个关键字意外,CG当中还有一个不常用的inout关键字,请根据所学知识,分析它的作用

  • in:表示是输入参数,表示由函数外部传递给函数内部,内部不会修改该参数,只会使用该参数进行计算,允许有多个

  • out:表示是输出参数,表示由函数内部传递给函数的调用者,在函数内部必须对该参数值进行初始化或修改,允许有多个

  • inout:表示输入输出参数,既作为输入in又作为输出out。参数的值可以在函数内部被修改,并且该修改会在函数调用结束后保留在参数中。在函数外部可以继续使用修改后的内容



转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏