当前位置: 首页 > news >正文

Unity中Shader的ShaderLOD

文章目录

  • 前言
  • 一、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 600Blend OffCull Back/*ZWrite [_ZWrite]ZTest [_ZTest]*/Offset -1,-1UsePass "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 ,命名方式 在纹理名 后加 _STfloat4 _DissolveTex_ST;//因为 在使用渐变纹理时,只使用了 渐变纹理的 u 坐标,所以把  sampler2D 换为 samplersampler _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 400Pass{}}
}

选择高配效果:

在这里插入图片描述

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

相关文章:

Unity中Shader的ShaderLOD

文章目录 前言一、ShaderLOD的使用步骤1、ShaderLOD使用在不同的SubShader中,用于区分SubShader所对应的配置2、在 C# 中使用 Shader.globalMaximumLOD 赋值来选择不同的 SubShader,以达到修改配置对应Shader的效果3、在设置LOD时,是需要和程序讨论统一 …...

图像压缩(4)《数字图像处理》第八章 8.3节 数字图像水印

图像压缩(3)《数字图像处理》第八章8.3节数字图像水印 一. 前言二.章节引言三.简单综述三.本章小结四.参考文献四. 小结 一. 前言 始于那本深蓝色的大块头,冈萨勒斯的《数字图像处理》,从此走上了图像信号处理的不归路&#xff0…...

