Forked from: cx20's [WebGL] Grimoire.js で小惑星を表示させてみるテスト(フラットシェーディング編) View Diff (240) [WebGL] Grimoire.js で Draco 形式のファイルを読み込んでみるテスト cx20 Follow 2017-07-09 21:59:21 License: MIT License Fork1 Fav0 View668 Play Stop Reload Fullscreen Smart Phone Fork tree Readme JavaScript 197 lines HTML 67 lines CSS 11 lines [WebGL] Grimoire.js で Draco 形式のファイルを読み込んでみるテスト Draco 形式は Google の提唱する新しい 3D Mesh の圧縮形式です。 <対応した点> ・頂点データを Draco 形式で用意するよう対応。 ・index の数が 16bit の上限を超えたため、OES_element_index_uint 拡張を使用するよう変更。 表示モデル: (25143) Itokawa - 3D Asteroid Catalogue https://space.frieger.com/asteroids/asteroids/25143-Itokawa Itokawa (Hayabusa, 200k poly) (OBJ 6.6 MB) https://space.frieger.com/asteroids/data/asteroids/models/i/25143_Itokawa_200k.obj → Draco 形式に変換して使用(6.6MB → 212KB) <変更履歴> 2017/07/09 grimoire-preset-basic.js v1.8.6 → v1.10.16 に変更。スクリプトタグに記載したシェーダをマテリアル名で参照するよう対応。 2017/03/20 初版作成 <参考> ■ google/draco https://github.com/google/draco#javascript-decoder-api ■ three.js webgl - loaders - Draco loader https://storage.googleapis.com/demos.webmproject.org/draco/draco_loader_throw.html ■ [簡易版] WebGL で小惑星に光を当ててみるテスト(その3) http://jsdo.it/cx20/kWuS ■ three.js で Draco 形式のデータを表示してみるテスト(改) http://jsdo.it/cx20/y3XD ■ GLBoost で Draco 形式のデータを表示してみるテスト(調整中) http://jsdo.it/cx20/M6uB [WebGL] Grimoire.js で Draco 形式のファイルを読み込んでみるテスト // forked from cx20's "[WebGL] Grimoire.js で小惑星を表示させてみるテスト(フラットシェーディング編)" http://jsdo.it/cx20/WLYg // forked from cx20's "[WebGL] Grimoire.js で小惑星を表示させてみるテスト" http://jsdo.it/cx20/UkgF // forked from cx20's "[WebGL] Grimoire.js で3次元リサージュ図形を描いてみるテスト" http://jsdo.it/cx20/SM1B // forked from cx20's "[WebGL] Grimoire.js でリサージュ図形を描いてみるテスト" http://jsdo.it/cx20/8Fx0 // forked from cx20's "[WebGL] Grimoire.js を試してみるテスト(VBO編)" http://jsdo.it/cx20/iUdQ // forked from cx20's "[WebGL] Grimoire.js を試してみるテスト" http://jsdo.it/cx20/4ZEB // forked from cx20's "[WebGL] jThree を試してみるテスト" http://jsdo.it/cx20/Go5s // Module that exposes all the core funcionality of the Draco decoder. const DracoModule = Module; var isInitialized = false; var isDracoLoaded = false; var g_positions; var g_indices; var Vector3 = gr.lib.math.Vector3; var Quaternion = gr.lib.math.Quaternion; var GLExtRequestor = gr.lib.fundamental.Resource.GLExtRequestor; GLExtRequestor.request("OES_element_index_uint"); GLExtRequestor.request("OES_standard_derivatives"); var Geometry = gr.lib.fundamental.Geometry.Geometry; gr.registerComponent('Rotate', { attributes: { speed: { default: '1', converter: 'Number', }, }, $mount: function () { this.phi = 0; //this.isInitialized = false; //this.isDracoLoaded = false; loadOneModel(); }, $update: function () { if ( !isInitialized && isDracoLoaded ) { var gl = this.node.companion.get("gl"); var geometry = new Geometry(gl); geometry.addAttributes(g_positions, {POSITION:{size: 3}}); geometry.addIndex("default", g_indices, WebGLRenderingContext.TRIANGLES); gr("#canvas")("mesh").setAttribute("geometry", geometry); isInitialized = true; } if (isInitialized) { this.phi += this.getAttribute('speed'); // オイラー角による回転 //this.node.setAttribute('rotation', this.phi + ',' + this.phi + ',' + 0); // クォータニオンによる回転 var axis = new Vector3(1, 1, 1); var angle = this.phi * Math.PI / 180; var q = Quaternion.angleAxis(angle, axis); this.node.setAttribute('rotation', q.normalize()); } }, }); gr(function () { var $$ = gr('#canvas'); $$('mesh').addComponent('Rotate'); }); function loadOneModel() { let draco_file = new XMLHttpRequest(); //draco_file.open("GET", "throw_14.drc", true); //draco_file.open("GET", "http://jsrun.it/assets/6/E/0/L/6E0Lv", true); // Itokawa Hayabusa 50k poly.drc draco_file.open("GET", "http://jsrun.it/assets/k/Y/X/g/kYXge", true); // Itokawa Hayabusa 200k poly.drc draco_file.responseType = "arraybuffer"; draco_file.send(); draco_file.onload = function(e) { loadGeometry(draco_file.response); isDracoLoaded = true; } } function loadGeometry(raw_data) { const buffer = new DracoModule.DecoderBuffer(); let rawBuffer = raw_data; buffer.Init(new Int8Array(rawBuffer), rawBuffer.byteLength); const wrapper = new DracoModule.WebIDLWrapper(); /* * Determine what type is this file, mesh or point cloud. */ const geometryType = wrapper.GetEncodedGeometryType(buffer); if (geometryType == DracoModule.TRIANGULAR_MESH) { console.log("Loaded a mesh."); } else if (geometryType == DracoModule.POINT_CLOUD) { console.log("Loaded a point cloud."); } else { console.log("Error: Unknown geometry type."); } convertDracoGeometryTo3JS(wrapper, geometryType, buffer); } function convertDracoGeometryTo3JS(wrapper, geometryType, buffer) { let dracoGeometry; if (geometryType == DracoModule.TRIANGULAR_MESH) { dracoGeometry = wrapper.DecodeMeshFromBuffer(buffer); } else { dracoGeometry = wrapper.DecodePointCloudFromBuffer(buffer); } DracoModule.destroy(buffer); let numFaces, numPoints, numVertexCoordinates, numAttributes; // For output basic geometry information. let geometryInfoStr = ""; if (geometryType == DracoModule.TRIANGULAR_MESH) { numFaces = dracoGeometry.num_faces(); geometryInfoStr += "Number of faces loaded: " + numFaces.toString() + ".\n"; } else { numFaces = 0; } console.log(geometryInfoStr); numPoints = dracoGeometry.num_points(); count = numPoints; numVertexCoordinates = numPoints * 3; numAttributes = dracoGeometry.num_attributes(); geometryInfoStr = "Number of points loaded: " + numPoints.toString() + ".\n"; geometryInfoStr += "Number of attributes loaded: " + numAttributes.toString() + ".\n"; // Get position attribute. Must exists. const posAttId = wrapper.GetAttributeId(dracoGeometry, Module.POSITION); if (posAttId == -1) { const errorMsg = "No position attribute found in the mesh."; console.log(errorMsg); DracoModule.destroy(wrapper); DracoModule.destroy(dracoGeometry); throw new Error(errorMsg); } const posAttribute = wrapper.GetAttribute(dracoGeometry, posAttId); const posAttributeData = new DracoModule.DracoFloat32Array(); wrapper.GetAttributeFloatForAllPoints(dracoGeometry, posAttribute, posAttributeData); // Get color attributes if exists. const colorAttId = wrapper.GetAttributeId(dracoGeometry, Module.COLOR); let colAttributeData; if (colorAttId != -1) { geometryInfoStr += "\nLoaded color attribute.\n"; const colAttribute = wrapper.GetAttribute(dracoGeometry, colorAttId); colAttributeData = new DracoModule.DracoFloat32Array(); wrapper.GetAttributeFloatForAllPoints(dracoGeometry, colAttribute, colAttributeData); } // Get normal attributes if exists. const normalAttId = wrapper.GetAttributeId(dracoGeometry, Module.NORMAL); let norAttributeData; if (normalAttId != -1) { geometryInfoStr += "\nLoaded normal attribute.\n"; const norAttribute = wrapper.GetAttribute(dracoGeometry, normalAttId); norAttributeData = new DracoModule.DracoFloat32Array(); wrapper.GetAttributeFloatForAllPoints(dracoGeometry, norAttribute, norAttributeData); } console.log(geometryInfoStr); var positions = []; var normals = []; var colors = []; var indices = []; for (let i = 0; i < numVertexCoordinates; i += 3) { positions.push(posAttributeData.GetValue(i+0)); positions.push(posAttributeData.GetValue(i+1)); positions.push(posAttributeData.GetValue(i+2)); } DracoModule.destroy(posAttributeData); if (colorAttId != -1) DracoModule.destroy(colAttributeData); if (normalAttId != -1) DracoModule.destroy(norAttributeData); // For mesh, we need to generate the faces. if (geometryType == DracoModule.TRIANGULAR_MESH) { const numIndices = numFaces * 3; const ia = new DracoInt32Array(); for (let i = 0; i < numFaces; ++i) { wrapper.GetFaceFromMesh(dracoGeometry, i, ia); indices.push(ia.GetValue(0)); indices.push(ia.GetValue(1)); indices.push(ia.GetValue(2)); } DracoModule.destroy(ia); } DracoModule.destroy(wrapper); DracoModule.destroy(dracoGeometry); g_positions = new Float32Array(positions); g_indices = new Uint32Array(indices); } <!-- grimoire-preset-basic.js v1.10.16 --> <script src="https://unpkg.com/grimoirejs-preset-basic@1.10.16/register/grimoire-preset-basic.js"></script> <!-- draco_decoder.js --> <script src="https://cdn.rawgit.com/google/draco/6114eed6/javascript/draco_decoder.js"></script> <div id="page-wrapper"> <p style="position:absolute; color: #fff;">Load Draco Mesh</p> <pre id="fileDisplayArea" style="display:none"><pre> </div> <script type="text/sort" id="shader" typeName="flatShader"> @Pass{ #ifdef FS #extension GL_OES_standard_derivatives : enable #endif FS_PREC(mediump,float) @Disable(CULL_FACE) varying vec4 vColor; varying vec4 vPosition; varying float vTime; #ifdef VS @POSITION attribute vec3 position; uniform mat4 _matPVM; uniform float _time; void main(){ vec3 p = position; //vColor = vec4(p.x + 0.5, p.y + 0.5, p.z + 0.5, 1.0 ); vColor = vec4(1.0); vPosition = _matPVM * vec4(position * 3.0, 1.0); gl_Position = _matPVM * vec4(position, 1.0); } #endif #ifdef FS void main(){ vec3 lightDirection = vec3(0.0, -1.0, 1.0); vec3 dx = dFdx(vPosition.xyz); vec3 dy = dFdy(vPosition.xyz); vec3 n = normalize(cross(normalize(dx), normalize(dy))); vec3 light = normalize(lightDirection); float diff = clamp(dot(n, light), 0.1, 1.0); gl_FragColor = vec4(vColor.rgb * diff, 1.0); } #endif } </script> <script type="text/goml" id="canvas"> <goml width="fit" height="fit" bgColor="black"> <goml.components> </goml.components> <!-- <import-material typeName="flatShader" src="http://jsrun.it/assets/W/i/l/s/WilsP"/> --> <scene> <camera class="camera" position="0,0,1"> <camera.components> <MouseCameraControl/> </camera.components> </camera> <mesh material="new(flatShader)" /> </scene> </goml> </script> [WebGL] Grimoire.js で Draco 形式のファイルを読み込んでみるテスト * { margin: 0; padding: 0; border: 0; } body { background: #fff; font: 30px sans-serif; overflow: hidden; } [WebGL] Grimoire.js で Draco 形式のファイルを読み込んでみるテスト Draco 形式は Google の提唱する新しい 3D Mesh の圧縮形式です。 <対応した点> ・頂点データを Draco 形式で用意するよう対応。 ・index の数が 16bit の上限を超えたため、OES_element_index_uint 拡張を使用するよう変更。 表示モデル: (25143) Itokawa - 3D Asteroid Catalogue https://space.frieger.com/asteroids/asteroids/25143-Itokawa Itokawa (Hayabusa, 200k poly) (OBJ 6.6 MB) https://space.frieger.com/asteroids/data/asteroids/models/i/25143_Itokawa_200k.obj → Draco 形式に変換して使用(6.6MB → 212KB) <変更履歴> 2017/07/09 grimoire-preset-basic.js v1.8.6 → v1.10.16 に変更。スクリプトタグに記載したシェーダをマテリアル名で参照するよう対応。 2017/03/20 初版作成 <参考> ■ google/draco https://github.com/google/draco#javascript-decoder-api ■ three.js webgl - loaders - Draco loader https://storage.googleapis.com/demos.webmproject.org/draco/draco_loader_throw.html ■ [簡易版] WebGL で小惑星に光を当ててみるテスト(その3) http://jsdo.it/cx20/kWuS ■ three.js で Draco 形式のデータを表示してみるテスト(改) http://jsdo.it/cx20/y3XD ■ GLBoost で Draco 形式のデータを表示してみるテスト(調整中) http://jsdo.it/cx20/M6uB // forked from cx20's "[WebGL] Grimoire.js で小惑星を表示させてみるテスト(フラットシェーディング編)" http://jsdo.it/cx20/WLYg // forked from cx20's "[WebGL] Grimoire.js で小惑星を表示させてみるテスト" http://jsdo.it/cx20/UkgF // forked from cx20's "[WebGL] Grimoire.js で3次元リサージュ図形を描いてみるテスト" http://jsdo.it/cx20/SM1B // forked from cx20's "[WebGL] Grimoire.js でリサージュ図形を描いてみるテスト" http://jsdo.it/cx20/8Fx0 // forked from cx20's "[WebGL] Grimoire.js を試してみるテスト(VBO編)" http://jsdo.it/cx20/iUdQ // forked from cx20's "[WebGL] Grimoire.js を試してみるテスト" http://jsdo.it/cx20/4ZEB // forked from cx20's "[WebGL] jThree を試してみるテスト" http://jsdo.it/cx20/Go5s // Module that exposes all the core funcionality of the Draco decoder. const DracoModule = Module; var isInitialized = false; var isDracoLoaded = false; var g_positions; var g_indices; var Vector3 = gr.lib.math.Vector3; var Quaternion = gr.lib.math.Quaternion; var GLExtRequestor = gr.lib.fundamental.Resource.GLExtRequestor; GLExtRequestor.request("OES_element_index_uint"); GLExtRequestor.request("OES_standard_derivatives"); var Geometry = gr.lib.fundamental.Geometry.Geometry; gr.registerComponent('Rotate', { attributes: { speed: { default: '1', converter: 'Number', }, }, $mount: function () { this.phi = 0; //this.isInitialized = false; //this.isDracoLoaded = false; loadOneModel(); }, $update: function () { if ( !isInitialized && isDracoLoaded ) { var gl = this.node.companion.get("gl"); var geometry = new Geometry(gl); geometry.addAttributes(g_positions, {POSITION:{size: 3}}); geometry.addIndex("default", g_indices, WebGLRenderingContext.TRIANGLES); gr("#canvas")("mesh").setAttribute("geometry", geometry); isInitialized = true; } if (isInitialized) { this.phi += this.getAttribute('speed'); // オイラー角による回転 //this.node.setAttribute('rotation', this.phi + ',' + this.phi + ',' + 0); // クォータニオンによる回転 var axis = new Vector3(1, 1, 1); var angle = this.phi * Math.PI / 180; var q = Quaternion.angleAxis(angle, axis); this.node.setAttribute('rotation', q.normalize()); } }, }); gr(function () { var $$ = gr('#canvas'); $$('mesh').addComponent('Rotate'); }); function loadOneModel() { let draco_file = new XMLHttpRequest(); //draco_file.open("GET", "throw_14.drc", true); //draco_file.open("GET", "http://jsrun.it/assets/6/E/0/L/6E0Lv", true); // Itokawa Hayabusa 50k poly.drc draco_file.open("GET", "http://jsrun.it/assets/k/Y/X/g/kYXge", true); // Itokawa Hayabusa 200k poly.drc draco_file.responseType = "arraybuffer"; draco_file.send(); draco_file.onload = function(e) { loadGeometry(draco_file.response); isDracoLoaded = true; } } function loadGeometry(raw_data) { const buffer = new DracoModule.DecoderBuffer(); let rawBuffer = raw_data; buffer.Init(new Int8Array(rawBuffer), rawBuffer.byteLength); const wrapper = new DracoModule.WebIDLWrapper(); /* * Determine what type is this file, mesh or point cloud. */ const geometryType = wrapper.GetEncodedGeometryType(buffer); if (geometryType == DracoModule.TRIANGULAR_MESH) { console.log("Loaded a mesh."); } else if (geometryType == DracoModule.POINT_CLOUD) { console.log("Loaded a point cloud."); } else { console.log("Error: Unknown geometry type."); } convertDracoGeometryTo3JS(wrapper, geometryType, buffer); } function convertDracoGeometryTo3JS(wrapper, geometryType, buffer) { let dracoGeometry; if (geometryType == DracoModule.TRIANGULAR_MESH) { dracoGeometry = wrapper.DecodeMeshFromBuffer(buffer); } else { dracoGeometry = wrapper.DecodePointCloudFromBuffer(buffer); } DracoModule.destroy(buffer); let numFaces, numPoints, numVertexCoordinates, numAttributes; // For output basic geometry information. let geometryInfoStr = ""; if (geometryType == DracoModule.TRIANGULAR_MESH) { numFaces = dracoGeometry.num_faces(); geometryInfoStr += "Number of faces loaded: " + numFaces.toString() + ".\n"; } else { numFaces = 0; } console.log(geometryInfoStr); numPoints = dracoGeometry.num_points(); count = numPoints; numVertexCoordinates = numPoints * 3; numAttributes = dracoGeometry.num_attributes(); geometryInfoStr = "Number of points loaded: " + numPoints.toString() + ".\n"; geometryInfoStr += "Number of attributes loaded: " + numAttributes.toString() + ".\n"; // Get position attribute. Must exists. const posAttId = wrapper.GetAttributeId(dracoGeometry, Module.POSITION); if (posAttId == -1) { const errorMsg = "No position attribute found in the mesh."; console.log(errorMsg); DracoModule.destroy(wrapper); DracoModule.destroy(dracoGeometry); throw new Error(errorMsg); } const posAttribute = wrapper.GetAttribute(dracoGeometry, posAttId); const posAttributeData = new DracoModule.DracoFloat32Array(); wrapper.GetAttributeFloatForAllPoints(dracoGeometry, posAttribute, posAttributeData); // Get color attributes if exists. const colorAttId = wrapper.GetAttributeId(dracoGeometry, Module.COLOR); let colAttributeData; if (colorAttId != -1) { geometryInfoStr += "\nLoaded color attribute.\n"; const colAttribute = wrapper.GetAttribute(dracoGeometry, colorAttId); colAttributeData = new DracoModule.DracoFloat32Array(); wrapper.GetAttributeFloatForAllPoints(dracoGeometry, colAttribute, colAttributeData); } // Get normal attributes if exists. const normalAttId = wrapper.GetAttributeId(dracoGeometry, Module.NORMAL); let norAttributeData; if (normalAttId != -1) { geometryInfoStr += "\nLoaded normal attribute.\n"; const norAttribute = wrapper.GetAttribute(dracoGeometry, normalAttId); norAttributeData = new DracoModule.DracoFloat32Array(); wrapper.GetAttributeFloatForAllPoints(dracoGeometry, norAttribute, norAttributeData); } console.log(geometryInfoStr); var positions = []; var normals = []; var colors = []; var indices = []; for (let i = 0; i < numVertexCoordinates; i += 3) { positions.push(posAttributeData.GetValue(i+0)); positions.push(posAttributeData.GetValue(i+1)); positions.push(posAttributeData.GetValue(i+2)); } DracoModule.destroy(posAttributeData); if (colorAttId != -1) DracoModule.destroy(colAttributeData); if (normalAttId != -1) DracoModule.destroy(norAttributeData); // For mesh, we need to generate the faces. if (geometryType == DracoModule.TRIANGULAR_MESH) { const numIndices = numFaces * 3; const ia = new DracoInt32Array(); for (let i = 0; i < numFaces; ++i) { wrapper.GetFaceFromMesh(dracoGeometry, i, ia); indices.push(ia.GetValue(0)); indices.push(ia.GetValue(1)); indices.push(ia.GetValue(2)); } DracoModule.destroy(ia); } DracoModule.destroy(wrapper); DracoModule.destroy(dracoGeometry); g_positions = new Float32Array(positions); g_indices = new Uint32Array(indices); } <!-- grimoire-preset-basic.js v1.10.16 --> <script src="https://unpkg.com/grimoirejs-preset-basic@1.10.16/register/grimoire-preset-basic.js"></script> <!-- draco_decoder.js --> <script src="https://cdn.rawgit.com/google/draco/6114eed6/javascript/draco_decoder.js"></script> <div id="page-wrapper"> <p style="position:absolute; color: #fff;">Load Draco Mesh</p> <pre id="fileDisplayArea" style="display:none"><pre> </div> <script type="text/sort" id="shader" typeName="flatShader"> @Pass{ #ifdef FS #extension GL_OES_standard_derivatives : enable #endif FS_PREC(mediump,float) @Disable(CULL_FACE) varying vec4 vColor; varying vec4 vPosition; varying float vTime; #ifdef VS @POSITION attribute vec3 position; uniform mat4 _matPVM; uniform float _time; void main(){ vec3 p = position; //vColor = vec4(p.x + 0.5, p.y + 0.5, p.z + 0.5, 1.0 ); vColor = vec4(1.0); vPosition = _matPVM * vec4(position * 3.0, 1.0); gl_Position = _matPVM * vec4(position, 1.0); } #endif #ifdef FS void main(){ vec3 lightDirection = vec3(0.0, -1.0, 1.0); vec3 dx = dFdx(vPosition.xyz); vec3 dy = dFdy(vPosition.xyz); vec3 n = normalize(cross(normalize(dx), normalize(dy))); vec3 light = normalize(lightDirection); float diff = clamp(dot(n, light), 0.1, 1.0); gl_FragColor = vec4(vColor.rgb * diff, 1.0); } #endif } </script> <script type="text/goml" id="canvas"> <goml width="fit" height="fit" bgColor="black"> <goml.components> </goml.components> <!-- <import-material typeName="flatShader" src="http://jsrun.it/assets/W/i/l/s/WilsP"/> --> <scene> <camera class="camera" position="0,0,1"> <camera.components> <MouseCameraControl/> </camera.components> </camera> <mesh material="new(flatShader)" /> </scene> </goml> </script> * { margin: 0; padding: 0; border: 0; } body { background: #fff; font: 30px sans-serif; overflow: hidden; } use an iframe compat browser, deer Play on jsdo.it games Author Share ブログに埋め込む QR Tag Download Complete! Description どんなゲームですか? [WebGL] Grimoire.js で Draco 形式のファイルを読み込んでみるテスト Draco 形式は Google の提唱する新しい 3D Mesh の圧縮形式です。 <対応した点> ・頂点データを Draco 形式で用意するよう対応。 ・index の数が 16bit の上限を超えたため、OES_element_index_uint 拡張を使用するよう変更。 表示モデル: (25143) Itokawa - 3D Asteroid Catalogue https://space.frieger.com/asteroids/asteroids/25143-Itokawa Itokawa (Hayabusa, 200k poly) (OBJ 6.6 MB) https://space.frieger.com/asteroids/data/asteroids/models/i/25143_Itokawa_200k.obj → Draco 形式に変換して使用(6.6MB → 212KB) <変更履歴> 2017/07/09 grimoire-preset-basic.js v1.8.6 → v1.10.16 に変更。スクリプトタグに記載したシェーダをマテリアル名で参照するよう対応。 2017/03/20 初版作成 <参考> ■ google/draco https://github.com/google/draco#javascript-decoder-api ■ three.js webgl - loaders - Draco loader https://storage.googleapis.com/demos.webmproject.org/draco/draco_loader_throw.html ■ [簡易版] WebGL で小惑星に光を当ててみるテスト(その3) http://jsdo.it/cx20/kWuS ■ three.js で Draco 形式のデータを表示してみるテスト(改) http://jsdo.it/cx20/y3XD ■ GLBoost で Draco 形式のデータを表示してみるテスト(調整中) http://jsdo.it/cx20/M6uB Control Device スマートフォンコントローラー jsdo.it WebSocket Controller» マウス キーボード タッチデバイス Fullscreen 有効 無効 jsdo.it games から削除する Submit Author cx20 URLhttp://profile.hatena.ne.jp/cx20/ プログラマ(マイクロソフト系の言語を使用することが多いです。) JavaScript のライブラリを色々と試して遊んでます。 ■ 各種 WebGL ライブラリによる基本サンプル一覧 http://qiita.com/cx20/items/0fa19c96aa6470d98807 ■ 各種 WebGLライブラリと3D物理演算ライブラリの組み合わせ一覧 http://qiita.com/cx20/items/3ebed669fb9c9e797935 ■ glTF 対応ライブラリのサンプル一覧 https://github.com/cx20/gltf-test ■ Grimoire.js サンプル一覧 http://jsdo.it/tag/Grimoire.js ■ GLBoost サンプル一覧 http://jsdo.it/tag/GLBoost Tweet Default Panel Auto play Screenshot Readme JavaScript HTML CSS Size Width: px Height: px code <script type="text/javascript" src="http://jsdo.it/blogparts/UOJ0/js"></script> 実行画面をスマートフォンで確認できます。お父さん QR - App Store art&design GLSL Grimoire.js html5_elements&api library&test WebGL Discussion このコードについて質問してみる! 标签 GLSL Grimoire.js WebGL art&design html5_elements&api library&test 派生作品 排序 投稿时间 浏览量 收藏数 派生数 [WebGL] Grimoire.js で Draco 形式 cx20 00 235 199/68/11 GLSL Grimoire.js WebGL art&design html5_elements&api library&test