gpt4 book ai didi

javascript - p5.j​​s WebGL 3d 图形在旋转时被 2d 背景覆盖

转载 作者:行者123 更新时间:2023-12-04 17:29:50 25 4
gpt4 key购买 nike

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

enter image description here

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

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

下面是我当前的实现,2d 背景是在离屏 Canvas 中生成的,然后用 image() 放到主 Canvas 上生成 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 深度缓冲区。这是缓冲区存储到目前为止已绘制的每个像素的深度,以便在绘制后续三 Angular 形时,如果其中一些或全部位于先前在该位置绘制的任何内容后面,则可以剪裁它们。在对 draw() 的调用之间会自动清除此缓冲区在 p5.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 内部结构的 kludgy 解决方案,但我只能使其适用于方形 Canvas :
  • 在绘制背景图像之前切换到正交相机模式。
  • 在不超出“远”剪裁平面的情况下尽可能在负 Z 方向平移。
  • 绘制您的背景图像。
  • 将状态弹回普通透视相机。

  • 这使用正交投影允许您在场景的其余部分后面绘制背景图像,而不会因透视而缩小尺寸。但是,我还没有想出一个万无一失的方法来确定完美的翻译值是什么,也没有想出如何可靠地设置正交项目来控制“远”剪裁平面的位置。

    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>

    关于javascript - p5.j​​s WebGL 3d 图形在旋转时被 2d 背景覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60769621/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com