zoukankan      html  css  js  c++  java
  • 14-THREE.JS 聚光灯

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title></title>

    <script src="https://cdn.bootcss.com/three.js/r67/three.js"></script>
    <script src="https://cdn.bootcss.com/stats.js/r10/Stats.min.js"></script>
    <script type="text/javascript" src="https://cdn.bootcss.com/dat-gui/0.7.3/dat.gui.js"></script>

        <style>
            body {
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <div id="Stats-output">
    </div>
    <div id="WebGL-output">
    </div>
    
    <script type="text/javascript">
    
        // 初始化
        function init() {
    
            var stopMovingLight = false;
    
            var stats = initStats();
    
            // 创建一个场景
            var scene = new THREE.Scene();
    
            // 创建一个照相机
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // 创建一个渲染器
            var renderer = new THREE.WebGLRenderer();
    
            renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.shadowMapEnabled = true;
            renderer.shadowMapType = THREE.PCFShadowMap;
    
            // 创建一个地板
            var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
            var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
            var plane = new THREE.Mesh(planeGeometry, planeMaterial);
            plane.receiveShadow = true;
    
            // 给地板一个坐标
            plane.rotation.x = -0.5 * Math.PI;
            plane.position.x = 15;
            plane.position.y = 0;
            plane.position.z = 0;
    
            // 给场景添加一个地板
            scene.add(plane);
    
            // 创建一个形状
            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;
    
            // 给这个正方体坐标
            cube.position.x = -4;
            cube.position.y = 3;
            cube.position.z = 0;
    
            // 把正方体添加到场景中去
            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);
    
            // 正方体坐标位置
            sphere.position.x = 20;
            sphere.position.y = 0;
            sphere.position.z = 2;
            sphere.castShadow = true;
    
            // 把正方体添加到场景中
            scene.add(sphere);
    
            // 创建位置和朝向
            camera.position.x = -35;
            camera.position.y = 30;
            camera.position.z = 25;
            camera.lookAt(new THREE.Vector3(10, 0, 0));
    
            // 添加自然光
            var ambiColor = "#1c1c1c";
            var ambientLight = new THREE.AmbientLight(ambiColor);
            scene.add(ambientLight);
    
            // 添加聚光灯
            var spotLight0 = new THREE.SpotLight(0xcccccc);
            spotLight0.position.set(-40, 30, -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);
            spotLight.position.set(-40, 60, -10);
            spotLight.castShadow = true;
            spotLight.shadowCameraNear = 2;
            spotLight.shadowCameraFar = 200;
            spotLight.shadowCameraFov = 30;
            spotLight.target = plane;
            spotLight.distance = 0; //光的距离
            spotLight.angle = 0.4; //光的强度
    
    
            scene.add(spotLight);
    
    
            // 添加一个小的圆形  点光源
            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);
    
    
            // 把渲染元素放到DOM元素里面去
            document.getElementById("WebGL-output").appendChild(renderer.domElement);
    
            // 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 = 1;  //影子大小
                this.distance = 0;
                this.exponent = 30;
                this.angle = 0.1;
                this.debug = false; //是否调试
                this.castShadow = true;
                this.onlyShadow = false;
                this.target = "Plane";
                this.stopMovingLight = false;
    
            };
    
            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, 'distance', 0, 200).onChange(function (e) {
                spotLight.distance = e;
            });
    
            gui.add(controls, 'exponent', 0, 100).onChange(function (e) {
                spotLight.exponent = e;
            });
    
            gui.add(controls, 'debug').onChange(function (e) {
                spotLight.shadowCameraVisible = e;
            });
    
            gui.add(controls, 'castShadow').onChange(function (e) {
                spotLight.castShadow = e;
            });
    
            gui.add(controls, 'onlyShadow').onChange(function (e) {
                spotLight.onlyShadow = e;
            });
    
            gui.add(controls, 'target', ['Plane', 'Sphere', 'Cube']).onChange(function (e) {
                console.log(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;
            });
    
    
            render();
    
            function render() {
                stats.update();
                // 旋转正方体
                cube.rotation.x += controls.rotationSpeed;
                cube.rotation.y += controls.rotationSpeed;
                cube.rotation.z += controls.rotationSpeed;
    
                // 控制球体的移动
                step += controls.bouncingSpeed;
                sphere.position.x = 20 + ( 10 * (Math.cos(step)));
                sphere.position.y = 2 + ( 10 * Math.abs(Math.sin(step)));
    
                // 移动光点
                if (!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 = 10;
    
                    if (invert < 0) {
                        var pivot = 14;
                        sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;
                    }
    
                    spotLight.position.copy(sphereLightMesh.position);
                }
    
                
                requestAnimationFrame(render);
    
    
                renderer.render(scene, camera);
            }
    
            function initStats() {
    
                var stats = new Stats();
    
                stats.setMode(0); // 0: fps, 1: ms
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.left = '0px';
                stats.domElement.style.top = '0px';
    
                document.getElementById("Stats-output").appendChild(stats.domElement);
    
                return stats;
            }
        }
    
        window.onload = init;
    
    
    </script>
    </body>
    </html>
  • 相关阅读:
    STM32 USART整理说明(转)
    C++ 如何初始化静态类成员
    scp、sftp和ftps
    PostGIS介绍
    string.h和strings.h的区别
    linux编程中的段错误
    Linux中的man命令
    undefinded reference to 'pthread_create'问题
    多核编程框架
    与ComboBox有相似行为的下拉控件的实现
  • 原文地址:https://www.cnblogs.com/shuaihan/p/9878606.html
Copyright © 2011-2022 走看看