WebGL入門(mén)demo
three.js入門(mén)
開(kāi)場(chǎng)白
哇哦,繪制氣球耶,在網(wǎng)頁(yè)上?對(duì)啊!厲害了!3D效果圖也能在網(wǎng)頁(yè)上繪制出來(lái)啊,這么好玩的事情,趕緊來(lái)看看!
這里是屬于WebGL的應(yīng)用,webGL可以讓我們?cè)赾anvas上實(shí)現(xiàn)3D效果。而three.js是一款webGL框架,由于其易用性被廣泛應(yīng)用。如果要學(xué)習(xí)webGL,拋棄那些復(fù)雜的原生接口從這款框架入手是一個(gè)不錯(cuò)的選擇。跟著我一起走!
??:three.js參考文檔 英文
??:three.js參考文檔 中文
看地球咯!
哈哈,別說(shuō)了。先看地球:
怎么畫(huà)?
首先要理清邏輯。three.js框架是個(gè)法寶,要畫(huà)東西的工具,模塊,材料等等里面都有,找到API去用。所以,我們只需要:
- 一張圖片,也就是包裹地球身體的那張圖片,
- 一個(gè)球模型,
- 把圖片貼到球模型上去,地球就出來(lái)了,
- 再給球加上一些動(dòng)畫(huà)效果,完工!
開(kāi)始畫(huà)!
上面講完了畫(huà)的大致流程,現(xiàn)在要開(kāi)始畫(huà)了。但是你還需要知道,不止這么簡(jiǎn)單!遠(yuǎn)不止這么簡(jiǎn)單!你需要:
1.設(shè)置three.js渲染器-renderer
2.設(shè)置攝像機(jī)camera
3.設(shè)置場(chǎng)景scene br>
4.設(shè)置物體object-地球
5.設(shè)置組織者
是不是一臉懵逼?別怕,來(lái)講個(gè)故事??
其實(shí),就是拍電影啦。需要相機(jī),演員(這里是地球),場(chǎng)景(scene),導(dǎo)演(group)。導(dǎo)演組織這些活動(dòng),導(dǎo)演也要看場(chǎng)景的,他受場(chǎng)景的約束,演員也要聽(tīng)導(dǎo)演的。最后拍好了戲交給渲染器(renderer)來(lái)制片,發(fā)布。
好吧,這么形象估計(jì)懂了,來(lái),我們具體來(lái)講講。
一步步畫(huà):
每個(gè)元素都是再定義了之后,在初始化函數(shù)內(nèi)部執(zhí)行。
做準(zhǔn)備:
用到three.js框架,要先引入以下:
<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/renderers/Projector.js"></script>
<script src="https://threejs.org/examples/js/renderers/CanvasRenderer.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
畫(huà)地球:
看代碼:
// 加載材質(zhì)
var loader = new THREE.TextureLoader();
loader.load('https://threejs.org/examples/textures/land_ocean_ice_cloud_2048.jpg',
function(texture) {
//畫(huà)球體 形狀
var geometry = new THREE.SphereGeometry(200, 20, 20);
// 貼圖 材質(zhì)紋理
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: 0.5
})
// 地球
var mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
}
畫(huà)地球需要地球外面那張圖片,還需要球模型geometry。圖片需要裁剪之后變成material。再用這兩個(gè)元素來(lái)new地球mesh,把地球交給group.
設(shè)置場(chǎng)景:
var scene;
scene = new THREE.Scene();
scene.add(group);
設(shè)置分組(導(dǎo)演):
var group;
group = new THREE.Group();
設(shè)置相機(jī):
var camera;
// 準(zhǔn)備好鏡頭
camera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight,1,2000);//相機(jī)擺上 設(shè)置相機(jī)擺放位置 產(chǎn)生鏡頭
camera.position.z = 500;//拍的景物離我500px
先設(shè)置一下相機(jī),把他放到里面去。
設(shè)置渲染器:
var renderer;
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0xffffff);//設(shè)置canvas背景顏色
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);//container展示的大小
container.appendChild(renderer.domElement)//追加 【canvas】 元素到 【container】 元素中
stats = new Stats();
container.appendChild(stats.dom);
先設(shè)置一下渲染器,設(shè)置在畫(huà)布上面顯示的屬性,再把畫(huà)布添加到瀏覽器頁(yè)面上面去。還有在動(dòng)畫(huà)過(guò)程中的循環(huán)渲染在下面講解。
加動(dòng)畫(huà)啦!
var container,stas;
var mouseX=0,mouseY=0;
var windowHalfX=window.innerWidth/2;
var windowHalfY=window.innerHeight/2;
animate();
document.addEventListener('mousemove', onDocumentMouseMove, false);//用鼠標(biāo)拖
window.addEventListener('resize',onWindowResize,false);
function onDocumentMouseMove (event) {
mouseX = event.clientX - windowHalfX;//鼠標(biāo)基于中心點(diǎn)的偏移量;
mouseY = event.clientY - windowHalfY;//鼠標(biāo)基于中心點(diǎn)的偏移量;
}
function onWindowResize (event) {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
function animate () {
// 每秒60針遞歸調(diào)用 使地球旋轉(zhuǎn)
requestAnimationFrame(animate);
render();
stats.update();
}
function render () {
camera.position.x
+= (mouseX-camera.position.x)*0.05;//在x軸上,相機(jī)根據(jù)鼠標(biāo)的位置移動(dòng)來(lái)移動(dòng)的距離
camera.position.y
+= (-mouseY - camera.position.y)*0.05;//在y軸上,相機(jī)根據(jù)鼠標(biāo)的位置移動(dòng)來(lái)移動(dòng)的距離
camera.lookAt(scene.position);//設(shè)置視野的中心坐標(biāo)
group.rotation.y -= 0.005;//讓它饒著y軸旋轉(zhuǎn) (間接的得到旋轉(zhuǎn)的速度)
renderer.render(scene, camera);//將webgl視圖往外輸出
}
設(shè)置在鼠標(biāo)動(dòng)的時(shí)候監(jiān)聽(tīng)到,而且此時(shí)camera隨即改變而改變。camera要改變根據(jù)鼠標(biāo)的移動(dòng)來(lái)移動(dòng)它的距離在函數(shù)onDocumentMouseMove中得到,而且地球要有一種遠(yuǎn)小近大的感覺(jué)。隨著鼠標(biāo)移動(dòng),camera變化,地球的大小也在改變,也就是前面說(shuō)的遠(yuǎn)小近大的感覺(jué)。在函數(shù)onWindowResize中實(shí)現(xiàn)。然后地球要?jiǎng)赢?huà)起來(lái)要調(diào)用animate函數(shù),每秒60針遞歸調(diào)用 使地球旋轉(zhuǎn),然后render函數(shù)就一直在不停的循環(huán)。狀態(tài)也在不停的更新。
小結(jié):
WebGL是是一種3D繪圖標(biāo)準(zhǔn),這種繪圖技術(shù)里面用了JavaScript,所以會(huì)JavaScript,走遍天下都不怕啊??
??:源碼
思考好邏輯,就可以動(dòng)手的!好玩就要去嘗試,就在慢慢成長(zhǎng)。大家共同進(jìn)步吧!