unity shader之LOD以及渲染队列

本文详细介绍了Unity引擎中的LOD(Level of Detail)设置及其作用,包括如何通过Shader.maximumLOD设置最大LOD值,以及不同LOD值下SubShader的选择机制。同时,深入探讨了Unity的渲染队列系统,解释了默认队列如Geometry、AlphaTest和Transparent的工作原理,以及如何通过修改Shader的Queue属性并关闭深度测试来调整物体的渲染顺序。

LOD设置

LOD全称Level of Detail
作用:unity引擎会根据不同的LOD值在不同的平台上使用不同的SubShader
注意:在上几篇博客中已经说过在一个着色器中会有一到多个SubShader,但是系统每次只会执行一个子着色器,选择子着色器的标准就是根据子着色器所设置的LOD的值来进行选择,每一次使用着色器,都会选择第一个小于等于LOD值的子着色器。

如何设置Shader的LOD的值
:通过Shader maximumlOOD来设置最大的LOD值即Shader.globalMaximumLOD;

unity内置着色器分LOD等级
在这里插入图片描述
注意在设置最大LOD值的时候不能小于 Ver texLit kind of shaders 的值(100),否则unity将不会显示使用此着色器的物体
Demo:
场景
在这里插入图片描述
shader代码

Shader "Custom/LODShader"
{
    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(根据LOD的值来使用)
//找到第一个<=Shader.maximumLOD这个subShader执行;如果所有的均不符合,则最后使用fallback
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 600

        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)
        {
           o.Albedo = fixed4(1.0,0.0,0.0,1.0);
            
        }
        ENDCG
    }
			SubShader
		{
			Tags { "RenderType" = "Opaque" }
			LOD 500

			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)
			{
			   o.Albedo = fixed4(0.0,1.0,0.0,1.0);

			}
			ENDCG
		}
			SubShader
			{
				Tags { "RenderType" = "Opaque" }
				LOD 400

				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)
				{
				   o.Albedo = fixed4(0.0,0.0,1.0,1.0);

				}
				ENDCG
			}
    FallBack "Diffuse"
}

c#控制LOD值的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 根据不同的平台选择不同的SubShader 
/// </summary>
public class My_Scripts : MonoBehaviour
{
    public Shader shader;
    public int LOD_Value = 600;
    //这个值最小为100,如果小于100将什么都不显示(系统内置的shaderLOD值最小为100,如果小于100将什么都不显示)
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log(this.shader.maximumLOD);
        //this.shader.maximumLOD = this.LOD_Value;
    }

    // Update is called once per frame
    void Update()
    {
        //当前这个shader最大的LOD值
        this.shader.maximumLOD = this.LOD_Value;
    }
}

显示效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

渲染队列

渲染队列
Unity引擎会将需要渲染的物体分成几个渲染的队列
Unity默认有几个渲染队列
背景1000、Geometry(几何队列)2000、Alpha Test Alpha测试(2450)、Transparent(透明)对应值为3000、Overlay(覆盖)对应值为4000这个队列是最后的渲染队列
从数值小的开始一直到数值最大(需要注意是否透明)
Unity渲染模式:普通物体从前向后渲染Alpha从后向前绘制
Demo:
场景:
将红球放置在篮球的后面
在这里插入图片描述
摄像机观测场景如下
红球shader代码

Shader "Custom/Render_text"
{
    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" "Queue" = "Geometry" }
			LOD 200
			ZTest off//关闭深度测试
        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)
        {
            o.Albedo = _Color.rgb;        
        }
        ENDCG
    }
    FallBack "Diffuse"
}

注意如果要修改某着色器的渲染队列并且令其起作用的话,需要将深度测试关闭
修改后的场景
在这里插入图片描述

Unity Shader渲染顺序主要涉及两个方面,一是 SubShader 的选择,二是渲染队列的确定。 当第一次使用 Shader object 渲染几何体、shader LOD value 改变或者当前激活的 render pipeline 改变时,需要重新设定激活的 SubShaderUnity 会遍历 SubShader 列表,检查它们是否与当前硬件设备兼容、LOD 值是否等于或小于当前的 shader LOD 值以及是否与当前激活的 render pipeline 兼容。若列表中有一个或多个 SubShader 符合要求,第一个符合要求的 SubShader 会被选为 Active SubShader;若不存在符合所有要求的 SubShader,但有满足硬件兼容要求但不满足 LOD 或 RenderPipeline 要求的,会选择第一个这样的 SubShader;若不存在满足硬件兼容要求的 SubShader,则显示 error shader渲染一个 Batch 时,Unity 会确定当前 Active SubShader 的哪个 pass 需要被渲染以及在当前帧的哪个点渲染,该行为会根据 render pipeline 变化。渲染每个 Pass 时,若当前的 render state 和 Pass 中定义的 render state 不匹配,Unity 会根据 Pass 中的定义设置 render state,GPU 则使用相关的 shader 变体进行渲染[^1]。 渲染队列由 SubShader 的 Queue 标签决定,Unity 内部使用一系列整数索引表示每个渲染队列,索引号越小越早被渲染。各渲染队列的情况如下: - Background(队列索引号 1000):在任何其他队列之前被渲染,用于渲染需要绘制在背景上的物体[^2][^3]。 - Geometry(队列索引号 2000):默认的渲染队列,大多数物体和不透明物体使用该队列[^2][^3]。 - AlphaTest(队列索引号 2450):需要透明度测试的物体使用该队列,在 Unity 5 中从 Geometry 队列中单独分出,在所有不透明物体渲染后再渲染它们更高效[^2][^3]。 - Transparent(队列索引号 3000):在所有 Geometry 和 AlphaTest 物体渲染后,按从后往前的顺序进行渲染,使用透明度混合(如关闭了深度写入的 Shader)的物体应使用该队列[^2][^3]。 - Overlay(队列索引号 4000):用于实现叠加效果,需要在最后渲染的物体使用该队列[^2][^3]。 此外,RenderQueue 有个关键值 2500,它是透明与不透明的分界点。RenderQueue <= 2500 的物体先遵循 RenderQueue 越小越先渲染,当 RenderQueue 相同时距离摄像机越近越先渲染;RenderQueue > 2500 的物体先遵循 RenderQueue 越小越先渲染,当 RenderQueue 相同时距离摄像机越远越先渲染,且 RenderQueue 优先级大于深度值[^4]。 ### 代码示例 以下是一个简单的 Unity Shader 示例,展示了如何使用 Queue 标签: ```glsl Shader "Custom/ExampleShader" { SubShader { Tags { "Queue" = "Transparent" } Pass { // Pass 内容 } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值