ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

读UnityShader入门精要第五章-开始Unity Shader之旅

2022-08-07 14:34:09  阅读:158  来源: 互联网

标签:1.0 语义 Shader SV Unity UnityShader POSITION 着色器


1.一个最简单的顶点/片元着色器

1.1  顶点/片元着色器的基本结构

//定义Shader的位置和名称
Shader " Unity Shaders Book/Chapter 5/ Simple Shader"
{
    //可以不定义Properties,但是必须有至少一个SubShader
    SubShader
    {
        Pass
        {
            //使用CGPROGRAM和ENDCG包裹CG代码片段
            CGPROGRAM

            //编译指令,指明顶点着色器代码是vert函数
            #pragma vertex vert
            //编译指令,指明片元着色器代码是frag函数
            #pragma fragment frag

            //顶点着色器函数,v为形参名称,POSITION为CG/HLSL的语义,代表将模型的顶点坐标输入,SV_POSITION也是CG/HLSL的语义,代表输出为裁剪空间中的顶点坐标
            float4 vert(float4 v : POSITION) : SV_POSITION
            {
                return UnityObjectToClipPos(v);
            }

            //片元着色器函数,SV_Target语义代表将输出颜色存储到一个渲染目标中
            fixed4 frag() : SV_Target
            {
                return fixed4(1.0, 0.0, 0.0, 1.0);
            }

            ENDCG
        }
    }
}

1.2  模型数据从哪里来

  在着色器中使用语义(semantics)定义数据的来源,想得到更多的数据,我们可以定义一个结构体参数获取这些数据:

Shader " Unity Shaders Book/Chapter 5/ Simple Shader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            //使用结构体定义参数
            struct a2v 
            {
                //POSITION语义,代表使用模型空间的顶点坐标填充这个变量
                float4 vertex : POSITION;
                //NORMAL语义,代表使用模型空间的法线方向填充这个变量
                float3 normal : NORMAL;
                //TEXCOORD0语义,代表使用模型的第一套纹理坐标填充这个变量
                float4 texcoord : TEXCOORD0;
            };

            //顶点着色器函数
            float4 vert(a2v v) : SV_POSITION
            {
                return UnityObjectToClipPos(v.vertex);
            }

            fixed4 frag() : SV_Target
            {
                return fixed4(1.0, 0.0, 0.0, 1.0);
            }

            ENDCG
        }
    }
}

1.3  顶点着色器和片元着色器之间的通信

Shader " Unity Shaders Book/Chapter 5/ Simple Shader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            struct a2v 
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            //在结构体中存储顶点着色器的输出
            struct v2f
            {
                //SV_POSITION语义代表这里存储了裁剪空间的位置信息
                float4 pos : SV_POSITION;
                //COLOR0语义用于存储颜色信息
                fixed3 color : COLOR0;
            };

            v2f vert(a2v v)
            {
                //声明一个结构体
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                //根据发现方向计算一个颜色并存储
                o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                //将插值后的颜色显示到屏幕上
                return fixed4(i.color, 1.0);
            }

            ENDCG
        }
    }
}

  注意:

    1)在结构体v2f中,必须包含语义为SV_POSITION的float4类型变量,否则片元着色器无法得到片元的位置信息;

    2)顶点着色器输出的v2f结构体中存储的信息和片元着色器中输入的v2f结构体中的信息并不一致,片元着色器得到的点可能是三角片元内的点,它的信息是经过三角形顶点的插值得到的.

1.4  如何使用属性

Shader " Unity Shaders Book/Chapter 5/ Simple Shader"
{
    Properties
    {
        //声明一个color类型的属性
        //属性名_Color, 在Shader属性面板中显示名称Color Tint,属性类型Color, 属性默认值(1.0, 1.0, 1.0, 1.0)
        _Color("Color Tint", Color) = (1.0, 1.0, 1.0, 1.0)
    }

        SubShader
    {
        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            //在CG代码中,需要定义一个与属性名称相同,类型匹配的变量,才能使用这个变量
            fixed4 _Color;

            struct a2v 
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                fixed3 color : COLOR0;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 c = i.color;
                //使用_Color属性控制颜色输出
                c *= _Color.rgb;
                return fixed4(c, 1.0);
            }

            ENDCG
        }
    }
}

  ShaderLab的属性类型和Cg的变量类型匹配关系如下:

2.Unity提供的内置文件

  在Unity中,包含文件的后缀是.cginc.在编写Shader是,可以使用#include指令将这些文件包含进来,类似于C#包含其他命名空间.#include指令在CGPROGRAM和ENDCG中间的代码块中定义.

3.Unity提供的Cg/HLSL语义

3.1  语义的概念

  语义(semantics)是一个赋给Shader输入和输出的字符串,这个字符串表达了这个参数的含义.通常情况下,语义可以让我们指定Shader从哪里读取数据,或者指定Shader将数据输出到哪里.

  一些语义有特殊的含义规定,如TEXCOORD0,但是其他语义则没有这样的含义,如COLOR0,这些语义修饰的变量Shader并不关心它是用来做什么的,我们可以自己决定这些变量的用途.

  在DirecX 10以后,出现了一种新的语义类型:系统数值语义(system-value semantics).系统数值语义都是以SV(system value)开头的,如SV_POSITION.在Unity中有时系统数值语义和普通语义是可以替换的,但是最好使用系统数值语义,因为某些平台上必须使用系统数值语义.

3.2  Unity支持的语义

3.3  CG的数据类型

  Cg支持7种基础数据类型:

  1)float, 32位浮点数据

  2)half, 16位浮点数据

  3)fixed, 12位定点数据

  4)int, 32位整形数据

  5)bool, 布尔数据

  6)sampler*, 纹理对象的句柄,分为6类:sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, samplerRECT

  7)string, 字符类型(几乎不会用到)

标签:1.0,语义,Shader,SV,Unity,UnityShader,POSITION,着色器
来源: https://www.cnblogs.com/movin2333/p/16558829.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有