簡體   English   中英

Threejs合並乘法材料,但渲染不正確

[英]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;

}

JSFiddle示例

 <!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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM