深入URP之Shader篇15: Shader关键字和变体

之前说了很多shader关键字的事情,本篇好好说一下关键字和变体。

关键字是干什么的

我们写shader的时候,经常会遇到需要处理不同的情况,比如是否启用雾,光源是平行光还是点光源,是否使用法线贴图等等。如果为每一种情况都写一个单独的shader,那么这些不同的条件就会组合出非常多的可能性,要写太多的shader显然不现实。那么另外一种方法就是像写程序那样在shader里面进行逻辑判断,如果直接用if就属于动态分支了,对效率有一定的影响,另外就是像c语言预处理宏那样使用#if#ifdef这类,而此时的条件就是关键字。编译器会对关键字进行预处理,从而产生匹配当前所使用的关键字的shader版本,比如开启雾,使用平行光但不使用法线贴图的shader版本。

什么是变体

每种关键字的组合对应的shader版本就是一个shader变体。所谓变体,就是同一份shader源码,由于启用了不同的关键字组合,经过编译器预处理就得到了最终不一样的shader代码。

使用关键字还是使用动态分支

使用关键字可以避免动态分支,从单个shader的效率来说是最高的。但是使用关键字会造成变体增多,这就意味着GPU需要切换更多的变体来完成渲染。之前我们讨论的SRP Batcher的原理就是只要变体不切换,可以高效的重新绑定CBuffer完成draw call,如果变体切换了只能调用一次set pass call,这就打断了SRP Batcher。根据Unity的建议,尽量减少变体,让SRP Batcher包含的draw call数目尽量多是首选。当然了,按照我自己的经验,如果动态分支实在太费,比如会增加贴图的采样次数,或者非常复杂的计算,且这个分支在一个warp中是不可能一致的,那么就还是用关键字来代替动态分支吧。当然最靠谱的是需要经过profile来决定。

声明shader keywords

有两种声明关键字的指令

#pragma multi_compile

  • 声明一组关键字,比如
#pragma multi_compile QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_ULTRA
  • 默认情况下关键字是全局作用域的(即针对所有的shader)
  • 并且影响所有的shader stage(如VS, FS)
  • 构建系统会包含该组中所有关键字,例如#pragma multi_compile a b c,会分别编译出包含定义了a,b和c的shader变体。

#pragma shader_feature

multi_compile有两点不同:

  • 构建系统只会包含该组中被使用的关键字。比如我们可以将shader feature关键字在Properties中设置:
Properties
{[MaterialToggle(_USE_FOG)] _UseFog("Use Fog", int)=0 
}
#pragma shader_feature _USE_FOG

当材质启用_USE_FOG时,这个关键字就被使用。当然,如果是multi_compile也可以在材质属性里面设置,但是无论是否设置该组中的某个关键字,这些关键字都还是会被编译,但shader_feature就只有选择的那些关键字会被编译。

  • 虽然也是声明一组关键字,但是隐含了一个任何关键字都没启用的情况。
  • 但是如果将shader设置到图形设置窗口的Always Included Shaders中,那么所有的关键字都会被包含。

全局关键字和本地关键字

上面的声明方式都是全局关键字,所谓全局就是可以使用Shader.EnableKeyword针对所有使用该shader的材质统一开启或关闭的关键字。
而本地关键字声明的时候要加上_local,比如#pragma multi_compile_local,使用Material.EnableKeyword修改,只影响这个材质。

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

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

相关文章

基于springboot+vue的大创管理系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

【selenium】执行 Javascript 脚本 滚动、元素的特殊操作等

某些特殊情况下,使用selenium的api无法操作页面元素,点击、滚动实现的某些功能,可以考虑通过执行js来完成。 为什么不用js写自动化?——selenium第一版是js写的,但js兼容性存在问题,所以引入webdriver 现在…

ad15 PCB3D模型导出到SOLIDWORKS

注意,工程文件目录不能用中文,否则导出的文件会不存在 将这个文件直接拖到 SOLIDWORKS 中 下一步很关键 显示出来了 另存为一个转配体就可以了

12 个对开发人员有用的 Python 脚本

目录 Create strong random passwordsExtract text from a PDFText processing with PandocManipulate audio with PydubFilter textLocate addressesConvert a CSV to ExcelPattern match with regular expressionsConvert images to JPGCompress imagesGet content from Wiki…

FPS游戏之漫谈网络抖动引发客户端的卡顿优化

话说各位大神 你们遇到过因为网络抖动导致客户端的卡顿现象吗,或者说测试反馈模拟弱网环境的时候某个功能点会卡顿一下,然后通过各种定位,发现原来是一次性下发了好多包???? 问题来了如果我们在…

