如何使用 Three.js 实现“窗口”网格?

问题描述 投票:0回答:1

我正在使用 Three.js 作为实验室项目构建一个小游戏,并且想要实现一个可以“穿透”图层的“窗口”元素。具体来说:

这是第 0 层: 第 0 层屏幕截图

这是第 1 层: 第 1 层屏幕截图

接下来我继续尝试将两个图层渲染在一起。

如果我渲染这两层,我得到的结果如下: 两层屏幕截图

但我所希望的是: 想要的效果

相机、块和层的代码如下:

// Create camera
const ratio = 130;
const camera = new THREE.OrthographicCamera(window.innerWidth / -ratio, window.innerWidth / ratio, window.innerHeight / ratio, window.innerHeight / -ratio, 0.1, 1000);
// const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 10);

// Rotate camera
const angleY = THREE.MathUtils.degToRad(-30);
const rotationMatrixY = new THREE.Matrix4().makeRotationY(-angleY); // Apply negative angle for clockwise rotation
camera.applyMatrix4(rotationMatrixY); // Apply the rotation to the camera
const angleZ = THREE.MathUtils.degToRad(-45);
const rotationMatrixZ = new THREE.Matrix4().makeRotationZ(-angleZ);
camera.applyMatrix4(rotationMatrixZ);
camera.lookAt(0, 0, 0); // Point the camera at the origin

// Translate camera
const translationMatrix = new THREE.Matrix4().makeTranslation(0, 1.5, 0);
camera.applyMatrix4(translationMatrix);
const blockMaterialYellow = new THREE.MeshBasicMaterial({color: 0xffcc00});
const blockMaterialRed = new THREE.MeshBasicMaterial({color: 0xff3300});
const blockMaterialBlue = new THREE.MeshBasicMaterial({color: 0x0000ff});

// Yellow block
const yellowBlockGeometry = new THREE.BoxGeometry(1, 1, 4);
yellowBlockGeometry.applyMatrix4(new THREE.Matrix4().makeTranslation(0, 0, 0.5));
const yellowBlock = new THREE.Mesh(yellowBlockGeometry, blockMaterialYellow);
yellowBlock.position.set(-5, 0, -3);
scene.add(yellowBlock);

// Red block
const redBlockGeometry = new THREE.BoxGeometry(4, 1, 1);
redBlockGeometry.applyMatrix4(new THREE.Matrix4().makeTranslation(1.5, 0, 0));
const redBlock = new THREE.Mesh(redBlockGeometry, blockMaterialRed);
redBlock.position.set(-1, 0, -2);
scene.add(redBlock);

// Blue block
const blueBlockGeometry = new THREE.BoxGeometry(4, 1, 1);
blueBlockGeometry.applyMatrix4(new THREE.Matrix4().makeTranslation(1.5, 0, 0));
const blueBlock = new THREE.Mesh(blueBlockGeometry, blockMaterialBlue);
blueBlock.position.set(-1, 0, -8);
scene.add(blueBlock);

// Create mirror
const mirrorWidth = 3;
const mirrorHeight = 5;
const mirrorGeometry = new THREE.PlaneGeometry(mirrorWidth, mirrorHeight);
const mirrorMaterial = new THREE.MeshBasicMaterial({color: 0x000000, side: THREE.DoubleSide});
const mirror = new THREE.Mesh(mirrorGeometry, mirrorMaterial);
mirror.position.set(0, 0, -6);
scene.add(mirror);
// Layer configuration
const MAIN_LAYER = 0;
const REFLECTION_LAYER = 1;

yellowBlock.layers.set(MAIN_LAYER);
redBlock.layers.set(MAIN_LAYER);
mirror.layers.set(MAIN_LAYER);
blueBlock.layers.set(REFLECTION_LAYER);
mirrorCamera.layers.set(REFLECTION_LAYER);

我是 Three.js 的真正初学者,并且希望收到任何建议。谢谢~!

animation three.js 3d
1个回答
0
投票

您需要将蓝色框绘制到另一个缓冲区,并使用该缓冲区作为窗口网格的纹理。尝试研究WebGLRenderTarget。

ThreeJs 文档:https://thirdjs.org/docs/?q=rendertarget#api/en/renderers/WebGLRenderTarget

WebGLFundamentals 文档:https://webglfundamentals.org/webgl/lessons/webgl-render-to-texture.html

示例:https://thirdjs.org/examples/webgl_framebuffer_texture.html

© www.soinside.com 2019 - 2024. All rights reserved.