渲染状态决定了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;
      }前往 游乐场