webgl 您所在的位置:网站首页 webgl深度测试 webgl

webgl

2023-11-18 15:12| 来源: 网络整理| 查看: 265

        今天研究了一个混合与模板测试相结合的案例,这里做以总结。         案例中一个篮球在地板上不断弹起并且落下,这里主要涉及到了两项技术:混合与模板测试。首先篮球在地板上反射出来的镜像篮球就是通过混合技术实现的,为了让镜像体在运动脱离地板时消失,实现真实的效果,还需要加入模板测试。         首先介绍他们的绘制顺序     1.开启模板测试,关闭深度检测  2.绘制实体地板   3.设置模板测试参数     4.绘制镜像球 ,禁用模板测试    5.开启混合     6.设置混合参数,绘制半透明地板 7.关闭混合,开启深度检测         看到这里是不是有些头晕了,不过没关系,我们来一起理一理其中的思路。         首先关于深度检测:深度检测在此案例中不需要使用,我们完全可以根据绘制的顺序来确定他们的显示顺序,当不开启深度检测时,会根据我们绘制的顺序来决定谁会覆盖谁。

        其次是模板测试,先清除上一次绘制产生的模板缓冲,使得缓冲中所有值为0,然后给地板设置模板缓冲的参数,其中设置  glStencilFunc(GL_ALWAYS, 1, 1); 这样一来,地板的像素的“模板值”为1,而其它地方像素的“模板值”为0。glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);这个函数第一个参数是未通过模板测试时的操作,第二个参数是通过模板测试,未通过深度测试的操作,第三个是深度测试和模板测试都通过时的操作。我对这个函数的理解是:当其它物体通过模板测试与深度测试时用其它物体的像素,取代该物体的像素。

//设置模板测试参数 gl.stencilFunc(gl.ALWAYS, 1, 1); //设置模板测试后的操作 gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);

        然后设置模板参数为equal,当进行比较时,通过比较ref也就是stencilFunc的第二个参数来确定是否通过模板测试,比较的方式是第一个参数也就是equal相等。所以当镜像体篮球在地板范围内时通过模板测试与深度测试,显示镜像。当球体超出地板范围之后模板测试失败,不显示该球体。

//设置模板测试参数 gl.stencilFunc(gl.EQUAL,1, 1); //设置模板测试后的操作 gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);         最后是混合当理解了模板测试之后,混合也就更为简单了,我们在绘制地板时,实际是绘制了两次,第一次绘制了不透明度为1的地板,第二次绘制了不透明度为0.5的地板(也就是一个半透明的地板),半透明地板的作用就是参与混合,使得镜像篮球看起来更加真实,不会和实体篮球一样。所以这里使用了混合,目标因子是篮球的颜色,源因子是半透明地板,(用半透明地板去混合篮球,所以篮球是目标因子,地板是源因子)所以该参数的意思是根据(源因子的不透明度:目标因子减原因子的不透明度)这个比例来混合他们的颜色,最终达到镜像效果。

//开启混合 gl.enable(gl.BLEND); //设置混合因子 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

下面是绘制部分的代码:

function drawFrame() { if(!rectdb||!ball) { alert("加载未完成!");//提示信息 return; } //清除着色缓冲与深度缓冲 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //清除模板缓存 gl.clear(gl.STENCIL_BUFFER_BIT); //关闭深度检测 gl.disable(gl.DEPTH_TEST); //允许模板测试 gl.enable(gl.STENCIL_TEST); //设置模板测试参数 gl.stencilFunc(gl.ALWAYS, 1, 1); //设置模板测试后的操作 gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); ms.pushMatrix(); ms.scale(0.3,0.3,0.3); //绘制反射面地板 rectdb.drawSelf(ms,texMap["db"]); ms.popMatrix(); //设置模板测试参数 gl.stencilFunc(gl.EQUAL,1, 1); //设置模板测试后的操作 gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); //绘制镜像体 drawmirror(); //禁用模板测试 gl.disable(gl.STENCIL_TEST); //开启混合 gl.enable(gl.BLEND); //设置混合因子 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); ms.pushMatrix(); ms.scale(0.3,0.3,0.3); //绘制半透明反射面地板 rectdb.drawSelf(ms,texMap["tm"]); ms.popMatrix(); //开启深度检测 gl.enable(gl.DEPTH_TEST); //关闭混合 gl.disable(gl.BLEND); //绘制实际物体 drawball(); }

最后是图片和github地址:https://github.com/StringKun/WebGL-mirror-image



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有