收藏
回答

VKFrame.getCameraTexture方法导致无法正常渲染模型?

我们目前使用的playcanvas引擎渲染3D场景,在AR开发时,我们已经定位到如果不使用VKFrame.getCameraTexture方法,模型可以正常渲染,使用该方法会导致部分模型材质无法正常渲染(全变成黑色)。

我们参考的是官方”小程序示例“里的代码。链接:https://github.com/wechat-miniprogram/miniprogram-demo/blob/master/miniprogram/packageAPI/pages/ar/plane-ar/yuvBehavior.js

在此,我想请问该方法是否针对WebGLContext有过操作?具体操作了哪些东西?我们需要再校正过来,万分谢谢。

最后一次编辑于  2022-10-12
回答关注问题邀请回答
收藏

3 个回答

  • 社区技术运营专员--许涛
    社区技术运营专员--许涛
    2022-10-13

    你好,麻烦提供出现问题的具体机型、微信版本号、系统版本号,以及能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)

    2022-10-13
    有用
    回复 7
    • 王瑞鹏
      王瑞鹏
      2022-10-15
      您好,由于我们的引擎文件体积较大,已经超出了代码片段1MB的限制,所以我将复现代码上传到了github。您可以克隆下来复现问题。
      设备详情:
      机型:华为mate30pro
      微信版本号:8.0.25

      系统版本号:HarmonyOS 2.0.0.273
      (iPhone12 Pro是同样的问题)
      复现步骤:
      以下列举3种情况,只有yuvBehavior.js里的renderGL方法不同。
      第一种情况参考第1,2图片,使用官方小程序示例的renderGL方法,相机渲染成功,但是模型材质全部为黑色。
      第二种情况参考第3,4图片,renderGL方法只使用了getCameraTexture方法,没有渲染相机,模型材质为黑,所以全屏黑色。
      第三种情况参考第5,6图片,renderGL方法为空,模型正常显示。
      如上,第二种情况与第三种情况的不同之处只在于调用了VKFrame.getCameraTexture(gl)方法,就导致了模型材质无法正常渲染。
      所以,我想了解一下该方法针对WebGLContext有什么操作?
      2022-10-15
      回复
    • 王瑞鹏
      王瑞鹏
      2022-10-15
      git地址:https://github.com/ruipeng-wang/getCameraTexture_test.git
      2022-10-15
      回复
    • 王瑞鹏
      王瑞鹏
      2022-10-19
      请问官方能解答一下吗?十分感谢
      2022-10-19
      回复
    • 社区技术运营专员--许涛
      社区技术运营专员--许涛
      2022-10-19回复王瑞鹏
      gl.activeTexture(gl.TEXTURE0 + 5)
       const bindingTexture5 = gl.getParameter(gl.TEXTURE_BINDING_2D)
        gl.bindTexture(gl.TEXTURE_2D, yTexture)


      将模型的纹理 往后点的序号绑定一下
      2022-10-19
      回复
    • 半盏酒
      半盏酒
      2022-11-24回复王瑞鹏
      遇到同样的问题,怀疑WebGLContext某些参数被修改了,请问你现在找到问题了吗?
      2022-11-24
      回复
    查看更多(2)
  • 腾飞
    腾飞
    2023-03-27

    问题解决了,记录一下:

    输出一下 `VKFrame.getCameraTexture` 的方法,内容如下:

    function getCameraTexture(e, t = "yuv") {
      if (!this[jse].native || !this[jse].session) return null;
      "string" == typeof e && (t = e, e = null);
      var r = this[jse].session;
      if (!(e = e || r[Vse].options.gl)) return null;
      if ("yuv" === t) {
        var n = r[Vse].yTexture;
        n || (n = e.createTexture());
        var i, a = r[Vse].uvTexture;
        a || (a = e.createTexture());
        var o = !1;
        if (he && Use) {
          o = this[jse].native.updateCameraYUVTextureIOS(n, a, e)
        } 
        else {
          i = this[jse].native.getCameraYUVBuffer()
        }
        e.bindTexture(e.TEXTURE_2D, n);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE);
        if (i) {
          e.texImage2D(e.TEXTURE_2D, 0, e.LUMINANCE, i.width, i.height, 0, e.LUMINANCE, e.UNSIGNED_BYTE, new Uint8Array(i.yAddress))
        }
        r[Vse].yTexture = n;
        n._gl = e;
        e.bindTexture(e.TEXTURE_2D, null);
        e.bindTexture(e.TEXTURE_2D, a);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE);
        e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE);
        if (i) {
          e.texImage2D(e.TEXTURE_2D, 0, e.LUMINANCE_ALPHA, i.width / 2, i.height / 2, 0, e.LUMINANCE_ALPHA, e.UNSIGNED_BYTE, new Uint8Array(i.uvAddress))
        }
        r[Vse].uvTexture = a;
        a._gl = e;
        e.bindTexture(e.TEXTURE_2D, null);
        return {
          yTexture: n,
          uvTexture: a
        }
      }
      return null
    }
    


    可以看到,创建纹理后直接绑定了,并没有指定激活纹理序号,所以默认绑定到了 `gl.TEXTURE0`。

    而这时候模型的贴图也使用了这个序号,第一帧渲染的时候应该是没有问题的,问题是在第二的时候,这个纹理又被重新更新覆盖了。

    解决办法很简单,在调用 `getCameraTexture` 前提前激活一个不会用到的纹理号:

    gl.disable(gl.DEPTH_TEST);
    gl.activeTexture(gl.TEXTURE0 + 7); // 比如这样
    const { yTexture, uvTexture } = frame.getCameraTexture(gl, "yuv");
    


    如此,问题就解决了。

    哎,不开源,只能这样迂回 hack 了。

    2023-03-27
    有用 1
    回复
  • 枫
    2022-11-26

    普通模型加个贴图 都出不来 这种东西 真的是一堆问题

    2022-11-26
    有用
    回复
登录 后发表内容