前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Three.js中光源

Three.js中光源

作者头像
小刀c
发布2024-04-03 08:19:25
720
发布2024-04-03 08:19:25
举报
文章被收录于专栏:cc logcc log

toc

Intro

Three.js中光源

光源

THREE.AmbientLight

基本光源,该光源的颜色会叠加到场景现有物体的颜色上

THREE.PointLight

点光源,从空间上的一点向所有方向发射光线。点光源不能用来创建阴影(新版本支持了)

THREE.SpotLight

这种光源有聚光的效果,类似台灯、吊灯或者手电筒。这种光源可以投射阴影

THREE.DirectionalLight

无限光,从这种光源发出的光可以看作是平行的,就像太光,这种光源可以创建阴影

THREE.HemisphereLight

一种特殊的光源,可以通过模拟反光面和光线微弱的太空来创建更加自然的室外光线。此光源不提供任何与阴影相关的功能

THREE.AreaLight

使用这种光源可以指定散发光线的平面,而不是一个点。不投射任何阴影

THREE.LensFlare

这不是一种光源,但是通过THREE.LensFlare为场景中的光源添加镜头光晕的效果

上述都是基于THREE.Light对象扩展.

基础光源

THREE.AmbientLight

创建AmbientLight很简单,一般和其他光源配合使用来产生阴影。

代码语言:javascript
复制
var ambientLight = new THREE.AmbientLight("#606008", 1);
scene.add(ambientLight);

show code

代码语言:javascript
复制
function init() {

  // use the defaults
  var stats = initStats();
  var renderer = initRenderer();
  var camera = initCamera();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // add ambient lighting
  var ambientLight = new THREE.AmbientLight("#606008", 1);
  scene.add(ambientLight);

  // add spotlight for the shadows
  var spotLight = new THREE.SpotLight(0xffffff, 1, 180, Math.PI / 4);
  spotLight.shadow.mapSize.set(2048, 2048);
  spotLight.position.set(-30, 40, -10);
  spotLight.castShadow = true;
  scene.add(spotLight);

  // add a simple scene
  addHouseAndTree(scene)

  // add controls
  var controls = setupControls();

  // call the render function
  render();

  function render() {
    stats.update();
    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }

  function setupControls() {
    var controls = new function () {
      this.intensity = ambientLight.intensity;
      this.ambientColor = ambientLight.color.getStyle();
      this.disableSpotlight = false;
    };

    var gui = new dat.GUI();
    gui.add(controls, 'intensity', 0, 3, 0.1).onChange(function (e) {
      ambientLight.color = new THREE.Color(controls.ambientColor);
      ambientLight.intensity = controls.intensity;
    });
    gui.addColor(controls, 'ambientColor').onChange(function (e) {
      ambientLight.color = new THREE.Color(controls.ambientColor);
      ambientLight.intensity = controls.intensity;
    });
    gui.add(controls, 'disableSpotlight').onChange(function (e) {
      spotLight.visible = !e;
    });

    return controls;
  }
}

THREE.SpotLight聚光灯

创建聚光灯SpotLight的经典步骤

代码语言:javascript
复制
var spotLight = new THREE.SpotLight("#ffffff");
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 100;
spotLight.target = plane;
spotLight.distance = 0;
spotLight.angle = 0.4;
spotLight.shadow.camera.fov = 120;

show code

