1. 程式人生 > >[webGL學習]基於three.js構建WebGL例項第三講

[webGL學習]基於three.js構建WebGL例項第三講

這裡寫圖片描述這裡寫圖片描述

大多程式設計師在剛開始理解3D(webGL)的知識時,通常對三維空間可能理解的比較困難,你也可能有困難理解不同的光線是如何工作的,或軸甚至如何位於空間。

今天,我會幫你處理這些問題。three.js所擁有一切必要的手段來為這個 - 幫手。在今天的例子中,我已經準備好為你工作的所有現有傭工示範:ArrowHelper,AxisHelper,BoundingBoxHelper,CameraHelper,DirectionalLightHelper,GridHelper,HemisphereLightHelper,PointLightHelper,SpotLightHelper。所有這些將有助於你理解的WebGL的內部工作原理。

HTML

這部分沒有變,跟之前的一樣.

<!DOCTYPE html>
<html lang="en" >
    <head>
        <meta charset="utf-8" />
        <meta name="author" content="Script Tutorials" />
        <title>WebGL With Three.js - Lesson 2 | Script Tutorials</title>
        <meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="css/main.css" rel="stylesheet" type="text/css" /> </head> <body> <script src="js/three.min.js"></script> <script src="js/THREEx.WindowResize.js"
>
</script> <script src="js/OrbitControls.js"></script> <script src="js/stats.min.js"></script> <script src="js/script.js"></script> <div style="position: absolute; top: 10px; left: 20px; text-align: center;"></div> <!-- Only used for Script Tutorial's Demo site. Please ignore and remove. --> <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> <script src="http://www.script-tutorials.com/assets/ads.js" async></script> </body> </html>

Javascript程式碼

首先,讓我們來建立一些簡單的場景,包括以下內容:攝像頭,光線直射,地面和兩個領域:


var dLight, bboxHelper, dlightHelper;

// load texture
var texture = THREE.ImageUtils.loadTexture('texture.png');
texture.repeat.set(10, 10);
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.anisotropy = 16;
texture.needsUpdate = true;

var textureBump = THREE.ImageUtils.loadTexture('bump.png');
textureBump.repeat.set(10, 10);
textureBump.wrapS = textureBump.wrapT = THREE.RepeatWrapping;
textureBump.anisotropy = 16;
textureBump.needsUpdate = true;

