【Three.js】四(2)、three.js中的光源——特殊光源

一、THREE.HemisphereLight

创建更加贴近自然的户外光照效果。

1.1 构造器

/**
* skyColor: 从天空发出颜色
* groundColor:从地面发出的颜色
* intensity:光线照射强度
*/
HemisphereLight( skyColor : Integer, groundColor : Integer, intensity : Float )

1.2 属性说明

属性说明
color从天空发出的颜色
groundColor从地面发出的颜色
intensity光照强度
visible是否可见

示例:

import '../../stylus/index.styl';
import image from '../../assets/images/grasslight-big.jpg'
import * as THREE from 'three';
import * as dat from 'dat.gui';
import {initStats,initTrackballControls} from "../../util/util";

function init() {
    let stats = initStats();
    let scene = new THREE.Scene();
    let camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 10000);
    camera.position.set(-30,30,30);
    let renderer = new THREE.WebGLRenderer();
    renderer.shadowMap.enabled = true;
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    let textureGrass = new THREE.TextureLoader().load(image);
    textureGrass.wrapS = THREE.RepeatWrapping;
    textureGrass.wrapT = THREE.RepeatWrapping;
    textureGrass.repeat.set(10, 10);
    let planeGeometry = new THREE.PlaneBufferGeometry(500, 500,20,20);
    let planeMaterial = new THREE.MeshLambertMaterial({
        map: textureGrass
    });
    let plane = new THREE.Mesh(planeGeometry,planeMaterial);
    plane.receiveShadow = true;
    plane.rotation.x = -0.5 * Math.PI;
    plane.position.set(0,0,0);
    scene.add(plane);

    let spotLight = new THREE.SpotLight(0xcccccc);
    spotLight.position.set(-40, 60, -10);
    scene.add(spotLight);

    let hemisphereLight = new THREE.HemisphereLight(0x0000ff, 0x00ff00, 0.6);
    hemisphereLight.castShadow = true;
    hemisphereLight.position.set( 0, 500, 0 );
    scene.add(hemisphereLight);

    let dirLight = new THREE.DirectionalLight(0xffffff);
    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.set(2048, 2048);
    scene.add(dirLight);

    let ambientLight = new THREE.AmbientLight(0xc2c2c2);
    scene.add(ambientLight);

    let cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
    let cubeMaterial = new THREE.MeshLambertMaterial({
        color: 0xff3333
    });
    let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.castShadow = true;
    cube.position.set(-4,3,0);
    scene.add(cube);

    let sphereGeometry = new THREE.SphereGeometry(4, 25, 25);
    let sphereMaterial = new THREE.MeshPhongMaterial({
        color: 0x7777ff
    });
    let sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
    sphere.position.set(10,5,10);
    sphere.castShadow = true;
    scene.add(sphere);
    let gui = new dat.GUI();
    let controls = {
        visible: hemisphereLight.visible,
        skyColor: hemisphereLight.color.getStyle(),
        groundColor: hemisphereLight.groundColor.getStyle(),
        intensity: hemisphereLight.intensity
    };
    gui.add(controls, 'visible');
    gui.addColor(controls, 'skyColor');
    gui.addColor(controls, 'groundColor');
    gui.add(controls, 'intensity', 0, 2);
    let trackballControl = initTrackballControls(camera, renderer);
    function render(){
        stats.update();
        trackballControl.update();
        hemisphereLight.visible = controls.visible;
        hemisphereLight.color = new THREE.Color(controls.skyColor);
        hemisphereLight.groundColor = new THREE.Color(controls.groundColor);
        hemisphereLight.intensity = controls.intensity;
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    }
    render();
}
init();

完整示例(src/three_HemisphereLight_demo):https://github.com/MAXLZ1/threejs_demo

二、THREE.RectAreaLight

在一个矩形平面上均匀地发出光线。这种光可用于模拟光源,如明亮的窗户或条状照明。

