unity学习-shader(二)

本文介绍了Unity中Shader的基础知识,包括Shader的命名、Properties属性定义、SubShader结构,以及不同类型的Shader形式,如表面着色器、顶点/片元着色器和固定函数着色器。着重讲解了如何创建和配置Shader以达到预期的渲染效果。
摘要由CSDN通过智能技术生成

概述

在unity中我们需要配合使用材质(Material)和shader来达到效果。

  • 常见流程:
    • 创建Material
    • 创建shader,赋值给上面创建的Material
    • 把Material赋值给要渲染的对象
    • 在Material面板中调整shader的属性,得到满意的效果
  • 创建shader:
    • Project视图右键
    • Create
    • Shader
  • unity提供的Shader模板:
    • Standard Surface Shader–带有标准光照模型的表面着色器模板
    • Unlit Shader–不包含光照的基本的顶点/片元着色器
    • Image Effect Shader–实现屏幕后处理效果
    • Compute Shader–一段运行在 GPU上的程序,利用GPU的并行性进行一些和常规渲染流水线无关的计算
    • Ray Tracing Shader–射线追踪的着色器,目前是实验阶段,后续可能会更改或删除

下面是使用Unlit Shader模板创建的一个shader,关于shader的基础结构,用注释标注了一下

// '/'表示路径 位置:Shader->MyShader->TestShader
Shader "MyShader/TestShader"    
{
    // 材质和shader的桥梁
    Properties  
    {
        // _MainTex是shader中使用的名称
        // Texture是材质面板上的名称
        // 2D是这个属性的类型
        // "white" {}是默认值
        _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;
            };

            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);
                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
        }
    }
}

1. shader命名

Shader “MyShader/TestShader”
在材质面板中的位置
材质面板

2. Properties

在这个语义块中,我们可以定义一些属性,这些属性可以显示在材质面板中
Properties支持的属性

Properties  
{
   _Int ("Int", Int) = 2
   _Float ("Float", Float) = 1.4
   _Range ("Range", Range(0.0,5.0)) = 3.0
   _Color ("Color", Color) = (1,0,1,1)
   _Vector ("Vector", Vector) = (1,2,3,4)
   _Cube ("Cube", Cube) = ""{}
   _3D ("3D", 3D) = "Black"{}
   _2D ("2D", 2D) = "white" {}
}

材质面板上的显示

3. SubShader

每个shader文件中,可以包含多个SubShader,但最少要有一个。当unity需要加载这个unity shader时,unity会扫描所有的SubShader语义块,然后选择第一个可以在目标平台中运行的SubShader。如果都不支持的话,会返回FallBack语义指定的SubShader。

SubShader
    {
        // 可选的 
        Tags { "RenderType"="Opaque" }
        // 可选的 [RenderSetup]
        Cull Off
        pass{
        }
        //可以有多个pass
    }

3.1 Tags

Tags的类型

3.2 RenderSetup

常见渲染状态设置:
渲染状态

3.3 Pass语义块

UsePass "MyShader/TestShader/MYPASS"
pass{
    Name "TestPass"
    Tags {"LightMode" = "ForwardBase"}
    Cull Off
}

UsePass 可以使用其他Shader中的Pass
GrabPass负责抓取屏幕,并将结果存储在一张纹理中,用于后处理
pass的标签类型:
pass的标签类型

3.4 FallBack

FallBack "MyShader/TestShader2"
// 或者
FallBack Off

表示如果上面的shader都执行不了,那么就执行FallBack指定的shader。也可以选择关闭FallBack,代表如果都执行不了,就算了。

4. Unity Shader的形式

Unity Shader的大概格式:

Shader "MyShader/TestShader2"
{
    Properties
    {
        // 需要的各种属性
    }
    SubShader
    {
        // 真正意义上的shader
        // 表面着色器(Surface Shader)或者
        // 定点/片元着色器(Vertex/Fragment Shader)或者
        // 固定函数着色器(Fixed Function Shader)
        Tags { "RenderType"="Opaque" }
        Cull Off
        UsePass "MyShader/TestShader/MYPASS"
        pass{
            Name "TestPass"
            Tags {"LightMode" = "ForwardBase"}
            Cull Off
        }
        pass{
        }
    }
    SubShader
    {
    }
    
    FallBack Off
}

4.1 表面着色器

Unity做了很多工作,需要的代码量较少,渲染代价较大。Unity会将表面着色器转换成对应的顶点/片元着色器。
新建一个表面着色器,内容是这样的:

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

表面着色器的内容被定义在CGPROGRAM和ENDCG中间,而不是在Pass中,因为我们不需要关注有多少个pass,unity会处理好这些。代码使用CG/HLSL编写的,也就是需要把CG/HLSL嵌套在ShaderLab中。

4.2 顶点/片元着色器

代码如下:

Shader "Unlit/MyShader"
{
    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;
            };

            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);
                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
        }
    }
}

需要我们自己定义好每个pass,更复杂一些,灵活度也更高。

4.3 固定函数着色

目前应该只有非常旧的设备会使用。

本文来源《unity shader入门精要》冯乐乐著

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值