阴影需要什么?
1.只有支持阴影的灯光才可以
pointLight,spotlight,directionallight
点光源,聚光灯,平行光
2.添加摄像机辅助器 THREE.CameraHelper
var helper = new THREE.CameraHelper(directionalLight.shadow.camera);
scene.add(helper);
3.查看阴影摄像机的相关设置
light.shadow.camera.left //此四项值为阴影投射方向,需要注意,正负值不确定,可以使用dat.gui.js,设置灯光等值,调试查看
light.shadow.camera. right
left为负,bottom为负,其他为正阴影投射在屏幕正前方
right为负,bottom为负阴影投射到屏幕的后方
light.shadow.camera.top
light.shadow.camera.bottom
light.shadow.camera.near //如果看不到阴影,远近截面设置不对,尝试远截面设置大一点
light.shadow.camera.far
4.最后一步需要确认几项设置
renderer.shadowMap.enabled = true; // // 告诉渲染器需要阴影效果
light.castShadow = true; // 灯光开启投影影射
mesh.castShdow = true; // 几何图形生成投影
plane.receiveShaow = true; // 平面接收阴影设置
可以查看这里:
https://www.hangge.com/blog/cache/detail_1812.html
测试案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> html, body { margin: 0; height: 100%; } canvas { display: block; } </style> </head> <body> </body> <script src="https://johnson2heng.github.io/three.js-demo/lib/three.js"></script> <script> var width = window.innerWidth; var height = window.innerHeight; var scene = new THREE.Scene(); var renderer; var camera; var mesh1; var mesh2; var mesh3; // 渲染器 function renders() { renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); // 告诉渲染器需要阴影效果 renderer.shadowMap.enabled = true; // 默认的没有设置的这个清晰 THREE.PCFShadowMap renderer.shadowMap.type = THREE.PCFSoftShadowMap; document.body.appendChild(renderer.domElement); } // 相机 function cameras() { camera = new THREE.PerspectiveCamera(45, width / window.height, 0.1, 1000); camera.position.set(0, 40, 100); camera.lookAt(new THREE.Vector3(0, 0, 0)); } // 灯光 function light() { // 环境光 var ambientLight = new THREE.AmbientLight("#111111"); scene.add(ambientLight); // 平行光 var directionalLight = new THREE.DirectionalLight("#ffffff"); directionalLight.position.set(0, 40, 0); // 灯光位置 // 产生阴影设置 directionalLight.shadow.camera.near = 20; //产生阴影的最近距离 directionalLight.shadow.camera.far = 200; //产生阴影的最远距离 directionalLight.shadow.camera.left = -50; //产生阴影距离位置的最左边位置 directionalLight.shadow.camera.right = 50; //最右边 directionalLight.shadow.camera.top = 50; //最上边 directionalLight.shadow.camera.bottom = -50; //最下面 //这两个值决定使用多少像素生成阴影 默认512 directionalLight.shadow.mapSize.height = 1024; directionalLight.shadow.mapSize.width = 1024; //告诉平行光需要开启阴影投射 directionalLight.castShadow = true; scene.add(directionalLight); var helper = new THREE.CameraHelper(directionalLight.shadow.camera); scene.add(helper); } // 几何体 function geometry() { var geometry3 = new THREE.CylinderGeometry(5, 5, 10, 10); var material3 = new THREE.MeshLambertMaterial({ color: 0xffff00 }); mesh1 = new THREE.Mesh(geometry3, material3); //网格模型对象Mesh mesh1.position.set(-20, 10, 10);//设置mesh3模型对象的xyz坐标为120,0,0 mesh1.castShadow = true; scene.add(mesh1); //立方体 var cubeGeometry = new THREE.CubeGeometry(10, 10, 10); var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff }); mesh2 = new THREE.Mesh(cubeGeometry, cubeMaterial); mesh2.position.set(30, 15, 10); mesh2.castShadow = true;// 告诉立方体需要投射阴影 scene.add(mesh2); } // 底部平面 function plan() { var planeGeometry = new THREE.PlaneGeometry(500, 500, 1, 1); // planeGeometry.vertices[0].uv = new THREE.Vector2(0, 0); // planeGeometry.vertices[1].uv = new THREE.Vector2(1, 0); // planeGeometry.vertices[2].uv = new THREE.Vector2(1, 1); // planeGeometry.vertices[3].uv = new THREE.Vector2(0, 1); // var texture = new THREE.TextureLoader().load("images/a.jpg"); // 如果使用图片填充平面,需要启动web 服务器才可以 var planeMaterial = new THREE.MeshLambertMaterial({ // map: texture, color: 0xf1f1f1 }); var plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -0.5 * Math.PI; plane.position.y = -0.5 * Math.PI; //告诉底部平面需要接收阴影 plane.receiveShadow = true; scene.add(plane); } function draw() { renderer.render(scene, camera); mesh1.rotation.x += 0.01; mesh1.rotation.y += 0.01; mesh2.rotation.x += 0.01; mesh2.rotation.y += 0.01; requestAnimationFrame(draw); } function main() { renders(); cameras(); light(); geometry(); plan(); draw(); } main(); </script> </html>
web 服务器可以使用 http-server 通过npm 全局安装 使用很方便
http-server -c-1 命令行进入指定文件夹 启动服务