Unity Shader学习日志 part4 Shader 底子结构

[复制链接]
发表于 2025-11-14 08:34:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
着实在这一篇之前,应该另有一个关于坐标空间转换的内容,但是内容囤积的有些多,就先把Shader的底子结构先纪录一下。
条记告急纪录在代码中,以是知识点告急是图和代码的展示。
Unity Shader分类


在Unity中,Shader的种类,告急是这几种 
1.Standard Surface Shder(标准曲面着色器)
        包罗标准光照模子的外貌着色器模板
2.Unlit Shder
         不包罗光照的根本顶点/片元着色器
3.Image Effect Shader
        用于实现屏幕后处理惩罚的结果的根本模板
4.Comput Shader
        利用GPU并行盘算一些和通例渲染流水线无关的内容
5.Ray Tracing Shader
        用于实现光线追踪结果的着色器

之后学习的也告急是Unlit Shader干系的知识。
 
下面来看看Shader的根本构成,我们创建一个Standard Surface Shder,可以发现它的告急结构是如许的


以是Shader 的告急结构就是如许的,接下来是每个部门的详细结构
着色器名字

        着色器的名字告急用来决定外部材质利用时的路径,在有其他Shader引用时也会用到


Properties部门

        这个部门告急用来界说一些外部属性,如许就可以通过外部赋值的方式来对Shader的数据举行更改。

可以看到属性的结构是如许的
        //属性结构
        // _name ("Display Name",type)=defaultValue[{options}]
        // _name 属性名字,加下划线,方便获取
        // Display Name 材质面板上表现的名字
        // type  详细的范例 (数值,颜色和向量,纹理贴图)
        //defaultValue 将Shader指定给材质的初始化的默认值
既然知道了详细的写法,那么来看看在Shader中的属性可以或许界说哪些范例。
Shader中的属性范例告急包罗数值,颜色和向量,纹理贴图

数值范例


数值(整形,浮点型,范围浮点型)
底子范例是浮点型,整形会被主动转为浮点型
如
  1.         _intvalue ("IntValue",Int)=0
  2.         _floatvalue("FloatValue",Float)=0
  3.         _rangevalue("RangeValue",Range(1,2))=1.5
复制代码

颜色和向量范例

颜色RGBA 向量XYZW 都是四个值,以是放一起
  1.         _ColorValue("ColorValue",Color)=(1,1,1,1)//取值0-1,映射0-255   
  2.         _VectorValue("ColorValue",Vector)=(1,1,1,1)//取值不限
复制代码
纹理贴图

纹理贴图告急包罗:
2D纹理,包罗漫反射贴图,法线贴图等
2DArray纹理(纹理数组,允许存储多层图像数据,每一层看作一个2D图像,一样寻常利用脚本创建)
Cube(map texture)纹理,立方体纹理,由上下左右6张有接洽的2d贴图拼成,如天空盒,反射探针
3D纹理,一样寻常脚本创建,利用不多
  1.         //纹理贴图
  2.         _MainTex ("Texture", 2D) = "white" {}
复制代码
注意
white:defaultValue
不写:默以为空
 white:白色贴图
black:玄色贴图
gray:灰色贴图
bump:凸贴图
red:赤色贴图    

SubShader部门

subshader子着色器,在每一个Shader中,大概会存在多个SubShader,告急是为了装备多种装备,当步调运行时,会逐一去实验每一个SubShader,直到找到可以或许利用的SubShader。
来看看他的构成:
        /*构成部门
            标签 Tags  确定什么时间渲染物体和怎样渲染物体
            渲染状态  确定渲染时间的剔除方式,深度测试,肴杂方式等内容
            渲染通道 Pass 详细的代码实现,每个子着色器至少有一个,每界说一个Pass,就会对物体实验一次渲染,
                            对于一些高级的Shader,必要多个Pass叠加,我们必要只管镌汰Pass,他会增长渲染斲丧
        */