C++之lambda匿名函数总结(二百四十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

STM32F103单片机内部RTC实时时钟驱动程序

一、STM32f103系列RTC功能 RTC实时时钟功能是嵌入式软件开发中比较常用的功能,一般MCU的RTC功能都带有年月日时间寄存器,比如STM32F4xx系列,RTC描述如下: 可见F4系列的RTC功能比较强大,设置好初始时间后,读…...

ChinaSoft 论坛巡礼 | 开源软件生态健康度量论坛

2023年CCF中国软件大会(CCF ChinaSoft 2023)由CCF主办,CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办,将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…...

Leetcode.2698 求一个整数的惩罚数

题目链接 Leetcode.2698 求一个整数的惩罚数 rating : 1679 题目描述 给你一个正整数 n n n ,请你返回 n n n 的 惩罚数 。 n n n 的 惩罚数 定义为所有满足以下条件 i i i 的数的平方和: 1 ≤ i ≤ n 1 \leq i \leq n 1≤i≤n i ∗ i i * i i∗i 的…...

大数据Flink(一百零二):SQL 聚合函数(Aggregate Function)

文章目录 SQL 聚合函数(Aggregate Function) SQL 聚合函数(Aggregate Function) Python UDAF,即 Python AggregateFunction。Python UDAF 用来针对一组数据进行聚合运算,比如同一个 window 下的多条数据、或者同一个 key 下的多条数据等。针对同一组输入数据,Python A…...

因mapjoin加载内存溢出而导致return code 3

因mapjoin加载内存溢出而导致return code 3 问题描述:日志定位: 问题描述: 例行Hive作业报错 日志定位: Starting to launch local task to process map join; maximum memory 5172101120 [2023-10-16 07:56:51,530] - INFO:…...

pip 指定源

pip定源 # 指定豆瓣 python -m pip install transformers -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com参考 出现错误:Looking in indexes:https://pypi.tuna.tsinghua.edu.cn/simple...

嵌入式中的MCU、ARM、DSP、FPGA

目录 “角色扮演” MCU ARM 特点 DSP 特点 FPGA 特点 应用 “角色扮演” MCU(Microcontroller Unit)、ARM(Advanced RISC Machine)、DSP(Digital Signal Processor)和FPGA(Field-Progr…...

二、PHP基础学习[变量]

部分内容引用自&#xff1a;https://blog.csdn.net/lady_killer9/article/details/108978062 一、PHP基础学习 1.语法与注释 示例&#xff1a; <?php // PHP 代码/* 这是 PHP 多行 注释 */ ?>2.输出 示例&#xff1a;echo 123; 3.变量 规矩&#xff1a; 变量以 …...

k8s kubeadm配置

master 192.168.41.30 docker、kubeadm、kubelet、kubectl、flannel node01 192.168.41.31 docker、kubeadm、kubelet、kubectl、flannel node02 192.168.41.32 do…...

B-3:Web安全之综合渗透测试

B-3:Web安全之综合渗透测试 任务环境说明: 服务器场景:Server2104(关闭链接) 服务器场景用户名、密码:未知 1.通过URL访问http://靶机IP/1,对该页面进行渗透测试,将完成后返回的结果内容作为FLAG值提交; 通过访问IP/1,查看源代码发现flagishere,访问后发现什么也没…...

设计模式—设计模式总览

设计模式—设计模式总览 在 1994 年&#xff0c;由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 《Design Patterns - Elements of Reusable Object-Oriented Software》&#xff08;中文译名&#xff1a;《设计模式 - 可复用的面向对…...

C++ 流程控制(分支、循环、跳转)

#include<iostream>using namespace std;int main() {// 单分支和双分支cout << "please enter your age:" << endl;int age;cin >> age;if(age > 18){cout << "welcome! adult." << endl;}else{cout << &qu…...

【网络协议】聊聊TCP的三挥四握

上一篇我们说了网络其实是不稳定的&#xff0c;TCP和UDP其实是两个不同的对立者&#xff0c;所以TCP为了保证数据在网络中传输的可靠性&#xff0c;从丢包、乱序、重传、拥塞等场景有自己的一套打法。 TCP格式 源端口和目标端口是不可缺少的&#xff0c;用以区分到达发送给拿…...

Docker镜像仓库

Docker镜像仓库 一、Docker镜像的创建1.1、基于已有镜像创建1.2、基于本地模板创建1.3、基于Dockerfile创建&#xff08;使用最广泛&#xff09;1.3.1、联合文件系统&#xff08;UnionFS&#xff09;1.3.2、镜像加载原理1.3.3、Dockerfile1.3.4、Docker 镜像结构的分层 二、如何…...

跨界技术:SOCKS5代理在电商、爬虫与游戏领域的应用

随着技术的日益发展&#xff0c;各种工具和技术手段被广泛应用于不同的领域。其中&#xff0c;SOCKS5代理、跨界电商、爬虫技术、出海策略以及游戏产业都成为了当下最热门的话题。本文将探讨这些关键技术如何相互融合&#xff0c;为企业和个人带来更多的机会和挑战。 1. SOCKS…...

LeetCode--快速排序

文章目录 1 排序原理2 代码实现 1 排序原理 quickSort(int[] arr, int left, int right) 参数描述 arr: 待排序的数组left: 排序的左边位置right: 排序的右边位置 排序步骤: 先选取左边节点的数据作为 pivot从右边开始, 向左遍历节点数据, 在满足right > left 条件前提下…...

2023年CSP-S赛后总结(2023CSP-S题解)

目录 T1 题目描述 输入格式 输出格式 代码 T2 题目描述 输入格式 输出格式 题目描述 输入格式 输出格式 题意翻译 代码 T3 题目背景 题目描述 输入格式 输出格式 代码 T4 题目描述 输入格式 输出格式 总结 T1 题目描述 小 Y 有一把五个拨圈的密码锁。…...

Ubuntu 虚拟机 Python3 + pip 完整安装教程

文章目录一、先检查系统是否自带 Python3二、安装 Python3 和 pip&#xff08;必装&#xff09;1. 更新软件源2. 安装 python3 和 pip3. 验证安装成功三、最简单的使用方法1. 运行 Python2. 用 pip 安装第三方库&#xff08;如 requests、numpy&#xff09;3. 运行 .py 文件四、…...

Qt QTabWidget标签页文字方向调校实战:当标签在左侧时,如何让文字乖乖水平显示?

Qt QTabWidget标签页文字方向调校实战&#xff1a;当标签在左侧时&#xff0c;如何让文字乖乖水平显示&#xff1f; 在桌面应用开发中&#xff0c;Qt框架的QTabWidget组件因其灵活性和易用性广受开发者青睐。但当我们尝试将标签页位置调整为左侧时&#xff0c;一个令人头疼的问…...

VBA循环到底用For、Do While还是Do Until?看完这篇别再傻傻分不清

VBA循环结构深度解析&#xff1a;如何精准选择For、Do While与Do Until&#xff1f; 刚接触VBA时&#xff0c;看到各种循环结构总让人眼花缭乱——For循环、For Each、Do While、Do Until...它们看起来都能完成相似的任务&#xff0c;但实际编码中选错循环类型&#xff0c;轻则…...

无人机开发者必看:如何基于QGC源码定制你的专属地面站?从环境搭建到第一个插件开发

无人机开发者必看&#xff1a;如何基于QGC源码定制你的专属地面站&#xff1f;从环境搭建到第一个插件开发 在无人机技术迅猛发展的今天&#xff0c;开源地面站软件QGroundControl&#xff08;QGC&#xff09;已成为行业标准工具之一。但对于追求个性化功能或特定应用场景的开发…...

【Git】深入解析 ‘.git/index.lock‘ 文件冲突:从报错到彻底解决

1. 当Git突然罢工&#xff1a;index.lock报错现场还原 那天下午我正忙着切换分支部署新功能&#xff0c;突然终端弹出红字警告&#xff1a;fatal: Unable to create .git/index.lock: File exists。这就像你急着上厕所却发现门被反锁&#xff0c;更糟的是你不知道里面到底有没有…...

郭老师-悟性高的人,为何不合群?

悟性高的人&#xff0c;为何不合群&#xff1f; ——他们在独处中&#xff0c;与道同行“你以为他孤独&#xff0c; 其实—— 他正与万物对话。”&#x1f33f; 不合群&#xff0c;不是缺陷&#xff0c; 而是—— 为悟性留出呼吸的空间。&#x1f9d8; 一、独处 ≠ 孤独&#x…...

LeetCode 200. 岛屿数量(C++):深度优先与广度优先的实战对比

1. 岛屿数量问题解析 第一次看到LeetCode 200题岛屿数量时&#xff0c;很多人会感到困惑&#xff1a;这个看似简单的矩阵遍历问题&#xff0c;为什么会被标记为中等难度&#xff1f;让我用一个生活中的例子来解释&#xff1a;想象你面前有一张卫星地图&#xff0c;上面蓝色代表…...

保姆级教程:用STM32F103C8T6(CUBEMX HAL库)读取航模遥控器PPM信号,附完整代码

低成本STM32F103C8T6读取航模PPM信号实战指南 航模遥控器的PPM信号解析一直是DIY爱好者的热门话题。相比昂贵的专用解码器&#xff0c;一块十几元的STM32F103C8T6开发板就能实现相同功能。本文将手把手教你用最常见的"蓝板"完成从硬件连接到代码调试的全过程。 1. 硬…...

如何从业务出发,设计一个可落地的智能客服 RAG 系统

一、核心原则以业务需求为锚点&#xff0c;而不是技术驱动很多 RAG 项目失败的根因&#xff1a;没搞清楚“解决谁的问题”一开始就堆模型、堆技术&#x1f449; 正确做法&#xff1a;先拆需求&#xff0c;再设计系统二、三方核心需求拆解设计前必须明确三类角色目标&#xff1a…...

光模块技术解析:从封装到以太网标准的全面指南

1. 光模块的封装类型与演进 第一次拆开数据中心机柜时&#xff0c;我看到那些花花绿绿的光模块插在交换机上&#xff0c;像极了乐高积木。后来才知道&#xff0c;这些"积木"的形态差异背后是封装技术的迭代史。目前主流的光模块封装类型可以分成三代产品&#xff1a;…...