逐片元操作
这一阶段也叫做输出合并阶段
主要任务有:
1.决定每个片元的可见性 涉及很多测试 例如:模版测试、深度测试等
2.如果一个片元通过了所有的测试,就需要把这个片元的颜色值和已经存储在颜色缓冲区的颜色进行合并,也叫做混合
帧缓冲区
帧缓冲区也叫做帧缓存,是用于存放一帧中数据信息的容器
在逐片元操作时,当一个片元通过了所有的测试,就会将此片元写入帧缓存中
在写入帧缓存的时会将此片元与帧缓存内部的数据进行混合操作
帧缓存区有:
Frame Debugger
在unity程序运行的状态下使用
可以用来观察当前帧渲染的信息,例如可以观察不同渲染队列中物体渲染的先后顺序等
在 Window 中打开 Analysis 选择Frame Debugger
在弹出的对话窗中点击Disable
特效通用材质功能点
1.半透明效果的实现
Tags{"Queue"="Transparent"}; //渲染队列
Blend ____ ____ // Blend 用于对象间的颜色混合
Queue 渲染队列
其中渲染队列数目小于2500的对象被认为是不透明的物体 从前往后渲染 后面被前面的不透明对象遮挡住的部分可以不用渲染,这样可以大大的提升渲染效率
渲染队列数目大于2500的对象被认为是半透明的物体 从后往前渲染
在程序中通常先渲染不透明对象再渲染半透明对象
"Queue" = "Background" 值为1000 处于此队列的对象最先渲染
"Queue" = "Geometry" 值为2000 此队列通常用于不透明对象
"Queue" = "AlphaTest" 值为2450 此队列通常用于透贴
"Queue" = "Transparent" 值为3000 此队列常用于半透明对象 从后往前渲染 建议将需要进行 混合的对象写入此列
"Queue" = "Overlay" 值为4000 此队列通常用于叠加效果 例如镜头光晕
Blend (相当于ps中的各种叠加效果)
用来实现半透明的效果
源颜色 * SrcFactor BlendOP DstFactor * 目标颜色
(源颜色因子) (运算符) (目标颜色因子)
定义进行混合的枚举类型属性
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("SrcBlend",int)=0
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("DstBlend",int)=0
之后在SubShader中声明
Blend [_SrcBlend] [_DstBlend]
在Shader中若没有定义混合操作,Shader会自动将源颜色因子和目标颜色因子定义为1和0所以在混合操作后存入帧缓冲区内的颜色还是源颜色
2.面剔除属性
三种面剔除指令
Cull Off 不剔除
Cull Back 剔除背面
Cull Front 剔除前面
须在SubShader中声明该指令
使用枚举类型显示属性
[Enum(UnityEngine.Renedering.CullMode)]_Cull("Cull",int)=0
Cull [_Cull] //在SubShader中声明
3.定义颜色
//颜色属性
_Color("Color",Color)=(1,1,1,1) // 默认值设为1 因为之后需要进行颜色相乘操作
Pass中声明
fixed4 _Color;
在片元着色器中写 //实现颜色的变化
float4 c;
float4 tex=tex2D(_MainTex,i.uv.xy);
c=tex;
c*=_Color;
return c;
添加一个滑杆属性参数调整颜色的明亮程度
_Intensity("Intensity",Range(-3,3))=1
Pass中声明
half _Intensity; /注意使用half定义
片元着色器中写
c*=_Color*_Intensity;
return c;
4.纹理自动流动的实现
//定义主贴图UV流动的属性
_MainUVSpeedX("MainUVSpeed X",float)=0
_MainUVSpeedY("MainUVSpeed Y",float)=0
Pass中声明
float _MainUVSpeedX;
float _MainUVSpeedY;
顶点着色器中写
o.uv.xy=TRANSFORM_TEX(v.uv,_MainTex)+float2(_MainUVSpeedX,_MainUVSpeedY)*_Time.y;
当改变_MainUVSpeedX和_MainUVSpeedY的值时 就会实现主纹理的自流动
5.遮罩功能实现
//定义遮罩贴图
_MaskTex("MaskTex",2D)="white"{}
//遮罩贴图UV流动属性
_MaskUVSpeedX("MaskUVSpeed X",float)=0
_MaskUVSpeedY("MaskUVSpeed Y",float)=0
Pass中声明
sampler2D _MaskTex;
float4 _MaskTex_ST;
float _MaskUVSpeedX;
float _MaskUVSpeedY;
在顶点着色器中写 //实现遮罩贴图UV流动
o.uv.zw=TRANSFORM_TEX(v.uv,_MaskTex)+float2(_MaskUVSpeedX,_MaskUVSpeedY)*_Time.y;
最后在片元着色器中加入遮罩贴图采样后的颜色来实现遮罩的效果
float4 maskTex=tex2D(_MaskTex,i.uv.zw);
c*=maskTex;
Shader"unity/Effects2"
{
Properties
{
//Blend混合枚举属性
[Enum(UnityEngine.Rendering.BlendMode)]_SrcBlend("SrcBlend",int)=0
[Enum(UnityEngine.Rendering.BlendMode)]_DstBlend("DstBlend",int)=0
//剔除属性
[Enum(UnityEngine.Rendering.CullMode)]_Cull("Cull",int)=0
//主贴图
_MainTex("MainTex",2D)="white"{}
//颜色属性
_Color("Color",Color)=(1,1,1,1)
//主贴图UV流动
_MainUVSpeedX("MainUVSpeed X",float)=0
_MainUVSpeedY("MainUVSpeed Y",float)=0
//遮罩贴图
_MaskTex("MaskTex",2D)="white"{}
//遮罩贴图UV流动
_MaskUVSpeedX("MaskUVSpeed X",float)=0
_MaskUVSpeedY("MaskUVSpeed Y",float)=0
//滑杆
_Intensity("Intensity",Range(-3,3))=1
}
SubShader
{
Tags{"Queue"="Transparent"} //半透明队列
Blend [_SrcBlend][_DstBlend] //混合
Cull [_Cull] //剔除
Pass
{
CGPROGRAM
#pragma vertex vert;
#pragma fragment frag;
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
float _MainUVSpeedX;
float _MainUVSpeedY;
sampler2D _MaskTex;
float4 _MaskTex_ST;
float _MaskUVSpeedX;
float _MaskUVSpeedY;
half _Intensity; //注意使用half定义
struct appdate
{
float4 vertex :POSITION;
float4 uv:TEXCOORD;
};
struct v2f
{
float4 pos:SV_POSITION;
float4 uv:TEXCOORD;
};
v2f vert(appdate v)
{
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
o.uv.xy=TRANSFORM_TEX(v.uv,_MainTex)+float2(_MainUVSpeedX,_MainUVSpeedY)*_Time.y;
o.uv.zw=TRANSFORM_TEX(v.uv,_MaskTex)+float2(_MaskUVSpeedX,_MaskUVSpeedY)*_Time.y;
return o;
}
float4 frag(v2f i):SV_TARGET
{
float4 c;
float4 tex=tex2D(_MainTex,i.uv.xy);
c=tex;
c*=_Color*_Intensity;
float4 maskTex=tex2D(_MaskTex,i.uv.zw);
c*=maskTex;
return c;
}
ENDCG
}
}
}
标签:Cull,特效,uv,渲染,float,float4,材质,MaskTex,半透明
From: https://blog.csdn.net/2401_83878847/article/details/143376973