P5.js旋转时被2D背景覆盖的WebGL 3D图形

p5.js WebGL 3d graphics covered by 2d background when rotated(P5.js旋转时被2D背景覆盖的WebGL 3D图形)
本文介绍了P5.js旋转时被2D背景覆盖的WebGL 3D图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用P5显示两个东西,一个是2D背景,另一个是3D WebGL前景,两者都是由P5生成的。我注意到的是,即使我在draw()函数中绘制2D背景之前绘制3D内容,当rotateX()rotateY()被调用时,3D内容仍然会被背景部分覆盖。它看起来像这样:

我怀疑发生的情况是2D和3D都在同一个Z平面上,因此当前景旋转时,其中一些会被背景覆盖,与覆盖的部分相比,背景现在位于前面。

所以我的问题是,我如何才能将背景完全保留在后面(即,无论旋转与否,都不覆盖前景)?

下面是我当前的实现,2D背景是在屏幕外的画布中生成的,然后使用image()放到主画布上,在主画布上生成3D内容,但我将采用任何其他方法。

let bg;
p.setup = () => {
    p.createCanvas(width,height,p.WEBGL);
    bg = p.createGraphics(width,height);
}

p.draw = () => {
    ... // draw background bg
    p.image(bg,x,y); // draw background on canvas

    ... // draw foreground
    p.rotateX(degrees);//rotate
}

WebGL

完成此操作的最佳方法是清除推荐答案深度缓冲区。此缓冲区存储到目前为止绘制的每个像素的深度,以便在绘制后续三角形时,如果它们中的一些或全部位于先前在该位置绘制的任何内容的后面,则可以对其进行剪裁。此缓冲区在调用p5.js中的draw()之间自动清除,但您也可以在帧中调用它:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
let bg;
let zSlider;
let glContext;

function setup() {
  let c = createCanvas(200, 200, WEBGL);
  glContext = c.GL;

  bg = createGraphics(width, height);
  bg.background('red');
  for (let y = 0; y < height; y += 20) {
    for (let x = 0; x < width; x += 20) {
      if ((x / 20 + y / 20) % 2 === 0) {
        bg.fill('black');
      } else {
        bg.fill(
          map(x + y, 0, width + height, 0, 360),
          map(y, 0, height, 50, 100),
          map(x, 0, width, 50, 100)
        );
      }

      bg.square(x, y, 20)
    }
  }

  zSlider = createSlider(0, width * 2, width);
  zSlider.position(10, 10);
}

function draw() {
  image(bg, -width / 2, -height / 2, width, height);
  // Clear the z-buffer, subsequent drawing commands will not clip, even if they
  // intersect with or are behind previously drawn elements (like our background
  // image)
  glContext.clear(glContext.DEPTH_BUFFER_BIT);

  push();
  translate(0, 0, (zSlider.value() - width) * 2);
  rotateX(millis() / 1000 * PI / 4);
  rotateY(millis() / 1000 * PI / 8);
  box(100);
  pop();
}
<script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>

也有一个笨拙的解决方案,不依赖于调用WebGL内部,但我只能让它在方形画布上工作:

  1. 在绘制背景图像之前切换到正交相机模式。
  2. 在不超出&q;远剪裁平面的情况下,尽可能沿负Z方向平移。
  3. 绘制背景图像。
  4. 将状态弹回普通透视相机。

这使用正交投影来允许您在场景的其余部分后面绘制背景图像,而不会因透视而减小大小。然而,我还没有想出一个可靠的方法来确定完美的平移值是什么,也没有想出如何可靠地设置拼写项目来控制剪裁平面的位置。

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
let bg;
let zSlider;

function setup() {
  createCanvas(200, 200, WEBGL);
  bg = createGraphics(width, height);
  bg.background('red');
  for (let y = 0; y < height; y += 20) {
    for (let x = 0; x < width; x += 20) {
      if ((x / 20 + y / 20) % 2 === 0) {
        bg.fill('black');
      } else {
        bg.fill(
          map(x + y, 0, width + height, 0, 360),
          map(y, 0, height, 50, 100),
          map(x, 0, width, 50, 100)
        );
      }

      bg.square(x, y, 20)
    }
  }

  zSlider = createSlider(0, width * 2, width);
  zSlider.position(10, 10);
}

function draw() {
  push();
  ortho();
  translate(0, 0, min(width, height) * -0.13);
  image(bg, -width / 2, -height / 2, width, height);
  pop();

  push();
  translate(0, 0, (zSlider.value() - width) * 2);
  rotateX(millis() / 1000 * PI / 4);
  rotateY(millis() / 1000 * PI / 8);
  box(100);
  pop();
}
<script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>

这篇关于P5.js旋转时被2D背景覆盖的WebGL 3D图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

本文给大家介绍Javascript js中实现和PHP一样的时间戳格式化函数的方法,具有一定的参考借鉴价值,需要的朋友可以参考下,我们知道在php中有一个date()函数,可以方便的把时间戳格式化为时间字符串。可是在js中,我们要想实现这种效果,要写好
需求是模板字符串中不允许出现script 标签、不允许有javascript: 和 .js 文件引用,主要方法如下: clearScriptTag (str) { const reg = /script[^]*([\S\s]*?)\/script/gim; // 清除标签内 相关 xss 安全代码 const reg1 = /javascript:/gim; const reg2 = / *.js/gim; if (reg.test(str)) { str
javascript中Replace全部替换字符用法实例代码,替换1次和多次,主要是正则表达式 var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace("\n",";"));//结果:1;2\n3\n 只替换了第一个var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace(/\n/g, ";"));//结果:1;2;3; replac
js输出当前日期和时间的实例代码,具体实例代码如下,有兴趣的朋友可以尝试运行下。 !doctype htmlhtml lang="en" head meta charset="UTF-8" title获取当前时间/title /head body script type="text/javascript" /** *获取当前时间 *format=1精确到天 *format=2精确到秒 */ function
Static vector field with classic arrows at every point on p5.js(P5.js上每个点都有经典箭头的静态向量场)
How would I go about writing a program to rotate at point around a sphere based on an angle as if walking around it?(我该如何编写一个程序,让它以一个角度为基础,在球体周围的点上旋转,就像绕着它走一样?)