海思SD3403,SS928/926,hi3519dv500,hi3516dv500移植yolov7,yolov8(14)

自己挖了一个坑,准备做SS928/SD3403的Yolov8的移植,主要是后台私信太多人在问相关的问题。先别着急去写代码,因为在hi3516dv500下的移植还是比较顺利。之前在hi3519av100和hi3559av100系列时遇到过一些问题,所以没有继续去移植新的算法。 SS928架构乍一看和hi3559av100特别…

Ubuntu系统本地部署Inis博客结合内网穿透实现远程访问本地站点

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道(云端设置)2.3.Cpolar稳定隧道(本地设置) 3. 公网访问测试总…

git 使用总结

文章目录 git merge 和 git rebasegit mergegit rebase总结 git merge 和 git rebase git merge git merge 最终效果说明: 假设有一个仓库情况如下,现需要进行 merge: merge 操作流程: merge 的回退操作: git reba…

Java适配器模式 - 灵活应对不匹配的接口

Java适配器模式 - 灵活应对不匹配的接口 引言: 在软件开发中,我们经常遇到不同系统、库或框架之间的接口不兼容问题。为了解决这些问题,我们可以使用适配器模式。适配器模式是一种结构型设计模式,它允许不兼容的接口之间进行协作…

用Python采集动态网页Requests就不那么好用了,试试Selenium

Requests + BeautifulSoup + 额外的库: 对于一些简单的动态内容,你能通过分析网络请求来找到并直接获取这些数据。 使用 requests 库来发送 HTTP 请求,并使用 BeautifulSoup 来解析 HTML。 对于 AJAX 请求,你可能需要使用额外的库(如 mitmproxy 或 BrowserMob Proxy)来…

武汉AAA企业信用等级认证

AAA企业信用等级认证 1. 什么是AAA企业信用等级认证 AAA企业信用等级认证是由国家知名的第三方机构对企业的信用状况进行评估和认证的一种方式。它是根据企业在市场经济中所展示出的信用水平、经营实力、企业形象等方面的表现来确定企业的信用等级,以此为企业提供…

在线进制转换工具

在线进制转换 - BTool在线工具软件,为开发者提供方便。 在线进制转换器提供了二进制,八进制,十进制,十六进制等相互转换功能。

Putty中运行matlab文件

首先使用命令 cd /home/ya/CodeTest/Matlab进入路径:到Matlab文件夹下 然后键入matlab,进入matlab环境,如果main.m文件在Matlab文件夹下,直接键入main即可运行该文件。细节代码如下: Unable to use key file "y…

LeetCode 2828.判别首字母缩略词

给你一个字符串数组 words 和一个字符串 s ,请你判断 s 是不是 words 的 首字母缩略词 。 如果可以按顺序串联 words 中每个字符串的第一个字符形成字符串 s ,则认为 s 是 words 的首字母缩略词。例如,“ab” 可以由 [“apple”, “banana”…

【OpenAI官方课程】第三课:ChatGPT文本总结Summarizing

欢迎来到ChatGPT 开发人员提示工程课程(ChatGPT Prompt Engineering for Developers)!本课程将教您如何通过OpenAI API有效地利用大型语言模型(LLM)来创建强大的应用程序。 本课程由OpenAI 的Isa Fulford和 DeepLearn…

【数据分析——Python Pandas库——数据清洗——电商数据分析】

引言 现如今,我们在电商平台上购物已经成为日常生活的一部分。对于电商公司而言,如何准确理解消费者的需求,提供更好的服务是非常重要的。在这里,数据分析成为提供关键洞察力的工具。Python语言与其数据处理库Pandas,…

K8S部署Java项目 pod报错 logs日志内容:no main manifest attribute, in app.jar

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

hash,以及数据结构——map容器

1.hash是什么? 定义:hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出, 该输出就是散列值。这种转换是一种压缩映射&…

Ubuntu/WSL下生产密钥脚本

说明: 有时候需要为开发人员配发密钥,为方便写了个小脚本,在linux下运行,要求 python10, putty-tools。 使用时,在staffList定义用户列表,运行后程序自动产生对应目录及密钥。 安装: apt inst…

jenkins报错:Pseudo-terminal will not be allocated because stdin is not a terminal

jenkins的流水线部分代码如下 sh ssh root192.168.2.234 << remotessh cd /var/lib/jenkins/workspace/txkc /usr/local/maven/apache-maven-3.8.6/bin/mvn clean package -U ls remotessh执行流水线出现报错&#xff1a;Pseudo-terminal will not be allocated because…