Unity中Shader的ShaderLOD

news2024/9/28 3:28:12

文章目录

  • 前言
  • 一、ShaderLOD的使用步骤
    • 1、ShaderLOD使用在不同的SubShader中,用于区分SubShader所对应的配置
    • 2、在 C# 中使用 Shader.globalMaximumLOD 赋值来选择不同的 SubShader,以达到修改配置对应Shader的效果
    • 3、在设置LOD时,是需要和程序讨论统一 LOD 对应的数值所对应的配置
  • 二、ShaderLOD实现不同配置对应不同SubShader
    • 1、我们基于之前的文章代码,继续测试该功能
    • 2、编写C#脚本来控制选择不同的ShaderLOD,并且把该脚本挂载在摄像机上
    • 3、在用来测试的SubShader中添加 LOD 600 对应高配,并且添加一个只有空Pass的SubShader设置LOD 400 对应中配。(一般来说,SubShader的顺序按LOD从大到小来排序最合适,不容易出错)


前言

Unity中Shader的ShaderLOD,这个功能用于让游戏支持 高配、中配、低配不同效果之间切换时使用。


一、ShaderLOD的使用步骤

1、ShaderLOD使用在不同的SubShader中,用于区分SubShader所对应的配置

LOD 100;

2、在 C# 中使用 Shader.globalMaximumLOD 赋值来选择不同的 SubShader,以达到修改配置对应Shader的效果

Shader.globalMaximumLOD = 100;

3、在设置LOD时,是需要和程序讨论统一 LOD 对应的数值所对应的配置

二、ShaderLOD实现不同配置对应不同SubShader

1、我们基于之前的文章代码,继续测试该功能

因为需要使用LOD来区分不同的配置,所以不能使用上一篇的Fallback了

  • Unity中Shader的Fallback

我们使用没实现Fallback的Shader来继续测试

  • Unity中Shader阴影的接收

2、编写C#脚本来控制选择不同的ShaderLOD,并且把该脚本挂载在摄像机上

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

[ExecuteInEditMode]
public class ShaderLOD : MonoBehaviour
{
    public enum Quality
    {
        High,Medium,Low
    }

    public Quality theQuality = Quality.High;
    
    void Update()
    {
        switch (theQuality)
        {
            case Quality.High:
                Shader.globalMaximumLOD = 600; 
                break;
            case Quality.Medium:
                Shader.globalMaximumLOD = 400;
                break;
            case Quality.Low:
                Shader.globalMaximumLOD = 200;
                break;
        }
    }
}


3、在用来测试的SubShader中添加 LOD 600 对应高配,并且添加一个只有空Pass的SubShader设置LOD 400 对应中配。(一般来说,SubShader的顺序按LOD从大到小来排序最合适,不容易出错)

Shader代码:

