公司网站如何优化,阿里云php做网站,网站建设加优化,网络营销跟做网站有什么区别代码以及实例图可以看github #xff1a;zaizai77/Shader-Learn: 实现一些书里讲到的shader
在实时渲染中要实现透明效果#xff0c;通常会在渲染模型时控制它的透明通道#xff08;Alpha Channel#xff09;。当开启透明混合后#xff0c;当一个物体被渲染到屏幕上时zaizai77/Shader-Learn: 实现一些书里讲到的shader
在实时渲染中要实现透明效果通常会在渲染模型时控制它的透明通道Alpha Channel。当开启透明混合后当一个物体被渲染到屏幕上时每个片元除了颜色值和深度值之外它还有另一个属性——透明度。当透明度为1时表示该像素是完全不透明的而当其为0时则表示该像素完全不会显示。
我们通常使用两种方法来实现透明效果第一种是使用透明度测试Alpha Test这种方法其实无法得到真正的半透明效果另一种是透明度混合Alpha Blending。
在实时渲染中深度缓冲是用于解决可见性visibility问题的它可以决定哪个物体的哪些部分会被渲染在前面而哪些部分会被其他物体遮挡。它的基本思想是根据深度缓存中的值来判断该片元距离摄像机的距离当渲染一个片元时需要把它的深度值和已经存在于深度缓冲中的值进行比较如果开启了深度测试如果它的值距离摄像机更远那么说明这个片元不应该被渲染到屏幕上有物体挡住了它否则这个片元应该覆盖掉此时颜色缓冲中的像素值并把它的深度值更新到深度缓冲中如果开启了深度写入。
简单来说透明度测试和透明度混合的基本原理如下。
透明度测试它采用一种“霸道极端”的机制只要一个片元的透明度不满足条件通常是小于某个阈值那么它对应的片元就会被舍弃。被舍弃的片元将不会再进行任何处理也不会对颜色缓冲产生任何影响否则就会按照普通的不透明物体的处理方式来处理它即进行深度测试、深度写入等。也就是说透明度测试是不需要关闭深度写入的它和其他不透明物体最大的不同就是它会根据透明度来舍弃一些片元。虽然简单但是它产生的效果也很极端要么完全透明即看不到要么完全不透明就像不透明物体那样。
透明度混合这种方法可以得到真正的半透明效果。它会使用当前片元的透明度作为混合因子与已经存储在颜色缓冲中的颜色值进行混合得到新的颜色。但是透明度混合需要关闭深度写入我们下面会讲为什么需要关闭这使得我们要非常小心物体的渲染顺序。需要注意的是透明度混合只关闭了深度写入但没有关闭深度测试。这意味着当使用透明度混合渲染一个片元时还是会比较它的深度值与当前深度缓冲中的深度值如果它的深度值距离摄像机更远那么就不会再进行混合操作。这一点决定了当一个不透明物体出现在一个透明物体的前面而我们先渲染了不透明物体它仍然可以正常地遮挡住透明物体。也就是说对于透明度混合来说深度缓冲是只读的。
为什么渲染顺序重要
如果不关闭深度写入一个半透明表面背后的表面本来是可以透过它被我们看到的但由于深度测试时判断结果是该半透明表面距离摄像机更近导致后面的表面将会被剔除我们也就无法透过半透明表面看到后面的物体了
渲染引擎一般都会先对物体进行排序再渲染。常用的方法是。
先渲染所有不透明物体并开启它们的深度测试和深度写入。把半透明物体按它们距离摄像机的远近进行排序然后按照从后往前的顺序渲染这些半透明物体并开启它们的深度测试但关闭深度写入。
在一些情况下半透明物体还是会出现“穿帮镜头”。深度缓冲中的值其实是像素级别的即每个像素有一个深度值但是现在我们对单个物体级别进行排序这意味着排序结果是要么物体A全部在B前面渲染要么A全部在B后面渲染。但如果存在循环重叠的情况那么使用这种方法就永远无法得到正确的结果 为了减少错误排序的情况我们可以尽可能让模型是凸面体并且考虑将复杂的模型拆分成可以独立排序的多个子模型等。其实就算排序错误结果有时也不会非常糟糕如果我们不想分割网格可以试着让透明通道更加柔和使穿插看起来并不是那么明显。我们也可以使用开启了深度写入的半透明效果来近似模拟物体的半透明
Unity Shader 的渲染顺序
Unity为了解决渲染顺序的问题提供了渲染队列render queue这一解决方案。我们可以使用SubShader的Queue标签来决定我们的模型将归于哪个渲染队列。Unity在内部使用一系列整数索引来表示每个渲染队列且索引号越小表示越早被渲染。 因此如果我们想要通过透明度测试实现透明效果代码中应该包含类似下面的代码 SubShader {Tags { QueueAlphaTest }Pass {...}}
如果我们想要通过透明度混合来实现透明效果代码中应该包含类似下面的代码 SubShader {Tags { QueueTransparent }Pass {ZWrite Off...}}
ZWrite Off用于关闭深度写入在这里我们选择把它写在Pass中。我们也可以把它写在SubShader中这意味着该SubShader下的所有Pass都会关闭深度写入。
透明度测试