webGL 投影

阴影需要什么? 

  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   命令行进入指定文件夹 启动服务

  

原文地址:https://www.cnblogs.com/bruce-gou/p/13041735.html