渲染状态决定了GPU如何处理几何体,包括混合、深度测试、面剔除等。本教程通过对比不透明和透明物体,学习渲染状态的配置,通过本教程,你将学会:
渲染状态是告诉GPU"如何渲染"的一系列设置,主要包括:
前往 渲染状态 了解可配置的所有渲染状态。
混合状态控制新绘制的像素如何与已有像素混合:
BlendState customBlendState {
Enabled = false; // 关闭混合
}
不透明物体不需要混合,直接覆盖背景色。
BlendState customBlendState {
Enabled = true; // 开启混合
SourceColorBlendFactor = BlendFactor.SourceAlpha;
DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;
SourceAlphaBlendFactor = BlendFactor.One;
DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha;
}
混合公式:
最终颜色 = 源颜色 × SrcAlpha + 目标颜色 × (1 - SrcAlpha)
常用混合因子:
SrcAlpha
:源像素的透明度OneMinusSrcAlpha
:1减去源像素的透明度One
:1.0Zero
:0.0深度状态控制深度缓冲区的使用:
DepthState customDepthState {
WriteEnabled = true; // 开启深度写入(透明物体通常不写深度)
CompareFunction = CompareFunction.LessEqual; // 但仍然进行深度测试
}
// 指定不透明队列
RenderQueueType = Opaque;
DepthState customDepthState {
WriteEnabled = false; // 关闭深度写入(透明物体通常不写深度)
CompareFunction = CompareFunction.LessEqual; // 但仍然进行深度测试
}
// 指定透明队列
RenderQueueType = Transparent;
为什么透明物体要关闭深度写入?
深度测试函数:
Less
:小于时通过测试LessEqual
:小于等于时通过测试Greater
:大于时通过测试Always
:总是通过测试Never
:从不通过测试Shader "Tutorial/02-Opaque" {
SubShader "Default" {
Pass "Forward" {
// 渲染状态:不透明物体的标准设置
BlendState customBlendState {
Enabled = false; // 关闭混合
}
DepthState customDepthState {
WriteEnabled = true; // 开启深度写入
CompareFunction = CompareFunction.LessEqual; // 深度测试函数
}
BlendState = customBlendState;
DepthState = customDepthState;
RenderQueueType = Opaque;
mat4 renderer_MVPMat;
vec4 material_BaseColor;
struct Attributes {
vec4 POSITION;
};
VertexShader = vert;
FragmentShader = frag;
void vert(Attributes attr) {
gl_Position = renderer_MVPMat * attr.POSITION;
}
void frag() {
gl_FragColor = material_BaseColor;
}
}
}
}
Shader "Tutorial/02-Transparent" {
SubShader "Default" {
Pass "Forward" {
// 渲染状态:透明物体的标准设置
BlendState customBlendState {
Enabled = true; // 开启混合
SourceColorBlendFactor = BlendFactor.SourceAlpha;
DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;
SourceAlphaBlendFactor = BlendFactor.One;
DestinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha;
}
DepthState customDepthState {
WriteEnabled = false; // 关闭深度写入(透明物体通常不写深度)
CompareFunction = CompareFunction.LessEqual; // 但仍然进行深度测试
}
BlendState = customBlendState;
DepthState = customDepthState;
RenderQueueType = Transparent;
mat4 renderer_MVPMat;
vec4 material_BaseColor;
float material_Alpha;
struct Attributes {
vec4 POSITION;
};
VertexShader = vert;
FragmentShader = frag;
void vert(Attributes attr) {
gl_Position = renderer_MVPMat * attr.POSITION;
}
void frag() {
vec4 color = material_BaseColor;
color.a = material_Alpha; // 使用自定义的透明度
gl_FragColor = color;
}
}
}
}
在片元着色器中控制透明度:
void frag() {
vec4 color = material_BaseColor;
color.a = material_Alpha; // 设置透明度
gl_FragColor = color;
}
透明物体的渲染顺序很重要:
// 引擎会自动处理渲染顺序,但你需要正确设置渲染状态
RenderQueueType = **;
BlendState customBlendState {
Enabled = true; // 开启混合
SourceColorBlendFactor = BlendFactor.SourceAlpha;
DestinationColorBlendFactor = BlendFactor.One;
SourceAlphaBlendFactor = BlendFactor.Zero;
DestinationAlphaBlendFactor = BlendFactor.One;
}
前往 游乐场