当前位置:   article > 正文

第八章 透明效果

第八章 透明效果

在渲染模型中控制透明通道。透明度为1,完全不透明;透明度为0,完全不会显示。

两种方法:

(1)透明度测试

(2)透明度混合

深度缓冲(z-buffer)用于解决可见性问题。可以决定哪个物体的哪些部分被渲染到前面,哪些部分会被其他物体遮掩。根据深度缓存中的值来判断该片元距离摄像机的距离,当渲染一个片元时,需要把它的深度值和已经存在于深度缓冲中的值进行比较,如果它的值距离摄像机更远,那么说明这个片元不应被渲染到屏幕上;否则,这个片元应该覆盖掉此时颜色缓冲中的像素值,并把它的深度值更新到深度缓冲中(如果开启了深度写入)。可以不关心物体渲染顺序。

基本原理

(1)透明度测试

只要一个片元的透明度不满足条件,那么它对应的片元就会被舍弃。被舍弃的片元不会再进行任何处理,也不会对颜色缓冲产生任何影响;否则,就会按照普通的不透明物体来处理,即深度测试、深度写入。透明度测试不需要关闭深度写入,它会根据透明度来舍弃一些片元,效果极端,要么完全透明,要么完全不透明。

(2)透明度混合

可以得到真正的半透明效果。它会使用当前片元的透明度作为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色。透明度混合需要关闭深度写入,要小心物体的渲染顺序。透明度混合只关闭了深度写入,没有关闭深度测试。当使用透明度混合渲染一个片元时,还是会比较它的深度值和当前深度缓冲中的深度值。如果它的深度值距离摄像机更远,那么就不会再进行混合操作。当一个不透明物体出现在一个透明物体前面,而我们先渲染了不透明物体,它仍然可以正常地遮挡住透明物体。对于透明度混合来说,深度缓冲是只读的。

为什么渲染顺序很重要

应该在不透明物体渲染完之后再渲染半透明物体。半透明物体之间也要符合渲染顺序。

渲染引擎一般都会对物体先排序再渲染,常用方法是

(1)先渲染所有不透明物体,并开启它们的深度测试和深度写入

(2)把半透明按它们距离摄像机的远近进行排序,然后按照从后往前的顺序渲染这些半透明物体,并开启它们的深度测试,但关闭深度写入。

为了减少错误排序,我们尽可能让模型是凸面体,并考虑将复杂模型拆分成可以独立排序的多个子模型。

Unity Shader的渲染顺序

Unity提供了渲染队列来解决渲染顺序问题。可以使用SubShader的Queue标签来决定我们的模型将归于哪个渲染队列。Unity在内部使用一系列整数索引来表示每个渲染队列,且索引号越小越早被渲染。

透明度测试

透明度测试:只要一个片元的透明度不满足条件,那么它对应的片元就会被舍弃。被舍弃的片元将不会再进行任何处理,也不会对颜色缓冲产生任何影响;否则,就会按照普通的不透明方式去处理。

通常,在片元着色器中使用clip函数进行透明度测试。clip是一个Cg函数

函数:void clip(float4 x); void clip(float3 x); void clip(float2 x); void clip(float1 x); void clip(float x);

参数:裁剪时使用的标量或矢量条件

描述:如果给定参数的任何一个分量是负数,就会舍弃当前像素的颜色。它等同于下面的代码

  1. void clip(float4 x)
  2. {
  3. if (any(x < 0))
  4. discard;
  5. }
  1. Shader "Unity Shaders Book/Chapter 8/Alpha Test"{
  2. Properties {
  3. _Color ("Main Tint", Color) = (1, 1, 1, 1)
  4. _MainTex ("Main Tex", 2D) = "white"{}
  5. //_Cutoff用于决定我们调用clip进行透明度测试时使用的判断条件。范围是[0,1]
  6. _Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
  7. }
  8. SubShader{
  9. //透明度测试使用的渲染队列是AlphaTest
  10. //把IgnoreProjector设为True,不受投影器的影响
  11. //RenderType可以让Unity把Shader归入提前定义的组TransparentCutout
  12. //指明该Shader是一个使用了透明度测试的Shader,RenderType通常被用于着色器的替换功能
  13. //使用了透明度测试的Shader都应该设置这三个标签
  14. Tags{
  15. "Queue"="AlphaTest"
  16. "IgnoreProjector"="True"
  17. "RenderType"="TransparentCutout"
  18. }
  19. Pass{
  20. Tags{"LightMode"="ForwardBase"}
  21. CGPROGRAM
  22. #pragma vertex vert
  23. #pragma fragment frag
  24. #include "Lighting.cginc"
  25. fixed4 _Color;
  26. sampler2D _MainTex; float4 _MainTex_ST;
  27. fixed _Cutoff;
  28. struct a2v{
  29. float4 vertex : POSITION;
  30. float3 normal : NORMAL;
  31. float4 texcoord : TEXCOORD0;
  32. };
  33. struct v2f{
  34. float4 pos : SV_POSITION;
  35. float3 worldNormal : TEXCOORD0;
  36. float3 worldPos : TEXCO
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/451993
推荐阅读
相关标签
  

闽ICP备14008679号