注意:

  1. 该光源无阴影支持。
  2. 只支持MeshStandardMaterial和MeshPhysicalMaterial
  3. 必须在场景中包含RectAreaLightUniformsLib并调用init()
import '../../stylus/index.styl'
import * as THREE from 'three';
import * as dat from 'dat.gui';
import Stats from 'stats-js';

import {initTrackballControls, initStats} from "../../util/util";
import {RectAreaLightUniformsLib} from '../../libs/RectAreaLightUniformsLib'
const OrbitControls = require('three-orbitcontrols')
var renderer, scene, camera;
var origin = new THREE.Vector3();
var rectLight;
var param = {};
var stats;
init();
animate();
function init() {
    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.gammaInput = true;
    renderer.gammaOutput = true;
    document.body.appendChild( renderer.domElement );
    camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.set( 0, 20, 35 );
    scene = new THREE.Scene();
    var ambient = new THREE.AmbientLight( 0xffffff, 0.1 );
    scene.add( ambient );
    RectAreaLightUniformsLib.init();
    rectLight = new THREE.RectAreaLight( 0xffffff, 1, 10, 10 );
    rectLight.position.set( 5, 0, 0 );
    scene.add( rectLight );
    var rectLightMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( { side: THREE.BackSide } ) );
    rectLightMesh.scale.x = rectLight.width;
    rectLightMesh.scale.y = rectLight.height;
    rectLight.add( rectLightMesh );
    var rectLightMeshBack = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( { color: 0x080808 } ) );
    rectLightMesh.add( rectLightMeshBack );
    var geoFloor = new THREE.BoxBufferGeometry( 2000, 0.1, 2000 );
    var matStdFloor = new THREE.MeshStandardMaterial( { color: 0x808080, roughness: 0, metalness: 0 } );
    var mshStdFloor = new THREE.Mesh( geoFloor, matStdFloor );
    mshStdFloor.position.set(0,0,0);
    scene.add( mshStdFloor );
    var matStdObjects = new THREE.MeshStandardMaterial( { color: 0xA00000, roughness: 0, metalness: 0 } );
    var geoBox = new THREE.BoxBufferGeometry( Math.PI, Math.sqrt( 2 ), Math.E );
    var mshStdBox = new THREE.Mesh( geoBox, matStdObjects );
    mshStdBox.position.set( 0, 5, 0 );
    mshStdBox.rotation.set( 0, Math.PI / 2.0, 0 );
    mshStdBox.castShadow = true;
    mshStdBox.receiveShadow = true;
    scene.add( mshStdBox );

    var geoSphere = new THREE.SphereBufferGeometry( 1.5, 32, 32 );
    var mshStdSphere = new THREE.Mesh( geoSphere, matStdObjects );
    mshStdSphere.position.set( - 5, 5, 0 );
    mshStdSphere.castShadow = true;
    mshStdSphere.receiveShadow = true;
    scene.add( mshStdSphere );
    var geoKnot = new THREE.TorusKnotBufferGeometry( 1.5, 0.5, 100, 16 );
    var mshStdKnot = new THREE.Mesh( geoKnot, matStdObjects );
    mshStdKnot.position.set( 5, 5, 0 );
    mshStdKnot.castShadow = true;
    mshStdKnot.receiveShadow = true;
    scene.add( mshStdKnot );
    var controls = new OrbitControls( camera, renderer.domElement );
    controls.target.copy( mshStdBox.position );
    controls.update();
    // GUI
    var gui = new dat.GUI( { width: 300 } );
    gui.open();
    param = {
        motion: true,
        width: rectLight.width,
        height: rectLight.height,
        color: rectLight.color.getHex(),
        intensity: rectLight.intensity,
        'ambient': ambient.intensity,
        'floor color': matStdFloor.color.getHex(),
        'object color': matStdObjects.color.getHex(),
        'roughness': matStdFloor.roughness,
        'metalness': matStdFloor.metalness
    };
    gui.add( param, 'motion' );
    var lightFolder = gui.addFolder( 'Light' );
    lightFolder.add( param, 'width', 1, 20 ).step( 0.1 ).onChange( function ( val ) {
        rectLight.width = val;
        rectLightMesh.scale.x = val;
    } );
    lightFolder.add( param, 'height', 1, 20 ).step( 0.1 ).onChange( function ( val ) {
        rectLight.height = val;
        rectLightMesh.scale.y = val;
    } );
    lightFolder.addColor( param, 'color' ).onChange( function ( val ) {
        rectLight.color.setHex( val );
        rectLightMesh.material.color.copy( rectLight.color ).multiplyScalar( rectLight.intensity );
    } );
    lightFolder.add( param, 'intensity', 0.0, 4.0 ).step( 0.01 ).onChange( function ( val ) {
        rectLight.intensity = val;
        rectLightMesh.material.color.copy( rectLight.color ).multiplyScalar( rectLight.intensity );
    } );
    lightFolder.add( param, 'ambient', 0.0, 0.2 ).step( 0.01 ).onChange( function ( val ) {
        ambient.intensity = val;
    } );
    lightFolder.open();
    var standardFolder = gui.addFolder( 'Standard Material' );
    standardFolder.addColor( param, 'floor color' ).onChange( function ( val ) {
        matStdFloor.color.setHex( val );
    } );
    standardFolder.addColor( param, 'object color' ).onChange( function ( val ) {
        matStdObjects.color.setHex( val );
    } );
    standardFolder.add( param, 'roughness', 0.0, 1.0 ).step( 0.01 ).onChange( function ( val ) {
        matStdObjects.roughness = val;
        matStdFloor.roughness = val;
    } );
    standardFolder.add( param, 'metalness', 0.0, 1.0 ).step( 0.01 ).onChange( function ( val ) {
        matStdObjects.metalness = val;
        matStdFloor.metalness = val;
    } );
    standardFolder.open();
    stats = new Stats();
    document.body.appendChild( stats.dom );
}
function animate() {
    requestAnimationFrame( animate );
    if ( param.motion ) {
        var t = ( Date.now() / 2000 );
        var r = 15.0;
        var lx = r * Math.cos( t );
        var lz = r * Math.sin( t );
        var ly = 5.0 + 5.0 * Math.sin( t / 3.0 );
        rectLight.position.set( lx, ly, lz );
        rectLight.lookAt( origin );
    }
    renderer.render( scene, camera );
    stats.update();
}

