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>
14-THREE.JS 聚光灯的更多相关文章
- 2016.02.14 总结JS事件
今天主要总结JS事件的基本知识以及使用技巧,并作出相应的DEMO.
- 14 (H5*) JS第4天 函数、作用域、预解析
目录 1:函数的其他定义 2:函数作为参数 3:函数作为返回值 4:作用域 5:作用域链 6:预解析 7:预解析分段 复习 <script> /* * 复习: * 函数:把一些重复的代码封 ...
- 14.data.js
dict_data = { "_id":1, name:"王五", age:55, gender:true } db.stu.insert(dict_data) ...
- arcgis api for js入门开发系列一arcgis api离线部署
在我的GIS之家QQ群里,很多都是arcgis api for js开发的新手,他们一般都是GIS专业的学生,或者从计算机专业刚刚转向来的giser,他们难免会遇到各种webgis开发的简单问题,由于 ...
- [转]OC与JS的交互详解
事情的起因还是因为项目需求驱动.折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾. 我要实现这样一个需求:按照本地的CSS ...
- 关于JS
首先推荐一个小插件:W3Cfuns前端开发工具箱 整理一些杂乱的知识点. 1,Dom用于操作html元素 2,window.location.reload();//刷新当前页********** 3, ...
- JS疑难点和GC原理
js解析与序列化json数据(一)json.stringify()的基本用法: 对象有两个方法:stringify()和parse().在最简单的情况下,这两个方法分别用于把JavaScript对象序 ...
- Vue.js实例练习
最近学习Vue.js感觉跟不上节奏了,Vue.js用起来很方便. 主要实现功能,能添加书的内容和删除.(用的Bootstrap的样式)demo链接 标题用了自定义组件,代码如下: components ...
- iOS之与JS交互通信
随着苹果SDK的不断升级,越来越多的新特性增加了进来,本文主要讲述从iOS6至今,Native与JavaScript的交互方法 一.UIWebview && iframe && ...
随机推荐
- JDBC请求
做JDBC请求,首先需要两个jar包:mysql驱动-mysql-connector-java-5.1.13-bin.jar 和 sqlServer驱动-sqljdbc4.jar,将这两个jar包放到 ...
- 如何高效地分析Android_log中的问题?——查看Android源码
在日常解bugs时,需要通过log日志来分析问题,例如查看crash发生时的堆栈信息时,就会有Android的源码的调用,这是就要去查看Android源码. 1.进入Android源码网址查看,例如 ...
- zabbix3.2.4监控MySQL5.7.16状态
一.添加监控用户mysql> grant all privileges on *.* to 'zabbix'@'localhost' identified by 'zabbix';mysql&g ...
- 剑指offer 面试40题
面试40题: 题目:最小的k个数 题:输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 解题代码一: # -*- coding ...
- gearman知识文章
一篇文章: Gearman介绍.调研.测试与原理分析 gearman是什么? 它是分布式的程序调用框架,可完成跨语言的相互调用,适合在后台运行工作任务.最初是2005年perl版本,2008年发布C/ ...
- Amend Last Commit选项使用注意点
1.创建master分支并上传到remote分支 create 2 folders and 4 files 2.修改folder1/file1.java,commit并push. 3.修改folder ...
- 3.6中的range()
在python3中range()是这样的: >>> range(4) range(0, 4) #额,列表跑哪去了 在之前的python2中是这样的: >>> ran ...
- 服务熔断、降级、限流、异步RPC -- HyStrix
背景 伴随着业务复杂性的提高,系统的不断拆分,一个面向用户端的API,其内部的RPC调用层层嵌套,调用链条可能会非常长.这会造成以下几个问题: API接口可用性降低 引用Hystrix官方的一个例子, ...
- 设计模式—迭代器Iterator模式
什么是迭代器模式? 让用户通过特定的接口访问容器的数据,不需要了解容器内部的数据结构. 首先我们先模仿集合中ArrayList和LinkedList的实现.一个是基于数组的实现.一个是基于链表的实现, ...
- eclipse新建自定义EL函数
==================================================================================================== ...