认识光源
来源:互联网 发布:php网络验证源码 编辑:程序博客网 时间:2024/04/30 08:24
光源基类
在Threejs中,光源用Light表示,它是所有光源的基类。它的构造函数是:
THREE.Light (color)
它有一个参数color,接受一个16进制的颜色值。例如要定义一种红色的光源,我们可以这样来定义:
Var light = new THREE.Light(0xFF0000);
由基类派生出来的其他种类光源
THREE.Light只是其他所有光源的基类,要让光源除了具有颜色的特性之外,我们需要其他光源。看看,下面的类图,是目前光源的继承结构。
环境光
经过多次反射而来的光称为环境光(或者也可以这么说:无法确定光最初的方向的光就叫环境光。比如阴天的时候没有太阳,你无法确定光是从哪里照射出来的。)
环境光的颜色会影响整个场景,并且其光线没有特定的来源,所以你无须指定它的位置。在使用其它光源的同时使用环境光,目的是弱化阴影或添加一些颜色。
环境光用THREE.AmbientLight来表示,它的构造函数如下所示:
AmbientLight( color,intensity )
color: 光的颜色
intensity : 光的强度,默认是1.0,就是说是100%强度的灯光
例子 :
<!DOCTYPE html><html><head> <meta charset="utf-8"> <style> body{padding: 0; margin: 0; overflow: hidden;} </style> <title>环境光</title> </head><body> <div id="WebGL-output"></div> </body><script src='three.js'></script><script src='dat.gui.js'></script><script>var scene = new THREE.Scene(); var axes = new THREE.AxisHelper(100); scene.add(axes); var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.set(-8,8,20); camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor('#fff');document.body.appendChild(renderer.domElement); //矩形var mshFloor = new THREE.Mesh( new THREE.CubeGeometry( 2000, 1, 2000 ), new THREE.MeshPhongMaterial());mshFloor.position.set( 0, -1, 0 );scene.add(mshFloor)//立方体 var cube = new THREE.Mesh(new THREE.CubeGeometry(1,2,3), new THREE.MeshLambertMaterial({ color : 0x7777ff })); cube.position.set(0,0.5,0); scene.add(cube); //环境光var light = new THREE.AmbientLight(0xffffff);light.position.set( 0, 5, 0 ); scene.add(light); //小球,它的位置就是光源的位置var sphereLight = new THREE.SphereGeometry(0.2); var sphereLightMaterial = new THREE.MeshBasicMaterial({color: 0xac6c25}); var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial); sphereLightMesh.position.set(light.position.x, light.position.y, light.position.z); scene.add(sphereLightMesh); //GUI var controls = new function(){ this.color = light.color.getHex(); this.intensity = light.intensity; this.light_x = light.position.x; this.light_y = light.position.y; this.light_z = light.position.z; } var gui = new dat.GUI();gui.addColor(controls, 'color').onChange(function (e) { light.color = new THREE.Color(e);});gui.add(controls, 'intensity', 0,1).onChange(function (e) { light.intensity = e;});gui.add(controls, 'light_x', -50,50).onChange(function (e) { light.position.x = e; sphereLightMesh.position.x = e;});gui.add(controls, 'light_y', -50,50).onChange(function (e) { light.position.y = e; sphereLightMesh.position.y = e;});gui.add(controls, 'light_z', -50,50).onChange(function (e) { light.position.z = e; sphereLightMesh.position.z = e;});//更新函数function updata(){ cube.rotation.y +=0.01; axes.rotation.y +=0.01; mshFloor.rotation.y +=0.01; renderer.render(scene, camera); requestAnimationFrame(updata); } updata(); //窗口事件window.onresize = function(){renderer.setSize(window.innerWidth, window.innerHeight); }</script></html>
效果图:
从上面的例子可以看出,光的位置对环境光是没有影响的。
点光源
点光源是一种单点发光并照射所有方向的光源。比如夜空中的照明灯。
点光源用PointLight来表示,它的构造函数如下所示:
PointLight( color, intensity, distance,decay)color:光的颜色
intensity:光的强度,默认是1.0,就是说是100%强度的灯光
distance:光能照射到的最远的距离。
decay : 值为0~1. 此值越大,光的衰减程度越多。
例子 :
<!DOCTYPE html><html><head> <meta charset="utf-8"> <style> body{padding: 0; margin: 0; overflow: hidden;} </style> <title>点光源</title> </head><body> <div id="WebGL-output"></div> </body><script src='three.js'></script><script src='dat.gui.js'></script><script>var scene = new THREE.Scene(); var axes = new THREE.AxisHelper(100); scene.add(axes); var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.set(-8,8,20); camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor('#fff');document.body.appendChild(renderer.domElement); //矩形var mshFloor = new THREE.Mesh( new THREE.CubeGeometry( 2000, 1, 2000 ), new THREE.MeshPhongMaterial());mshFloor.position.set( 0, -1, 0 );scene.add(mshFloor)//立方体 var cube = new THREE.Mesh(new THREE.CubeGeometry(1,2,3), new THREE.MeshLambertMaterial({ color : 0x7777ff })); cube.position.set(0,0.5,0); scene.add(cube); //点光源var light = new THREE.PointLight(0xffffff, 1, 1000);light.position.set( 0, 5, 0 ); scene.add(light); //小球,它的位置就是光源的位置var sphereLight = new THREE.SphereGeometry(0.2); var sphereLightMaterial = new THREE.MeshBasicMaterial({color: 0xac6c25}); var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial); sphereLightMesh.position.set(light.position.x, light.position.y, light.position.z); scene.add(sphereLightMesh); //GUI var controls = new function(){ this.color = light.color.getHex(); this.intensity = light.intensity; this.distance = light.distance; this.light_x = light.position.x; this.light_y = light.position.y; this.light_z = light.position.z; } var gui = new dat.GUI();gui.addColor(controls, 'color').onChange(function (e) { light.color = new THREE.Color(e);});gui.add(controls, 'intensity', 0,1).onChange(function (e) { light.intensity = e;});gui.add(controls, 'distance', 0,1000).onChange(function (e) { light.distance = e;});gui.add(controls, 'light_x', -50,50).onChange(function (e) { light.position.x = e; sphereLightMesh.position.x = e;});gui.add(controls, 'light_y', -50,50).onChange(function (e) { light.position.y = e; sphereLightMesh.position.y = e;});gui.add(controls, 'light_z', -50,50).onChange(function (e) { light.position.z = e; sphereLightMesh.position.z = e;});//更新函数function updata(){ cube.rotation.y +=0.01; axes.rotation.y +=0.01; mshFloor.rotation.y +=0.01; renderer.render(scene, camera); requestAnimationFrame(updata); } updata(); //窗口事件window.onresize = function(){renderer.setSize(window.innerWidth, window.innerHeight); }</script></html>
效果图:
聚光灯
聚光灯有一种锥形的效果。比如手电筒发射出来的光。
聚光灯用SpotLight来表示,它的构造函数如下所示:
SpotLight( color, intensity, distance, angle, penumbra, decay)
color:光的颜色
intensity:光的强度,默认是1.0,就是说是100%强度的灯光
distance:光能照射到的最远的距离。
angle : 椎体的角度
penumbra : 羽化程度
decay : 值为0~1. 此值越大,光的衰减程度越多。
例子:
<!DOCTYPE html><html><head> <meta charset="utf-8"> <style> body{padding: 0; margin: 0; overflow: hidden;} </style> <title>聚光灯</title> </head><body> <div id="WebGL-output"></div> </body><script src='three.js'></script><script src='dat.gui.js'></script><script>var scene = new THREE.Scene(); var axes = new THREE.AxisHelper(100); scene.add(axes); var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.set(-8,8,20); camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor('#fff');renderer.shadowMapEnabled = true;document.body.appendChild(renderer.domElement); //矩形var mshFloor = new THREE.Mesh( new THREE.CubeGeometry( 2000, 1, 2000 ), new THREE.MeshPhongMaterial());mshFloor.receiveShadow = true;mshFloor.position.set( 0, -1, 0 );scene.add(mshFloor)//立方体 var cube = new THREE.Mesh(new THREE.CubeGeometry(1,2,3), new THREE.MeshLambertMaterial({ color : 0x7777ff })); cube.position.set(0,0.5,0); cube.castShadow = true;scene.add(cube); //聚光灯var light = new THREE.SpotLight(0xffffff, 1, 1000, 1);light.position.set( 0, 5, 0 );light.castShadow = true;light.shadowMapWidth = 2048;//阴影的宽度用多少像素绘制light.shadowMapHeight = 2048;//阴影的高度用多少像素绘制 scene.add(light); //小球,它的位置就是光源的位置var sphereLight = new THREE.SphereGeometry(0.2); var sphereLightMaterial = new THREE.MeshBasicMaterial({color: 0xac6c25}); var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial); sphereLightMesh.position.set(light.position.x, light.position.y, light.position.z); scene.add(sphereLightMesh); //辅助线,帮助我们看到聚光灯angle的变化 var lightHelper = new THREE.SpotLightHelper( light ); scene.add( lightHelper ); //GUI var controls = new function(){ this.color = light.color.getHex(); this.intensity = light.intensity; this.distance = light.distance; this.angle = light.angle; this.penumbra = 1; //聚光灯的模糊度 this.light_x = light.position.x; this.light_y = light.position.y; this.light_z = light.position.z; } var gui = new dat.GUI();gui.addColor(controls, 'color').onChange(function (e) { light.color = new THREE.Color(e);});gui.add(controls, 'intensity', 0,1).onChange(function (e) { light.intensity = e;});gui.add(controls, 'distance', 0,1000).onChange(function (e) { light.distance = e;}); gui.add(controls, 'angle', 0,1).onChange(function (e) { light.angle = e; lightHelper.update();});gui.add(controls, 'penumbra', 0,1).onChange(function (e) { light.penumbra = e;});gui.add(controls, 'light_x', -50,50).onChange(function (e) { light.position.x = e; sphereLightMesh.position.x = e; lightHelper.update();});gui.add(controls, 'light_y', -50,50).onChange(function (e) { light.position.y = e; sphereLightMesh.position.y = e; lightHelper.update();});gui.add(controls, 'light_z', -50,50).onChange(function (e) { light.position.z = e; sphereLightMesh.position.z = e; lightHelper.update();});//更新函数function updata(){ cube.rotation.y +=0.01; axes.rotation.y +=0.01; mshFloor.rotation.y +=0.01; renderer.render(scene, camera); requestAnimationFrame(updata); } updata(); //窗口事件window.onresize = function(){renderer.setSize(window.innerWidth, window.innerHeight); }</script></html>
效果图:
方向光
方向光可以看作是距离很远的光源,比如太阳光。被方向光照亮的整个区域接收到的光的强度是一样的。你可以用方向光来模拟晚上到早上的过渡效果。
方向光用DirectionalLight来表示,它的构造函数如下所示:
DirectionalLight(color, intensity)color :颜色
intensity :光的强度,默认是1.0,就是说是100%强度的灯光
例子:
<!DOCTYPE html><html><head> <meta charset="utf-8"> <style> body{padding: 0; margin: 0; overflow: hidden;} </style> <title>方向光</title> </head><body> <div id="WebGL-output"></div> </body><script src='three.js'></script><script src='dat.gui.js'></script><script>var scene = new THREE.Scene(); var axes = new THREE.AxisHelper(100); scene.add(axes); var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.set(-8,8,20); camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor('#fff');renderer.shadowMapEnabled = true;document.body.appendChild(renderer.domElement); //矩形var mshFloor = new THREE.Mesh( new THREE.CubeGeometry( 2000, 1, 2000 ), new THREE.MeshPhongMaterial());mshFloor.position.set( 0, -1, 0 );mshFloor.receiveShadow = true;scene.add(mshFloor)//立方体 var cube = new THREE.Mesh(new THREE.CubeGeometry(1,2,3), new THREE.MeshLambertMaterial({ color : 0x7777ff })); cube.position.set(0,0.5,0);cube.castShadow = true; scene.add(cube); //方向光var light = new THREE.DirectionalLight (0xffffff, 0.5);light.castShadow = true;light.position.set( 0, 5, 0 ); scene.add(light); //小球,它的位置就是光源的位置var sphereLight = new THREE.SphereGeometry(0.2); var sphereLightMaterial = new THREE.MeshBasicMaterial({color: 0xac6c25}); var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial); sphereLightMesh.position.set(light.position.x, light.position.y, light.position.z); scene.add(sphereLightMesh); //GUI var controls = new function(){ this.color = light.color.getHex(); this.intensity = light.intensity; this.light_x = light.position.x; this.light_y = light.position.y; this.light_z = light.position.z; } var gui = new dat.GUI();gui.addColor(controls, 'color').onChange(function (e) { light.color = new THREE.Color(e);});gui.add(controls, 'intensity', 0,1).onChange(function (e) { light.intensity = e;});gui.add(controls, 'light_x', -50,50).onChange(function (e) { light.position.x = e; sphereLightMesh.position.x = e;});gui.add(controls, 'light_y', -50,50).onChange(function (e) { light.position.y = e; sphereLightMesh.position.y = e;});gui.add(controls, 'light_z', -50,50).onChange(function (e) { light.position.z = e; sphereLightMesh.position.z = e;});//更新函数function updata(){ cube.rotation.y +=0.01; axes.rotation.y +=0.01; mshFloor.rotation.y +=0.01; renderer.render(scene, camera); requestAnimationFrame(updata); } updata(); //窗口事件window.onresize = function(){renderer.setSize(window.innerWidth, window.innerHeight); }</script></html>
效果图:
区域光
区域光也叫平面光,使用平面光你可以定义一个发光的矩形。该光源不在标准的three.js库中,而是在扩展库中,所以使用之前需要导入几个额外的js文件。另外该光源是一种非常复杂的光源,它会对WebglRenderer对象造成非常严重的性能损失。所以使用该光源时要使用WebGLDeferredRenderer来代替WebglRenderer。
平面光用AreaLight来表示,它的构造函数如下所示:
AreaLight(color, intensity)
color :颜色
intensity :光的强度,默认是1.0,就是说是100%强度的灯光
例子 :
<!DOCTYPE html><html><head> <meta charset="utf-8"> <style> body{padding: 0; margin: 0; overflow: hidden;} </style> <title>平面光</title> </head><body> <div id="WebGL-output"></div> </body><script src='three_AreaLight.js'></script><script src='dat.gui.js'></script><!--平面光需要导入的js库--><script type="text/javascript" src="WebGLDeferredRenderer.js"></script><script type="text/javascript" src="ShaderDeferred.js"></script><script type="text/javascript" src="RenderPass.js"></script><script type="text/javascript" src="EffectComposer.js"></script><script type="text/javascript" src="CopyShader.js"></script><script type="text/javascript" src="ShaderPass.js"></script><script type="text/javascript" src="FXAAShader.js"></script><script type="text/javascript" src="MaskPass.js"></script><script>var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.set(0,30,30); camera.lookAt(scene.position);//WebGLDeferredRenderervar renderer = new THREE.WebGLDeferredRenderer({ width: window.innerWidth, height: window.innerHeight, scale: 1, antialias: true, tonemapping: THREE.FilmicOperator, brightness: 2.5 });document.body.appendChild(renderer.domElement);//平面 var mshFloor = new THREE.Mesh( new THREE.PlaneGeometry(70, 70, 1, 1), new THREE.MeshPhongMaterial({ color: 0xffffff, specular: 0xffffff, shininess: 200 }) ); mshFloor.rotation.x = -0.5 * Math.PI; scene.add(mshFloor);//平面光var light = new THREE.AreaLight(0xffffff, 1.5);light.position.set(0, 5, -10); light.rotation.set(-Math.PI / 2, 0, 0); light.width = 2; light.height = 4; scene.add(light); //伪发光的立方块 var geom = new THREE.CubeGeometry(2, 4, 0); var mesh = new THREE.MeshBasicMaterial({color: 0xffffff}) var cube = new THREE.Mesh(geom, mesh); cube.position = light.position; scene.add(cube); //GUI var controls = new function(){ this.color = light.color.getHex(); this.intensity = light.intensity; this.light_x = light.position.x; this.light_y = light.position.y; this.light_z = light.position.z; } var gui = new dat.GUI();gui.addColor(controls, 'color').onChange(function (e) { light.color = new THREE.Color(e); //重新设置材质的颜色 mesh.color = new THREE.Color(e); scene.remove(cube); cube = new THREE.Mesh(geom, mesh); cube.position = light.position; scene.add(cube);});gui.add(controls, 'intensity', 0,3).onChange(function (e) { light.intensity = e;});gui.add(controls, 'light_x', -50,50).onChange(function (e) { light.position.x = e; cube.position.x = e;});gui.add(controls, 'light_y', -50,50).onChange(function (e) { light.position.y = e; cube.position.y = e;});gui.add(controls, 'light_z', -50,50).onChange(function (e) { light.position.z = e; cube.position.z = e;});//更新函数function updata(){ renderer.render(scene, camera); requestAnimationFrame(updata); } updata(); //窗口事件window.onresize = function(){renderer.setSize(window.innerWidth, window.innerHeight); }</script></html>
效果图 :
生成阴影
上面的例子中,有一些光源能生成阴影,而有一些光源不能。因为在three.js中,能形成阴影的光源只有 方向光 和 聚光灯;而相对的能表现阴影效果的材质只有 LambertMaterial 和 PhongMaterial。因此在设置光源和材质的时候,一定要注意这一点。给物体生成阴影需要4个步骤 :
1、renderer.shadowMapEnabled = true;
告诉渲染器我们需要阴影。为此可以将shadowMapEnabled (允许阴影映射)属性设为true
2、plane.receiveShadow = true;
接受阴影的物体需要把receiveShadow 设为true
3、cube.castShadow = true;
投射阴影的物体需要啊castShadow 设为true
4、light.castShadow = true;
把光源的castShadow 也设为true (需要注意改光源是否能产生阴影)
设置阴影的像素
设置光源的 shadowMapWidth 和shadowMapHeight 可以调整阴影的真实程度。如下图 :设置之前
设置之后
例子 :
light.shadowMapWidth = 2048; //阴影的宽度用多少像素绘制light.shadowMapHeight = 2048; //阴影的高度用多少像素绘制
本章代码下载地址 :http://download.csdn.net/detail/qq408896436/9725640
0 0
- 认识光源
- 光源
- 光源
- 光源
- 光源基本
- 光源参数
- OpenGL: 光源
- 激光光源
- 标准光源
- 光源选择
- 5.2光源
- ogre 光源
- 点光源
- 光源(Light)
- 光源选型
- 光源设置
- 聚光灯光源
- 点光源
- 游戏与算法的必经之路
- 设计模式学习之七大原则
- Express.js Middleware Tutorial
- ECMALL创建模板
- 隐藏excel分组框中的边框
- 认识光源
- java maven项目常用 build配置及启动脚本
- 我的GIT使用笔记
- Unique Paths
- Centos6.5安装zabbix2.4
- 强大的SpannableStringBuilder
- 关于ShareSdk分享新浪微博停止工作问题
- mkfs.ext4 大于2T 的目录
- iOS 怎么删除项目中的多余分支