[英]ThreeJS: How to render scene to texture and temporarily override materials?
[英]Threejs merge multiply materials, but render incorrectly
我想合並兩個具有不同材質的網格。
這就是我所做的,但是渲染不正確,就像渲染對象的一側一樣。
這是我在codeandbox上的代碼:
https://codesandbox.io/s/summer-dawn-5nq05?fontsize=14
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Title</title> <script src="https://threejs.org/build/three.js"></script> <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script> </head> <body> <script> let renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Scene let scene = new THREE.Scene(); scene.background = new THREE.Color(0xcce0ff); // Camera let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.set(30, 0, 100); let controls = new THREE.OrbitControls(camera); for (let i = 0; i < 1; i++) { // Geometry let cube1Geometry = new THREE.PlaneGeometry(10, 10, 10); let cube2Geometry = new THREE.PlaneGeometry(10, 15, 5); // Material let cube1Material = new THREE.MeshStandardMaterial({ color: 0x7c3c3c, roughness: 1 }); let cube2Material = new THREE.MeshStandardMaterial({ color: 0x01b8ba, roughness: 0.1 }); // Mesh let cube1 = new THREE.Mesh(cube1Geometry, cube1Material); let cube2 = new THREE.Mesh(cube2Geometry, cube2Material); // Combine let singleGeometry = combine([cube1, cube2]); let single = new THREE.Mesh(singleGeometry, [ cube1Material, cube2Material ]); // scene.add(cube1); // scene.add(cube2); scene.add(single); single.position.set( Math.random() * 5, Math.random() * 10, Math.random() * 20 ); } function combine(meshes) { let mergeGeometry = new THREE.Geometry(); for (let i = 0; i < meshes.length; i++) { meshes[i].updateMatrix(); // update materialIndex for (let j = 0; j < meshes[i].geometry.faces.length; j++) { meshes[i].geometry.faces[j].materialIndex = 0; } mergeGeometry.merge(meshes[i].geometry, meshes[i].matrix, i); } return mergeGeometry; } // LIGHT let light1 = new THREE.AmbientLight(0x666666); scene.add(light1); let light = new THREE.SpotLight(0xdfebff, 1); light.position.set(50, 200, 100); scene.add(light); requestAnimationFrame(function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); }); </script> </body> </html>
發生這種現象的原因是BoxGeometry
( 源 )為其每個面規定了不同的MaterialIndex
。 反過來,當使用一系列材料時,這又控制了將用於該面的材料。
為確保每個幾何圖形僅使用數組中的指定材質,您需要將幾何圖形的每個面的MaterialIndex
重置為0
。 這樣, geometry.merge()
將正確調整每個幾何以使用正確的材質。
我已經修改了您的combine
函數來即時執行此操作。 我不確定是否有更好的方法來重置MaterialIndex
,至少我找不到任何方法。
function combine(meshes) {
let mergeGeometry = new THREE.Geometry();
for (let i = 0; i < meshes.length; i++) {
meshes[i].updateMatrix();
// update materialIndex
for ( let j = 0; j < meshes[i].geometry.faces.length; j++ ) {
meshes[i].geometry.faces[j].materialIndex = 0;
}
mergeGeometry.merge( meshes[i].geometry, meshes[i].matrix, i );
}
return mergeGeometry;
}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Title</title> <style> body { margin: 0; position: fixed; } canvas { width: 100%; height: 100%; display: block; } </style> <script src="https://threejs.org/build/three.js"></script> <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script> </head> <body> <script> let renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Scene let scene = new THREE.Scene(); scene.background = new THREE.Color(0xcce0ff); // Camera let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.set(30, 0, 50); let controls = new THREE.OrbitControls(camera); // Geometry let cube1Geometry = new THREE.BoxGeometry(10, 10, 10); let cube2Geometry = new THREE.BoxGeometry(10, 15, 5); // Material let cube1Material = new THREE.MeshStandardMaterial({ color: 0x7c3c3c, roughness: 1 }); let cube2Material = new THREE.MeshStandardMaterial({ color: 0x01b8ba, roughness: 0.1 }); // Mesh let cube1 = new THREE.Mesh(cube1Geometry, cube1Material); let cube2 = new THREE.Mesh(cube2Geometry, cube2Material); // Combine let singleGeometry = combine([cube1, cube2]); let single = new THREE.Mesh(singleGeometry, [ cube1Material, cube2Material ]); scene.add(single); function combine(meshes) { let mergeGeometry = new THREE.Geometry(); for (let i = 0; i < meshes.length; i++) { meshes[i].updateMatrix(); // update materialIndex for ( let j = 0; j < meshes[i].geometry.faces.length; j++ ) { meshes[i].geometry.faces[j].materialIndex = 0; } mergeGeometry.merge( meshes[i].geometry, meshes[i].matrix, i ); } return mergeGeometry; } // LIGHT let light1 = new THREE.AmbientLight(0x666666); scene.add(light1); let light = new THREE.SpotLight(0xdfebff, 1); light.position.set(50, 200, 100); scene.add(light); requestAnimationFrame(function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); }); </script> </body> </html>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.