代码语言:javascript
复制
function init() {

  // use the defaults
  var stats = initStats();
  var renderer = initRenderer();
  var camera = initCamera();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  var cubeAndSphere = addDefaultCubeAndSphere(scene);
  var cube = cubeAndSphere.cube;
  var sphere = cubeAndSphere.sphere;
  var plane = addGroundPlane(scene);
  

  // add subtle ambient lighting
  var ambiColor = "#1c1c1c";
  var ambientLight = new THREE.AmbientLight(ambiColor);
  scene.add(ambientLight);

  // add spotlight for a bit of light
  var spotLight0 = new THREE.SpotLight(0xcccccc);
  spotLight0.position.set(-40, 30, -10);
  spotLight0.lookAt(plane);
  scene.add(spotLight0);

  // add target and light
  var target = new THREE.Object3D();
  target.position = new THREE.Vector3(5, 0, 0);

  var spotLight = new THREE.SpotLight("#ffffff");
  spotLight.position.set(-40, 60, -10);
  spotLight.castShadow = true;
  spotLight.shadow.camera.near = 1;
  spotLight.shadow.camera.far = 100;
  spotLight.target = plane;
  spotLight.distance = 0;
  spotLight.angle = 0.4;
  spotLight.shadow.camera.fov = 120;
  scene.add(spotLight);
  var debugCamera = new THREE.CameraHelper(spotLight.shadow.camera);

  var pp = new THREE.SpotLightHelper(spotLight)
  scene.add(pp)

  // add a small sphere simulating the pointlight
  var sphereLight = new THREE.SphereGeometry(0.2);
  var sphereLightMaterial = new THREE.MeshBasicMaterial({
    color: 0xac6c25
  });
  var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
  sphereLightMesh.castShadow = true;

  sphereLightMesh.position = new THREE.Vector3(3, 20, 3);
  scene.add(sphereLightMesh);

  // for controlling the rendering
  var step = 0;
  var invert = 1;
  var phase = 0;

  var controls = setupControls();
  render();

  function render() {
    stats.update();
    // rotate the cube around its axes
    cube.rotation.x += controls.rotationSpeed;
    cube.rotation.y += controls.rotationSpeed;
    cube.rotation.z += controls.rotationSpeed;

    // bounce the sphere up and down
    step += controls.bouncingSpeed;
    sphere.position.x = 20 + (10 * (Math.cos(step)));
    sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));

    // move the light simulation
    if (!controls.stopMovingLight) {
      if (phase > 2 * Math.PI) {
        invert = invert * -1;
        phase -= 2 * Math.PI;
      } else {
        phase += controls.rotationSpeed;
      }
      sphereLightMesh.position.z = +(7 * (Math.sin(phase)));
      sphereLightMesh.position.x = +(14 * (Math.cos(phase)));
      sphereLightMesh.position.y = 15;

      if (invert < 0) {
        var pivot = 14;
        sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;
      }

      spotLight.position.copy(sphereLightMesh.position);
    }

    pp.update();
    // render using requestAnimationFrame
    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }

  function setupControls() {
    var controls = new function () {
      this.rotationSpeed = 0.03;
      this.bouncingSpeed = 0.03;
      this.ambientColor = ambiColor;
      this.pointColor = spotLight.color.getStyle();
      this.intensity = 1;
      this.distance = 0;
      this.angle = 0.1;
      this.shadowDebug = false;
      this.castShadow = true;
      this.target = "Plane";
      this.stopMovingLight = false;
      this.penumbra = 0;
    };

    var gui = new dat.GUI();
    gui.addColor(controls, 'ambientColor').onChange(function (e) {
      ambientLight.color = new THREE.Color(e);
    });

    gui.addColor(controls, 'pointColor').onChange(function (e) {
      spotLight.color = new THREE.Color(e);
    });

    gui.add(controls, 'angle', 0, Math.PI * 2).onChange(function (e) {
      spotLight.angle = e;
    });

    gui.add(controls, 'intensity', 0, 5).onChange(function (e) {
      spotLight.intensity = e;
    });

    gui.add(controls, 'penumbra', 0, 1).onChange(function (e) {
      spotLight.penumbra = e;
    });

    gui.add(controls, 'distance', 0, 200).onChange(function (e) {
      spotLight.distance = e;
    });

    gui.add(controls, 'shadowDebug').onChange(function (e) {
      if (e) {
        scene.add(debugCamera);
      } else {
        scene.remove(debugCamera);
      }
    });

    gui.add(controls, 'castShadow').onChange(function (e) {
      spotLight.castShadow = e;
    });

    gui.add(controls, 'target', ['Plane', 'Sphere', 'Cube']).onChange(function (e) {
      switch (e) {
        case "Plane":
          spotLight.target = plane;
          break;
        case "Sphere":
          spotLight.target = sphere;
          break;
        case "Cube":
          spotLight.target = cube;
          break;
      }

    });

    gui.add(controls, 'stopMovingLight').onChange(function (e) {
      stopMovingLight = e;
    });

    return controls;
  }

}

官方文档:https://threejs.org/docs/index.html#api/zh/lights/SpotLight

THREE.SpotLight 属性

描述

默认值

angle (角度)

光源发射出的光束的宽度,单位是弧度

Math.PI/3

catShadow (投影)

如果设为true,光源会产生阴影

color (颜色)

光源颜色

decay (衰减)

光源强度随着离开光源的激励而衰减的速度。该值为2时更接近现实中的效果。只有当WebGLRenderer的属性physicallyCorrectLights(物理正确光源)被设置为启用时,才生效

1

distance (距离)

光源照射距离

0 (意味着光线强度不会随着距离增加而减弱)

intensity (强度)

光源照射的强度

1

penumbra (半影区)

设置聚光灯的锥形照明区域在其区域边缘附近的平滑衰减速度

0

position (位置)

光源在场景中的位置

power (功率)

当WebGLRenderer的属性physicallyCorrectLights(物理正确光源)被设置为启用时,可设置光源的功率,单位为流明

4*Math.PI

target (目标)

THREE.SpotLight 的指向很重要。指向场景中特定的对象或位置。需要一个THREE.Object3D对象(THREE.mesh)。

