Fixed function shader从字面意思理解,就是固定功能的渲染着色器 这种Shader功能有限,但速度却是最快的 但是能够在基本上所有的硬件平台上执行
案例1:固定着色
Shader"Unlit/firstFixedShader"
{
SubShader
{
pass
{
color(1,1,1,1)
}
}
}
Properties
使用Properties,提供外部的Shader属性参数配置
案例
Shader"Unlit/firstFixedShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
}
SubShader
{
pass
{
//color(1,0,0,1)
color[_Color]
}
}
}
() 小括号是固定的值 [ ]中括号是属性的值 所以填入color[_Color] 就可以把属性_Color给color 从而达到着色效果
Material材质
案例1:漫反射光照Shader
Shader "Unlit/firstFixedShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
}
SubShader
{
pass
{
material
{
diffuse[_Color]
}
lighting on //off
}
}
}
material是一个功能块 diffuse是漫反射 diffuse[_Color]设置漫反射颜色 lighting on 开启光照,这样才能让Shader接受光照,从而实现漫反射效果
案例2:加入环境光
Shader "Unlit/firstFixedShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
}
SubShader
{
pass
{
material
{
diffuse[_Color]
ambient[_Ambient]
}
lighting on //off
}
}
}
红色部分就是环境光影响的部分 ambient 是环境光 在真实世界当中,一个物体会受到其环境光的影响 所以我们可以在Shader中加入环境光的效果,来模拟真实世界 创建一个属性**_Ambient** 为环境光传入属性ambient[_Ambient] 环境光Alpha通道,不会对环境光有任何影响
案例3:高光
Shader "Unlit/firstFixedShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
}
SubShader
{
pass
{
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]//高光
}
lighting on //off
separatespecular on //高光计算 要使用specular功能,必须开启
}
}
}
如果不SeparateSpecular On,那么是不会计算高光的。 如果SeparateSpecular On,计算高光,但是高光是单独计算的。即计算漫反射环境光(但不包括高光)等相加起来得到的光照,跟纹理混合。混合之后的颜色再加上我们单独计算的高光,这样得到最终的颜色。要起作用,必须Lighting On
真实世界中物体收到光照影响,会有高光部分 在固定渲染管线的Shader中 可以使用specular高光功能 来添加材质的高光着色 **specular[Color]**
案例3:shininess调整高光集中度
Shader "Unlit/firstFixedShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
}
SubShader
{
pass
{
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]//高光
shininess[_Shiness]//高光集中度
}
lighting on //off
separatespecular on //要使用specular功能,必须开启
}
}
}
shininess可以控制高光的集中度 shininess需要传入一个浮点值 所以外部定义属性的时候 可以将类型设置成float 或者是range
案例4:Emission自发光
Shader "Unlit/firstFixedShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
_Emission("Emission",color)=(0.5,0.5,0.5,1)
}
SubShader
{
pass
{
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]
shininess[_Shiness]
emission[_Emission]//自发光
}
lighting on //off
separatespecular on //要使用specular功能,必须开启
}
}
}
Emission控制从表面发出的光的颜色和强度。当你在场景中使用Emission材质时,它以可见光源的形式出现。自发光。 Emission材质通常是用在GameObjects需要从内部亮了起来,如监视器上的屏幕,如汽车在夜间行驶时闪亮的仪表盘,或是再漆黑地方闪亮着怪物的眼睛。 在计算机中,会根据自发光颜色深度来处理自发光的效果 如果自发光颜色为纯白色,那渲染的材质就是非常亮
可以减少颜色深度,提高真实感
纯黑色的话就,看不到自发光效果
Lighting
在Pass中 lighting on//可以启用光照 启动的是定点光照
SetTexture
在绘制材质过程中,有些时候,我们想要绘制指定的贴图纹理 在ShaderLab中,固定渲染着色器里可以使用settexture指令进行贴图绘制
案例1:绘制纹理
Shader "Unlit/FixedTextureShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
_Emission("Emission",color)=(0.5,0.5,0.5,1)
_MainTex("MainTex",2D)=""
}
SubShader
{
pass
{
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]
shininess[_Shiness]
emission[_Emission]
}
lighting on
separatespecular on
settexture[_MainTex]
}
}
}
_MainTex(“MainTex”,2D)=""//定义了一个2D纹理贴图的属性,默认值为字符串“”,默认值其实就是给纹理取一个名称,这里填写了空字符串 shaderlab不分大小写,所以属性类型写成2d或者2D都可以编译的 settexture[纹理属性] 传入纹理属性,来设置贴图
案例2:使用combine混合纹理
Shader "Unlit/FixedTextureShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
_Emission("Emission",color)=(0.5,0.5,0.5,1)
_MainTex("MainTex",2D)=""
}
SubShader
{
pass
{
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]
shininess[_Shiness]
emission[_Emission]
}
lighting on
separatespecular on
settexture[_MainTex]
{
combine texture * primary double
}
}
}
}
settexture[_Maintex] { //花阔号内可以设置绘制纹理时的功能命令 } combine就是一个混合纹理颜色的命令 texture就是当前设置的纹理颜色 primary是当前pass中material中设置的材质效果,和灯光还有高光反射颜色 texture*primary相当于对两个颜色进行正片叠底 也就是将两个颜色每个RGB通道的分量相乘 double 相当于将 混合的颜色再乘两倍,这样可以提高整体亮度,也可以乘4倍 quad
案例3:多张纹理贴图混合
Shader "Unlit/FixedTextureShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
_Emission("Emission",color)=(0.5,0.5,0.5,1)
_MainTex("MainTex",2D)=""
_SecondTex("SecondTex",2D)=""
}
SubShader
{
pass
{
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]
shininess[_Shiness]
emission[_Emission]
}
lighting on
separatespecular on
settexture[_MainTex]
{
combine texture * primary double
}
settexture[_SecondTex]
{
combine texture * previous double
}
}
}
}
这里要注意settexture并不是无限次的 不同的显卡支持的纹理混合次数是不同的
在第二层settexture中 combine 命令混合时 是由当前纹理texture他颜色和previous颜色相乘 previous包含了上一次settexture混合的纹理颜色加上primary颜色 如果这里用primary的话 可以会导致无法获取到第一次settexture设置的纹理颜色 最终效果也就只有_SecondTex纹理的效果了
ShaderLab:Blending
确定 GPU 如何将片元着色器的输出与渲染目标进行合并。 此命令的功能取决于混合操作,您可以使用 BlendOp 命令进行设置。请注意,虽然所有图形 API 和硬件都支持混合功能,但对某些混合操作的支持较为有限。 启用混合会禁用 GPU 上的一些优化(主要是删除隐藏的表面/Early-Z),这些优化会增加 GPU 帧时间。
语法
Blend Off:关闭混合(这是默认设置) Blend SrcFactor DstFactor:配置并启用混合。生成的颜色乘以SrcFactor。屏幕上已有的颜色乘以DstFactor,然后将两者相加。 Blend SrcFactor DstFactor, SrcFactorA DstFactorA:与上面相同,但使用不同的因素来混合 Alpha 通道。 BlendOp Op:不是将混合颜色添加到一起,而是对它们执行不同的操作。 BlendOp OpColor, OpAlpha: 同上,但对颜色 (RGB) 和 alpha (A) 通道使用不同的混合操作。 此外,您可以设置上渲染目标混合模式。使用多渲染目标 (MRT) 时渲染,上面的常规语法为所有渲染目标设置了相同的混合模式。以下语法可以为各个渲染目标设置不同的混合模式,其中N是渲染目标索引 (0..7)。此功能适用于大多数现代 API/GPU(DX11/12、GLCore、Metal、PS4):
Blend N SrcFactor DstFactorBlend N SrcFactor DstFactor, SrcFactorA DstFactorABlendOp N OpBlendOp N OpColor, OpAlpha
AlphaToMask On:打开 alpha-to-coverage。当使用 MSAA 时,alpha-to-coverage 会根据像素着色器结果 alpha 值按比例修改多样本覆盖掩码。这通常用于比常规 alpha 测试更少锯齿的轮廓;对植被和其他经过 alpha 测试的着色器很有用。
混合因子
以下所有属性对Blend命令中的 SrcFactor 和 DstFactor 均有效。Source是指计算出的颜色,Destination是屏幕上已有的颜色。如果BlendOp使用逻辑运算,则混合因子将被忽略。
混合操作
常见混合类型 (Blend Type)
以下是最常见的混合类型的语法:
Blend SrcAlpha OneMinusSrcAlpha // 传统透明度
Blend One OneMinusSrcAlpha // 预乘透明度
Blend One One // 加法
Blend OneMinusDstColor One // 软加法
Blend DstColor Zero // 乘法
Blend DstColor SrcColor // 2x 乘法
案例4:实现材质的透明效果
当我们在渲染鼠标指的球体的时候的颜色,我们称之为源颜色 除了鼠标所指的球体以外的渲染的颜色(包括天空盒),我们称之为目标颜色 目标颜色,在我们渲染源颜色之前已经渲染过了
Shader "Unlit/FixedTextureShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
_Emission("Emission",color)=(0.5,0.5,0.5,1)
_MainTex("MainTex",2D)=""
_SecondTex("SecondTex",2D)=""
}
SubShader
{
pass
{
Blend SrcAlpha OneMinusSrcAlpha
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]
shininess[_Shiness]
emission[_Emission]
}
lighting on
separatespecular on
settexture[_MainTex]
{
combine texture * primary double
}
settexture[_SecondTex]
{
combine texture * previous double
}
}
}
}
可以看到 SrcAlpha OneMinusSrcAlpha 经过a*(1-a) 处理之后得到了传统的透明度的混合
案例5:Tags与渲染队列
管理Tags的Unity文档⬇️
Shader "Unlit/FixedTextureShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
_Emission("Emission",color)=(0.5,0.5,0.5,1)
_MainTex("MainTex",2D)=""
_SecondTex("SecondTex",2D)=""
}
SubShader
{
Tags{"Queue"="Transparent"}
pass
{
Blend SrcAlpha OneMinusSrcAlpha
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]
shininess[_Shiness]
emission[_Emission]
}
lighting on
separatespecular on
settexture[_MainTex]
{
combine texture * primary double
}
settexture[_SecondTex]
{
combine texture * previous double
}
}
}
}
通过标签设置渲染队列为Transparent,透明物体,加上传统Alpha的混合,就可以实现透明物体的效果,透过物体可以看到背后渲染的物体
案例6:使用纹理的Alpha通道,实现透明效果
Shader "Unlit/FixedTextureShader"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
_Specular("Specular",color)=(1,1,1,1)
_Shiness("Shininess",range(0,1))=1
_Emission("Emission",color)=(0.5,0.5,0.5,1)
_MainTex("MainTex",2D)="white"{}
_SecondTex("SecondTex",2D)=""{}
_ConstantColor("ConstantColor",color)=(1,1,1,0.3)
}
SubShader
{
Tags{"Queue"="Transparent"}
pass
{
Blend SrcAlpha OneMinusSrcAlpha
material
{
diffuse[_Color]
ambient[_Ambient]
specular[_Specular]
shininess[_Shiness]
emission[_Emission]
}
lighting on
separatespecular on
settexture[_MainTex]
{
combine texture * primary double
}
settexture[_SecondTex]
{
constantColor[_ConstantColor]
combine texture * previous double,texture*constant//,逗号之后取颜色的Alpha通道
}//不同显卡有不同的最多支持混合次数
}
}
}
constantColor命令指定一个颜色可以用于Combine指令。 combine逗号之后的参数 表示混合的Alpha颜色 让当前纹理texture颜色*constant指定的颜色 这样可以通过外部暴露的 _ConstantColor整体调整材质透明度,并且同时可以应用材质_SecondTex的透明度 注意: 除非后面都是2D纹理的属性否则定义2D纹理属性 初始化的值要写上{} 这里因为后面是颜色属性所以要写上{} 这样编译器才不会报错


...