下面来逐一看
标签 Tags



 
  1.         //Tags 标签
  2.         //渲染队列
  3.         Tags {
  4.             "Queue"="BackGround"//队列号1000,最早渲染的物体,一般用于天空和或者背景
  5.             "Queue"="Geometry"//队列号 2000,一般用于不透明的集合体,当没有声明是,Unity会自动申明
  6.             "Queue"="AlphaTest"//队列号 2450,有透明通道的,需要透明测试的几何体
  7.             "Queue"="Transparent"//队列号 3000,这个队列中的几何体按照由远到近的顺序绘制,半透明的渲染队列,所有进行透明混合的几何体都应该在这个队列中,如玻璃,粒子特效等
  8.             "Queue"="Overlay"//队列号 4000,用于最后的叠加效果,如镜头光晕等
  9.             "Queue"="Transparent+1"//自定义队列,通过队列的加减确定队列顺序
  10.             }
  11.         //渲染类型,对着色器进行分类,用于着色器的替换功能
  12.         //摄像机上有对于的API,通过调用来替换着色器
  13.         Tags{
  14.             "RenderType"="Opaque"//不透明的,一些普通的Shader,如不透明,自发光,反射等
  15.             "RenderType"="Transparent"//透明的,一些半透明效果
  16.             "RenderType"="TransparentCutout"//透明切割,用于透明测试的Shader.如植物叶子等
  17.             "RenderType"="BackGround"//背景,一般用于天空和Shader
  18.             "RenderType"="Overlay"//覆盖,用于GUI纹理,光环,光晕等
  19.             //以下了解即可
  20.             "RenderType"="TreeOpaque"//地形系统中的树干
  21.             "RenderType"="TreeTransparentCutout"//地形系统中的树叶
  22.             "RenderType"="TreeBillboard"//地形系统中的树
  23.             "RenderType"="Grass"//地形系统中的草
  24.             "RenderType"="GrassBillboard"//地形系统中的Billboard草
  25.             }
  26.         //禁用批处理
  27.         //批处理时模型会被转换到世界空间,从而舍弃模型空间
  28.         //可能会导致一些使用模型顶点信息的Shader失效
  29.         
  30.         //总是禁用批处理
  31.         Tags{"DisableBatching"="True"}
  32.         //Tags{"DisableBatching"="False"}//不禁用
  33.         //禁止投射阴影 控制SubShader的物体是否允许投射阴影
  34.         Tags{"ForceNoShadowCasting"="True"}//不投射
  35.         //Tags{"ForceNoShadowCasting"="False"} //投射阴影(默认)
  36.         //禁止投影机
  37.         //物体是否受到投影机的投射
  38.         //忽略投射(一般在一些半透明效果中使用)
  39.         Tags{"IngoreProjector"="True"}//不投射
  40.         Tags{"IngoreProjector"="False"}//投射(默认)
复制代码
渲染状态 State

  1.         /*
  2.         States 渲染状态 确定渲染时候的剔除方式,深度测试,混合方式等内容
  3.         片元,光栅化阶段生成的像素或像素片段,是像素级操作和计算的基本单位,代表了像素的各种属性(颜色,深度值等)
  4.         基本结构
  5.         渲染状态关键词+空格+状态类型
  6.         剔除方式
  7.         所谓剔除,就是不渲染,主要有正面剔除,背面剔除(默认),和不剔除
  8.         分别是 Cull Front, Cull Back ,Cull Off
  9.         Cull Back
  10.         深度缓冲
  11.         是否写入深入缓冲区(Depth Buffer)
  12.         记录每一个像素的深度值,初始为最大深度,意味着所有像素都在屏幕外,通过深度测试之后,决定是否写入缓冲,最后渲染缓冲区中的像素
  13.         ZWrite On //写入 一般做透明等效果
  14.         ZWrite Off  //不写入(默认)
  15.         深度测试
  16.         主要是保证像素按照正确的顺序进行渲染
  17.         我们可以自定义深度的对比方式,来进行像素的深度测试
  18.         ZTest Less //小于缓冲区的值就通过测试,决定是否写入缓冲 (透明)
  19.         ZTest Greater //大于缓冲区的值就通过测试,决定是否写入缓冲(描边)
  20.         ZTest LEqual //小于等于(默认)
  21.         ZTest GEqual //大于等于
  22.         ZTest Equal //等于
  23.         ZTest NotEqual//不等于
  24.         ZTest Always //总是
  25.         注意:深度测试和混合测试都是在光栅化阶段的逐片元操作中进行的,一般实现一些特殊效果我们回去设置
  26.         混合方式
  27.         设置图像颜色的混合方式,多种颜色的混合,比如透明,半透明,不透明之间的混合
  28.         默认为不混合
  29.         Blend One One //线性减淡
  30.         等等
  31.         其他
  32.         
  33.         注意:这些渲染状态不仅可以在SubShader中申明,也可以在Pass中申明,只是两者的影响范围不同
  34.         */