visible (是否可见)

true时光源就会打开;false光源关闭

THREE.SpotLightshadowendable时:

THREE.SpotLight.shadow属性

描述

默认值

shadow.bias (阴影偏移)

用来偏移阴影的位置。当你使用非常薄的对象时,可以用来解决奇怪的效果(将奇设置为更小的值,例如0.01)

0

shadow.camera.far (投影远点)

到距离光源的那一个位置可以产生阴影。 你可以设置所有提供给THREE.PerspectiveCamera的其他属性

5000

shadow.camera.fov (投影视场)

用于生成阴影的视场大小

50

shadow.camera.near (投影近点)

从距离光源的那一个位置可以产生阴影

50

shadow.mapSize.width 和shadow.mapSize.height (阴影映射宽高)

决定了有多少像素用来生成阴影。当阴影有锯齿边缘,或者看起来不光滑的时候,可以增加这个值。在场景渲染之后无法更改

512

shadow.radius (半径)

当值大于1时,阴影的边缘将有平滑的效果。该属性在THREE.WebGIRenderer的shadowMap.type属性为Three.BasicShadowMap时无效

添加摄像机或者光源辅助线

如上述demo所示,开发3D时候,添加辅助线通常会很方便,也很有用

添加摄像机辅助线

代码语言:javascript
复制
var debugCamera = new THREE.CameraHelper(spotLight.shadow.camera);

scene.add(debugCamera)

类似聚光灯也能添加辅助线,可以用来观察形状和朝向

代码语言:javascript
复制
var helper = new THREE.SpotLightHelper(spotLight)
scene.add(helper)

function render() {
	...
	helper.update()
	...
}

THREE.PointLight点光源

show code

代码语言:javascript
复制
function init() {

  // use the defaults
  var stats = initStats();
  var renderer = initRenderer();

  var camera = initCamera();
  var trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // add a simple scene
  addHouseAndTree(scene)

  // add subtle ambient lighting
  var ambientLight = new THREE.AmbientLight("#0c0c0c");
  scene.add(ambientLight);

  // the point light where working with
  var pointColor = "#ccffcc";
  var pointLight = new THREE.PointLight(pointColor);
  pointLight.decay = 0.1

  pointLight.castShadow = true;

  scene.add(pointLight);

  var helper = new THREE.PointLightHelper(pointLight);
  // scene.add(helper);

  var shadowHelper = new THREE.CameraHelper(pointLight.shadow.camera)
  // scene.add(shadowHelper)



  // add a small sphere simulating the pointlight
  var sphereLight = new THREE.SphereGeometry(0.2);
  var sphereLightMaterial = new THREE.MeshBasicMaterial({
    color: 0xac6c25
  });
  var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
  sphereLightMesh.position = new THREE.Vector3(3, 0, 5);
  scene.add(sphereLightMesh);

  // call the render function
  var step = 0;

  // used to determine the switch point for the light animation
  var invert = 1;
  var phase = 0;

  var controls = setupControls();
  render();

  function render() {

    helper.update();
    shadowHelper.update();

    stats.update();
    pointLight.position.copy(sphereLightMesh.position);
    trackballControls.update(clock.getDelta());

    // move the light simulation
    if (phase > 2 * Math.PI) {
      invert = invert * -1;
      phase -= 2 * Math.PI;
    } else {
      phase += controls.rotationSpeed;
    }
    sphereLightMesh.position.z = +(25 * (Math.sin(phase)));
    sphereLightMesh.position.x = +(14 * (Math.cos(phase)));
    sphereLightMesh.position.y = 5;

    if (invert < 0) {
      var pivot = 14;
      sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;
    }


    // render using requestAnimationFrame
    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }

  function setupControls() {
    var controls = new function () {
      this.rotationSpeed = 0.01;
      this.bouncingSpeed = 0.03;
      this.ambientColor = ambientLight.color.getStyle();;
      this.pointColor = pointLight.color.getStyle();;
      this.intensity = 1;
      this.distance = pointLight.distance;
    };

    

    var gui = new dat.GUI();
    gui.addColor(controls, 'ambientColor').onChange(function (e) {
      ambientLight.color = new THREE.Color(e);
    });

    gui.addColor(controls, 'pointColor').onChange(function (e) {
      pointLight.color = new THREE.Color(e);
    });

    gui.add(controls, 'distance', 0, 100).onChange(function (e) {
      pointLight.distance = e;
    });

    gui.add(controls, 'intensity', 0, 3).onChange(function (e) {
      pointLight.intensity = e;
    });

    return controls;
  }
}

官方文档:https://threejs.org/docs/index.html#api/zh/lights/PointLight

THREE.PointLight属性

描述

