Skip to content

Transparent

zilch edited this page Feb 14, 2021 · 1 revision

半透明物体渲染(Transparent Object Render)

在之前的管线实现中,我们并没有考虑半透明物体。现在加入对半透明物体的渲染支持。

通常来说,在渲染场景时,一般:

  • 先按照由近及远的方式渲染非透明物体(这样可以利用深度测试充分过滤掉被遮挡的像素,避开无用的计算)
  • 再按照由远及近的顺序绘制半透明物体(因为半透明物体要显示其背后的像素,并与之混合)。在绘制半透明物体时,一般要关闭ZWrite.

效果图

SRP 实现

改造之前的XRenderPipeline,将其中的物体渲染部分代码抽成一个单独的类RenderObjectPass

RenderObjectPass构造的时候,接受一个isTransparent作为参数,表示当前是透明Pass,还是非透明Pass。

public RenderObjectPass(bool transparent){
    _isTransparent = transparent;
}

执行渲染:

public void Execute(ScriptableRenderContext context, Camera camera,ref CullingResults cullingResults){
    var drawSetting = CreateDrawSettings(camera);
    //根据_isTransparent,利用RenderQueueRange来过滤出透明物体,或者非透明物体
    var filterSetting = new FilteringSettings(_isTransparent? RenderQueueRange.transparent:RenderQueueRange.opaque);
    //绘制物体
    context.DrawRenderers(cullingResults,ref drawSetting,ref filterSetting);
}

此处使用RenderQueueRange,来对渲染物体进行过滤。

CreateDrawSettings的时候,还要指定物体排序规则:

private DrawingSettings CreateDrawSettings(Camera camera){
    var sortingSetting = new SortingSettings(camera);
    //设置物体渲染排序标准
    sortingSetting.criteria = _isTransparent?SortingCriteria.CommonTransparent:SortingCriteria.CommonOpaque;
    var drawSetting = new DrawingSettings(_shaderTag,sortingSetting);
    return drawSetting;
}

然后在XRenderPipeline中,构造两个Pass,分别代表非透明物体和透明物体渲染:

private RenderObjectPass _opaquePass = new RenderObjectPass(false);
private RenderObjectPass _transparentPass = new RenderObjectPass(true);

各自绘制:

//非透明物体渲染
_opaquePass.Execute(context,camera,ref cullingResults);

//透明物体渲染
_transparentPass.Execute(context,camera,ref cullingResults);

这样,我们的管线,就支持了透明物体的渲染。

但是,要真正渲染出透明物体,还需要写一个透明物体的渲染Shader。

Shader支持

在BlinnPongSpecular.shader的基础上,进行改造,得到BlinnPongSpecularTransparent.shader。其中针对阴影,有以下限制:

  • 透明物体不支持投射阴影
  • 透明物体可以受阴影影响

首先是将RenderTypeQueue都修改为Transparent

Tags { "RenderType"="Transparent" "LightMode"="XForwardBase" "Queue" = "Transparent"}

关闭ZWrite:

ZWrite Off

设置Blend模式:

Blend SrcAlpha OneMinusSrcAlpha

我们增加一个Color属性,来控制透明物体的颜色和透明度:

fixed4 _Color;

在最后颜色输出阶段,将_Color.a作为透明度输出:

color = half4(color.rgb * _Color.rgb * shadowAtten,_Color.a);
Clone this wiki locally