var lesson3 = {
    scene: null,
    camera: null,
    renderer: null,
    container: null,
    controls: null,
    clock: null,
    stats: null,

    init: function() { // Initialization

        // create main scene
        this.scene = new THREE.Scene();

        var SCREEN_WIDTH = window.innerWidth,
            SCREEN_HEIGHT = window.innerHeight;

        // prepare camera
        var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 10000;
        this.camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
        this.scene.add(this.camera);
        this.camera.position.set(-1600, 600, 1200);
        this.camera.lookAt(new THREE.Vector3(0,0,0));

        // prepare renderer
        this.renderer = new THREE.WebGLRenderer({antialias:true, alpha: false});
        this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
        this.renderer.setClearColor(0xffffff);

        this.renderer.shadowMapEnabled = true;
        this.renderer.shadowMapSoft = true;

        // prepare container
        this.container = document.createElement('div');
        document.body.appendChild(this.container);
        this.container.appendChild(this.renderer.domElement);

        // events
        THREEx.WindowResize(this.renderer, this.camera);

        // prepare controls (OrbitControls)
        this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
        this.controls.target = new THREE.Vector3(0, 0, 0);

        // prepare clock
        this.clock = new THREE.Clock();

        // prepare stats
        this.stats = new Stats();
        this.stats.domElement.style.position = 'absolute';
        this.stats.domElement.style.bottom = '0px';
        this.stats.domElement.style.zIndex = 10;
        this.container.appendChild( this.stats.domElement );

        // add directional light
        dLight = new THREE.DirectionalLight(0xffffff);
        dLight.position.set(0, 400, 0);
        dLight.castShadow = true;
        // dLight.shadowCameraVisible = true;
        dLight.shadowMapWidth = dLight.shadowMapHeight = 1000;
        this.scene.add(dLight);

        // add simple ground
        var groundGeometry = new THREE.PlaneGeometry(1200, 1200, 1, 1);
        ground = new THREE.Mesh(groundGeometry, new THREE.MeshLambertMaterial({
            color: 0x9669FE
        }));
        ground.position.y = -20;
        ground.rotation.x = - Math.PI / 2;
        ground.receiveShadow = true;
        this.scene.add(ground);

        // create a new group (Object3D)
        var group = new THREE.Object3D();

        // add two spheres
        var sphere  = this.drawSphere(-100, 150, new THREE.MeshPhongMaterial({ map: texture, bumpMap: textureBump, color: 0x00ff00, specular: 0xff2200, emissive: 0x004000 }));
        var sphere2 = this.drawSphere( 100, 150, new THREE.MeshPhongMaterial({ map: texture, bumpMap: textureBump, color: 0x00ff00, specular: 0xff2200, shininess: 3 }));

        // and add them into the group
        group.add(sphere);
        group.add(sphere2);

        this.scene.add(group);

        // add helpers:

        // 1. ArrowHelper
        var directionV3 = new THREE.Vector3(1, 0, 1);
        var originV3 = new THREE.Vector3(0, 200, 0);
        var arrowHelper = new THREE.ArrowHelper(directionV3, originV3, 100, 0xff0000, 20, 10); // 100 is length, 20 and 10 are head length and width
        this.scene.add(arrowHelper);

        // 2. AxisHelper
        var axisHelper = new THREE.AxisHelper(800); // 500 is size
        this.scene.add(axisHelper);

        // 3. BoundingBoxHelper
        bboxHelper = new THREE.BoundingBoxHelper(group, 0x999999);
        this.scene.add(bboxHelper);

        // 4. CameraHelper
        var cameraParObj = new THREE.Object3D();
        cameraParObj.position.y = 200;
        cameraParObj.position.z = 700;
        this.scene.add(cameraParObj);

        perspectiveCamera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.01, 1500);
        cameraParObj.add(perspectiveCamera);

        var cameraHelper = new THREE.CameraHelper(perspectiveCamera);
        this.scene.add(cameraHelper);

        // 5. DirectionalLightHelper
        dlightHelper = new THREE.DirectionalLightHelper(dLight, 50); // 50 is helper size
        this.scene.add(dlightHelper);
    },
    drawSphere: function(x, z, material) {
        var sphere = new THREE.Mesh(new THREE.SphereGeometry(70, 70, 20), material);
        sphere.rotation.x = sphere.rotation.z = Math.PI * Math.random();
        sphere.position.x = x;
        sphere.position.y = 100;
        sphere.position.z = z;
        sphere.castShadow = sphere.receiveShadow = true;
        return sphere;
    }
};

// Animate the scene
function animate() {
    requestAnimationFrame(animate);
    render();
    update();
}

// Update controls and stats
function update() {
    bboxHelper.update();
    dlightHelper.update();

    lesson3.controls.update(lesson3.clock.getDelta());
    lesson3.stats.update();

    // smoothly move the dLight
    var timer = Date.now() * 0.000025;
    dLight.position.x = Math.sin(timer * 5) * 300;
    dLight.position.z = Math.cos(timer * 5) * 300;
}

// Render the scene
function render() {
    if (lesson3.renderer) {
        lesson3.renderer.render(lesson3.scene, lesson3.camera);
    }
}

// Initialize lesson on page load
function initializeLesson() {
    lesson3.init();
    animate();
}

if (window.addEventListener)
    window.addEventListener('load', initializeLesson, false);
else if (window.attachEvent)
    window.attachEvent('onload', initializeLesson);
else window.onload = initializeLesson;

請注意兩個球體加入到該組(這是普通的物件的3D物件)。現在,我們可以開始下面的功能實現介紹。

ArrowHelper