三、THREE.LensFlare

光晕。

创建一个简单光晕:

	let textureLoader = new THREE.TextureLoader();
    let textureFlare1 = textureLoader.load( image1 );
    let textureFlare2 = textureLoader.load( image2 );
    let pointLight = new THREE.PointLight( 0xff0000, 1.5, 2000 );
    pointLight.position.set( 15, 15, 0 );
    scene.add( pointLight );
    let lensflare = new Lensflare();
    // 光晕
    lensflare.addElement( new LensflareElement( textureFlare1, 100, 0, pointLight.color ) );
    // 光斑
    lensflare.addElement( new LensflareElement( textureFlare2, 60, 0.6 ) );
    lensflare.addElement( new LensflareElement( textureFlare2, 70, 0.7 ) );
    lensflare.addElement( new LensflareElement( textureFlare2, 120, 0.9 ) );
    lensflare.addElement( new LensflareElement( textureFlare2, 70, 1 ) );
    pointLight.add( lensflare );

3.1 构造器

/**
* texture:纹理
* size: 大小
* distance: 距离
* color: 光晕颜色
*/
LensflareElement( texture : Texture, size : Float, distance : Float, color : Color )

示例:

import '../../stylus/index.styl'
import * as THREE from 'three';
import image1 from '../../assets/images/lensflare0.png';
import image2 from '../../assets/images/lensflare3.png';
import {Lensflare,LensflareElement} from "../../libs/Lensflare";
import * as dat from 'dat.gui';
import {initStats,initTrackballControls} from "../../util/util";

