利用Three.js如何實現陰影效果實例代碼
前言
眾所周知作為webgl的插件,three.js肯定沒有原生webgl那樣,添加一個陰影這么費勁。所以,經過一小時的研究(笨人不聰明,已經是極限速度了)。終于將陰影效果做了出來,并且還發(fā)現一些容易犯錯的地方。話不多說了,來一起看看詳細的介紹吧。
先上效果圖:

實現這個效果其實很簡單,只需要設置幾個屬性就可以實現當前的效果。而上面的材質問題我將放到下一節(jié):
(1)首先需要告訴渲染器我需要陰影,你給我生成陰影:
renderer.shadowMap.enabled = true;
(2)然后告訴燈光,我需要陰影:
light.castShadow = true;
(3)告訴模型哪些需要投射陰影:
//告訴球需要投射陰影 sphere.castShadow = true; //告訴立方體需要投射陰影 cube.castShadow = true;
(4)最后告訴最底下的平面長方形你要接受陰影:
plane.receiveShadow = true;
上面四步只要設置好了,就可以實現陰影的效果了。
注意事項:你的模型的材質一定要選擇對燈光有反應的材質,要不然不會出現效果,就是因為這個問題導致好長時間沒有整出來陰影。
案例全部代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
html, body {
margin: 0;
height: 100%;
}
canvas {
display: block;
}
</style>
</head>
<body onload="draw();">
</body>
<script src="build/three.js"></script>
<script src="examples/js/controls/TrackballControls.js"></script>
<script src="examples/js/libs/stats.min.js"></script>
<script>
var renderer;
function initRender() {
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
//告訴渲染器需要陰影效果
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默認的是,沒有設置的這個清晰 THREE.PCFShadowMap
document.body.appendChild(renderer.domElement);
}
var camera;
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0, 40, 100);
camera.lookAt(new THREE.Vector3(0,0,0));
}
var scene;
function initScene() {
scene = new THREE.Scene();
}
var light;
function initLight() {
scene.add(new THREE.AmbientLight(0x444444));
light = new THREE.SpotLight(0xffffff);
light.position.set(60,30,0);
//告訴平行光需要開啟陰影投射
light.castShadow = true;
scene.add(light);
}
function initModel() {
//上面的球
var sphereGeometry = new THREE.SphereGeometry(5,20,20);
var sphereMaterial = new THREE.MeshStandardMaterial({color:0x7777ff});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.y = 5;
//告訴球需要投射陰影
sphere.castShadow = true;
scene.add(sphere);
//輔助工具
var helper = new THREE.AxisHelper(10);
scene.add(helper);
//立方體
var cubeGeometry = new THREE.CubeGeometry(10,10,8);
var cubeMaterial = new THREE.MeshLambertMaterial({color:0x00ffff});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 25;
cube.position.y = 5;
cube.position.z = -5;
//告訴立方體需要投射陰影
cube.castShadow = true;
scene.add(cube);
//底部平面
var planeGeometry = new THREE.PlaneGeometry(100,100);
var planeMaterial = new THREE.MeshStandardMaterial({color:0xaaaaaa});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = - 0.5 * Math.PI;
plane.position.y = -0;
//告訴底部平面需要接收陰影
plane.receiveShadow = true;
scene.add(plane);
}
//初始化性能插件
var stats;
function initStats() {
stats = new Stats();
document.body.appendChild(stats.dom);
}
//用戶交互插件 鼠標左鍵按住旋轉,右鍵按住平移,滾輪縮放
var controls;
function initControls() {
controls = new THREE.TrackballControls( camera );
//旋轉速度
controls.rotateSpeed = 5;
//變焦速度
controls.zoomSpeed = 3;
//平移速度
controls.panSpeed = 0.8;
//是否不變焦
controls.noZoom = false;
//是否不平移
controls.noPan = false;
//是否開啟移動慣性
controls.staticMoving = false;
//動態(tài)阻尼系數 就是靈敏度
controls.dynamicDampingFactor = 0.3;
//未知,占時先保留
//controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
}
function render() {
renderer.render( scene, camera );
}
//窗口變動觸發(fā)的函數
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
controls.handleResize();
render();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
//更新控制器
render();
//更新性能插件
stats.update();
controls.update();
requestAnimationFrame(animate);
}
function draw() {
initRender();
initScene();
initCamera();
initLight();
initModel();
initControls();
initStats();
animate();
window.onresize = onWindowResize;
}
</script>
</html>
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者使用Three.js具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
JavaScript面向對象知識串結(讀JavaScript高級程序設計(第三版))
最近在看JavaScript高級程序設計(第三版),面向對象一章20多頁,來來回回看了三五遍,每次看的收獲都不一樣2012-07-07

