Three.js 控制阴影

Three.js controlling shadows

我在 THREE.js 中无法控制阴影。首先,我场景中的阴影太暗了。从我读到的内容来看,有一个 shadowDarkness 属性,在当前版本 three.js 中已知不再可用。有人知道解决方法吗?

此外,在附图中:"backface" 几何体没有遮挡座椅阴影上的光线 - 但是,您可以在球体(cubeCamera)的反射中看到凳子的背面。有谁知道如何解决这个问题?

旁注:chrome 给我一个关于

的错误 "Uncaught TypeError: Cannot set property 'visible' of undefined,"
 frameMesh.visible = false;
    cubeCameraFrame.position.copy(frameMesh.position);
    cubeCameraFrame.updateCubeMap(renderer, scene);
    frameMesh.visible = true;

我的部分代码。这会以某种方式影响阴影吗?我可以评论那部分代码,它对 stoolframes "reflective" 外观影响不大。然而,它不再反映在球体中。任何帮助深表感谢。

///webGL - Locking down the Basics
/////////////////////////////////////////////////////////////Environment Settings///////////////////////////////////////////////////////////////////////
///Renderer 
var scene = new THREE.Scene();

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapType = THREE.PCFSoftShadowMap;
renderer.shadowMapEnabled = true;

document.body.appendChild(renderer.domElement);

///Camera's
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
scene.add(camera);

camera.position.set(0, 16, 25);
camera.rotation.x += -0.32;

var cubeCameraSphere = new THREE.CubeCamera(1, 1000, 256); // parameters: near, far, resolution
cubeCameraSphere.renderTarget.texture.minFilter = THREE.LinearMipMapLinearFilter; // mipmap filter
scene.add(cubeCameraSphere);

var cubeCameraFrame = new THREE.CubeCamera(1, 1000, 256); // parameters: near, far, resolution
cubeCameraFrame.renderTarget.texture.minFilter = THREE.LinearMipMapLinearFilter; // mipmap filter
scene.add(cubeCameraFrame);

///Controls



///Lights


var lightSpot_Right = new THREE.SpotLight(0xffffff);
lightSpot_Right.position.set(50, 50, 0);
lightSpot_Right.intensity = 1.25;
lightSpot_Right.castShadow = true;

lightSpot_Right.shadowDarkness = 0.1;

lightSpot_Right.shadowMapWidth = 2048;
lightSpot_Right.shadowMapHeight = 2048;

lightSpot_Right.shadowCameraNear = 1;
lightSpot_Right.shadowCameraFar = 100;
lightSpot_Right.shadowCameraFov = 65;
scene.add(lightSpot_Right);

var lightDirect_Left = new THREE.DirectionalLight(0xffffff, 0.25);
lightDirect_Left.position.set(-1, 0, 0);
scene.add(lightDirect_Left);

///Loaders
var loadTexture = new THREE.TextureLoader();
var loader = new THREE.JSONLoader();

///skyBox
var imagePrefix = "textures/";
var directions = ["skyboxRight", "skyboxLeft", "skyboxTop", "skyboxBottom", "skyboxFront", "skyboxBack"];
var imageSuffix = ".jpg";

var skyMaterialArray = [];
for (var i = 0; i < 6; i++)
    skyMaterialArray.push(new THREE.MeshBasicMaterial({
        map: new THREE.TextureLoader().load(imagePrefix + directions[i] + imageSuffix),
        side: THREE.BackSide
    }));
var skyMaterial = new THREE.MeshFaceMaterial(skyMaterialArray);


var skyGeometry = new THREE.CubeGeometry(1000, 1000, 1000);
var skyBox = new THREE.Mesh(skyGeometry, skyMaterial);
scene.add(skyBox);


////////////////////////////////////////////////////////Object Settings//////////////////////////////////////////////////////////////////

//Textures
var seatTexture = loadTexture.load("textures/Maharam_Mister_Notice_Diffuse.jpg");
seatTexture.wrapS = THREE.RepeatWrapping;
seatTexture.wrapT = THREE.RepeatWrapping;
seatTexture.repeat.set(3, 3);

var conceteDiffuse = loadTexture.load("textures/Contrete_Diffuse.jpg");
conceteDiffuse.wrapS = THREE.RepeatWrapping;
conceteDiffuse.wrapT = THREE.RepeatWrapping;
conceteDiffuse.repeat.set(3, 3);
var conceteNormal = loadTexture.load("textures/Contrete_Normal.jpg");
conceteNormal.wrapS = THREE.RepeatWrapping;
conceteNormal.wrapT = THREE.RepeatWrapping;
conceteNormal.repeat.set(3, 3);
var conceteSpecular = loadTexture.load("textures/Contrete_Specular.jpg");
conceteSpecular.wrapS = THREE.RepeatWrapping;
conceteSpecular.wrapT = THREE.RepeatWrapping;
conceteSpecular.repeat.set(3, 3);

