IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> ShaderLab开发规范之布局 -> 正文阅读

[游戏开发]ShaderLab开发规范之布局

一. ShaderLab 代码整体布局

?Shader?"Shader名字"
?{
?????//1.属性块
?????Properties{}

?????//2.代码块
?????CGINCLUDE
?????...
?????ENDCG
?????或者
?????HLSLINCLUDE
?????...
?????ENDHLSL
?????或者
?????GLSLINCLUDE
?????...
?????ENDGLSL

?????//3.子着色器列表块
?????SubShader{
?????????Tags{}
?????????Pass{...}
?????????Pass{...}
?????????...
?????}
?????SubShader{...}
?????...

?????//4.备用着色器定义块
?????FallBack?"..."
?}

二. 材质属性定义

  • 关键字:Properties

  • 属性定义格式: 属性名("属性描述",属性类型) = 属性默认值

  • 用处:只要在这里被定义的属性,就在Unity的Editor中,被材质的默认Inspector识别.也就是说可以通过编辑器修改这个属性,设置预设值.

  • 需要注意:
    1. 每个属性的定义,在语句最后一定不能有分号

    2. 这里定义了某个属性,那么使用这个Shader的材质,本属性就是不会被SetGlobalxxx来改变的.

  • 布局示例:

???Properties
???{
???????//主颜色,类型:颜色
???????_Color?("Main?Color",?Color)?=?(1,?1,?1,?1)
???????//颜色的调整值,?类型:范围值
???????_ColorMultiplier("Color?Multipler",?Range(0,10))?=?2??
???????//主纹理,?类型:纹理
???????_MainTex?("Effect?Texture",?2D)?=?"black"?{}?
???????//环境立方体贴图,?类型:?立方体贴图
???????_EnvCube("Env?Cube",?Cube)?=?"white"?{}?
???????//切割区域,?类型:向量
???????_ClipRect("ClipRect",?Vector)?=?(-50000,-50000,50000,50000)
???????//曝光系数,?类型:浮点值
???????_BloomFactor("BloomFactor",?Float)?=?0
???}

三. 逻辑代码区域

  • 关键字:会根据使用的语言有不同.
    • cg语言:CGINCLUDE ... ENDCG

    • hlsl语言:HLSLINCLUDE ... ENDHLSL

    • glsl语言:GLSLINCLUDE ... ENDGLSL

  • 用处:当前着色器中需要有不同逻辑的子着色器或者pass时,方便代码编写和统一管理.也是为了用于分离业务逻辑定义和渲染标记定义.

  • 需要注意:
    1. 每个着色器的代码文件中尽量只有一个逻辑代码块.

    2. 每个着色器的代码文件中尽量只使用一种高级语言,cg,hlsl,glsl.其中cg和hlsl语法几乎一样,并且推荐使用这两种.

    3. 在定义结构体时,一定不要忘记在定义的结束大括弧后加上分号

    4. 如果这个代码块内容需要被共享给其他着色器代码文件,那么可以把这个代码块提取出来,另外放到一个文件中,然后通过#include的方式引用.(如果是cg代码就放到xxx.cginc文件,如果时hlsl代码就放到xxx.hlsl文件中.)

  • 布局示例

?????//1.引用区域
?????#include?"...";
?????...

?????//2.常量或者宏的定义区域
?????#define?_XXX_XXX_ON?1
?????static?float?xxx?=?23;
?????const?float?xxx?=?23;
?????...

?????//3.结构体的定义区域
?????struct?xxx?{};
?????...

?????//4.需要外部赋值的变量定义区域
?????uniform?float?xxx;
?????...

?????//5.通用方法定义区域
?????inline?float?getNoise(...)
?????{...}
?????void?resetValue(...)
?????{...}

?????//6.顶点程序定义区域
?????v2f?vert(appdata?v)?
?????{...}

?????v2f?vertAdd(appdata?v)?
?????{...}

?????v2f?vertBlend(appdata?v)?
?????{...}
?????...?

?????//7.片元程序定义区域
?????fixed4?frag(v2f?i):SV_Target?
?????{...}

