【问题标题】:Three.js controlling shadows三.js控制阴影
【发布时间】:2016-04-05 21:03:56
【问题描述】:

我无法在 THREE.js 中控制阴影。首先,我场景中的阴影太暗了。根据我的阅读,有一个 shadowDarkness 属性,在当前版本的 three.js 中不再可用。有谁知道解决方法吗?

另外,在附图中:“背面”几何体没有遮挡座椅阴影上的光线 - 但是,您可以在球体(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;

我的代码的一部分。这会以某种方式影响阴影吗?我可以评论那部分代码,它对凳子的“反光”外观几乎没有影响。然而,它不再反映在球体中。任何帮助深表感谢。

///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();

【问题讨论】:

    标签: three.js shadows


    【解决方案1】:

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

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

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

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

    或者,您可以保留模型并进行试验

    renderer.shadowMap.cullFace = THREE.CullFaceNone;
    

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

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

    three.js r.75

    【讨论】:

    • 你的建议奏效了!非常感谢你。我已经阅读了有关环境光工作的信息 - 他们取消了阴影黑暗功能,这真是令人遗憾。您能否详细说明“最后,您收到错误是因为您在加载程序回调中定义之前在动画循环中访问 frameMesh。回调是异步的。”
    • 我是 javascript 和一般脚本的新手,所以在我在这个领域的知识点上,一些术语,如“在加载程序回调中定义”让我难以理解。
    • 关于环境光的解决方法:有没有办法从环境光中隐藏对象?我添加环境光的唯一原因是为了照亮阴影的灵魂目的 - 并且将来不希望这影响场景中的其他元素。
    • (1) MeshBasicMaterial 通常不响应灯光,尤其是环境光。或者您可以创建自己的ShaderMaterial,它不响应环境光。这些是你的选择。 (2) 如果您不了解这些概念,JavaScript 参考会对您有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多