繁体   English   中英

THREE.js:模拟 MeshBasicMaterial,同时允许彩色灯光

[英]THREE.js: Simulating MeshBasicMaterial while allowing colored lights

我正在使用three.js制作一个地牢爬虫类型的游戏。 我正在使用 MeshBasicMaterial 使所有内容都“真实明亮”,以使地牢始终可见。 然而,我想在门口或墙上的缝隙中添加“额外”的灯光,以营造氛围。 但是 BasicMaterial 上没有显示灯光,所以我切换到 Phong 来测试我地板上的灯光。 现在我的地板是黑色的! 很可能是因为没有全局光。

有没有什么方法可以模拟 MeshBasicMaterial 的属性,同时允许不同颜色的灯光? 地牢的四个侧面都是封闭的,所以我想如果放置一个非常大的全局光会在各处投下阴影或覆盖地面上的颜色。

不是我的问题的主要焦点,但另外:我如何做到让光线被墙壁挡住而不是仅仅穿过它们? 墙壁只是由映射系统生成的 1x1x1 3d 网格立方体。

使用 MeshBasicMaterial

使用MeshPhongMaterial

使用MeshPhongMaterial

一旦切换到MeshPhongMaterial ,材质就会变成阴影。 您可以设置一些参数使其更接近MeshBasicMaterial ,但您仍然会获得渐变照明,无论如何,这确实是您正在寻找的“奖励”照明。 在下面的代码中,我将shininess属性设置为 0,这消除了 Phong 着色的强光效果。

为了让光线不透过墙壁,您需要实施阴影投射。 这在 THREE.js 中实际上非常简单,网上有大量文章描述如何做到这一点,所以我不会在这里重复任何内容。 但你可以在我的简单的例子看,你需要将网格设置为演员和接受阴影( castShadows / receiveShadows ,分别),并设置你的光投他们以及( castShadows )。

 var renderer, scene, camera, controls, stats; var WIDTH = window.innerWidth, HEIGHT = window.innerHeight, FOV = 70, NEAR = 1, FAR = 1000; function populateScene() { var cfgeo = new THREE.PlaneBufferGeometry(100, 100), lwallgeo = new THREE.PlaneBufferGeometry(20, 20), rwallgeo = new THREE.PlaneBufferGeometry(50, 20), farwallgeo = new THREE.PlaneBufferGeometry(50, 20), bumpgeo = new THREE.PlaneBufferGeometry(10, 10); var mat = new THREE.MeshPhongMaterial({ color: 0xcccccc, emissive: new THREE.Color(0x0c0c0c), shininess: 0, side: THREE.DoubleSide }); var ceiling = new THREE.Mesh(cfgeo, mat), floor = new THREE.Mesh(cfgeo, mat), lwall = new THREE.Mesh(lwallgeo, mat), rwall = new THREE.Mesh(rwallgeo, mat), farwall = new THREE.Mesh(farwallgeo, mat), bump1 = new THREE.Mesh(bumpgeo, mat), bump2 = new THREE.Mesh(bumpgeo, mat); ceiling.castShadow = true; ceiling.receiveShadow = true; floor.castShadow = true; floor.receiveShadow = true; lwall.castShadow = true; lwall.receiveShadow = true; rwall.castShadow = true; rwall.receiveShadow = true; farwall.castShadow = true; farwall.receiveShadow = true; bump1.castShadow = true; bump1.receiveShadow = true; bump2.castShadow = true; bump2.receiveShadow = true; ceiling.position.y = 10; ceiling.rotation.x = Math.PI / 2; floor.position.y = -10; floor.rotation.x = Math.PI / -2; lwall.rotation.y = Math.PI / 2; lwall.position.x = -10; rwall.rotation.y = Math.PI / -2; rwall.position.x = 10; rwall.position.y = 2; farwall.position.z = -20; bump1.rotation.y = Math.PI / -2; bump2.rotation.y = Math.PI / -2; bump1.position.set(10, -10, -15); bump2.position.set(10, -10, 5); scene.add(ceiling); scene.add(floor); scene.add(lwall); scene.add(rwall); scene.add(farwall); scene.add(bump1); scene.add(bump2); var bonus = new THREE.SpotLight(0xcccc00, 0.5); bonus.position.set(15, -7, -5); bonus.castShadow = true; bonus.distance = 20; var tgt = new THREE.Object3D(); tgt.position.set(0, -10, -10); bonus.target = tgt; scene.add(bonus); scene.add(tgt); } function init() { document.body.style.backgroundColor = "slateGray"; renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; document.body.appendChild(renderer.domElement); document.body.style.overflow = "hidden"; document.body.style.margin = "0"; document.body.style.padding = "0"; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR); camera.position.z = 15; scene.add(camera); controls = new THREE.TrackballControls(camera, renderer.domElement); controls.dynamicDampingFactor = 0.5; controls.rotateSpeed = 3; var light = new THREE.PointLight(0xffffff, 1, Infinity); camera.add(light); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0'; document.body.appendChild(stats.domElement); resize(); window.onresize = resize; populateScene(); animate(); } function resize() { WIDTH = window.innerWidth; HEIGHT = window.innerHeight; if (renderer && camera && controls) { renderer.setSize(WIDTH, HEIGHT); camera.aspect = WIDTH / HEIGHT; camera.updateProjectionMatrix(); controls.handleResize(); } } function render() { renderer.render(scene, camera); } function animate() { requestAnimationFrame(animate); render(); controls.update(); stats.update(); } function threeReady() { init(); } (function() { function addScript(url, callback) { callback = callback || function() {}; var script = document.createElement("script"); script.addEventListener("load", callback); script.setAttribute("src", url); document.head.appendChild(script); } addScript("https://threejs.org/build/three.js", function() { addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() { addScript("https://threejs.org/examples/js/libs/stats.min.js", function() { threeReady(); }) }) }) })();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM