💡没有光源,渲染的场景将不可见(除非使用基础材质或线框材质)
THREE.AmbientLight
作用描述:
- 颜色会应用到全局
- 光源没有特别的来源方向
- 不会产生阴影,会将所有物体渲染为相同的颜色
- 最好在使用其他光源的同时使用它,目的是弱化阴影,或给场景添加一些额外的颜色
注意事项:
- 使用这种光源时,用色应该尽量保守。如果指定的颜色过于明亮,会发现画面的颜色过于饱和。
- 除了颜色之外,还可以设置强度值。
创建THREE.AmbientLight光源
- 首先添加实例化THREE.AmbientLight对象
var ambientLight = new THREE.AmbientLight("#606008");
- 将对象添加到场景
scene.add(ambientLight);
案例
结果:
完整代码:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name=viewport
content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
<script type="text/javascript" src="../libs/three/three.js"></script>
<script type="text/javascript" src="../libs/three/controls/OrbitControls.js"></script>
<script type="text/javascript" src="../libs/util/dat.gui.js"></script>
<script type="text/javascript" src="../libs/util/Stats.js"></script>
<script type="text/javascript" src="js/AmbientLight.js"></script>
<link rel="stylesheet" href="../css/default.css">
<title>Title</title>
<style></style>
<script></script>
</head>
<body>
<div id="webgl-output">
</div>
<script type="text/javascript">
(function(){
draw()
})()
</script>
</body>
</html>
var scene;
function initScene() {
scene = new THREE.Scene();
}
var camera;
function initCamera(){
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(50,30,30);
camera.lookAt(scene.position);
scene.add(camera);
}
var renderer;
function initRenderer(){
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
var sphereLightMesh;
var axes,cube,plane,sphere;
function initModel(){
axes = new THREE.AxesHelper(40);
var planeGeometry = new THREE.PlaneGeometry(60,40);
var planeMaterial = new THREE.MeshLambertMaterial({
color:0xAAAAAA,
});
plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.set(10,0,10);
plane.receiveShadow = true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-9,2,10);
cube.castShadow = true;
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4,20,20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
})
sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(15,4,10);
sphere.castShadow = true;
scene.add(sphere);
var sphereLight = new THREE.SphereGeometry(0.2);
var sphereLightMaterial = new THREE.MeshBasicMaterial({
color: 0xac6c25
});
sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
sphereLightMesh.position = new THREE.Vector3(3, 0, 5);
}
var ambientLight;
function initLight(){
ambientLight = new THREE.AmbientLight(0xffddff);
scene.add(ambientLight);
pointLight = new THREE.PointLight(0xffffff,1,180,Math.PI/2);
pointLight.position.set(-30,40,-10);
pointLight.shadow.mapSize.set(2048,2048);
pointLight.castShadow = true;
scene.add(pointLight);
}
var stats;
function initStats() {
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.dom);
}
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = true;
controls.autoRotate = true;
controls.enablePan = true;
}
function windowOnchange(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var light;
var gui;
function initGui(){
var Aml = new function(){
this.intensity = ambientLight.intensity;
this.ambientColor = ambientLight.color.getStyle();
this.disableSpotlight = false;
};
gui = new dat.GUI();
gui.add(Aml,'intensity',0,3,0.1).onChange(function (e){
ambientLight.intensity = Aml.intensity;
});
gui.addColor(Aml,'ambientColor').onChange(function (e) {
ambientLight.color = new THREE.Color(Aml.ambientColor);
});
gui.add(Aml,'disableSpotlight').onChange(function (e){
pointLight.visible = !e;
});
}
function render(){
renderer.render(scene,camera);
}
function animate(){
render();
stats.update();
requestAnimationFrame(animate);
}
function draw(){
initScene();
initCamera();
initRenderer();
initStats();
initControls();
initModel();
initLight();
initGui();
animate();
window.onresize = windowOnchange;
}
THREE.SpotLight
作用描述
- 聚光灯光源,从特定的一点以锥形发射光线
- 该光源产生的光具有方向和角度
THREE.SpotLight所有属性
属性 | 描述 |
---|
angle(角度) | 光源发射出的光束的宽度,单位是弧度,默认值为Math.PI/3 |
castShadow(投影) | 如果设置为true,这个光源就会生成阴影 |
color(颜色) | 光源颜色 |
decay(衰减) | 光源强度随着离开光源的距离而衰减的速度。该值为2时更接近现实世界中的效果,默认值为1。只有当WebGLReader的属性physicallyCorrectLights(物理正确光源)被设置为启用时,decay属性才有效 |
distance(距离) | 光源照射的距离。默认值为0,这意味着光线强度不会随着距离的增加而减弱。 |
intensity(强度) | 光源照射的强度。默认值为1 |
penumbra(半影区) | 该属性设置聚光灯的锥形照明区域在其区域边缘附近的平滑衰减速度。取值范围在0到1之间,默认值为0 |
position(位置) | 光源在场景中的位置 |
power(功率) | 当物理正确模式启用时(WebGLReader的属性physicallyCorrectLights被设置为启用时),该属性指定光源的功率,以流明为单位,默认值为4*Math.PI |
target(目标) | 使用THREE.SpotLight光源时,它的指向很重要。使用target属性,可以将THREE.SpotLight光源指向场景中的特定对象或特定位置。注意,此属性需要一个THREE.Object3D对象(如THREE.Mesh) |
visible(是否可见) | 光源是否可见。如果属性设置为true,该光源就会打开;如果设置为false,光源就会关闭 |
调节阴影特性的属性
当THREE.SpotLight的shadow属性为enable时,可以用以下属性调节阴影特性
属性 | 描述 |
---|
shadow.bias(阴影偏移) | 用来偏置阴影的位置。当用非常薄的对象时,可以使用它来解决一些奇怪的效果。如果看到一些奇怪的阴影效果,可以将该属性设置为很小的值(比如0.01)通常可以解决问题。默认值为0 |
shadow.camera.far(投影远点) | 到距离光源的哪一个位置可以生成阴影。默认值为5000. |
shadow.camera.fov(投影视场) | 用于生成阴影的视场大小。默认值为50 |
shadow.camera.near(投影近点) | 从距离光源的哪一个位置开始生成阴影。默认值为50 |
hadow.mapSize.width和shadow.mapSize.height(阴影映射宽度和阴影映射高度) | 决定了有多少像素用来生成阴影。当阴影具有锯齿状边缘或看起来不光滑时,可以增加这个值。在场景渲染之后无法更改。两者的默认值均为512 |
shadow.radius(半径) | 当该值大于1时,阴影的边缘将有平滑效果。该属性在THREE.WebGLRenderer的shadowMap.type属性为THREE.BasicShadowMap时无效。 |
案列
结果
代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name=viewport
content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
<script type="text/javascript" src="../libs/three/three.js"></script>
<script type="text/javascript" src="../libs/three/controls/OrbitControls.js"></script>
<script type="text/javascript" src="../libs/util/dat.gui.js"></script>
<script type="text/javascript" src="../libs/util/Stats.js"></script>
<script type="text/javascript" src="js/SpotLight.js"></script>
<link rel="stylesheet" href="../css/default.css">
<title>Title</title>
<style></style>
<script></script>
</head>
<body>
<div id="webgl-output">
</div>
<script type="text/javascript">
(function(){
draw()
})()
</script>
</body>
</html>
var scene;
function initScene() {
scene = new THREE.Scene();
}
var camera;
function initCamera(){
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-30,40,30);
camera.lookAt(scene.position);
scene.add(camera);
}
var renderer;
function initRenderer(){
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
var sphereLightMesh;
var axes,cube,plane,sphere;
function initModel(){
axes = new THREE.AxesHelper(40);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,120,120);
var planeMaterial = new THREE.MeshLambertMaterial({
color:0xAAAAAA,
});
plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.set(5,0,0);
plane.receiveShadow = true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-16,3,0);
cube.castShadow = true;
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4,20,20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
})
sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(20,4,0);
sphere.castShadow = true;
scene.add(sphere);
var sphereLight = new THREE.SphereGeometry(0.2);
var sphereLightMaterial = new THREE.MeshBasicMaterial({
color: 0xac6c25
});
sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
sphereLightMesh.position = new THREE.Vector3(3, 0, 5);
scene.add(sphereLightMesh);
}
var stats;
function initStats() {
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.dom);
}
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = true;
controls.autoRotate = true;
controls.enablePan = true;
}
function windowOnchange(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var ambientLight,spotLight0,spotLight;
var shadowDebug,pp;
function initLight(){
ambientLight = new THREE.AmbientLight("#1c1c1c");
scene.add(ambientLight);
spotLight0 = new THREE.PointLight(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);
spotLight = new THREE.SpotLight("#ffffff");
spotLight.position.set(-40,60,-10);
spotLight.castShadow = true;
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 100;
spotLight.target = plane;
spotLight.distance = 0;
spotLight.angle = 0.4;
spotLight.shadow.camera.fov = 120;
scene.add(spotLight);
shadowDebug = new THREE.CameraHelper(spotLight.shadow.camera);
pp = new THREE.SpotLightHelper(spotLight);
scene.add(pp);
}
var gui,Spl;
var step = 0
function initGui1(){
Spl = new function(){
this.rotationSpeed = 0.03;
this.bouncingSpeed = 0.03;
this.ambientColor = ambientLight.color.getStyle();
this.spotColor = spotLight.color.getStyle();
this.angle = spotLight.angle;
this.intensity = spotLight.intensity;
this.penumbra = spotLight.penumbra;
this.distance = spotLight.distance;
this.shadowDebug = false;
this.castShadow = true;
this.target = plane;
this.stopMovingLight = false;
this.disableSpotlight = false;
};
gui = new dat.GUI();
gui.add(Spl,'rotationSpeed',0,1);
gui.add(Spl,'bouncingSpeed',0,1);
gui.addColor(Spl,'ambientColor').onChange(function (e) {
ambientLight.color = new THREE.Color(Spl.ambientColor);
});
gui.addColor(Spl,'spotColor').onChange(function (e) {
spotLight.color = new THREE.Color(Spl.spotColor);
});
gui.add(Spl,'angle',0,6.28).onChange(function (e) {
spotLight.angle = e;
});
gui.add(Spl,'intensity',0,5,0.1).onChange(function (e){
spotLight.intensity = e;
});
gui.add(Spl,'penumbra',0,1).onChange(function (e){
spotLight.penumbra = e;
});
gui.add(Spl,'distance',0,200).onChange(function (e){
spotLight.distance = e;
});
gui.add(Spl,'shadowDebug').onChange(function (e) {
if(e){
scene.add(shadowDebug);
}
else{
scene.remove(shadowDebug);
}
});
gui.add(Spl,'castShadow').onChange(function (e) {
spotLight.castShadow = e;
});
gui.add(Spl,'target',['plane','cube','sphere']).onChange(function (e) {
switch(e){
case 'plane':
spotLight.target = plane;
break;
case 'cube':
spotLight.target = cube;
break;
case 'sphere':
spotLight.target = sphere;
break;
}
});
gui.add(Spl,'stopMovingLight').onChange(function (e){
stopMovingLight = e;
});
gui.add(Spl,'disableSpotlight').onChange(function (e){
spotLight.visible = !e;
});
}
function render(){
renderer.render(scene,camera);
}
var invert =1;
var phase = 0;
function animate(){
stats.update();
cube.rotation.x += Spl.rotationSpeed;
cube.rotation.y += Spl.rotationSpeed;
cube.rotation.z += Spl.rotationSpeed;
step += Spl.bouncingSpeed;
sphere.position.x = 10+(10*Math.cos(step));
sphere.position.y = 2+(10*Math.abs(Math.sin(step)));
if(!Spl.stopMovingLight){
if(phase >2*Math.PI){
invert = invert * -1;
phase -= 2*Math.PI;
}
else{
phase += Spl.rotationSpeed;
}
sphereLightMesh.position.z = +(7*(Math.sin(phase)));
sphereLightMesh.position.x = +(14*(Math.cos(phase)));
sphereLightMesh.position.y = 15;
if(invert < 0){
var pivot = 14;
sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot))+pivot;
}
spotLight.position.copy(sphereLightMesh.position);
}
pp.update();
render();
requestAnimationFrame(animate);
}
function draw(){
initScene();
initCamera();
initRenderer();
initStats();
initControls();
initModel();
initLight();
initGui1();
animate();
window.onresize = windowOnchange;
}
关于使用阴影的提示
- 如果阴影看上去有点粗糙(如阴影形状的边缘呈块状),可以增加shadow.mapSize.width和shadow.maoSize.height属性的值,或者保证用于计算阴影的区域紧密包围在对象周围。可以通过shadow.camera.near、shadow.camera.far、shadow.camera.fov属性配置这个区域。
- 不仅要告诉光源生成阴影,而且必去通过配置每个几何体的castShadow和receiveShadow属性来告诉几何体是否接收或投射阴影,同时也要开启渲染器的阴影投射(renderer.shadowMap.enabled = true)
- 使用较薄对象渲染阴影时,会出现阴影失真现象,可以使用shadow.bias属性轻微偏移阴影修复这些问题
THREE.PointLight
描述
- 点光源是一种单点发光,照射所有方向的光源。
- 点光源可以像聚光灯一样启用阴影并设置其属性
属性 | 描述 |
---|
color(颜色) | 光源颜色 |
distance(距离) | 光源照射的距离。默认值为0,这意味着光的强度不会随着距离增加而减少 |
intensity(强度) | 光源照射的强度。默认值为1 |
position(位置) | 光源在场景中的位置 |
visible(是否可见) | 该属性设置为true,光源就会打开,false——关闭 |
decay(衰减) | 光源强度随着离开光源的距离而衰减的速度。该值为2时更接近现实世界中的效果,默认值为1。只有当WebGLReader的属性physicallyCorrectLights(物理正确光源)被设置为启用时,decay属性才有效 |
power(功率) | 当物理正确模式启用时(WebGLReader的属性physicallyCorrectLights被设置为启用时),该属性指定光源的功率,以流明为单位,默认值为4*Math.PI |
案例
结果
代码
var scene;
function initScene() {
scene = new THREE.Scene();
}
var camera;
function initCamera(){
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-30,40,30);
camera.lookAt(scene.position);
scene.add(camera);
}
var renderer;
function initRenderer(){
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
var sphereLightMesh;
var axes,cube,plane,sphere;
function initModel(){
axes = new THREE.AxesHelper(40);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,120,120);
var planeMaterial = new THREE.MeshLambertMaterial({
color:0xAAAAAA,
});
plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.set(5,0,0);
plane.receiveShadow = true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-16,2,0);
cube.castShadow = true;
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4,20,20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
})
sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(20,4,0);
sphere.castShadow = true;
scene.add(sphere);
var sphereLight = new THREE.SphereGeometry(0.2);
var sphereLightMaterial = new THREE.MeshBasicMaterial({
color: 0xac6c25
});
sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
sphereLightMesh.position = new THREE.Vector3(3, 0, 5);
scene.add(sphereLightMesh);
}
var stats;
function initStats() {
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.dom);
}
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.enableZoom = true;
controls.autoRotate = true;
controls.minDistance = 1;
controls.maxDistance = 200;
controls.enablePan = true;
}
function windowOnchange(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var ambientLight,pointLight;
var shadowDebug,pp;
function initLight(){
ambientLight = new THREE.AmbientLight("#1c1c1c");
scene.add(ambientLight);
pointLight = new THREE.PointLight("#ccffcc");
pointLight.castShadow = true;
pointLight.decay = 1;
scene.add(pointLight);
}
var gui,Spl;
var step = 0
function initGui1(){
Spl = new function(){
this.rotationSpeed = 0.02;
this.ambientColor = ambientLight.color.getStyle();
this.pointColor = pointLight.color.getStyle();
this.intensity = pointLight.intensity;
this.distance = pointLight.distance;
this.stopMovingLight = false;
};
gui = new dat.GUI();
gui.addColor(Spl,'ambientColor').onChange(function (e) {
ambientLight.color = new THREE.Color(Spl.ambientColor);
});
gui.addColor(Spl,'pointColor').onChange(function (e) {
pointLight.color = new THREE.Color(Spl.pointColor);
});
gui.add(Spl,'intensity',0,3,0.1).onChange(function (e){
pointLight.intensity = e;
});
gui.add(Spl,'distance',0,100).onChange(function (e){
pointLight.distance = e;
});
gui.domElement.style.position = "absolute";
gui.domElement.style.right = "300px";
}
function render(){
renderer.render(scene,camera);
}
var invert =1;
var phase = 0;
function animate(){
stats.update();
pointLight.position.copy(sphereLightMesh.position);
if(phase >2*Math.PI){
invert = invert * -1;
phase -= 2*Math.PI;
}
else{
phase += Spl.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;
}
render();
requestAnimationFrame(animate);
}
function draw(){
initScene();
initCamera();
initRenderer();
initStats();
initControls();
initModel();
initLight();
initGui1();
animate();
window.onresize = windowOnchange;
}
THREE.DirectionalLight
描述
- 平行光,发出的所有光线都是互相平行的
- 平行光的一个范例就是太阳光
- 被平行光照亮的物体的整个区域接收到的光强是一样的
案例
结果
代码
var scene;
function initScene() {
scene = new THREE.Scene();
}
var camera;
function initCamera(){
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-80,80,80);
camera.lookAt(scene.position);
scene.add(camera);
}
var renderer;
function initRenderer(){
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
var sphereLightMesh;
var axes,cube,plane,sphere;
function initModel(){
axes = new THREE.AxesHelper(40);
var planeGeometry = new THREE.PlaneGeometry(600,200,120,120);
var planeMaterial = new THREE.MeshLambertMaterial({
color:0xAAAAAA,
});
plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.set(5,0,0);
plane.receiveShadow = true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-16,3,0);
cube.castShadow = true;
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4,20,20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
})
sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(20,4,0);
sphere.castShadow = true;
scene.add(sphere);
var sphereLight = new THREE.SphereGeometry(0.2);
var sphereLightMaterial = new THREE.MeshBasicMaterial({
color: 0xac6c25
});
sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
sphereLightMesh.position = new THREE.Vector3(3, 0, 5);
scene.add(sphereLightMesh);
}
var stats;
function initStats() {
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.dom);
}
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.enableZoom = true;
controls.autoRotate = true;
controls.minDistance = 1;
controls.maxDistance = 200;
controls.enablePan = true;
}
function windowOnchange(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var ambientLight,pointLight;
var shadowDebug,pp,target;
function initLight(){
ambientLight = new THREE.AmbientLight("#1c1c1c");
scene.add(ambientLight);
directionalLight = new THREE.DirectionalLight("#ccffcc");
directionalLight.castShadow = true;
directionalLight.shadow.camera.near = 2;
directionalLight.shadow.camera.far = 80;
directionalLight.shadow.camera.left = -30;
directionalLight.shadow.camera.right = 30;
directionalLight.shadow.camera.top = 30;
directionalLight.shadow.camera.bottom = -30;
scene.add(directionalLight);
target = new THREE.Object3D();
target.position = new THREE.Vector3(5,0,0);
shadowDebug = new THREE.CameraHelper(directionalLight.shadow.camera)
}
var gui,Drl;
var step = 0
function initGui1(){
Drl = new function(){
this.rotationSpeed = 0.03;
this.bouncingSpeed = 0.03
this.ambientColor = ambientLight.color.getStyle();
this.directionColor = directionalLight.color.getStyle();
this.intensity = directionalLight.intensity;
this.debug = false;
this.castShadow = true;
this.onlyShadow = false;
this.target = plane;
this.stopMovingLight = false;
};
gui = new dat.GUI();
gui.addColor(Drl,'ambientColor').onChange(function (e) {
ambientLight.color = new THREE.Color(Drl.ambientColor);
});
gui.addColor(Drl,'directionColor').onChange(function (e) {
directionalLight.color = new THREE.Color(Drl.directionColor);
});
gui.add(Drl,'intensity',0,3,0.1).onChange(function (e){
directionalLight.intensity = e;
});
gui.add(Drl,'debug').onChange(function (e){
if(e){
scene.add(shadowDebug);
}
else{
scene.remove(shadowDebug);
}
});
gui.add(Drl,'castShadow').onChange(function (e) {
directionalLight.castShadow = e;
});
gui.add(Drl,'onlyShadow').onChange(function (e) {
directionalLight.onlyShadow = e;
});
gui.add(Drl,'target',['plane','cube','sphere']).onChange(function (e) {
switch (e){
case "plane":
directionalLight.target = plane;
break;
case "cube":
directionalLight.target = cube;
break;
case "sphere":
directionalLight.target = sphere;
break;
}
})
}
function render(){
renderer.render(scene,camera);
}
var invert =1;
var phase = 0;
function animate(){
stats.update();
cube.rotation.x += Drl.rotationSpeed;
cube.rotation.y += Drl.rotationSpeed;
cube.rotation.z += Drl.rotationSpeed;
step += Drl.bouncingSpeed;
sphere.position.x = 10+(10*(Math.cos(step)));
sphere.position.y = 2+(10*(Math.abs(Math.sin(step))));
directionalLight.position.copy(sphereLightMesh.position);
sphereLightMesh.position.z = -8;
sphereLightMesh.position.y = +(27 * (Math.sin(step / 3)));
sphereLightMesh.position.x = 10 + (26 * (Math.cos(step / 3)));
render();
requestAnimationFrame(animate);
}
function draw(){
initScene();
initCamera();
initRenderer();
initStats();
initControls();
initModel();
initLight();
initGui1();
animate();
window.onresize = windowOnchange;
}
THREE.HemisphereLight
描述
- 可以创建出更贴近自然的户外光照效果
- 创建一个半球光光源
var hemisphereLight = new THREE.HemisphereLight(0xffffff,0x00ff00,0.6);
hemisphereLight.position.set(0,500,0);
scene.add(hemisphereLight);
属性
属性 | 描述 |
---|
groundColor | 从地面发出的光线的颜色 |
color | 从天空发出的光线的颜色 |
intensity | 光线照射的强度 |
案例
结果
代码
var scene;
function initScene() {
scene = new THREE.Scene();
}
var camera;
function initCamera(){
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-80,80,80);
camera.lookAt(scene.position);
scene.add(camera);
}
var renderer;
function initRenderer(){
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
var sphereLightMesh;
var axes,cube,plane,sphere;
function initModel(){
axes = new THREE.AxesHelper(40);
var planeGeometry = new THREE.PlaneGeometry(600,200,120,120);
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0x00ff00,
});
plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.set(5,0,0);
plane.receiveShadow = true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-16,3,0);
cube.castShadow = true;
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4,20,20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
})
sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(20,4,0);
sphere.castShadow = true;
scene.add(sphere);
var sphereLight = new THREE.SphereGeometry(0.2);
var sphereLightMaterial = new THREE.MeshBasicMaterial({
color: 0xac6c25
});
sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
sphereLightMesh.position = new THREE.Vector3(3, 0, 5);
scene.add(sphereLightMesh);
}
var stats;
function initStats() {
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.dom);
}
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.enableZoom = true;
controls.autoRotate = true;
controls.minDistance = 1;
controls.maxDistance = 200;
controls.enablePan = true;
}
function windowOnchange(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var ambientLight,hemisphereLight;
var shadowDebug,pp,target;
function initLight(){
var spotLight0 = new THREE.SpotLight(0xcccccc);
spotLight0.position.set(-40, 60, -10);
spotLight0.lookAt(plane);
spotLight0.penumbra = 1;
scene.add(spotLight0);
hemisphereLight = new THREE.HemisphereLight(0x0000ff,0x00ff00,0.6);
hemisphereLight.position.set(0,500,0);
scene.add(hemisphereLight);
var dirLight = new THREE.DirectionalLight("#ffffff");
dirLight.position.set(30, 10, -50);
dirLight.castShadow = true;
dirLight.target = plane;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 200;
dirLight.shadow.camera.left = -50;
dirLight.shadow.camera.right = 50;
dirLight.shadow.camera.top = 50;
dirLight.shadow.camera.bottom = -50;
dirLight.shadow.mapSize.width = 2048;
dirLight.shadow.mapSize.height = 2048;
scene.add(dirLight);
target = new THREE.Object3D();
target.position = new THREE.Vector3(5,0,0);
}
var gui,Hml;
var step = 0
function initGui1(){
Hml = new function(){
this.rotationSpeed = 0.03;
this.bouncingSpeed = 0.03
this.hemisphere = true;
this.groundColor = hemisphereLight.groundColor.getStyle();
this.color = hemisphereLight.color.getStyle();
this.intensity = hemisphereLight.intensity;
};
gui = new dat.GUI();
gui.add(Hml,'hemisphere').onChange(function (e){
if(e){
scene.add(hemisphereLight);
}
else{
scene.remove(hemisphereLight);
}
});
gui.addColor(Hml,'groundColor').onChange(function (e){
hemisphereLight.groundColor = new THREE.Color(e);
});
gui.addColor(Hml,'color').onChange(function (e){
hemisphereLight.color = new THREE.Color(e);
});
gui.add(Hml,'intensity',0,5,0.01).onChange(function (e){
hemisphereLight.intensity = e;
});
}
function render(){
renderer.render(scene,camera);
}
var invert =1;
var phase = 0;
function animate(){
stats.update();
cube.rotation.x += Hml.rotationSpeed;
cube.rotation.y += Hml.rotationSpeed;
cube.rotation.z += Hml.rotationSpeed;
step += Hml.bouncingSpeed;
sphere.position.x = 10+(10*(Math.cos(step)));
sphere.position.y = 2+(10*(Math.abs(Math.sin(step))));
render();
requestAnimationFrame(animate);
}
function draw(){
initScene();
initCamera();
initRenderer();
initStats();
initControls();
initModel();
initLight();
initGui1();
animate();
window.onresize = windowOnchange;
}
THREE.AreaLight
描述
- 使用THREE.AreaLight光源,可以定义一个长方形的发光区域
- 使用THREE.AreaLight光源,需要现在HTML中导入库RectAreaLightUniformsLib.js
- 添加THREE.AreaLight光源
var areaLight = new THREE.AreaLight(0xffffff,500,4,10);
areaLight.position.set(0,20,30);
scene.add(areaLight);
- 在创建THREE.AreaLight光源时,创建出一个垂直平面
- 不能看到光源本身,只能看到光源发射出的光,而且只有当光照射到某个物体上时才能看见。可以在光源位置增加平面对象来模拟光线照射区域。
案例
结果
代码
var scene;
function initScene() {
scene = new THREE.Scene();
}
var camera;
function initCamera() {
camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,1000);
camera.position.set(-50,30,50);
camera.lookAt(new THREE.Vector3(0,0,0));
scene.add(camera);
}
var renderer;
function initRenderer() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
var stats;
function initStats(){
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.domElement);
}
var axes,plane,plane1,plane2,plane3;
function initModels(){
axes = new THREE.AxesHelper(50);
var planeGeometry = new THREE.PlaneGeometry(70,70,1,1);
var planeMaterial = new THREE.MeshStandardMaterial({
});
plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.set(0,0,0);
scene.add(plane);
var plane1Geometry = new THREE.BoxGeometry(4,10,0);
var plane1Material = new THREE.MeshBasicMaterial({
color:0xff0000,
});
plane1 = new THREE.Mesh(plane1Geometry,plane1Material);
plane1.position.copy(areaLight1.position);
scene.add(plane1);
var plane2Geometry = new THREE.BoxGeometry(4,10,0);
var plane2Material = new THREE.MeshBasicMaterial({
color:0x00ff00,
});
plane2 = new THREE.Mesh(plane2Geometry,plane2Material);
plane2.position.copy(areaLight2.position);
scene.add(plane2);
var plane3Geometry = new THREE.BoxGeometry(4,10,0);
var plane3Material = new THREE.MeshBasicMaterial({
color:0x0000ff,
});
plane3 = new THREE.Mesh(plane3Geometry,plane3Material);
plane3.position.copy(areaLight3.position);
scene.add(plane3);
}
var areaLight1,areaLight2,areaLight3;
function initLight(){
var spotLight0 = new THREE.SpotLight(0xcccccc);
spotLight0.position.set(-40, 60, -10);
spotLight0.intensity = 0.1;
areaLight1 = new THREE.RectAreaLight(0xff0000, 500, 4, 10);
areaLight1.position.set(-10, 10, -35);
scene.add(areaLight1);
areaLight2 = new THREE.RectAreaLight(0x00ff00, 500, 4, 10);
areaLight2.position.set(0, 10, -35);
scene.add(areaLight2);
areaLight3 = new THREE.RectAreaLight(0x0000ff, 500, 4, 10);
areaLight3.position.set(10, 10, -35);
scene.add(areaLight3);
}
var controls;
function initControls() {
controls = new THREE.OrbitControls(camera);
}
function render(){
renderer.render(scene,camera);
}
var clock = new THREE.Clock();
function animate(){
render();
stats.update();
controls.update(clock.getDelta());
requestAnimationFrame(animate);
}
function windowOnresize(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
function draw(){
initScene();
initCamera();
initRenderer();
initStats();
initLight();
initModels();
initControls();
animate();
window.onresize = windowOnresize;
}
镜头光晕(Lens Flare)
描述
- 对于游戏和三维图像来说,可以更具真实感
- THREE.LensFlare对象接受如下参数
flare = new THREE.LensFlare(texture,size,distance,blending,color,opacity);
参数 | 描述 |
---|
texture(纹理) | 纹理——图片,用来决定光晕的形状 |
size(尺寸 | 可以指定光晕大小,单位是像素。如果设置为-1,将使用纹理本身的大小 |
distance(距离) | 从光源(0)到摄像机(1)的距离。使用这个参数将镜头光晕放置正确的位置 |
blending(混合) | 可以为光晕提供多种材质,混合模式决定了它们如何混合在一起。默认混合方式是THREE.AdditiveBlending |
color(颜色) | 光晕的颜色 |
opacity(不透明度) | 定义光晕的不透明度,0完全透明,1完全不透明 |
创建
var textureFlare0 = THREE.ImageUtils.loadTexture("../../..");
var flareColor = new THREE.Color(0xffffff);
var lensFlare = new THREE.LensFlare(textureFlare0,350,0.0,THREE.AdditiveBlending,flareColor);
lensFlare.position.copy(spotLight.position);
scene.add(lensFlare);
var textureFlare3 = THREE.ImageUtils.loadTexture("../../..");
lensFlare.add(textureFlare3,60,0.6,THREE.AdditiveBlending);
案例
结果
代码
function draw(){
var stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-20,10,45);
camera.lookAt(new THREE.Vector3(0,0,0));
scene.add(camera);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
document.getElementById("webgl-output").appendChild(renderer.domElement);
var textureGrass = new THREE.TextureLoader().load("../assets/textures/ground/grasslight-big.jpg");
textureGrass.wrapS = THREE.RepeatWrapping;
textureGrass.wrapT = THREE.RepeatWrapping;
textureGrass.repeat.set(10,10);
var planeGeometry = new THREE.PlaneGeometry(1000,1000,20,20);
var planeMaterial = new THREE.MeshLambertMaterial({
map:textureGrass,
});
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.castShadow = true;
plane.position.set(15,0,0);
plane.rotation.x = -0.5*Math.PI;
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.set(-4,3,0);
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4,25,25);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.castShadow = true;
sphere.position.set(10,5,10);
scene.add(sphere);
var ambientLight = new THREE.AmbientLight("#1c1c1c");
scene.add(ambientLight);
var sportLight0 = new THREE.SpotLight(0xcccccc);
sportLight0.position.set(-40,60,-10);
sportLight0.lookAt(plane);
scene.add(sportLight0);
var target = new THREE.Object3D();
target.position = new THREE.Vector3(5,0,0);
var spotLight = new THREE.DirectionalLight("#ffffff");
spotLight.position.set(30,10,-50);
spotLight.castShadow = true;
spotLight.shadowCameraNear = 0.1;
spotLight.shadowCameraFar = 100;
spotLight.shadowCameraFov = 50;
spotLight.target = plane;
spotLight.distance = 0;
spotLight.shadowCameraNear = 2;
spotLight.shadowCameraFar = 200;
spotLight.shadowCameraLeft = -100;
spotLight.shadowCameraRight = 100;
spotLight.shadowCameraTop = 100;
spotLight.shadowCameraBottom = -100;
spotLight.shadowMapWidth = 2048;
spotLight.shadowMapHeight = 2048;
scene.add(spotLight);
var textureFlare0 = new THREE.ImageUtils.loadTexture("js/lensflare0.png");
var flareColor = new THREE.Color(0xffaacc);
var lensFlare = new THREE.Lensflare();
lensFlare.addElement(new THREE.LensflareElement(textureFlare0,350,0.0,flareColor));
spotLight.add(lensFlare);
var controls = new function (){
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
this.ambientColor = "#1c1c1c";
this.pointColor = "#ffffff";
this.intensity = 0.1;
}
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,'intensity',0,5,0.01).onChange(function(e){
spotLight.intensity = e;
});
var orbitControls = new THREE.OrbitControls(camera,renderer.domElement);
orbitControls.enableZoom = true;
render();
var step = 0;
var clock = new THREE.Clock();
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)));
requestAnimationFrame(render);
renderer.render(scene, camera);
}
}