Shader的基本结构讲解

Shader "Custom/SimpleShader" {
    Properties {
        // 定义着色器的属性
        _MainTex ("Texture", 2D) = "white" {} // 纹理属性,默认为白色纹理
        _Color ("Color", Color) = (1,1,1,1) // 颜色属性,默认为白色
        _Speed ("Speed", Range(0, 10)) = 1 // 速度属性,默认值为1,最小值为0,最大值为10
    }

    SubShader {
        // 定义子着色器的Tag
        Tags {"Queue"="Transparent" "RenderType"="Opaque"}

        CGPROGRAM
        // 定义实际的着色器代码
        #pragma surface surf Lambert // 使用Lambert光照模型渲染表面

        // 定义结构体Input,包含纹理坐标和世界坐标
        struct Input {
            float2 uv_MainTex;
            float3 worldPos;
        };

        // 定义着色器属性
        sampler2D _MainTex;
        float4 _Color;
        float _Speed;

        // 定义表面着色函数
        void surf (Input IN, inout SurfaceOutput o) {
            // 使用_MainTex纹理和_Color颜色计算表面的漫反射颜色
            o.Albedo = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Alpha = 1; // 设置不透明度为1
            o.Emission = 0; // 设置自发光为0
            o.Metallic = 0; // 设置金属度为0
            o.Smoothness = 0; // 设置平滑度为0
            IN.worldPos += float3(sin(_Time.y * _Speed), cos(_Time.x * _Speed), 0); // 根据时间和速度修改世界坐标
            o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_MainTex)); // 从法线纹理中获取法线
        }
        ENDCG
    }
    FallBack "Diffuse" // 如果硬件不支持,回退到Diffuse着色器
}

现在,让我解释一下这个着色器的每个部分:

Shader “Custom/SimpleShader” { … }: 定义了着色器的名称和属性。在这个示例中,我们把它命名为“Custom/SimpleShader”,并定义了三个属性:一张名为“_MainTex”的纹理,一个名为“_Color”的颜色和一个名为“_Speed”的范围(Range)。

SubShader { … }: 定义了着色器的子着色器,这个子着色器的Tag定义了绘制顺序和渲染类型。在这个示例中,我们把绘制顺序设置为“Transparent”,渲染类型设置为“Opaque”。

CGPROGRAM … ENDCG: 定义了实际的着色器代码。在这个示例中,我们使用了Surface Shader结构,并且定义了一个结构体Input,它包含了纹理坐标和世界坐标。

#pragma surface surf Lambert: 声明使用Lambert光照模型来渲染表面。这里也可以使用其他光照模型,例如Phong或Blinn-Phong。

sampler2D _MainTex; float4 _Color; float _Speed;: 定义了着色器的属性。这里我们定义了_MainTex、_Color和_Speed三个属性,用来存储纹理、颜色和速度。

void surf (Input IN, inout SurfaceOutput o) { … }: 定义了表面着色函数。在这个函数中,我们使用了_MainTex纹理和_Color颜色来计算表面的漫反射颜色,然后使用_UnpackNormal函数从法线纹理中获取法线。

CGPROGRAM 和 ENDCG: 用于定义CG语言的代码块,其中的代码将被编译为GPU可执行的代码。
#pragma surface: 用于指定表面着色器函数的使用和属性设置,本例中指定使用Lambert光照模型。
sampler2D: 纹理类型的变量,用于存储纹理数据,本例中使用了_MainTex纹理属性。
SurfaceOutput: 用于定义表面着色函数的输出数据结构体,其中包含了表面的漫反射颜色、自发光、金属度、平滑度、法线等信息。
UnpackNormal: 用于从法线纹理中获取法线信息。
_Time: Unity内置的系统变量,包含了游戏运行的时间信息,可以用于实现时间相关的效果。
FallBack: 定义着色器在硬件不支持时的回退方案,默认为Diffuse着色器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值