默认值

color

光源颜色

distance (距离)

光源着色的距离

0(意味着光的强度不会随着距离增加而减少)

intensity (强度)

光源照射的强度

1

position (位置)

光源在场景的位置

visible (是否可见)

true | false

decay (衰减)

光源强度随着离开距离而衰减的速度。 2时接近现实世界中效果。当WebGLRenderer的属性physicallyCorrectLights(物理正确光源)被设置为启用时decay才有效。

1

power (功率)

当WebGLRenderer的属性physicallyCorrectLights(物理正确光源)被设置为启用时,可设置光源的功率,单位为流明。该属性与intensity属性为简单的线性关系(power = instensity * 4 Math.PI)

4*Math.PI

创建 THREE.PointLight点光源:

代码语言:javascript
复制
var pointColor = "#ccffcc";
var pointLight = new THREE.PointLight(pointColor);
pointLight.decay = 0.1
pointLight.castShadow = true;
scene.add(pointLight);

THREE.DirectionalLight平行光

show code

代码语言:javascript
复制
function init() {

  // use the defaults
  var stats = initStats();
  var renderer = initRenderer();
  var camera = initCamera();
  camera.position.set(-80, 80, 80);
  var trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();


  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // create the ground plane
  var planeGeometry = new THREE.PlaneGeometry(600, 200, 20, 20);
  var planeMaterial = new THREE.MeshLambertMaterial({
    color: 0xffffff
  });
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;

  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 15;
  plane.position.y = -5;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  // create a cube
  var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
  var cubeMaterial = new THREE.MeshLambertMaterial({
    color: 0xff3333
  });
  var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.castShadow = true;

  // position the cube
  cube.position.x = -4;
  cube.position.y = 3;
  cube.position.z = 0;

  // add the cube to the scene
  scene.add(cube);

  var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
  var sphereMaterial = new THREE.MeshLambertMaterial({
    color: 0x7777ff
  });
  var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

  // position the sphere
  sphere.position.x = 20;
  sphere.position.y = 0;
  sphere.position.z = 2;
  sphere.castShadow = true;

  // add the sphere to the scene
  scene.add(sphere);

  // add subtle ambient lighting
  var ambiColor = "#1c1c1c";
  var ambientLight = new THREE.AmbientLight(ambiColor);
  scene.add(ambientLight);

  var target = new THREE.Object3D();
  target.position = new THREE.Vector3(5, 0, 0);

  var pointColor = "#ff5808";
  var directionalLight = new THREE.DirectionalLight(pointColor);
  directionalLight.position.set(-40, 60, -10);
  directionalLight.castShadow = true;
  directionalLight.shadow.camera.near = 2;
  directionalLight.shadow.camera.far = 80;
  directionalLight.shadow.camera.left = -30;
  directionalLight.shadow.camera.right = 30;
  directionalLight.shadow.camera.top = 30;
  directionalLight.shadow.camera.bottom = -30;

  directionalLight.intensity = 0.5;
  directionalLight.shadow.mapSize.width = 1024;
  directionalLight.shadow.mapSize.height = 1024;

  scene.add(directionalLight);
  var shadowCamera = new THREE.CameraHelper(directionalLight.shadow.camera)

  // add a small sphere simulating the pointlight
  var sphereLight = new THREE.SphereGeometry(0.2);
  var sphereLightMaterial = new THREE.MeshBasicMaterial({
    color: 0xac6c25
  });
  var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
  sphereLightMesh.castShadow = true;

  sphereLightMesh.position = new THREE.Vector3(3, 20, 3);
  scene.add(sphereLightMesh);
  // call the render function
  var step = 0;
  var invert = 1;
  var phase = 0;

  var controls = new function () {
    this.rotationSpeed = 0.03;
    this.bouncingSpeed = 0.03;
    this.ambientColor = ambiColor;
    this.pointColor = pointColor;
    this.intensity = 0.5;
    this.debug = false;
    this.castShadow = true;
    this.onlyShadow = false;
    this.target = "Plane";

  };

  var gui = new dat.GUI();

  gui.addColor(controls, 'ambientColor').onChange(function (e) {
    ambientLight.color = new THREE.Color(e);
  });

  gui.addColor(controls, 'pointColor').onChange(function (e) {
    directionalLight.color = new THREE.Color(e);
  });

  gui.add(controls, 'intensity', 0, 5).onChange(function (e) {
    directionalLight.intensity = e;
  });

  gui.add(controls, 'debug').onChange(function (e) {
    e ? scene.add(shadowCamera) : scene.remove(shadowCamera);
  });

  gui.add(controls, 'castShadow').onChange(function (e) {
    directionalLight.castShadow = e;
  });

  gui.add(controls, 'onlyShadow').onChange(function (e) {
    directionalLight.onlyShadow = e;
  });

  gui.add(controls, 'target', ['Plane', 'Sphere', 'Cube']).onChange(function (e) {
    console.log(e);
    switch (e) {
      case "Plane":
        directionalLight.target = plane;
        break;
      case "Sphere":
        directionalLight.target = sphere;
        break;
      case "Cube":
        directionalLight.target = cube;
        break;
    }

  });


  render();

  function render() {
    stats.update();
    trackballControls.update(clock.getDelta());

    // rotate the cube around its axes
    cube.rotation.x += controls.rotationSpeed;
    cube.rotation.y += controls.rotationSpeed;
    cube.rotation.z += controls.rotationSpeed;

    // bounce the sphere up and down
    step += controls.bouncingSpeed;
    sphere.position.x = 20 + (10 * (Math.cos(step)));
    sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));

    sphereLightMesh.position.z = -8;
    sphereLightMesh.position.y = +(27 * (Math.sin(step / 3)));
    sphereLightMesh.position.x = 10 + (26 * (Math.cos(step / 3)));

    directionalLight.position.copy(sphereLightMesh.position);

    // render using requestAnimationFrame
    requestAnimationFrame(render);


    renderer.render(scene, camera);
  }
}