?????fixed4?fragAdd(v2f?i):SV_Target?
?????{...}

?????fixed4?fragBlend(v2f?i):SV_Target?
?????{...}
?????...

四. 可匹配的着色器列表

  • 关键字: SubShader

  • 用处:这里定义一系列的SubShader,在需要着色时,应用会从上到下的顺序,一个一个筛选可以执行的着色器.

  • 注意:
    1. 可以有多个子着色器.

    2. 每个子着色器内部可以有多个渲染遍Pass.

    3. 排列着色器代码时,一定把你最希望匹配的子着色器放在最前面.

  • 布局:

SubShader
{
????//1.子着色器等级
????LOD?100
????//2.标签
????Tags{...}
????//3.渲染设置列表
????[Render?Setup]
????//4.渲染遍列表(走一遍GPU的渲染流程,叫做渲染遍?Pass)
????Pass?
????{
????????...
????}

????Pass?
????{
????????...
????}
????//5.引用其他Shader的渲染遍.
????UsePass?"某个Shader的名字/Pass名字"
????...
}
  • 下面介绍一下子着色器的一些关键元素
    1. 着色标签:

      • 关键字: Tags

      • 格式模板: Tags{"Tag1"="Tag1Value" "Tag2"="Tag2Value"}

      • 用处: 这里的标签是给Unity3D的渲染逻辑使用的,用于判断在Unity渲染处理中是否执行某个逻辑.也可以自定义一些标签,用于自己独有的逻辑.

      • 注意:

        1. Tags标签可以在SubShader的域中定义,也可以在Pass的域中定义.

        2. 标签和值中间的赋值等号之间不可以有空格.

        3. 每个标签之间使用空格分隔.

        4. 标签和值都是用引号包括的字符串内容.

      • 一些常用标签的

        • Queue:这个是用来表示当前着色器在哪个渲染队列中.

          ?

          ?

        渲染队列描述渲染队列值
        Background这个队列被最先渲染。它被用于skyboxes等。1000
        Geometry这是默认的渲染队列。它被用于绝大多数对象。不透明几何体使用该队列。2000
        AlphaTest通道检查的几何体使用该队列。它和Geometry队列不同,对于在所有立体物体绘制后渲染的通道检查的对象,它更有效。2450
        Transparent该渲染队列在Geometry和AlphaTest队列后被渲染。任何通道混合的(也就是说,那些不写入深度缓存的Shaders)对象使用该队列,例如玻璃和粒子效果。3000
        Overlay该渲染队列是为覆盖物效果服务的。任何最后被渲染的对象使用该队列,例如镜头光晕。4000
        • LightMode:这个是用来表示当前着色器选择哪个光照模式

        光照模式描述
        Always适用与任何渲染模式,不使用任何光源
        ForwardBase用于前向渲染, 只能够使用:环境光,主光源,顶点/球谐光,光照贴图
        ForwardAdd用于前向渲染, 附加每个像素光源,每个pass对应一个像素光源.
        Deferred用于延迟渲染, 渲染G-Buffer
        ShadowCaster用于渲染对象深度到阴影贴图或者深度贴图
        PrepassBase用于遗留的延迟照明,渲染法线和高光指数
        PrepassFinal用于遗留的延迟照明,通过结合纹理,照明和发射渲染最终的颜色。
        Vertex用于遗留的没有光照贴图的顶点光渲染,所有顶点都能被使用.
        VertexLMRGBM用于遗留的带有光照忒图的顶点光渲染,在PC平台,这里的光照贴图使用RGBM格式来编码.
        VertexLM用于遗留的带有光照忒图的顶点光渲染;在移动平台,这里的光照贴图使用double-LDR格式来编码
        • RenderType:渲染类型,这个用处挺多,比如:Unity生成的深度图,就是利用这个标签.我们也可以使用这个标签,不过要使用Camera.SetReplacementShader函数.

          ?

    2. 渲染设置标记 (Render Setup )

      • 关键字:这个太多了,Blend,ZTest,ZWrite,Cull,Lighting 等等.

      • 用处:这里的标记主要是给GPU用的,通道设定显示硬件的各种状态,例如能打开alpha混合,能使用雾,等等

      • 注意:

        1. 标记定义完成后,不能有分号作为结束.

        2. 标记和值之间都是使用空格作为分割.

        3. 标记与标记之间使用空格或者换行作为分割.

      • 一些常用标记的作用

        标记格式值列表描述
        Lighting VALUEOn; Off开启或关闭顶点光照。开启灯光之后,顶点光照才会有作用
        Cull VALUEBack; Front; Off设置多边形剔除模式
        ZTest VALUE(Less; Greater; LEqual; GEqual; Equal; NotEqual; Always)设置深度测试模式
        ZWrite VALUEOn ; Off设置深度写模式
        Fog {VALUE}Mode; Color; Density; Range设置雾参数:模式,颜色,密度,区域
        AlphaTest VALUE1 VALUE2(Less; Greater; LEqual; GEqual; Equal; NotEqual; Always) CutoffValue开启alpha测试
        Blend VALUE1 VALUE2[,VALUE3 VALUE4]Zero; One; SrcAlpha; SrcColor; DstAlpha; DstColor; OneMinusXXXX设置alpha混合模式
        ColorMask VALUERGB; A; 0; any combination of R, G, B, A设置颜色写遮罩。设置为0将关闭所有颜色通道的渲染
        Offset VALUE1,VALUE2float 类型值设置深度偏移
    3. 着色器等级

      • 关键字: LOD

      • 格式: LOD 整数值

      • 用处: 用于在渲染时筛选子着色器.

      • 注意: 定义Lod数值越大的SubShader,应该放在前面.

    4. 渲染遍Pass

      • 关键字: Pass,UsePass

      • 用处: 每个Pass都表示从头到尾执行一遍GPU渲染流程.这里主要定义渲染设置,编译设置等.(本来这里可以定义业务逻辑,不过我们规范把业务逻辑全部定义到逻辑代码区域中.)

      • 注意:
        1. 在Pass中也可以使用着色标签和渲染设置,如果与SubShader中的有重复,就应用Pass中的.

        2. 每个Pass就是一次渲染提交,尽量减少Pass的数量.

        3. 在Pass中定义Name时,一定要使用全部大写.

        4. 使用UsePass关键字,可以引用其他着色代码文件中的Pass.引用格式为:UsePass "Shader名字/Pass名字"

        5. 这里如果这里没有逻辑的话,每个行后就不要有分号

      • 布局示例:

      Pass{
      ????//1.定义名字
      ????Name?"全部大写的Pass名字"
      ????//2.标签
      ????Tags{...}
      ????//3.渲染设置列表
      ????[Render?Setup]
      
      ????//4.使用cg或者hlsl语言来写的,决定着色器如何编译的一些编译指令.
      ????//cg语言
      ????CGPROGRAM
      ???????#pragma?target?3.0
      ???????#pragma?vertex?vert
      ???????#pragma?fragment?frag
      ???????#pragma?multi_compile?_XXX_ON?_XXX_OFF
      ???????#pragma?multi_feature?_XXXX_ON?_XXXX_OFF
      ???????....
      ????ENDCG
      ????或者
      ????//hlsl语言
      ????HLSLPROGRAM
      ???????#pragma?target?3.0
      ???????#pragma?vertex?vert
      ???????#pragma?fragment?frag
      ???????#pragma?multi_compile?_XXX_ON?_XXX_OFF
      ???????#pragma?multi_feature?_XXXX_ON?_XXXX_OFF
      ???????....
      ????ENDHLSL
      ?????或者
      ????//glsl语言
      ????GLSLPROGRAM??????????????
      ???????....
      ????ENDGLSL
      }
      

五. 备用着色器

  • 关键字: FallBack

  • 用处:当所有的子着色器都不被匹配时,就执行这里指定的着色器

  • 注意:
    1. 这里指定的是一个着色器的名字,并不是文件路径名.

    2. 如果使用关键字Off,就表示关掉了这个退路.

  • 示例:

Fallback?"Gonbest/FallBack/FBWithShadowAlpha"


?

?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-16 19:56:59  更:2021-10-16 19:59:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 0:52:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码