关注

如何在WebGL平台上创建透明画布?

问题

  • 希望使用WebGL透明背景。
  • 希望在其他html元素上渲染WebGL内容,并且通过WebGL内容中的透明部分展示 其他html元素。

原因

WebGL画布默认不透明,因为透明度信息没有写入帧缓存中,也就是说当渲染WebGL画布时,它会重写页面下的所有元素。

解决方案

解决方法是重写glClear的实现来跳过Unity清除alpha帧缓存的步骤,把原有的alpha值保留下来,这样就可以实现WebGL的透明。

 
实现这些,我们需要跟随以下步骤:

  1. 在资源文件夹下创建一个".jslib"文件,这是一个带有".jslib"扩展的空文本文件,比如可以命名为"TransparentBackground.jslib"。
  1. 复制并且粘贴以下代码到你创建的文件中:

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); 

  1. 当你创建工程时,上述代码可以用来代替内置的LibraryGLClear方法。

至此您已经成功创建一个透明的画布,可以看到网站页面后面的内容。

下一步是让着色器把透明度信息写到帧缓存中。需要确认已经使用了"ColorMask RGBA",如果使用表面着色器,Unity可能只使用RGB, 这时候我们需要:

  1. 在工程视图中选择表面着色器资源。
  1. 点击"Show generated code"按钮,Unity会打开表面着色器的代码块。
  1. 复制并保存着色器代码到工程文件的一个新着色器中。
  1. 把所有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/

 

 

这篇文章有帮助吗?
0 人中有 0 人觉得有帮助
还有其它问题?提交请求

0 评论

登录写评论。