three.js 04-09 之 LineBasicMaterial 材質
阿新 • • 發佈:2019-02-15
關於 three.js 中的材質部分介紹就快講完了。接下來要介紹關於線段幾何的兩種材質:LineBasicMaterial 和 LineDashedMatertial。如下所示:
- LineBasicMaterial:通過線段基礎材質,可以設定線段的顏色、寬度、斷點及連線點等屬性;
- LineDashedMaterial:跟 LineBasicMaterial 基本一樣,但是通過指定短劃線和間隔長度,可以創建出虛線效果;
我們先來介紹一下 LineBasicMaterial 材質,可用的常用屬性如下表所示:
屬性 | 描述 |
---|---|
color | 指定線的顏色。如果指定了 vertexColors,這個屬性就會被忽略 |
linewidth | 指定線的寬度 |
lineCap | 此屬性定義頂點間的線段端點如何顯示。可選的值包括:butt(平)、round(圓)、square(方)。預設值是 round。WebGLRenderer 不支援該屬性 |
lineJoin | 此屬性定義線段連線點如何顯示。可選的值包括:round(圓)、bevel(斜切)、miter(尖角)。預設值是 round。WebGLRenderer 不支援該屬性 |
vertexColors | 如果將這個屬性設定為 THREE.VertexColors 值時,就可以為每一個頂點指定一種顏色 |
fog | 此屬性指定當前物體是否受全域性霧化效果的影響 |
在這個示例中,用到了一個 gosper(a, b) 函式,此函式主要是產生一種叫“高斯帕曲線”(請讀者自行參考 http://en.wikipedia.org/wiki/Gosper_curve)。接著,我們建立一個 THREE.Geometry 例項,為每個座標建立一個頂點,並把它們放進該例項的線段屬性中。對於每個座標我們還會計算一個顏色值,用來設定 colors 屬性。最後,我們就可以建立一個 LineBasicMaterial 材質物件了,結合幾何體就能創建出 THREE.Line 網格了。<!DOCTYPE html> <html> <head> <title>示例 04.09 - LineBasicMaterial</title> <script src="../build/three.js"></script> <script src="../build/js/controls/OrbitControls.js"></script> <script src="../build/js/libs/stats.min.js"></script> <script src="../build/js/libs/dat.gui.min.js"></script> <script src="../jquery/jquery-3.2.1.min.js"></script> <style> body { /* 設定 margin 為 0,並且 overflow 為 hidden,來完成頁面樣式 */ margin: 0; overflow: hidden; } /* 統計物件的樣式 */ #Stats-output { position: absolute; left: 0px; top: 0px; } </style> </head> <body> <!-- 用於 WebGL 輸出的 Div --> <div id="webgl-output"></div> <!-- 用於統計 FPS 輸出的 Div --> <div id="stats-output"></div> <!-- 執行 Three.js 示例的 Javascript 程式碼 --> <script type="text/javascript"> var scene; var camera; var render; var webglRender; //var canvasRender; var controls; var stats; var guiParams; var ground; var cube; var lineMaterial; var ambientLight; var spotLight; $(function() { stats = initStats(); scene = new THREE.Scene(); webglRender = new THREE.WebGLRenderer( {antialias: true, alpha: true} ); // antialias 抗鋸齒 webglRender.setSize(window.innerWidth, window.innerHeight); webglRender.setClearColor(0x000000, 1.0); //webglRender.shadowMap.enabled = true; // 允許陰影投射 render = webglRender; camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000); // 2147483647 camera.position.set(-30, 40, 30); var target = new THREE.Vector3(0, 0 , 0); controls = new THREE.OrbitControls(camera, render.domElement); controls.target = target; camera.lookAt(target); $('#webgl-output')[0].appendChild(render.domElement); window.addEventListener('resize', onWindowResize, false); ambientLight = new THREE.AmbientLight(0x0c0c0c); scene.add(ambientLight); spotLight = new THREE.SpotLight({color: 0xffffff}); spotLight.position.set(-40, 60, -10); spotLight.castShadow = true; scene.add(spotLight); //scene.add(new THREE.AxisHelper(20));// 加入座標軸 var points = gosper(4, 60); var lines = new THREE.Geometry(); var colors = []; var i = 0; points.forEach(function(e){ lines.vertices.push(new THREE.Vector3(e.x, e.z, e.y)); colors[i] = new THREE.Color(0xffffff); // 色調(Hue)、飽和度(Saturation)、亮度(Lightness colors[i].setHSL(e.x / 100 + 0.5, e.y * 20 / 300, 0.8); i++; }); lines.colors = colors; lineMaterial = new THREE.LineBasicMaterial({ opacity: 1.0, linewidth: 1, vertexColors: THREE.VertexColors }); var line = new THREE.Line(lines, lineMaterial); line.position.set(25, -30, -60); scene.add(line); /** 用來儲存那些需要修改的變數 */ guiParams = new function() { this.rotationSpeed = 0.01; } /** 定義 dat.GUI 物件,並繫結 guiParams 的幾個屬性 */ //var gui = new dat.GUI(); renderScene(); }); /** 渲染場景 */ function renderScene() { stats.update(); rotateMesh(); // 旋轉物體 requestAnimationFrame(renderScene); render.render(scene, camera); } /** 初始化 stats 統計物件 */ function initStats() { stats = new Stats(); stats.setMode(0); // 0 為監測 FPS;1 為監測渲染時間 $('#stats-output').append(stats.domElement); return stats; } /** 當瀏覽器視窗大小變化時觸發 */ function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); render.setSize(window.innerWidth, window.innerHeight); } /** 旋轉物體 */ function rotateMesh() { scene.traverse(function(mesh) { if (mesh instanceof THREE.Line && mesh != ground) { //mesh.rotation.x += guiParams.rotationSpeed; //mesh.rotation.y += guiParams.rotationSpeed; mesh.rotation.z += guiParams.rotationSpeed; } }); } /** 高斯帕曲線 */ function gosper(a, b) { var turtle = [0, 0, 0]; var points = []; var count = 0; rg(a, b, turtle); // turtle: 龜殼圖案 return points; function rt(x) { turtle[2] += x; } function lt(x) { turtle[2] -= x; } function fd(dist) { //ctx.beginPath(); points.push({x: turtle[0], y: turtle[1], z: Math.sin(count) * 5}); //ctx.moveTo(turtle[0], turtle[1]); var dir = turtle[2] * (Math.PI / 180); turtle[0] += Math.cos(dir) * dist; turtle[1] += Math.sin(dir) * dist; points.push({x: turtle[0], y: turtle[1], z: Math.sin(count) * 5}); //ctx.lineTo(turtle[0], turtle[1]); //ctx.stroke(); } function rg(st, ln, turtle) { st--; ln = ln / 2.6457; if (st > 0) { //ctx.strokeStyle = '#111'; rg(st, ln, turtle); rt(60); gl(st, ln, turtle); rt(120); gl(st, ln, turtle); lt(60); rg(st, ln, turtle); lt(120); rg(st, ln, turtle); rg(st, ln, turtle); lt(60); gl(st, ln, turtle); rt(60); } if (st == 0) { fd(ln); rt(60); fd(ln); rt(120); fd(ln); lt(60); fd(ln); lt(120); fd(ln); fd(ln); lt(60); fd(ln); rt(60) } } function gl(st, ln, turtle) { st--; ln = ln / 2.6457; if (st > 0) { //ctx.strokeStyle = '#555'; lt(60); rg(st, ln, turtle); rt(60); gl(st, ln, turtle); gl(st, ln, turtle); rt(120); gl(st, ln, turtle); rt(60); rg(st, ln, turtle); lt(120); rg(st, ln, turtle); lt(60); gl(st, ln, turtle); } if (st == 0) { lt(60); fd(ln); rt(60); fd(ln); fd(ln); rt(120); fd(ln); rt(60); fd(ln); lt(120); fd(ln); lt(60); fd(ln); } } } </script> </body> </html>
未完待續···