23.CG语法顶点片元函数传多参数

23.CG-顶点片元着色器传递更多参数


23.1 知识点

新建顶点片元着色器shader,删除掉默认代码,只保留基本结构

Shader "ShaderTeach/Lesson23_NewUnlitShader"
{
    Properties
    {
        // 在这里定义着色器属性(如颜色、纹理等),暂时为空
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            float4 vert(float4 v:POSITION):SV_POSITION
            {
                return UnityObjectToClipPos(v);
            }


            fixed4 frag():SV_Target
            {
                return fixed4(0, 1, 0, 1); 
            }

            ENDCG
        }
    }
}

顶点着色器获取更多数据信息

  • 当我们在顶点着色器中想要获取更多模型相关信息时,可以使用结构体对数据进行封装。通过对结构体中成员变量加语义的方式来定义想要获取的信息。

  • 如下结构体是用于从应用阶段获取对应语义数据后传递给顶点着色器回调函数的。定义从应用阶段传递给顶点着色器的数据结构体,包含顶点坐标、法线和纹理坐标。

//该结构体
//是用于从应用阶段获取对应语义数据后
//传递给顶点着色器回调函数的
// 定义从应用阶段传递给顶点着色器的数据结构体
// 包含顶点坐标、法线和纹理坐标
struct a2v
{
    // 顶点坐标(基于模型空间)
    float4 vertex : POSITION;
    // 顶点法线(基于模型空间)
    float3 normal : NORMAL;
    // 纹理坐标(uv坐标)
    float2 uv : TEXCOORD0;
};
  • 在顶点着色器回调函数把参数改成我们声明的结构体a2v,UnityObjectToClipPos函数中传入的顶点坐标改成得到结构体中的值
float vert(a2v data) : SV_POSITION
{
    return UnityObjectToClipPos(data.vertex);
}

片元着色器获取更多数据信息

  • 当我们在片元着色器中想要获取更多信息时,采用的方式还是封装结构体的方式。

  • 注意:片元着色器中获取的数据基本上都是由顶点着色器传递过来的,所以我们封装的结构体还需要作为顶点着色器的返回值类型。

  • 定义从顶点着色器传递给片段着色器的数据结构体,包含裁剪空间下的坐标、法线和纹理坐标。

//从顶点着色器传递给片元着色器的 结构体数据 
//同样这里面的成员也需要用语义去进行修饰
// 定义从顶点着色器传递给片段着色器的数据结构体
// 包含裁剪空间下的坐标、法线和纹理坐标
struct v2f
{
    // 裁剪空间下的坐标
    float4 position : SV_POSITION;
    // 顶点法线(基于模型空间)
    float3 normal : NORMAL;
    // 纹理坐标(uv坐标)
    float2 uv : TEXCOORD0;
};
  • 修改顶点着色器函数,返回值改成返回v2f结构体类型。原来的返回值修饰语义: SV_POSITION也不需要了
  • position通过UnityObjectToClipPos得到,normal和uv直接赋值,之后可能要用
// 顶点着色器函数,将a2v数据转换为v2f数据
v2f vert(a2v data)
{
    // 定义顶点着色器传递给片段着色器的数据结构体 需要传递给片元着色器的数据
    v2f v2fData;
    // 将顶点坐标转换为裁剪空间下的坐标
    v2fData.position = UnityObjectToClipPos(data.vertex);
    // 传递顶点法线
    v2fData.normal = data.normal;
    // 传递纹理坐标
    v2fData.uv = data.uv;

    return v2fData;
}
  • 片段着色器回调函数,参数改成v2f
// 片段着色器函数,返回固定的绿色
fixed4 frag(v2f data) : SV_Target
{
    return fixed4(0, 1, 0, 1); // 固定绿色(RGBA)
}

总结

  • 如果顶点/片元着色器想要传递更多参数,我们需要通过结构体进行封装,用语义修饰结构体成员变量来达到目的。
  • 注意:只有顶点/片元着色器的回调函数相关参数和返回值才需要通过语义修饰,一般的自定义函数是不需要语义的,因为我们自己调用自己的自定义函数是可以明确知道每个参数的作用的。

23.2 知识点代码

Lesson23_CG_顶点片元着色器传递更多参数

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

public class Lesson23_CG_顶点片元着色器传递更多参数 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 顶点着色器获取更多数据信息

        //当我们在顶点着色器当中想要获取更多模型相关信息时
        //可以使用结构体对数据进行封装
        //通过对结构体中成员变量加语义的方式来定义想要获取的信息

        #endregion

        #region 知识点二 片元着色器获取更多数据信息

        //当我们在片元着色器当中想要获取更多信息时
        //采用的方式还是封装结构体的方式
        //注意:
        //片元着色器中获取的数据基本上都是由顶点着色器传递过来的
        //所以我们封装的结构体还需要作为顶点着色器的返回值类型

        #endregion

        #region 总结

        //如果顶点/片元着色器想要传递更多参数
        //我们需要通过结构体进行封装,用语义修饰结构体成员变量来达到目的
        //注意:
        //只有顶点/片元着色器的回调函数相关参数和返回值才需要通过语义修饰
        //一般的自定义函数是不需要语义的
        //因为我们自己调用自己的自定义函数是可以明确知道每个参数的作用的

        #endregion
    }
}

Lesson23_NewUnlitShader.shader

Shader "ShaderTeach/Lesson23_NewUnlitShader"
{
    Properties
    {
        // 在这里定义着色器属性(如颜色、纹理等),暂时为空
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //该结构体
            //是用于从应用阶段获取对应语义数据后
            //传递给顶点着色器回调函数的
            // 定义从应用阶段传递给顶点着色器的数据结构体
            // 包含顶点坐标、法线和纹理坐标
            struct a2v
            {
                //顶点坐标(基于模型空间)
                float4 vertex:POSITION;
                //顶点法线(基于模型空间)
                float3 normal:NORMAL;
                //纹理坐标(uv坐标)
                float2 uv:TEXCOORD0;
            };


            //从顶点着色器传递给片元着色器的 结构体数据 
            //同样这里面的成员也需要用语义去进行修饰
            // 定义从顶点着色器传递给片段着色器的数据结构体
            // 包含裁剪空间下的坐标、法线和纹理坐标
            struct v2f
            {
                //裁剪空间下的坐标
                float4 position:SV_POSITION;
                //顶点法线(基于模型空间)
                float3 normal:NORMAL;
                //纹理坐标(uv坐标)
                float2 uv:TEXCOORD0;
            };

            // float vert(a2v data):SV_POSITION
            // {
            //     return UnityObjectToClipPos(data.vertex);
            // }

            // 顶点着色器函数,将a2v数据转换为v2f数据
            v2f vert(a2v data)
            {
                //定义顶点着色器传递给片段着色器的数据结构体 需要传递给片元着色器的数据
                v2f v2fData;
                // 将顶点坐标转换为裁剪空间下的坐标
                v2fData.position = UnityObjectToClipPos(data.vertex);
                // 传递顶点法线
                v2fData.normal = data.normal;
                // 传递纹理坐标
                v2fData.uv = data.uv;

                return v2fData;
            }

            // 片段着色器函数,返回固定的绿色
            fixed4 frag(v2f data) : SV_Target
            {
                return fixed4(0, 1, 0, 1); // 固定绿色(RGBA)
            }
            ENDCG
        }
    }
}


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

×

喜欢就点赞,疼爱就打赏