Three.js通過RectAreaLight創(chuàng)造平面區(qū)域光

一、RectAreaLight的特性:
1、不支持陰影,無法通過設(shè)置castShadow來產(chǎn)生陰影。
2、RectAreaLight所散發(fā)的光源只能影響MeshStandardMaterial和MeshPhysicalMaterial兩種材質(zhì),其他材質(zhì)不受該光照的影響。
二、效果圖:
三、引入步驟:
1、引入RectAreaLight:
import {RectAreaLight} from 'three'
2、創(chuàng)造RectAreaLight并加入場(chǎng)景
 this.areaLight = new RectAreaLight(0xffffff, 1, 25, 25);
 this.areaLight.position.set(0, 0, 8);
 this.scene.add(this.areaLight);
3、創(chuàng)建兩個(gè)矩形平面作為平面區(qū)域光的載體
  const rectLightMesh = new Mesh(new PlaneGeometry(10, 10), new MeshBasicMaterial({ color:0xffffff, side:BackSide }));
  this.areaLight.add(rectLightMesh);

 const rectLightMeshBack = new Mesh(new PlaneGeometry(10, 10), new MeshBasicMaterial({ color:'#000000' }));
 rectLightMesh.add(rectLightMeshBack);

創(chuàng)建兩個(gè)矩形平面的原因是為了保證平面光的光源的指向是同一個(gè)方向。而且需要注意的是必須設(shè)置side = side:BackSide,這樣做是為了保證方面的平面緩沖幾何體能夠上色。

四、完整源代碼:
import { OrbitControls } from '../../node_modules/three/examples/jsm/controls/OrbitControls';//控制器
import Stats from 'stats.js';
import * as dat from 'dat.gui';
import { Mesh, PerspectiveCamera, Scene, WebGLRenderer, AmbientLight, MeshBasicMaterial, PlaneGeometry, BoxGeometry, MeshPhongMaterial,  Color,  RectAreaLight, PlaneBufferGeometry, BackSide, MeshStandardMaterial,  } from 'three';
export class LightProbeDemo {
    private camera: PerspectiveCamera;
    private scene: Scene;
    private renderer: WebGLRenderer;
    private stats: Stats;
    private dat: any;
    private params!: any;
    private planeGeometry!: PlaneBufferGeometry;
    private envlight!: AmbientLight;
    private areaLight!: RectAreaLight;
    constructor() {
        // 創(chuàng)建場(chǎng)景
        this.scene = new Scene();
        this.stats = new Stats();
        // 操作器
        this.dat = new dat.GUI();
        // 創(chuàng)建渲染器
        this.renderer = new WebGLRenderer({ antialias: true });
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.renderer.setPixelRatio(window.devicePixelRatio); //設(shè)備像素比 可以清晰物體
        this.renderer.setClearColor(0xEEEEEE, 1); //設(shè)置背景顏色
        this.renderer.shadowMap.enabled = true;
        document.body.appendChild(this.renderer.domElement);



        // 創(chuàng)建相機(jī)
        this.camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
        this.camera.position.set(10, 40, 40);
        this.camera.lookAt(this.scene.position);
        // 平面
        this.planeGeometry = new PlaneBufferGeometry(1600, 1400);
        // console.log(this.planeGeometry);
        
        const planeMaterial = new MeshPhongMaterial({
            specular: 0xffffff,
            color: 0xeeffff,
            shininess: 100,
            // side:DoubleSide
        });
        const planeMesh = new Mesh(this.planeGeometry, planeMaterial);
        planeMesh.rotation.x = -0.5 * Math.PI;
        planeMesh.position.y = -2;
        this.scene.add(planeMesh);

     
        const box = new BoxGeometry(5, 5, 5);
        const material = new MeshStandardMaterial({ color: '#A00000' });
        const boxmesh = new Mesh(box, material);
        boxmesh.rotation.y = 0.1*Math.PI;
        this.scene.add(boxmesh);

        // AreaLight
        this.areaLight = new RectAreaLight(0xffffff, 1, 25, 25);
        this.areaLight.position.set(0, 0, 10);
        this.scene.add(this.areaLight);
        // AreaLight載體
        const rectLightMesh = new Mesh(new PlaneGeometry(10, 10), new MeshBasicMaterial({ color:0xffffff, side:BackSide }));
        this.areaLight.add(rectLightMesh);

        const rectLightMeshBack = new Mesh(new PlaneGeometry(10, 10), new MeshBasicMaterial({ color:'#000000' }));
        rectLightMesh.add(rectLightMeshBack);

        // 環(huán)境光
        this.envlight = new AmbientLight(0xffffff, 0.7);

        this.scene.add(this.envlight);


        this.params = {
            envIntensity: 0.7,
            ambientLight: this.envlight.color.getStyle(),
            visible: false,
            
        };
        this.dat.add(this.params, 'envIntensity', 0.1, 1.0).onChange(e => {
            this.envlight.intensity = e;

        }).name('環(huán)境光強(qiáng)度');
        this.dat.addColor(this.params, 'ambientLight').onChange(e => {
            console.log(e);
            this.envlight.color = new Color(e);
        }).name('環(huán)境光顏色');

        this.dat.add(this.params, 'visible').onChange(e => {
            this.envlight.visible = !e;
        }).name('是否顯示環(huán)境光');


        // fps顯示器
        this.stats.showPanel(0);
        document.body.appendChild(this.stats.dom);
        // 相機(jī)控制器
        new OrbitControls(this.camera, this.renderer.domElement);
        window.addEventListener('resize', () => this.onWindowResize());
        this.render();
    }


    // 窗口變化
    private onWindowResize() {
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.camera.aspect = window.innerWidth / window.innerHeight;
        this.camera.updateProjectionMatrix(); //相機(jī)屬性發(fā)生變化更新投影矩陣
    }
    // 渲染
    private render() {
        this.stats.begin();

        window.requestAnimationFrame(() => this.render());
        this.renderer.render(this.scene, this.camera);
        this.stats.end();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容