如何在WebGL平台(Unity3D)上创建透明画布?
原文地址:https://support.unity3d.com/hc/zh-cn/articles/208892946-%E5%A6%82%E4%BD%95%E5%9C%A8WebGL%E5%B9%B3%E5%8F%B0%E4%B8%8A%E5%88%9B%E5%BB%BA%E9%80%8F%E6%98%8E%E7%94%BB%E5%B8%83-
问题
希望使用WebGL透明背景。
希望在其他html元素上渲染WebGL内容,并且通过WebGL内容中的透明部分展示 其他html元素。
原因
WebGL画布默认不透明,因为透明度信息没有写入帧缓存中,也就是说当渲染WebGL画布时,它会重写页面下的所有元素。
解决方案
解决方法是重写glClear的实现来跳过Unity清除alpha帧缓存的步骤,把原有的alpha值保留下来,这样就可以实现WebGL的透明。
实现这些,我们需要跟随以下步骤:
在资源文件夹下创建一个”.jslib”文件,这是一个带有”.jslib”扩展的空文本文件,比如可以命名为”TransparentBackground.jslib”。
复制并且粘贴以下代码到你创建的文件中:
var LibraryGLClear = {
glClear: function(mask)
{
if (mask == 0x00004000)
{
var v = GLctx.getParameter(GLctx.COLOR_WRITEMASK);
if (!v[0] && !v[1] && !v[2] && v[3])
// We are trying to clear alpha only — skip.
return;
}
GLctx.clear(mask);
}
};
mergeInto(LibraryManager.library, LibraryGLClear);
当你创建工程时,上述代码可以用来代替内置的LibraryGLClear方法。
至此您已经成功创建一个透明的画布,可以看到网站页面后面的内容。
下一步是让着色器把透明度信息写到帧缓存中。需要确认已经使用了”ColorMask RGBA”,如果使用表面着色器,Unity可能只使用RGB, 这时候我们需要:
在工程视图中选择表面着色器资源。
点击”Show generated code”按钮,Unity会打开表面着色器的代码块。
复制并保存着色器代码到工程文件的一个新着色器中。
把所有ColorMask RGB的实例修改为ColorMask RGBA。
另一个可能发生的问题是alpha通道中写入的三角形可能会重叠。这时,如果背景中物体的alpha值为不透明的话,会被新的alpha值所替换 。这会让原本不透明的物体变成透明物体。为了便于理解,我们可以想象一下渲染一棵由很多通过alpha blend树叶组成的树。其中一些树叶位于另一些树叶前面。由于最后一批树叶会在帧缓存中写入alpha信息,导致背景中其他树叶的alpha信息被替换,从而导致本来应该为不透明的区域显示为透明。
为了避免不透明的像素成为透明,可以将着色器中的阿尔法值设置为源fragment和目标fragment之间的最大值(使用了混合操作),代码如下:
Blend SrcAlpha OneMinusSrcAlpha, One One
BlendOp Add, Max
更多信息
http://docs.unity3d.com/Manual/SL-Pass.html
http://docs.unity3d.com/Manual/SL-Blend.html
http://forum.unity3d.com/threads/webgl-transparent-background.284699/
WEBGL学习网 » 如何在WebGL平台(Unity3D)上创建透明画布?