function init(){
    let states = initStats();
    let scene = new THREE.Scene();
    let camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
    camera.position.set(-40,30,30);
    let renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    document.body.appendChild(renderer.domElement);
    scene.add(camera);

    let planeGeometry = new THREE.PlaneGeometry(100,100,1,1);
    let planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    let plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.rotation.x = - 0.5 * Math.PI;
    plane.position.set(0,0,0);
    plane.receiveShadow = true;
    scene.add(plane);

    let spotLight = new THREE.SpotLight(0xffffff);
    spotLight.position.set(30, 30, 0);
    spotLight.shadow.mapSize.set(2048, 2048);
    spotLight.castShadow = true;
    scene.add(spotLight);

    let ambienLight = new THREE.AmbientLight(0xc2c2c2, 0.2);
    scene.add(ambienLight);

    // 光晕
    let textureLoader = new THREE.TextureLoader();
    let textureFlare1 = textureLoader.load( image1 );
    let textureFlare2 = textureLoader.load( image2 );
    let pointLight = new THREE.PointLight( 0xff0000, 1.5, 2000 );
    pointLight.position.set( 15, 15, 0 );
    scene.add( pointLight );
    let lensflare = new Lensflare();
    lensflare.addElement( new LensflareElement( textureFlare1, 100, 0, pointLight.color ) );
    lensflare.addElement( new LensflareElement( textureFlare2, 60, 0.6 ) );
    lensflare.addElement( new LensflareElement( textureFlare2, 70, 0.7 ) );
    lensflare.addElement( new LensflareElement( textureFlare2, 120, 0.9 ) );
    lensflare.addElement( new LensflareElement( textureFlare2, 70, 1 ) );
    pointLight.add( lensflare );

    let cubeGeometry = new THREE.BoxGeometry(4,4,4);
    let cubeMaterial = new THREE.MeshLambertMaterial({
        color: 0xff0000
    });

    let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(2,4, 2);
    cube.castShadow = true;
    scene.add(cube);

    camera.lookAt(scene.position);
    let trackballControls = initTrackballControls(camera, renderer);
    function render() {
        states.update();
        trackballControls.update();
        requestAnimationFrame(render);
        renderer.render(scene,camera);
    }
    render();
}

init();

完整示例(src/three_LensFlare_demo):https://github.com/MAXLZ1/threejs_demo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Three.js,点光源(Point Light)是常用的一种光照类型,它模拟的是一个发光的小点,通常用于创建局部或集光线效果。要创建一个点光源,你可以按照以下步骤进行: 1. 引入Three.js库和相关模块: ```javascript import * as THREE from 'three'; ``` 2. 创建一个新的点光源实例: ```javascript const pointLight = new THREE.PointLight(0xffffff, // 发光颜色 1.0, // 光源强度 0.5); // 光照衰减系数,范围从0到1,0表示无衰减 ``` 这里,`0xffffff`代表白色光源,`1.0`是强度(默认为1),`0.5`是光照衰减系数,值越小灯光越集。 3. 定义光源的位置: ```javascript pointLight.position.set(0, 10, 10); // 设置光源的初始位置 ``` 这一步非常重要,因为光源位置决定了光照的方向和范围。 4. 将光源添加到场景: ```javascript scene.add(pointLight); ``` `scene`是Three.js的主场景对象,将光源添加进去才能让它参与渲染。 5. 渲染器设置: ```javascript renderer.render(scene, camera); // 渲染器(Renderer)渲染场景 ``` 完整的示例代码片段如下: ```javascript // 初始化 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); // 创建光源 const pointLight = new THREE.PointLight(0xffffff, 1.0, 0.5); pointLight.position.set(0, 10, 10); // 添加光源到场景 scene.add(pointLight); // 创建渲染器和渲染 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 渲染循环 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MAXLZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值