官网文档:https://threejs.org/docs/index.html#api/zh/lights/DirectionalLight

THREE.DirectionalLight平行光就类似太阳对于地球而言,光线是“平行”的。和THREE.SpotLight聚光灯等最大的区别是:平行光不会离目标越远越暗。

平行光形成的阴影不是光锥,而是立方体。和THREE.SpotLight一样,包围对象的空间定义越紧密,投影的效果约好。

可以这样调整阴影下效果:

代码语言:javascript
复制
directionalLight.castShadow = true;
directionalLight.shadow.camera.near = 2;
directionalLight.shadow.camera.far = 80;
directionalLight.shadow.camera.left = -30;
directionalLight.shadow.camera.right = 30;
directionalLight.shadow.camera.top = 30;
directionalLight.shadow.camera.bottom = -30;

特殊光源

THREE.HemisphereLight半球光光源

要模拟户外的效果可以通过设置THREE.DirectionalLight平行光模拟太阳配合THREE.AmbientLight给场景提供基础色。但是这样不太自然。因为大自然中光不只有上方的太阳光,更多的是大气的散射和地面以及其他物体的反射。THREE.HemisphereLight半球光光源就是来解决这个问题的。

官方文档:https://threejs.org/docs/index.html#api/zh/lights/HemisphereLight

show code

代码语言:javascript
复制
function init() {

  var stats = initStats();
  var renderer = initRenderer();
  var camera = initCamera();

  var trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // create the ground plane
  var textureGrass = new THREE.TextureLoader().load("/assets/threejs/assets/textures/ground/grasslight-big.jpg");
  textureGrass.wrapS = THREE.RepeatWrapping;
  textureGrass.wrapT = THREE.RepeatWrapping;
  textureGrass.repeat.set(10, 10);

  var planeGeometry = new THREE.PlaneGeometry(1000, 1000, 20, 20);
  var planeMaterial = new THREE.MeshLambertMaterial({
    map: textureGrass
  });

  //        var planeMaterial = new THREE.MeshLambertMaterial();
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;

  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 15;
  plane.position.y = 0;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  // create a cube
  var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
  var cubeMaterial = new THREE.MeshLambertMaterial({
    color: 0xff3333
  });
  var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.castShadow = true;

  // position the cube
  cube.position.x = -4;
  cube.position.y = 3;
  cube.position.z = 0;

  // add the cube to the scene
  scene.add(cube);

  var sphereGeometry = new THREE.SphereGeometry(4, 25, 25);
  var sphereMaterial = new THREE.MeshPhongMaterial({
    color: 0x7777ff
  });
  var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

  // position the sphere
  sphere.position.x = 10;
  sphere.position.y = 5;
  sphere.position.z = 10;
  sphere.castShadow = true;

  // add the sphere to the scene
  scene.add(sphere);

  // add spotlight for a bit of light
  var spotLight0 = new THREE.SpotLight(0xcccccc);
  spotLight0.position.set(-40, 60, -10);
  spotLight0.lookAt(plane);
  scene.add(spotLight0);

  var target = new THREE.Object3D();
  target.position = new THREE.Vector3(5, 0, 0);

  var hemiLight = new THREE.HemisphereLight(0x0000ff, 0x00ff00, 0.6);
  hemiLight.position.set(0, 500, 0);
  scene.add(hemiLight);

  var pointColor = "#ffffff";
  var dirLight = new THREE.DirectionalLight(pointColor);
  dirLight.position.set(30, 10, -50);
  dirLight.castShadow = true;
  dirLight.target = plane;
  dirLight.shadow.camera.near = 0.1;
  dirLight.shadow.camera.far = 200;
  dirLight.shadow.camera.left = -50;
  dirLight.shadow.camera.right = 50;
  dirLight.shadow.camera.top = 50;
  dirLight.shadow.camera.bottom = -50;
  dirLight.shadow.mapSize.width = 2048;
  dirLight.shadow.mapSize.height = 2048;
  scene.add(dirLight);

  // call the render function
  var step = 0;

  // used to determine the switch point for the light animation
  var invert = 1;
  var phase = 0;
  var controls = addControls();



  render();

  function render() {
    stats.update();

    trackballControls.update(clock.getDelta());

    // rotate the cube around its axes
    cube.rotation.x += controls.rotationSpeed;
    cube.rotation.y += controls.rotationSpeed;
    cube.rotation.z += controls.rotationSpeed;

    // bounce the sphere up and down
    step += controls.bouncingSpeed;
    sphere.position.x = 20 + (10 * (Math.cos(step)));
    sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));

    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }

  function addControls() {
    var controls = new function () {
      this.rotationSpeed = 0.03;
      this.bouncingSpeed = 0.03;
      this.hemisphere = true;
      this.color = 0x0000ff;
      this.groundColor = 0x00ff00;
      this.intensity = 0.6;

    };

    var gui = new dat.GUI();

    gui.add(controls, 'hemisphere').onChange(function (e) {

      if (!e) {
        hemiLight.intensity = 0;
      } else {
        hemiLight.intensity = controls.intensity;
      }
    });
    gui.addColor(controls, 'groundColor').onChange(function (e) {
      hemiLight.groundColor = new THREE.Color(e);
    });
    gui.addColor(controls, 'color').onChange(function (e) {
      hemiLight.color = new THREE.Color(e);
    });
    gui.add(controls, 'intensity', 0, 5).onChange(function (e) {
      hemiLight.intensity = e;
    });

    return controls;
  }
}

