目录
课时05:固定管线Shader1
视频地址:https://www.bilibili.com/video/BV1YK41157AC?p=5
这节课主要讲material里面的各种颜色
参考:https://blog.csdn.net/lichaoguan/article/details/43229767
Material Block 材质块
这些是为了设置材质如何影响光照。任何这些属性都能被排除,在这种情况下它们被认为默认为黑色(没起到效果)。
Diffuse Color 漫反射颜色
这个是物体最基础的颜色。
Ambient Color 环境色
当物体被环境光影响时候给物体设置颜色,这个取决于在RenderSettings中设置的环境颜色。
Specular Color 反射光
设置物体的高光反射颜色
Shininess Number 清晰度
突出清晰度,值在0和1之间。为0时候,你得到1个巨大的高光看起来像很多漫射光照;为1时候,你得到一个小的斑点。
Emission Color 自发光颜色
当没被其他光线影响时候,物体本身的自发光颜色。
当物体被所有光线照射时候他的颜色的计算公式如下:
Ambient * RenderSettings ambient setting +(LightColor * Diffuse + Light Color * Specular) + Emission
在括号中的那部分光线计算,是计算所有照射到物体上的光线。
通常情况下,你要保持漫反射和环境的颜色相同(所有内建的Unity3dshader 都是这么做的)。
----------------------------
应该叫固定功能吧 Fiexed function:针对硬件能够支持的基本功能编写的Shader,功能有限,速度最快,在所有的硬件平台上良好运行
默认Shader:StandarSurfaceShader
Shader "Custom/NewSurfaceShader"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
这个Shader在HDRP下无法使用。
SurfaceShader没有Pass(渲染通道),被封装起来了。
修改为最小的fixed function shader
Shader "CustomFix/ff1"
{
SubShader
{
pass
{
color(1,1,1,1) //固定颜色
}
}
}
添加属性
Shader "CustomFix/ff1"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
}
SubShader
{
pass
{
//color(1,1,1,1) //固定颜色
color[_Color] //()固定值,[]参数值
}
}
}
---------------------
Shader不区分大小写
个人实验1:color是命令(因为下面的materal称为"命令块",不过也可能是"属性"),color和后面的值(1,1,1,1)或者[_Color]之间可以有空格,\t,\n,或者这几个的任意多个。也可以加注解
pass
{
//color (1,1,1,1) //固定颜色,
color
//aa
//color和(1,1,1,1直接可以有空格,\t,\n)
[_Color] //()固定值,[]参数值
}
-----------------------
个人实验2:pass里面没有任何命令也是正确的shader,和上面白色模型一样的效果
Shader "CustomFix/ff1"
{
SubShader
{
pass
{
}
}
}
但是pass整个去掉,就是错误材质了
---------------------------
material命令块:
material
{
diffuse [_Color] //diffuse:物体的固有颜色,反射的颜色,要结合lighting on
}
没有加lighting on时我的效果还是纯白的
加上lighting on 后
背光面是黑色的
灯光亮度(intensity)为0时,是全黑的。
个人实验3:随着光照不断增强,越来越白,到高光过大。
2,3,4,5,6,7,到7就基本全白了
--------------------------------------
个人实验4:模型的颜色(diffuse)和光照的颜色合并,为最终的颜色
加上ambient后:则是多个颜色偏移效果
Shader "CustomFix/ff1"
{
Properties
{
_Color("Main Color",color)=(1,1,1,1)
_Ambient("Ambient",color)=(0.3,0.3,0.3,1)
}
SubShader
{
pass
{
//color[_Color] //color:命令?/属性?/功能
material
{
diffuse [_Color] //diffuse:物体的固有颜色,反射的颜色,要结合lighting on
ambient [_Ambient]
}
lighting on //lighting:固定管线的功能
}
}
}
个人实验5:各种颜色组合
加上specular
Shader "CustomFix/ff1"
{
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
{
//color[_Color] //color:命令?/属性?/功能
material
{
diffuse [_Color] //diffuse:物体的固有颜色,反射的颜色,要结合lighting on才能生效
ambient [_Ambient] //ambient:环境光
specular [_Specular] //specular:高光,需要结合separatespecular on才能生效
}
lighting on //lighting:固定管线的功能
separatespecular on //separatespecular独立高光
}
}
}
现在有4种颜色了
Specular是光照照到的面的的颜色效果,MainColor(diffuse)是整体效果,Ambient是一种淡淡的环境光颜色。
光照颜色的话算是在模型光照颜色的基础上再叠加进去。
specular为黑色时,相当于没有高光。
个人实验6:各种颜色组合
加上光泽度:
这里的范围和教程不同,教程0-8,4看起来还不错,我这里(Unity2020),则0-1,到0.1一下看起来可以,
0.2,0.4,0.5,1
高光颜色
光照颜色太亮时高光则没效果
再加上自发光
Shader "CustomFix/ff1"
{
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)
//_Shininess("Shininess",range(0,8))=4
_Shininess("Shininess",range(0,1))=0.07
_Emission("Emission",color)=(1,1,1,1)
}
SubShader
{
pass
{
//color[_Color] //color:命令?/属性?/功能
material
{
diffuse [_Color] //diffuse:物体的固有颜色,反射的颜色,要结合lighting on才能生效
ambient [_Ambient] //ambient:环境光
specular [_Specular] //specular:高光,需要结合separatespecular on才能生效
shininess [_Shininess] //光泽度,高光范围
emission [_Emission] //自发光
}
lighting on //lighting:固定管线的功能
separatespecular on //separatespecular独立高光
}
}
}
颜色部分总算都过了一遍,这下印象很深刻了......截图花了挺多时间.....
-------------------------------------------------------------------------
课时06:固定管线Shader2
视频地址:https://www.bilibili.com/video/BV1YK41157AC?p=6
SetTexture
//settexture命令
settexture[_MainTex]
{
combine texture * primary double //primary是所有颜色光照计算
//double:texture (0-1) ,primary(0-1) ,0.5*0.5=0.25会变暗,需要double
//quad
}
settexture[_SecondTex]
{
combine texture * previous double //previous
}
//混合纹理有最大个数限制,受显卡硬件配置影响,2个基本是支持的。
ShaderLab: Blending
资料:https://blog.csdn.net/linjf520/article/details/94844034
文档:https://docs.unity3d.com/Manual/SL-Blend.html
Src(源)是模型自身,Dst(目标)是其他模型(包括环境、天空)
Blend SrcAlpha OneMinusSrcAlpha //Alpha Blending
设置MainColor的A,效果是之前的ff1的模型能够透过,Scene里面好像透明了,Game里面实际上没有透明:
SubShader里面加上Tags
https://docs.unity3d.com/Manual/SL-SubShaderTags.html
Tags { "Queue" = "Transparent" }
加上贴图后,很奇怪。
MainColor的A在125以下,或者说0.5以下时看起来正常的透明
但是高于0.5,特别是到1,后就不正常了。
--------------------------------------------------------
来自纹理的透明度值
settexture[_SecondTex]
{
constantColor [_Constant]
combine texture * previous double,texture*constant //previous
}
在没有constantColor时,则整体的透明与否有纹理图片决定,加上ConstantColor则又改Color的Alpha决定。
没有合适的灰度透明贴图,只有个树枝贴图。
-----------
matrix,不讲解。
-------------------------------
Blend和Tags部分视频教程没有继续扩展,仅仅是给了给一个固定的代码。
资料:https://blog.csdn.net/linjf520/article/details/94844034
Blend SrcAlpha OneMinusSrcAlpha // 传统透明
Blend One OneMinusSrcAlpha // 预乘Alpha的透明
Blend One One // 叠加
Blend OneMinusDstColor One // 软叠加
Blend DstColor Zero // 混合色调
Blend DstColor SrcColor // 双倍的混合色调
而且实际上我想问,那几个on,和这些参数能否放到Properties里面,还有上面我碰到的透明材质的不透明时有纹理的情况下的显示问题。
ConstantColor在combine的,后面颜色只有Aplha值启动效果,而这时候其他颜色(包括MainColor)的Alpha无效,那就是说我直接用MainColor放这里就好了嘛
settexture[_SecondTex]
{
constantColor [_Color]
combine texture * previous double,texture*constant //previous
}
而且这时候,前面的那个显示异常问题也没有了
完整代码
Shader "CustomFix/ff2"
{
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)
//_Shininess("Shininess",range(0,8))=4
_Shininess("Shininess",range(0,1))=0.07
_Emission("Emission",color)=(1,1,1,1)
_MainTex("MainTex",2d)=""{}
_SecondTex("SecondTex",2d)=""{}
//_Constant("ConstantColor",color)=(1,1,1,0.3)
}
SubShader
{
Tags { "Queue" = "Transparent" }
pass
{
Blend SrcAlpha OneMinusSrcAlpha //Alpha Blending
//color[_Color] //color:命令?/属性?/功能
material
{
diffuse [_Color] //diffuse:物体的固有颜色,反射的颜色,要结合lighting on才能生效
ambient [_Ambient] //ambient:环境光
specular [_Specular] //specular:高光,需要结合separatespecular on才能生效
shininess [_Shininess] //光泽度,高光范围
emission [_Emission] //自发光
}
lighting on //lighting:固定管线的功能
separatespecular on //separatespecular独立高光
//settexture命令
settexture[_MainTex]
{
combine texture * primary double //primary是所有颜色光照计算
//double:texture (0-1) ,primary(0-1) ,0.5*0.5=0.25会变暗,需要double
//quad
}
settexture[_SecondTex]
{
//matrix
constantColor [_Color]
combine texture * previous double,texture*constant //previous
}
//混合纹理有最大个数限制,受显卡硬件配置影响,2个基本是支持的。
}
}
}
-------------------------
Blend SrcFactor DstFactor:配置开启的混合方式。片段生成的颜色将乘以 SrcFactor。已经在屏幕了的颜色乘以 DstFactor,然后将他们的积相加,组合为新的颜色
Blend
枚举 | 描述 |
---|---|
One | (1,1,1)的分享值,可用于Src或Dst |
Zero | (0,0,0) |
SrcColor | (SrcColor.rgb) |
SrcAlpha | (SrcAlpha.aaa) |
DstColor | (DstColor.rgb) |
DstAlpha | (SrcAlpha.aaa) |
OneMinusSrcColor | (1 - SrcColor.rgb) |
OneMinusSrcAlpha | (1 - SrcColor.aaa) |
OneMinusDstColor | (1 - DstColor.rgb) |
OneMinusDstAlpha | (1 - DstColor.aaa) |
实验1:多个Blend,不能写在settexture后面,多个里最后一个生效。
Blend DstColor SrcColor // 双倍的混合色调
Blend DstColor Zero // 混合色调
Blend OneMinusDstColor One // 软叠加
Blend One One // 叠加
Blend One OneMinusSrcAlpha // 预乘Alpha的透明
Blend SrcAlpha OneMinusSrcAlpha // 传统透明
如果不使用constantColor的话Blend DstColor SrcColor或者Blend DstColor Zero似乎效果还可以
---------------------------------------------------
Blend SrcFactor DstFactor:配置开启的混合方式。片段生成的颜色将乘以 SrcFactor。已经在屏幕了的颜色乘以 DstFactor,然后将他们的积相加,组合为新的颜色
Blend DstColor SrcColor // 双倍的混合色调 <=> Blend SrcColor DstColor // 双倍的混合色调(SrcColor和DstColor反过来)
Dst是其他模型,Blend算法是突出后半部分吗?
Blend SrcColor Zero //
Zero导致环境的颜色都无效了,所以,就是不透明的效果了
-----------------------------------------
BlendOp
枚举 | 描述 |
---|---|
Add | 将source与destination相加。 |
Sub | Source - Destination |
RevSub | Destination-Source |
Min | Min(Source, Destination |
Max | Max(Source, Destination |
LogicalClear | 逻辑操作:Clear(0) 仅DX11.1 |
LogicalSet | 逻辑操作:Set(1) 仅DX11.1 |
LogicalCopy | 逻辑操作:Copy(s) 仅DX11.1 |
LogicalCopyInverted | 逻辑操作:Copy反向值(!s) 仅DX11.1 |
LogicalNoop | 逻辑操作:Noop(d) 仅DX11.1 (空操作) |
LogicalInvert | 逻辑操作:Invert(!d) 仅DX11.1 |
LogicalAnd | 逻辑操作:And(s&d) 仅DX11.1 |
LogicalOr | Or(s | d) 仅DX11.1 |
LogicalNor | Nor !(s | d) 仅DX11.1 |
LogicalXor | Xor (s ^ d) 仅DX11.1 |
LogcialEquiv | Equivalence !(s^d) 仅DX11.1 |
LogicAndReverse | Reverse And (s & !d) 仅DX11.1 |
LogicalAndInverted | Inverted And (!s & d) 仅DX11.1 |
LogicalOrReverse | Reverse Or (s | !d) 仅DX11.1 |
LogicalOrInverted | Inverted Or (!s | d) 仅DX11.1 |
发现默认是Add
在上面的Blend SrcAlpha OneMinusSrcAlpha基础上
BlendOp Min
BlendOp Max
其他不测试了...
总的来说就是传统透明要加上constantColor
----------------------------------------------------------------
要动手实验各种情况,和上学时做实验差不多,那时实验为了什么,不就是为了加深印象吗,实际上各种现象和结果都已经知道了。但是现在学习成本太高了,不动手的话,一节课30分钟够了,动手的话要1小时多。。。。
到这里Fixed function Shader好了,下节课是Surface Shader了,至少能看懂基本框架了。10位数加法入门了吧