《Learn Three.js》学习(3)光源

前言:

WebGL本身不支持光源,不使用three.js,则需使用着色程序来模拟光源。

学习大纲:

Three.js中的光源

特定光源的使用时机

如何调整和配置所有光源的行为

如何创建镜头光晕

光源表

基础光源:THRER.AmbientLight、THERE.PointLight、THERE.SpotLight

特殊光源和效果:THERE.HemisphereLight、THERE.AreaLight和LensFlare

基础光源

THREE.AmbientLight-环境光

**特点:**1、颜色运用至全局;2、光源无特定来源方向;3、不产生光照阴影 4、将所有物体无论形状渲染成一种颜色(故不能使用为唯一光照)

**注意:**使用环境光用色需保守些,不然画面颜色会过于饱和。

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

  // 添加控制变量
  var controls = new function(){
    this.intensity = ambientLight.intensity;
    this.ambientColor = ambientLight.color.getStyle();
    this.disableSpotlight = false;
  }
  var gui = new GUI();

  // 添加环境光强度控制
  gui.add(controls,'intensity').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;
  });
THREE.SpotLight-聚光灯

**特点:**1、锥型光源 2、具有角度和方向

javascript 复制代码
   // 聚光灯
    const 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.shadow.camera.fov = 120; // 设置阴影相机的视场角
    spotLight.angle = 0.4
    spotLight.intensity = 5; // 聚光灯强度
    spotLight.target = cube; // 设置聚光灯的目标
    spotLight.distance = 0; // 距离
    spotLight.decay = 0.06; // 衰减
    scene.add(spotLight);

当开启shadow enable时,可以调整其shadow属性

说明:spotLight可以指定某一确定物体,可以为scene中存在的也可以根据目标空间点选取创建;

javascript 复制代码
    // 创建空间对象
    var target = new THREE.Object3D();
    // target.position.set(5, 0, 0);
    target.position = new THREE.Vector3(5, 0, 0);
    scene.add(target);

可以用其属性angle定义光锥角度,distance定义光锥长度,penumbra设置光强从光锥中心向边缘递减的速度。

THERE.SpotLight对象设置castShadow为true生成阴影;

scene中渲染THERE.Mesh对象要确保投射阴影对象设置castShadow属性,为要显示阴影的对象设置receiveShadow属性。

javascript 复制代码
        var helper = new THREE.SpotLightHelper(spotLight);
        scene.add(helper);
        var debugCamera = new THREE.CameraHelper(spotLight.shadow.camera);
        scene.add(debugCamera);

        // 创建鼠标控制器
        let mouseControls = new OrbitControls(camera, renderer.domElement);
        // 监听控制器,每次拖动后重新渲染画面
        mouseControls.addEventListener('change', function(){
          renderer.render(scene, camera);
        });
        render();

        function render() {
            stats.update();
            helper.update();

注意:

如果在场景中使用薄对象,在渲染阴影时可能出现奇怪的渲染失真,可用bias属性轻微偏移来修复;

如果想使阴影更加柔和,使用THREE.WebGLRenderer设置为PCFShadowMap

THREE.PointLight-点光源

单点发光照射所有方向

属性:

power和decay属性对于模拟现实世界十分有效。

distance决定了光强度减为0前的距离。

也可使用THREE.CameraHelper 及THREE.PointLightHelper来展示光线

javascript 复制代码
 // 平行光
var directionalLight = new THREE.DirectionalLight("#ffffff", 0.1);
directionalLight.castShadow = true;
directionalLight.shadow.camera.near = 2;
directionalLight.shadow.camera.far = 100;
directionalLight.shadow.camera.left = -50;
directionalLight.shadow.camera.right = 50;
directionalLight.shadow.camera.top = 50;
directionalLight.shadow.camera.bottom = -50;
directionalLight.position.set(30, 10, -50);
scene.add(directionalLight);
THERE.DirectionalLight-平行光

**特点:**所有光线相互平行-eg:太阳光

javascript 复制代码
// 点光源
var pointColor = "#ccffcc";
var pointLight = new THREE.PointLight(pointColor);
pointLight.distance = 100;
scene.add(pointLight);

特殊光源和效果

THREE.HemisphereLight-半球光光源

户外更自然的光照,更多模拟大气散射和地面以及其他物体的反射

javascript 复制代码
const light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); scene.add( light );
THREE.RectAreaLight-区域光光源

从很大的区域发射光线,而不是单个点

不在标准库而在扩展库中,需要导入RectAreaLightUniformLib.js

javascript 复制代码
const width = 10;
const height = 10;
const intensity = 1;
const rectLight = new THREE.RectAreaLight( 0xffffff, intensity,  width, height );
rectLight.position.set( 5, 5, 0 );
rectLight.lookAt( 0, 0, 0 );
scene.add( rectLight )

const rectLightHelper = new RectAreaLightHelper( rectLight );
rectLight.add( rectLightHelper );
LensFlare - 镜头光晕
javascript 复制代码
import { Lensflare } from 'three/addons/objects/Lensflare.js';

blending混合,混合模式决定我们将如何将他们混合在一起,默认混合方式为THREE.AddtiveBlending

color 光晕的颜色。

opacity 不透明度,0完全透明。

如下使用add方法添加,还可以添加color颜色和opacity透明度。

javascript 复制代码
// 光晕
var textureFlare3 = new THREE.ImageUtils.loadTexture('./assets/lensflare0_alpha.png');
lensFare.add(textureFlare3,60,0.6,THREE.AdditiveBlending);
lensFare.add(textureFlare3,70,0.7,THREE.AdditiveBlending);
lensFare.add(textureFlare3,80,0.7,THREE.AdditiveBlending);

转换:

主要讲一下笔者将html的three应用转成vue3,反之亦然。

1、注意自己的导入方法名,html中的new dat.GUI ,但vue3中为

javascript 复制代码
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';

使用时直接new GUI便可添加图形化调试器

2、注意html可以直接操作dom,vue不可以,所以实例化一个全局变量,来为其原型链上挂载元素

html

javascript 复制代码
// 将渲染器添加到dom
document.getElementById('webgl-output').appendChild(renderer.domElement);

vue

javascript 复制代码
const webglOutput = ref(null);
webglOutput.value.appendChild(renderer.domElement);

3、注意上述的全局变量是否是响应式数据ref,记得添加value,再使用方法appendChildren。

相关推荐
啊阿狸不会拉杆1 分钟前
第二十二章:Python-NLTK库:自然语言处理
前端·python·自然语言处理
萧寂1732 分钟前
html实现手势密码
前端·css·html
excel5 分钟前
webpack 核心编译器 八 节
前端
JoyZ8 分钟前
AI的时代学习还有意义吗?
前端
好_快10 分钟前
Lodash源码阅读-getSymbolsIn
前端·javascript·源码阅读
好_快10 分钟前
Lodash源码阅读-baseAssignValue
前端·javascript·源码阅读
好_快11 分钟前
Lodash源码阅读-copyObject
前端·javascript·源码阅读
小王努力学编程12 分钟前
动态规划学习——背包问题
开发语言·c++·学习·算法·动态规划