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

實(shí)現(xiàn)這個(gè)效果其實(shí)很簡(jiǎn)單,只需要設(shè)置幾個(gè)屬性就可以實(shí)現(xiàn)當(dāng)前的效果。而上面的材質(zhì)問(wèn)題我將放到下一節(jié):
(1)首先需要告訴渲染器我需要陰影,你給我生成陰影:
renderer.shadowMap.enabled = true;
(2)然后告訴燈光,我需要陰影:
light.castShadow = true;
(3)告訴模型哪些需要投射陰影:
//告訴球需要投射陰影 sphere.castShadow = true; //告訴立方體需要投射陰影 cube.castShadow = true;
(4)最后告訴最底下的平面長(zhǎng)方形你要接受陰影:
plane.receiveShadow = true;
上面四步只要設(shè)置好了,就可以實(shí)現(xiàn)陰影的效果了。
注意事項(xiàng):你的模型的材質(zhì)一定要選擇對(duì)燈光有反應(yīng)的材質(zhì),要不然不會(huì)出現(xiàn)效果,就是因?yàn)檫@個(gè)問(wèn)題導(dǎo)致好長(zhǎng)時(shí)間沒(méi)有整出來(lái)陰影。
案例全部代碼:
<!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; // 默認(rèn)的是,沒(méi)有設(shè)置的這個(gè)清晰 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);
//告訴平行光需要開(kāi)啟陰影投射
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);
}
//用戶交互插件 鼠標(biāo)左鍵按住旋轉(zhuǎn),右鍵按住平移,滾輪縮放
var controls;
function initControls() {
controls = new THREE.TrackballControls( camera );
//旋轉(zhuǎn)速度
controls.rotateSpeed = 5;
//變焦速度
controls.zoomSpeed = 3;
//平移速度
controls.panSpeed = 0.8;
//是否不變焦
controls.noZoom = false;
//是否不平移
controls.noPan = false;
//是否開(kāi)啟移動(dòng)慣性
controls.staticMoving = false;
//動(dòng)態(tài)阻尼系數(shù) 就是靈敏度
controls.dynamicDampingFactor = 0.3;
//未知,占時(shí)先保留
//controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
}
function render() {
renderer.render( scene, camera );
}
//窗口變動(dòng)觸發(fā)的函數(shù)
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>
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)或者使用Three.js具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- JSP實(shí)現(xiàn)彈出登陸框以及陰影效果
- WebGL three.js學(xué)習(xí)筆記之陰影與實(shí)現(xiàn)物體的動(dòng)畫(huà)效果
- js當(dāng)前頁(yè)面登錄注冊(cè)框,固定div,底層陰影的實(shí)例代碼
- JS當(dāng)前頁(yè)面登錄注冊(cè)框,固定DIV,底層陰影的實(shí)例代碼
- js 實(shí)現(xiàn)無(wú)干擾陰影效果 簡(jiǎn)單好用(附文件下載)
- Div+Js實(shí)現(xiàn)的帶陰影菜單 微軟以前網(wǎng)站曾用過(guò)
- 用JS實(shí)現(xiàn)網(wǎng)頁(yè)元素陰影效果的研究總結(jié)
- JavaScript canvas實(shí)現(xiàn)帶有陰影的圖形和文字
相關(guān)文章
JavaScript實(shí)現(xiàn)飛舞的泡泡效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)飛舞的泡泡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
JS使用正則表達(dá)式除去字符串中重復(fù)字符的方法
這篇文章主要介紹了JS使用正則表達(dá)式除去字符串中重復(fù)字符的方法,以一個(gè)簡(jiǎn)單實(shí)例分析了JavaScript中正則過(guò)濾的相關(guān)使用技巧,需要的朋友可以參考下2015-11-11
Javascript動(dòng)畫(huà)的實(shí)現(xiàn)原理淺析
這篇文章主要介紹了Javascript動(dòng)畫(huà)的實(shí)現(xiàn)原理淺析,本文用兩個(gè)實(shí)例來(lái)解釋Javascript動(dòng)畫(huà)的實(shí)現(xiàn)原理,需要的朋友可以參考下2015-03-03
JavaScript canvas實(shí)現(xiàn)七彩時(shí)鐘效果
這篇文章主要為大家詳細(xì)介紹了JavaScript canvas實(shí)現(xiàn)七彩時(shí)鐘效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
JavaScript?split()方法定義及更多實(shí)例
這篇文章主要給大家介紹了關(guān)于JavaScript?split()方法定義及更多實(shí)例的相關(guān)資料,js里的split()方法大家都知道用于將字符串轉(zhuǎn)化為字符串?dāng)?shù)組,文中通過(guò)代碼實(shí)例介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03
JS簡(jiǎn)單循環(huán)遍歷json數(shù)組的方法
這篇文章主要介紹了JS簡(jiǎn)單循環(huán)遍歷json數(shù)組的方法,結(jié)合實(shí)例形式簡(jiǎn)單分析了JavaScript循環(huán)遍歷json數(shù)組的方法,并提供了jQuery遍歷json的方法,需要的朋友可以參考下2016-04-04
JavaScript面向?qū)ο笾R(shí)串結(jié)(讀JavaScript高級(jí)程序設(shè)計(jì)(第三版))
最近在看JavaScript高級(jí)程序設(shè)計(jì)(第三版),面向?qū)ο笠徽?0多頁(yè),來(lái)來(lái)回回看了三五遍,每次看的收獲都不一樣2012-07-07

