《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。

相关推荐
阿珊和她的猫2 小时前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
_Kayo_4 小时前
node.js 学习笔记3 HTTP
笔记·学习
加班是不可能的,除非双倍日工资6 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi7 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
CCCC13101637 小时前
嵌入式学习(day 28)线程
jvm·学习
gnip7 小时前
vite和webpack打包结构控制
前端·javascript
excel8 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
星星火柴9368 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头8 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
阿华的代码王国8 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端