它利用一個軸物件以視覺化的3軸以簡單的方式。X軸是紅色的。Y軸是綠色的。Z軸是藍色的。這有助於理解在空間的所有三個軸的方向。要新增這個幫手,使用下面的程式碼:

//  AxisHelper
var axisHelper = new THREE.AxisHelper(800);
this.scene.add(axisHelper);

BoundingBoxHelper

它繪製線條物件的任何物件(Object3D)的外接矩形框,顯示此物件的世界軸對齊邊框。記住我們結合在單組物件這兩個領域?要新增這個幫手,使用下面的程式碼:

//3. BoundingBoxHelper
bboxHelper = new THREE.BoundingBoxHelper(group, 0x999999);
this.scene.add(bboxHelper);

CameraHelper

它吸引的特定物件3D物件(它看起來像金字塔)與線幾何,這有助於視覺化什麼指定攝像機包含在它的視錐。要新增這個幫手,使用下面的程式碼:

// 4. CameraHelper
var cameraParObj = new THREE.Object3D();
cameraParObj.position.y = 200;
cameraParObj.position.z = 700;
this.scene.add(cameraParObj);
perspectiveCamera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.01, 1500);
cameraParObj.add(perspectiveCamera);
var cameraHelper = new THREE.CameraHelper(perspectiveCamera);
this.scene.add(cameraHelper);

DirectionalLightHelper

它繪製一個線物件以顯示定向的光的方向。我們將逐步把我們的光源的給你看顯然這幫手。要新增這個幫手,使用下面的程式碼:

// 5. DirectionalLightHelper
dlightHelper = new THREE.DirectionalLightHelper(dLight, 50); // 50 is helper siz
this.scene.add(dlightHelper);

GridHelper

要檢視傭工的其餘部分,我們建立了第二個演示。其次是GridHelper,這個輔助繪製線條的二維網格。要新增這個幫手,使用下面的程式碼:

var gridHelper = new THREE.GridHelper(500, 40); // 500 is grid size, 20 is grid step
gridHelper.position = new THREE.Vector3(0, 0, 0);
gridHelper.rotation = new THREE.Euler(0, 0, 0);
this.scene.add(gridHelper);
var gridHelper2 = gridHelper.clone();
gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0);
this.scene.add(gridHelper2);
var gridHelper3 = gridHelper.clone();
gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2);
this.scene.add(gridHelper3);

HemisphereLightHelper

其餘3個助手是燈,HemisphereLightHelper是HemisphereLight物件。我們不得不關閉我們的定向光,使半球光。要新增這個幫手,使用下面的程式碼:

// add hemisphere light
var hemiLight = new THREE.HemisphereLight(0x0000ff, 0x00ff00, 0.4);
hemiLight.color.setHSL(0.6, 1, 0.6);
hemiLight.groundColor.setHSL(0.095, 1, 0.75);
hemiLight.position.set(-200, 400, -200);
this.scene.add(hemiLight);
var hlightHelper = new THREE.HemisphereLightHelper(hemiLight, 50, 300); // 50 is sphere size, 300 is arrow length
this.scene.add(hlightHelper);

PointLightHelper

類似以前的點光源助手是點光源的物件。要新增這個幫手,使用下面的程式碼:

// add point light
var pointLight = new THREE.PointLight(0xffff00, 1.0);
pointLight.position.set(300,300,300);
this.scene.add(pointLight);
var pointLightHelper = new THREE.PointLightHelper(pointLight, 50); // 50 is sphere size
this.scene.add(pointLightHelper);

SpotLightHelper

最後,我們添加了聚光燈下:聚光燈Helper是聚光燈的物件。要新增這個幫手,使用下面的程式碼:

// add spot light
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-300,400,300);
spotLight.castShadow = true;
spotLight.shadowCameraFov = 60;
this.scene.add(spotLight);
var spotLightHelper = new THREE.SpotLightHelper(spotLight, 50); // 50 is sphere size
this.scene.add(spotLightHelper);

結束

未完繼續
原始碼下載請關注我的微信公眾號
這裡寫圖片描述