图形化开发(五)032-Three.js之光照——PointLight 点光源、SpotLight 聚光灯光源、实现聚光灯阴影、HemisphereLight室外光源

图形化开发(五)032-Three.js之光照——PointLight 点光源、SpotLight 聚光灯光源、实现聚光灯阴影、HemisphereLight室外光源

PointLight 点光源

点光源就是从一个点的位置向四面八方发射出去光,一个简单的例子就是一个裸露的灯泡。
实现一个最普通的点光源很简单:

var pointLight = new THREE.PointLight(0xff0000); //创建一个白色的点光源
pointLight.position.set( 50, 50, 50 );
scene.add( pointLight );

点光源支持四个参数配置,除了前两个颜色和光的强度外,另外两个是照射范围和衰减度:

var pointLight = new THREE.PointLight(0xff0000, 1, 100, 2); //创建一个白色的点光源
pointLight.position.set( 50, 50, 50 );
scene.add( pointLight );

第三个参数照射范围,如果物体距离点光源超过这个距离,将不会受到点光源的影响,默认是所有的物体会受到点光源的影响。如果设置了参数,将按照第四个参数,衰减度的值来慢慢减少影响,默认是1,如果需要模拟现实中的效果,这个参数可以设置为2。

这些属性也可以通过动态修改:

pointLight.color.set(0x000000); //修改光照颜色
pointLight.intensity = 0.5; //修改光的强度
pointLight.distance = 50; //修改光的照射范围
pointLight.decay = 1.0; //修改衰减度

实现点光源阴影效果和实现平行光的阴影效果的设置基本一样,而且由于点光源是散射,阴影效果会终止在点光源的影响范围内。我们可以仿照平行光的阴影实现过程进行实现,只是将平行光修改为了点光源:

pointLight = new THREE.PointLight("#ffffff");
pointLight.position.set(40, 60, 10);

//告诉平行光需要开启阴影投射
pointLight.castShadow = true;

scene.add(pointLight);
SpotLight 聚光灯光源

聚光灯光源的效果也是从一个点发出光线,然后沿着一个一个圆锥体进行照射,可以模仿手电筒,带有灯罩的灯泡等效果。
实现聚光灯的案例最简单是直接设置一个颜色即可,默认照射原点位置的光照:

var spotLight = new THREE.SpotLight( 0xffffff ); //创建一个白色光照
spotLight.position.set( 100, 1000, 100 );
scene.add( spotLight );

聚光灯光源和点光源一样,也可以设置光的强度和照射范围

spotLight = new THREE.SpotLight( 0xffffff, 2.0, 100); //设置光照强度是默认的两倍,照射范围为100

聚光灯由于是沿圆锥体照射,我们可以设置聚光灯的这个椎体的角度来影响:

spotLight = new THREE.SpotLight( 0xffffff, 2.0, 100, Math.PI/4); //设置光的照射圆锥范围为90度

因为聚光灯只能照射一定的区域的物体,所以会出现光亮和无法照射地方的交接,我们可以通过配置第五个值来设置交接渐变的过渡效果:

spotLight = new THREE.SpotLight( 0xffffff, 2.0, 100, Math.PI/4, 0.5); //设置交界过渡幅度为0.5,默认是0,没有过渡,最大值为1

我们也可以通过设置第六个值来设置聚光灯的衰减度,和点光源一样:

spotLight = new THREE.SpotLight( 0xffffff, 2.0, 100, Math.PI/4, 0.5, 2.0); // 设置衰减度为物理效果的值2.0

同样道理,我们也可以动态修改相关配置项:

spotLight.color.set(0x000000); //修改光照颜色
spotLight.intensity = 0.5; //修改光的强度
spotLight.distance = 50; //修改光的照射范围
spotLight.angle = Math.PI/3; //修改光的照射弧度
spotLight.penumbra = 1.0; //修改交界过渡
spotLight.decay = 1.0; //修改衰减度

我们也可以修改聚光灯的target来修改光的照射方向:

spotLight.target.set(0, 1, 1); //修改照射方向
实现聚光灯阴影

实现聚光灯阴影和实现平行光和点光源的设置一样,聚光灯的设置也是将可以生成阴影设置打开,并将聚光灯添加到场景中即可:

spotLight= new THREE.SpotLight("#ffffff");
spotLight.position.set(40, 60, 10);
//告诉平行光需要开启阴影投射
spotLight.castShadow = true;
scene.add(spotLight);
HemisphereLight室外光源