//ShaderLOD
Shader "MyShader/P1_7_5"
{
    Properties
    {
        [Enum(Off,0,On,1)]_ZWrite("ZWrite",int) = 0
        [Enum(UnityEngine.Rendering.CompareFunction)]_ZTest("ZTest",int) = 0
        //使用这个标签,可以使外部暴露属性,有标题
        [Header(Base)]
        [NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
        _Clip("Clip",Range(0,1)) = 0
        //使用这个标签可以 在两行暴露属性之间加 间隙
        [Space(10)]
        [Header(Dissolve)]
        _DissolveTex("DissolveTex",2D) = "black"{}

        [NoScaleOffset]_RampTex("RampTex(RGB)",2D) = "black" {}
        
    }
    SubShader
    {
        Tags{"Queue" = "Geometry"}
        LOD 600
        
        Blend Off
        Cull Back
        /*ZWrite [_ZWrite]
        
        ZTest [_ZTest]*/
        
        Offset -1,-1
        
        UsePass "MyShader/P1_6_4/XRay"
        
        Pass
        {
            //Tags{"LightMode"="ForwardBase"}
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //#pragma multi_compile_fwdbase
            //剔除无用的变体
            //#pragma skip_variants DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING LIGHTPROBE_SH SHADOWS_SHADOWMASK VERTEXLIGHT_ON
            //自己定义,阴影需要使用的变体
            #pragma multi_compile DIRECTIONAL SHADOWS_SCREEN
            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            
            sampler2D _MainTex;
            float _Clip;
            sampler2D _DissolveTex; 
            //这个四维向量,xyzw分别表示 Tilling 和 Offset 的 xy ,命名方式 在纹理名 后加 _ST
            float4 _DissolveTex_ST;


            //因为 在使用渐变纹理时,只使用了 渐变纹理的 u 坐标,所以把  sampler2D 换为 sampler
            sampler _RampTex;

            struct appdata
            {
                float4 vertex : POSITION;
                float4 uv : TEXCOORD0;
            };
            
            //1.在v2f中添加UNITY_SHADOW_COORDS(idx),unity会自动声明一个叫_ShadowCoord的float4变量,用作阴影的采样坐标.
            struct v2f
            {
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                UNITY_SHADOW_COORDS(1)
                float4 worldPos :TEXCOORD2;
            };
            //2.在顶点着色器中添加TRANSFER_SHADOW(o),用于将上面定义的_ShadowCoord纹理采样坐标变换到相应的屏幕空间纹理坐标,为采样阴影纹理使用.
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                
                //为了减少传入的值 ,所以就不创建新变量来存储,而是把 uv 改为  四维向量 来用
                //使用 o.uv 的 xy 来存放 原人物贴图
                //使用 o.uv 的 zw 来存放 噪波贴图缩放 和 偏移 后的值
                o.uv.xy = v.uv.xy;
                //o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;
                o.uv.zw = TRANSFORM_TEX(v.uv,_DissolveTex);

                TRANSFER_SHADOW(o)
                //把顶点转化到世界空间下
                o.worldPos = mul(unity_ObjectToWorld,v.vertex);
                
                return o;
            }
            //3.在片断着色器中添加UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos),其中atten即存储了采样后的阴影.
            fixed4 frag (v2f i) : SV_Target
            {

                UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos)
                
                fixed4 col = tex2D(_MainTex, i.uv.xy);

                //把阴影 和 纹理相乘
                col *= atten;
                
                //外部获取的 纹理 ,使用前都需要采样
                fixed4 dissolveTex = tex2D(_DissolveTex,i.uv.zw);
                
                //片段的取舍
                clip(dissolveTex.r -  _Clip);

                //进行归一化
                fixed4 dissolveValue = saturate((dissolveTex.r - _Clip) / (_Clip + 0.1 - _Clip));

                fixed4 rampTex = tex1D(_RampTex,dissolveValue.r);

                //col += rampTex;
                return col;
            }
            ENDCG
        }
        //阴影的投射
        Pass
        {
            //1、设置 "LightMode" = "ShadowCaster"
            Tags{"LightMode" = "ShadowCaster"}
            CGPROGRAM
            
            #pragma vertex vert
            #pragma fragment frag
            //需要添加一个 Unity变体
            #pragma multi_compile_shadowcaster

            
            #include "UnityCG.cginc"

            //声明消融使用的变量
            float _Clip;
            sampler2D _DissolveTex;
            float4 _DissolveTex_ST;
            
            //2、appdata中声明float4 vertex:POSITION;和half3 normal:NORMAL;这是生成阴影所需要的语义.
            //注意:在appdata部分,我们几乎不要去修改名字 和 对应的类型。
            //因为,在Unity中封装好的很多方法都是使用这些标准的名字
            struct appdata
            {
                float4 vertex:POSITION;
                half3 normal:NORMAL;
                float4 uv:TEXCOORD;
            };
            //3、v2f中添加V2F_SHADOW_CASTER;用于声明需要传送到片断的数据.
            struct v2f
            {
                float4 uv : TEXCOORD;
                V2F_SHADOW_CASTER;
            };
            //4、在顶点着色器中添加TRANSFER_SHADOW_CASTER_NORMALOFFSET(o),主要是计算阴影的偏移以解决不正确的Shadow Acne和Peter Panning现象.
            v2f vert(appdata v)
            {
                v2f o;
                o.uv.zw = TRANSFORM_TEX(v.uv,_DissolveTex);
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
                return o;
            }
            //5、在片断着色器中添加SHADOW_CASTER_FRAGMENT(i)
            
            fixed4 frag(v2f i) : SV_Target
            {
                //外部获取的 纹理 ,使用前都需要采样
                fixed4 dissolveTex = tex2D(_DissolveTex,i.uv.zw);
                
                //片段的取舍
                clip(dissolveTex.r -  _Clip);
                
                SHADOW_CASTER_FRAGMENT(i);
            }
            ENDCG
        }
    }
    SubShader
    {
        LOD 400
        Pass
        {
            
        }
        
    }
}