仔细观察,上述场景中球体表面底部有接近草地的绿色,而顶部有接近天空的蓝色(设置color).

创建THREE.HemisphereLight半球光光源:

代码语言:javascript
复制
var hemiLight = new THREE.HemisphereLight(0x0000ff, 0x00ff00, 0.6);
hemiLight.position.set(0, 500, 0);
scene.add(hemiLight);

THREE.HemisphereLight属性

Column 2

groundColor

从地面发出光线的颜色

color

从天空发出的光线的颜色

intensity

光线照射的强度

THREE.AreaLight区域光

show code

代码语言:javascript
复制
function init() {

  var stats = initStats();
  var renderer = initRenderer({
    antialias: true
  });
  var camera = initCamera();
  
  camera.position.set(-50, 30, 50)
  // camera.lookAt(new THREE.Vector3(0, 0, -35));

  var trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();

  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();

  // create the ground plane
  var planeGeometry = new THREE.PlaneGeometry(70, 70, 1, 1);
  var planeMaterial = new THREE.MeshStandardMaterial({
    roughness: 0.044676705160855, // calculated from shininess = 1000
    metalness: 0.0

  });
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  // plane.receiveShadow  = true;

  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = 0;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  // call the render function
  var step = 0;

  var spotLight0 = new THREE.SpotLight(0xcccccc);
  spotLight0.position.set(-40, 60, -10);
  spotLight0.intensity = 0.1;
  spotLight0.lookAt(plane);
  scene.add(spotLight0);

  var areaLight1 = new THREE.RectAreaLight(0xff0000, 500, 4, 10);
  areaLight1.position.set(-10, 10, -35);
  scene.add(areaLight1);

  var areaLight2 = new THREE.RectAreaLight(0x00ff00, 500, 4, 10);
  areaLight2.position.set(0, 10, -35);
  scene.add(areaLight2);

  var areaLight3 = new THREE.RectAreaLight(0x0000ff, 500, 4, 10);
  areaLight3.position.set(10, 10, -35);
  scene.add(areaLight3);

  var planeGeometry1 = new THREE.BoxGeometry(4, 10, 0);
  var planeGeometry1Mat = new THREE.MeshBasicMaterial({
    color: 0xff0000
  });
  var plane1 = new THREE.Mesh(planeGeometry1, planeGeometry1Mat);
  plane1.position.copy(areaLight1.position);
  scene.add(plane1);

  var planeGeometry2 = new THREE.BoxGeometry(4, 10, 0);
  var planeGeometry2Mat = new THREE.MeshBasicMaterial({
    color: 0x00ff00,
  });
  var plane2 = new THREE.Mesh(planeGeometry2, planeGeometry2Mat);

  plane2.position.copy(areaLight2.position);
  scene.add(plane2);

  var planeGeometry3 = new THREE.BoxGeometry(4, 10, 0);
  var planeGeometry3Mat = new THREE.MeshBasicMaterial({
    color: 0x0000ff
  });
  var plane3 = new THREE.Mesh(planeGeometry3, planeGeometry3Mat);

  plane3.position.copy(areaLight3.position);
  scene.add(plane3);


  var controls = new function () {
    this.rotationSpeed = 0.02;
    this.color1 = 0xff0000;
    this.intensity1 = 500;
    this.color2 = 0x00ff00;
    this.intensity2 = 500;
    this.color3 = 0x0000ff;
    this.intensity3 = 500;
  };

  var gui = new dat.GUI();
  gui.addColor(controls, 'color1').onChange(function (e) {
    areaLight1.color = new THREE.Color(e);
    planeGeometry1Mat.color = new THREE.Color(e);
    scene.remove(plane1);
    plane1 = new THREE.Mesh(planeGeometry1, planeGeometry1Mat);
    plane1.position.copy(areaLight1.position);
    scene.add(plane1);

  });
  gui.add(controls, 'intensity1', 0, 1000).onChange(function (e) {
    areaLight1.intensity = e;
  });
  gui.addColor(controls, 'color2').onChange(function (e) {
    areaLight2.color = new THREE.Color(e);
    planeGeometry2Mat.color = new THREE.Color(e);
    scene.remove(plane2);
    plane2 = new THREE.Mesh(planeGeometry2, planeGeometry2Mat);
    plane2.position.copy(areaLight2.position);
    scene.add(plane2);
  });
  gui.add(controls, 'intensity2', 0, 1000).onChange(function (e) {
    areaLight2.intensity = e;
  });
  gui.addColor(controls, 'color3').onChange(function (e) {
    areaLight3.color = new THREE.Color(e);
    planeGeometry3Mat.color = new THREE.Color(e);
    scene.remove(plane3);
    plane3 = new THREE.Mesh(planeGeometry1, planeGeometry3Mat);
    plane3.position.copy(areaLight3.position);
    scene.add(plane3);
  });
  gui.add(controls, 'intensity3', 0, 1000).onChange(function (e) {
    areaLight3.intensity = e;
  });


  render();

  function render() {
    stats.update();
    trackballControls.update(clock.getDelta());

    // render using requestAnimationFrame
    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }
}

