three.jsで多色グラデーションの2回目。
前回の記事ではShaderMaterialを使った裏技グラデーションでしたが、今回は正攻法です。
以下は全ソース(html)です。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>shade test</title> <script type="text/javascript" src="three.min.js"></script> <script type="text/javascript" src="OrbitControls.js"></script> <script type="text/javascript"> var renderer; var camera; var controls; var scene; var container; var light; var light2; var mesh; var geometry; function shadetest() { init_threejs(); init_scene(); init_camera(); init_light(); init_object(); reset_position(); loop(); } function init_threejs() { renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setClearColor(0xffffff, 1); renderer.setSize(1, 1); container = document.getElementById('canvas3d'); container.appendChild(renderer.domElement); } function init_scene() { scene = new THREE.Scene(); } function init_camera() { camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000); camera.up.x = 0; camera.up.y = 0; camera.up.z = 1; camera.position.set(0, 0, 5); controls = new THREE.OrbitControls(camera, renderer.domElement); } function init_light() { light = new THREE.DirectionalLight(0xcccccc, 1.6); light.position = new THREE.Vector3(-100, 500, 800); scene.add(light); light2 = new THREE.AmbientLight(0x333333); scene.add(light2); } function init_object() { var vertexPositions = [ [-1.0, -1.0, 1.0], [0.0, -1.0, 1.0], [1.0, -1.0, 1.0], [-1.0, 0.0, 1.0], [0.0, 0.0, 1.0], [1.0, 0.0, 1.0], [-1.0, 1.0, 1.0], [0.0, 1.0, 1.0], [1.0, 1.0, 1.0] ]; var vertexColors = [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0], [0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5] ]; var indices = [ [0, 1, 4], [1, 2, 4], [2, 5, 4], [5, 8, 4], [8, 7, 4], [7, 6, 4], [6, 3, 4], [3, 0, 4] ]; var geometry = new THREE.Geometry(); for (var i = 0; i < vertexPositions.length; i++) { geometry.vertices.push(new THREE.Vector3(vertexPositions[i][0], vertexPositions[i][1], vertexPositions[i][2])); } for (var i = 0; i < indices.length; i++) { var face = new THREE.Face3(indices[i][0], indices[i][1], indices[i][2]); for (var j = 0; j < 3; j++) { var idx = indices[i][j]; face.vertexColors[j] = new THREE.Color(vertexColors[idx][0], vertexColors[idx][1], vertexColors[idx][2]); } geometry.faces.push(face); } material = new THREE.MeshBasicMaterial({vertexColors: THREE.FaceColors}); var mesh = new THREE.Mesh(geometry, material); mesh.position.set(0, 0, 0); scene.add(mesh); } function reset_position() { var sz = {w:container.offsetWidth, h:container.offsetHeight}; renderer.setSize(sz.w, sz.h); camera.aspect = sz.w / sz.h; camera.updateProjectionMatrix(); } function loop() { requestAnimationFrame(loop); controls.update(); renderer.clear(); renderer.render(scene, camera); } </script> </head> <body onload="shadetest();" onresize="reset_position();"> <div id="canvas3d" style="width:300px;height:300px;"> </div> </body> </html>
faceの頂点(vertexColors)にそれぞれ異なる色を設定するとfaceが多色グラデーションとなる。
face.colorが設定されていてもvertexColorsを優先するが、face.colorを優先したいなら、
face.vertexColors = [];
とすればOKだ。