选择高配效果:

在这里插入图片描述

选择中配效果:(因为是空Pass,所以返回白色)
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1133229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebGL笔记:矩阵的变换之平移的实现

矩阵的变换 变换 变换有三种状态:平移、旋转、缩放。当我们变换一个图形时,实际上就是在移动这个图形的所有顶点。解释 webgl 要绘图的话,它是先定顶点的,就比如说我要画个三角形,那它会先把这三角形的三个顶点定出来…

为什么需要山洪灾害监测预警系统?

在山洪高发地区,安装山洪灾害监测预警系统能够通过实时监测,预警山洪信息,对于保障我们的生命财产安全具有重要意义。 监测山洪不仅需要对山体进行监测,还要监测降雨量以及水位上升情况。山洪灾害监测预警系统是由GNSS监测站和水…

linux安装node(含npm命令) 并配置淘宝镜像源

1. 下载压缩包 wget https://nodejs.org/dist/v16.14.0/node-v16.14.0-linux-x64.tar.xz # node14 https://nodejs.org/dist/v14.15.4/node-v14.15.4-linux-x64.tar.xz # 推荐将压缩包放置到/usr/local/node文件夹中安装 mv node-v16.14.0-linux-x64.tar.xz /usr/local/node …

LeetCode217——存在重复元素