最后我们说一下室外光源,这个光源主要是为了模拟在户外的环境光效果,比如在蓝天绿地的户外,模型下面会显示出来绿色的环境光,而上方则会受到蓝天的影响而颜色偏蓝。
实例化室外光源支持三个参数:天空的颜色,地面的颜色,和光的强度。

//添加户外光源
var hemisphereLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
scene.add(hemisphereLight);

同样的道理,我们也可以通过配置属性实时修改:

hemisphereLight.color.set(0xffffff); //将天空颜色修改为白色
hemisphereLight.groundColor.set(0x000000); //将地面颜色修改为黑色

我们也可以修改position配置项来修改渲染的方向:

hemisphereLight.position.set(0, -1, 0); //默认从上往下渲染,也就是天空在上方,当前修改为了,天空颜色从下往上渲染
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里给出一个使用 Three.js 实现的带有 Blinn-Phong 光照模型和聚光灯模式的多个立方体的代码示例: ```javascript // 初始化场景、相机、渲染器等 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加聚光灯光源 var spotLight = new THREE.SpotLight(0xffffff, 1); spotLight.position.set(0, 100, 0); spotLight.angle = Math.PI / 4; spotLight.penumbra = 0.05; spotLight.decay = 2; spotLight.distance = 200; scene.add(spotLight); // 添加多个立方体 var cube1 = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('texture1.png') }) ); cube1.position.set(-2, 0, -5); scene.add(cube1); var cube2 = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('texture2.png') }) ); cube2.position.set(0, 0, -5); scene.add(cube2); var cube3 = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('texture3.png') }) ); cube3.position.set(2, 0, -5); scene.add(cube3); // 设置相机位置和控制器 camera.position.z = 5; var controls = new THREE.OrbitControls(camera, renderer.domElement); // 渲染循环 function render() { requestAnimationFrame(render); // 计算每个立方体的 Blinn-Phong 光照 cube1.material.needsUpdate = true; cube2.material.needsUpdate = true; cube3.material.needsUpdate = true; spotLight.position.copy(camera.position); spotLight.lookAt(cube1.position); var distance = spotLight.position.distanceTo(cube1.position); var intensity = spotLight.intensity / (spotLight.decay * distance * distance); cube1.material.uniforms.lightPosition.value = spotLight.position; cube1.material.uniforms.lightColor.value = spotLight.color; cube1.material.uniforms.lightIntensity.value = intensity; cube1.material.uniforms.lightDistance.value = distance; cube1.material.uniforms.lightAngle.value = spotLight.angle; cube1.material.uniforms.lightPenumbra.value = spotLight.penumbra; cube1.material.uniforms.lightDecay.value = spotLight.decay; spotLight.lookAt(cube2.position); distance = spotLight.position.distanceTo(cube2.position); intensity = spotLight.intensity / (spotLight.decay * distance * distance); cube2.material.uniforms.lightPosition.value = spotLight.position; cube2.material.uniforms.lightColor.value = spotLight.color; cube2.material.uniforms.lightIntensity.value = intensity; cube2.material.uniforms.lightDistance.value = distance; cube2.material.uniforms.lightAngle.value = spotLight.angle; cube2.material.uniforms.lightPenumbra.value = spotLight.penumbra; cube2.material.uniforms.lightDecay.value = spotLight.decay; spotLight.lookAt(cube3.position); distance = spotLight.position.distanceTo(cube3.position); intensity = spotLight.intensity / (spotLight.decay * distance * distance); cube3.material.uniforms.lightPosition.value = spotLight.position; cube3.material.uniforms.lightColor.value = spotLight.color; cube3.material.uniforms.lightIntensity.value = intensity; cube3.material.uniforms.lightDistance.value = distance; cube3.material.uniforms.lightAngle.value = spotLight.angle; cube3.material.uniforms.lightPenumbra.value = spotLight.penumbra; cube3.material.uniforms.lightDecay.value = spotLight.decay; renderer.render(scene, camera); } render(); ``` 其中,纹理贴图的加载需要使用 `THREE.ImageUtils.loadTexture()` 方法,同时为了实现 Blinn-Phong 光照模型,需要在材质中添加 uniform 变量,并在渲染循环中对每个立方体的材质进行更新。具体的实现细节可以参考代码中的注释。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值