我正在制作一个地牢爬虫类型的游戏使用three.js。我使用MeshBasicMaterial使所有的东西都“真光”,使地牢始终可见。然而,我想添加“额外”的灯光通过门道下或在墙上的狭缝,以营造气氛。但是BasicMaterial上没有显示光线,所以我转到Phong去测试地板上的光线。现在我的地板是黑色的!很可能是因为没有全球光。
有什么方法可以模拟MeshBasicMaterial的特性,同时允许不同颜色的灯光?地牢四面八方都是封闭的,所以我认为放一个非常大的全球光会在任何地方投下阴影,或者盖过地面上的颜色。
这不是我问题的主要焦点,但另外:我怎样才能使光线被墙壁所阻挡,而不是仅仅通过墙壁进行剪辑?墙壁仅仅是由映射系统生成的1x1x1三维网格立方体。
发布于 2017-06-14 12:49:24
一旦你切换到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();
})
})
})
})();
https://stackoverflow.com/questions/44480512
复制相似问题