LeetCode217——存在重复元素 1.题目描述: 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。 2.Result01(暴力解) public static boolean containsDuplicate(in…

SRAM与DRAM的区别

目录 SRAM 特点 应用场景 DRAM 特点 应用场景 SRAM和DRAM的区别 SRAM SRAM(静态随机存取存储器)是一种用于存储和检索数据的类型的计算机内存。SRAM的存储单元通过触发器(flip-flop)实现,它们可以保持数据的状态…

语雀崩溃7个小时的原因是什么??

1 语雀是什么 语雀是蚂蚁集团旗下的在线文档编辑与协同工具,使用了“结构化知识库管理”,形式上类似书籍的目录。用户量在千万级别,是非常强大的。身边有不少朋友是付费会员,有许多公司也付费在使用语雀作为知识库进行文档的存储…

通过社工进网站后台的渗透测试

目录 通过社工进网站后台 0X0 开始: 0X1 获取icp备案企业: 0X2 通过备案获取姓名: 0X3 通过姓名获取手机号: 0X4 弱口令进后台: 0X5 总结 通过社工进网站后台 记录一次通过简单社工获取信息后进入后台的经过。…

近似熵的计算

我们计算两个函数,一个是henon,另外一个是TriMap: 代码: 构造henon函数: function [x,y]=Henon(x0,y0,a,b,M) M=M+10000; x = zeros(1,M+1); y = zeros(1,M+1); x(1)=x0; y(1)=y0; for i = 1:Mx(i+1) = 1+y(i)-a*x(i)^2;y(i+1) = b*x(i); endx=x(10001:M); y=y(10001:M)…

【人工智能Ⅰ】实验1:谓词表示法与产生式知识表示

实验1 谓词表示法与产生式知识表示 一、实验目的 1、熟悉谓词逻辑表示法; 2、理解和掌握产生式知识表示方法,实现产生式系统的规则库。 二、实验内容 要求通过C/C/python语言编程实现: 1、猴子摘香蕉问题 2、动物识别系统 &#xff08…

C# 基于腾讯云人脸核身和百度云证件识别技术相结合的 API 实现

目录 腾讯云人脸核身技术 Craneoffice.net 采用的识别方式 1、活体人脸核身(权威库): 2、活体人脸比对: 3、照片人脸核身(权威库): 调用成本 百度云身份证识别 调用成本 相关结合点 核心代码 实现调用人脸核身API的示例 实现调用身…

css 三栏布局的实现?

目录 前言 用法 代码 理解 高质量图片 1. 左侧栏 - 导航菜单 2. 中间栏 - 主要内容 3. 右侧栏 - 小部件和广告 布局的响应式设计 三栏布局在前端页面设计中是一个常见的布局方式,通常包含左侧、中间和右侧三个部分。这种布局方式在多种场景中都很受欢迎&am…

企业安全—DevSecOps概述详情

0x00 前言 SDL存在的问题在于体量过于庞大,不利于快速进行适配和进行,所以就有了DevSecOps,实际上是因为敏捷开发也就是DevOps的推进,并且坐上了云服务模式的火车,所以这一系列的东西都开始普及。DevSecOps作为DevOps…

龙迅LT9211 是MIPI/TTL/2 PORT LVDS互转的一颗高性能芯片,支持车规级

龙迅LT9211 描述: Lontium LT9211是一个高性能转换器,可以在MIPI DSI/CSI-2/双端口LVDS和TTL之间互转换,除了24位TTL到24位TTL与同步和DE。LT9211反序列化输入的MIPI/LVDS/TTL视频数据,解码数据包,并将格式化的视频数…

2006-2021年上市公司社会责任报告基本信息数据

2006-2021年上市公司社会责任报告基本信息表数据 1、时间:2006-2021年 2、来源为上市公司社会责任BG 3、指标:股票代码、统计截止日期、GG日期、所属省份、行业代码、行业名称、纳税总额、每股社会贡献值、社会捐赠额、是否经第三方机构审验、审验机构…

Python Opencv实践 - 入门使用Tesseract识别图片中的文字

做车牌识别项目前试一试tesseract识别中文。tesseract的安装使用请参考: Python OCR工具pytesseract详解 - 知乎pytesseract是基于Python的OCR工具, 底层使用的是Google的Tesseract-OCR 引擎,支持识别图片中的文字,支持jpeg, png…

Android 中如何使用 App Links

1. 简介 什么是 App Links呢?App Links 是 Android 6.0 (API 级别23) 引入的新功能,它是基于 DeepLinking,允许应用自动处理网站的 URL,而无需提示用户启动相应的应用。 例如:如果你在手机浏览器中输入了某个网站&am…

小红书女性用户洞察|2023「她研究」深度数据报告

作为新时代女性群体的聚集地、发声场,小红书不断涌现的「她」话题,承载着不同的女性特质,对理想自我、理想生活的期待,以及消费行为与决策偏好。 当代女性为回答「我是谁」、「我要什么」、「我想成为什么样的自己」,倾…

YOLOv7改进:全网原创首发 | 新颖的多尺度卷积注意力(MSCA),即插即用,助力小目标检测 | NeurIPS2022

💡💡💡本文全网首发独家改进:多尺度卷积注意力(MSCA),有效地提取上下文信息,新颖度高,创新十足。 1)作为注意力MSCA使用; 推荐指数:五星 MSCA | 亲测在多个数据集能够实现涨点,多尺度特性在小目标检测表现也十分出色。 收录: YOLOv7高阶自研专栏介绍:…

【网安大模型专题10.19】论文4:大模型+自动生成代码评估:改进自动化测试方法、创建测试输入生成器、探索新的评估数据集扩充方法,提高编程基准的精度

Is Your Code Generated by ChatGPT Really Correct? 写在最前面主要贡献这篇论文的创新点,为之后的论文提供了一些的启发未来研究的方向:改进自动化测试方法、创建测试输入生成器、探索新的评估数据集扩充方法,以及提高编程基准的精度。实验…

【单链表,循环链表和双向链表的时间效率比较,顺序表和链表的比较,有序表的合并------用顺序表实现,用链表实现】

文章目录 一、单链表,循环链表和双向链表的时间效率比较二、顺序表和链表的比较三、线性表的应用1.线性表的合并1.1有序表的合并------用顺序表实现1.2有序表的合并--------用链表实现 一、单链表,循环链表和双向链表的时间效率比较 查找表头结点&#…