WebGL入門(mén)demo

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ō)了。先看地球:

GIF1.gif

怎么畫(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)步吧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本文主要是講解 Three.js 的相關(guān)概念,幫助大家對(duì) Three.js 以及相關(guān)知識(shí)形成比較完整的理解。今年來(lái)...
    Simon王小白閱讀 8,500評(píng)論 2 9
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,242評(píng)論 25 708
  • 人其實(shí)挺奇怪的,有的時(shí)候明明不喜歡做一件事但是卻也礙于情面勉強(qiáng)做了,心中抱怨著,嘴里卻說(shuō)“沒(méi)關(guān)系啊不客氣啊咱倆啥關(guān)...
    溯沼滄滄閱讀 207評(píng)論 0 0
  • 我知道我快死了,就在不久后的某天,也許就在今晚,我的牙齒很脆,我的皮膚也是脆的,我的胃從未有過(guò)的舒服,還有,我嘎嘣...
    碧落_7113閱讀 363評(píng)論 0 2