新版貌似改为THREE.RectAreaLighthttps://threejs.org/docs/index.html#api/zh/lights/RectAreaLight

Lensflare镜头光晕

创建镜头光晕效果。

官方文档:https://threejs.org/docs/index.html?q=lens#examples/zh/objects/Lensflare

show code

代码语言:javascript
复制
function init() {


  var stats = initStats();
  var renderer = initRenderer({
    alpha: true
  });

  var camera = initCamera();
  camera.position.x = -20;
  camera.position.y = 10;
  camera.position.z = 45;
  camera.lookAt(new THREE.Vector3(10, 0, 0));

  var trackballControls = initTrackballControls(camera, renderer);
  var clock = new THREE.Clock();


  // create a scene, that will hold all our elements such as objects, cameras and lights.
  var scene = new THREE.Scene();


	
  // create the ground plane
  var textureGrass = new THREE.TextureLoader().load("/assets/threejs/assets/textures/ground/grasslight-big.jpg");
  textureGrass.wrapS = THREE.RepeatWrapping;
  textureGrass.wrapT = THREE.RepeatWrapping;
  textureGrass.repeat.set(10, 10);

  var planeGeometry = new THREE.PlaneGeometry(1000, 1000, 20, 20);
  var planeMaterial = new THREE.MeshLambertMaterial({
    map: textureGrass
  });
  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;

  // rotate and position the plane
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 15;
  plane.position.y = 0;
  plane.position.z = 0;

  // add the plane to the scene
  scene.add(plane);

  // create a cube
  var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
  var cubeMaterial = new THREE.MeshLambertMaterial({
    color: 0xff3333
  });
  var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.castShadow = true;

  // position the cube
  cube.position.x = -4;
  cube.position.y = 3;
  cube.position.z = 0;

  // add the cube to the scene
  scene.add(cube);

  var sphereGeometry = new THREE.SphereGeometry(4, 25, 25);
  var sphereMaterial = new THREE.MeshLambertMaterial({
    color: 0x7777ff
  });
  var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

  // position the sphere
  sphere.position.x = 10;
  sphere.position.y = 5;
  sphere.position.z = 10;
  sphere.castShadow = true;

  // add the sphere to the scene
  scene.add(sphere);

  // add subtle ambient lighting
  var ambiColor = "#1c1c1c";
  var ambientLight = new THREE.AmbientLight(ambiColor);
  scene.add(ambientLight);

  // add spotlight for a bit of light
  var spotLight0 = new THREE.SpotLight(0xcccccc);
  spotLight0.position.set(-40, 60, -10);
  spotLight0.lookAt(plane);
  scene.add(spotLight0);


  var target = new THREE.Object3D();
  target.position = new THREE.Vector3(5, 0, 0);


  var pointColor = "#ffffff";
  //    var spotLight = new THREE.SpotLight( pointColor);
  var spotLight = new THREE.DirectionalLight(pointColor);
  spotLight.position.set(30, 10, -50);
  spotLight.castShadow = true;
  spotLight.shadowCameraNear = 0.1;
  spotLight.shadowCameraFar = 100;
  spotLight.shadowCameraFov = 50;
  spotLight.target = plane;
  spotLight.distance = 0;
  spotLight.shadowCameraNear = 2;
  spotLight.shadowCameraFar = 200;
  spotLight.shadowCameraLeft = -100;
  spotLight.shadowCameraRight = 100;
  spotLight.shadowCameraTop = 100;
  spotLight.shadowCameraBottom = -100;
  spotLight.shadowMapWidth = 2048;
  spotLight.shadowMapHeight = 2048;


  scene.add(spotLight);


  // call the render function
  var step = 0;

  // used to determine the switch point for the light animation
  var invert = 1;
  var phase = 0;

  var controls = new function () {
    this.rotationSpeed = 0.03;
    this.bouncingSpeed = 0.03;
    this.ambientColor = ambiColor;
    this.pointColor = pointColor;
    this.intensity = 0.1;
    this.distance = 0;
    this.exponent = 30;
    this.angle = 0.1;
    this.debug = false;
    this.castShadow = true;
    this.onlyShadow = false;
    this.target = "Plane";

  };

  var gui = new dat.GUI();
  gui.addColor(controls, 'ambientColor').onChange(function (e) {
    ambientLight.color = new THREE.Color(e);
  });

  gui.addColor(controls, 'pointColor').onChange(function (e) {
    spotLight.color = new THREE.Color(e);
  });

  gui.add(controls, 'intensity', 0, 5).onChange(function (e) {
    spotLight.intensity = e;
  });
	
	var textureFlare0 = THREE.ImageUtils.loadTexture("/assets/threejs/assets/textures/flares/lensflare0.png");
  var textureFlare3 = THREE.ImageUtils.loadTexture("/assets/threejs/assets/textures/flares/lensflare3.png");

  var flareColor = new THREE.Color(0xffaacc);

  var lensFlare = new THREE.Lensflare();

  lensFlare.addElement(new THREE.LensflareElement(textureFlare0, 350, 0.0, flareColor));
  lensFlare.addElement(new THREE.LensflareElement(textureFlare3, 60, 0.6, flareColor));
  lensFlare.addElement(new THREE.LensflareElement(textureFlare3, 70, 0.7, flareColor));
  lensFlare.addElement(new THREE.LensflareElement(textureFlare3, 120, 0.9, flareColor));
  lensFlare.addElement(new THREE.LensflareElement(textureFlare3, 70, 1.0, flareColor));
  spotLight.add(lensFlare);

  render();

  function render() {
    stats.update();
    trackballControls.update(clock.getDelta());
    // rotate the cube around its axes
    cube.rotation.x += controls.rotationSpeed;
    cube.rotation.y += controls.rotationSpeed;
    cube.rotation.z += controls.rotationSpeed;

    // bounce the sphere up and down
    step += controls.bouncingSpeed;
    sphere.position.x = 20 + (10 * (Math.cos(step)));
    sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));

    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }
};

创建镜头光晕:

代码语言:javascript
复制
var lensFlare = new THREE.Lensflare(texture, size, distance, blending, color, opacity);

THREE.Lensflare参数

描述

texture(纹理)

纹理就是一个图片,决定光晕的形状

size

指定光晕的尺寸,单位像素。如果-1,将使用纹理本身的尺寸

distance(距离)

从光源(0)到摄像机(1)的距离。 使用这个属性,设置镜头光晕在正确的位置

blending(混合)

可以为镜头光晕设置多个材质。混合模式决定混合方式。默认THREE.AdditiveBlending

color

光晕的颜色

opacity

光晕的透明度。 0完全透明,1完全不透明

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • toc
  • Intro
    • Three.js中光源
      • 基础光源
        • THREE.AmbientLight
        • THREE.SpotLight聚光灯
        • THREE.PointLight点光源
        • THREE.DirectionalLight平行光
      • 特殊光源
        • THREE.HemisphereLight半球光光源
        • THREE.AreaLight区域光
        • Lensflare镜头光晕
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档