复制代码
在这里我们必要相识一下什么是深度测试和颜色肴杂
深度测试 

        它告急是用在处理惩罚一些遮挡关系和透视关系,举个列子,方块A和方块B,相对于摄像机来说,A比B更近,而且两个方块存在遮挡关系,就像如许
        

那么摄像机怎么知道重叠部门怎么渲染呢?没错,深度测试。
在渲染管线中存在深度值缓冲区,内里有初始值,设置为最大,这意味着全部物体都在摄像机之外,都不会渲染。
在渲染片元(像素)的时间,他会去将这个位置的深度值和像素的深度值对比,在默认情况下,假如像素的深度值更小,他就会将这个值写入深度缓冲区(可以不写入),在下次渲染的时间,继承这个流程,知道渲染完成,那么留着缓冲区中的像素就是必要渲染的像素了,如许就能处理惩罚遮挡关系了。
必要注意的是,假如没有开启深度写入,当像素通过深度测试后,任然会被渲染。这表现,一个像素是否渲染,取决于是否通过深度测试。

颜色肴杂 

 和深度测试差不多的原理,这个属性一样寻常用在一些透明结果上。

渲染通道 Pass


 
  1. //Pass 渲染通道
  2.         //结构
  3.         /*
  4.         Pass
  5.         {
  6.             名字
  7.             渲染标签
  8.             渲染状态
  9.             着色器相关
  10.         }
  11.         
  12.         名字:主要为了在其他Shader中服用Pass代码
  13.         如:
  14.         Pass{ Name MyPass }
  15.         其他Shader中 UsePass "Lesson1/Test01/MYPASS"
  16.         unity 会将Pass名字转为大写,所以引用的时候需要大写名字
  17.         
  18.         Pass中的渲染标签
  19.         //和SubShader中的语法相同,只是它具有自己独立的渲染标签
  20.         1.Tags{"LightMode"="标签值"}
  21.         可以指定这个Pass应该在哪个阶段执行
  22.         可以将着色器代码分配给适当的渲染阶段,以实现具体的效果
  23.         Always  始终渲染,不应用光照
  24.         ForwardBase 在向前渲染中使用,应用环境光,主方向光,顶点/sh 光源和光照贴图
  25.         ForwardAdd 在向前渲染中使用,应用附加的每个像素光源(每个光源有一个通道)
  26.         Deferred 延迟渲染中使用,渲染G缓冲区
  27.         ShadowCaster 将对象深度渲染到阴影贴图或深度纹理中
  28.         等等
  29.         2.Tags{"RequoreOptions"="标签值"}
  30.         用于指定满足某些条件时才渲染这个pass
  31.         目前unity只支持SoftVegetation
  32.         仅当Quality窗口开启SoftVegetation时才渲染
  33.         3.Tags{"PassFlags"="标签值"}
  34.         指定一些特定的数据传入着色器中
  35.         目前unity只支持OnlyDirectional
  36.         在向前渲染中使用,这个标志只允许主方向光和环境光/光照探针数据传入
  37.         这意味着非重要的光源数据不会传递到 顶点光源或球谐函数着色器变量
  38.         Pass中的渲染状态
  39.         SubShader中的渲染状态同样在Pass中适用,只是两个的影响范围有所区别
  40.         此外,Pass中还可以使用固定管线着色器的命令
  41.         GrabPass命令
  42.         使用这个命令可以将绘制对象时的屏幕内容抓取到纹理中,在后续的通道中就可以使用这个纹理,从而执行一些高级效果
  43.         如:
  44.         将绘制对象之前的屏幕抓取到_BackGroundTexture纹理中
  45.         GrabPass{
  46.             "_BackGroundTexture"
  47.         }
  48.         注意:这个命令一般写在某个Pass之前,在之后的Pass中就可以利用_BackGroundTexture变量来进行处理
  49.         */
复制代码
 备用Shader
  1.         /*
  2.             备用Shader
  3.             防止所有SubShader都没办法正常渲染的情况,让画面至少能被渲染
  4.             FallBack "Shader名"
  5.             或者不写(类似于FallBack Off)
  6.         */
复制代码

那么以上就是Shader的底子结构了,个人条记,大概存在不全或错误
之后就是学习Shader的详细写法了。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表