///Materials
var seatMaterial = new THREE.MeshLambertMaterial({
    map: seatTexture,
    side: THREE.DoubleSide
});
var frameMaterial = new THREE.MeshPhongMaterial({
    envMap: cubeCameraFrame.renderTarget,
    color: 0xcccccc,
    emissive: 0x404040,
    shininess: 10,
    reflectivity: .8
});
var frameHardwareMat = new THREE.MeshPhongMaterial({
    color: 0x000000
});
var feetMat = new THREE.MeshPhongMaterial({
    color: 0x050505,
    shininess: 99
});

var sphereMat = new THREE.MeshPhongMaterial({
    envMap: cubeCameraSphere.renderTarget

});

var groundMat = new THREE.MeshPhongMaterial({
    map: conceteDiffuse,
    specularMap: conceteSpecular,
    normalMap: conceteNormal,
    normalScale: new THREE.Vector2( 0.0, 0.6 ),
    shininess: 50
});

///Geometry and Meshes
var barStool = new THREE.Object3D();
scene.add(barStool);

var seatMesh;
loader.load("models/stoolSeat.js", function (geometry, material) {
    seatMesh = new THREE.Mesh(geometry, seatMaterial);
    seatMesh.scale.set(.5, .5, .5);
    seatMesh.castShadow = true;
    seatMesh.receiveShadow = true;
    barStool.add(seatMesh);

});

var frameMesh;
loader.load("models/stoolFrame.js", function (geometry, material) {
    frameMesh = new THREE.Mesh(geometry, frameMaterial);
    frameMesh.scale.set(.5, .5, .5);
    frameMesh.castShadow = true;
    barStool.add(frameMesh);
});

var frameFeetMesh;
loader.load("models/stoolFeet.js", function (geometry, material) {
    frameFeetMesh = new THREE.Mesh(geometry, feetMat);
    frameFeetMesh.scale.set(.5, .5, .5);
    frameFeetMesh.castShadow = true;
    barStool.add(frameFeetMesh);
});

var frameHardwareMesh;
loader.load("models/stoolHardware.js", function (geomtry, material) {
    frameHardwareMesh = new THREE.Mesh(geomtry, frameHardwareMat);
    frameHardwareMesh.scale.set(.5, .5, .5);
    barStool.add(frameHardwareMesh);
});


var sphereGeo = new THREE.SphereGeometry(2.5, 50, 50);
var sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
scene.add(sphereMesh);

sphereMesh.position.set(-10, 5, 0);

var groundGeo = new THREE.PlaneGeometry(100, 50, 1);
var groundMesh = new THREE.Mesh(groundGeo, groundMat);
scene.add(groundMesh);

groundMesh.rotation.x = -90 * Math.PI / 180;
groundMesh.receiveShadow = true;

///Render Scene

var render = function () {

    requestAnimationFrame(render);
    barStool.rotation.y += 0.01;
    skyBox.rotation.y -= 0.0002;

    sphereMesh.visible = false;
    cubeCameraSphere.position.copy(sphereMesh.position);
    cubeCameraSphere.updateCubeMap(renderer, scene);
    sphereMesh.visible = true;

    //frameMesh.visible = false;
    //cubeCameraFrame.position.copy(frameMesh.position);
    //cubeCameraFrame.updateCubeMap(renderer, scene);
    //frameMesh.visible = true;

    renderer.render(scene, camera);
};

render();

暗影黑暗已被移除。最好的解决方法是为您的场景添加环境光。

scene.add( new THREE.AmbientLight( 0xffffff, 0.3 );

您可能想同时降低 SpotLight 的强度。

阴影实际上是正确的,因为只有背面在投射阴影。看起来凳子在座位下面是空心的——换句话说,座位不是一个封闭的体积。在您的座椅下方添加一个底部。

或者,您可以按原样保留模型并试验

renderer.shadowMap.cullFace = THREE.CullFaceNone;

最后,您收到错误是因为您在动画循环中访问 frameMesh,然后才在加载程序回调中定义它。回调是异步的。

if ( frameMesh !== undefined ) {
    // your code
}

three.js r.75