├── css3d ├── 1 │ └── index.html ├── 2 │ └── index.html ├── 3 │ └── index.html ├── viewer.css ├── map.js ├── pieces.css └── viewer.js ├── README.md └── webgl ├── index.html ├── w.js ├── mario.js └── mariotexture.js /css3d/viewer.css: -------------------------------------------------------------------------------- 1 | /* 3D scene */ 2 | #viewport{width:700px;height:600px;overflow:hidden;border:1px solid;position:relative;perspective:500px} 3 | #viewport *{transform-style:preserve-3d;box-sizing:border-box} 4 | #camera{width:0;height:0;position:absolute;top:50%;left:50%} 5 | #scene{position:fixed;transform:translate3D(-50%,-50%,-2000px)rotateX(65deg)rotateZ(-35deg)} 6 | #floor{position:fixed;background:#4B4} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Mini 3D Platformer bootstrap/demo 2 | === 3 | 4 | CSS3D: 5 | 6 | Demo 1: https://xem.github.io/mini3DPlatformer/css3d/1 (hero moves north / east / south / west only) 7 | 8 | Demo 2: https://xem.github.io/mini3DPlatformer/css3d/2 (hero rotates on itself and moves forward and backwards) 9 | 10 | Demo 3: https://xem.github.io/mini3DPlatformer/css3d/3 (3rd person camera) 11 | 12 | 13 | WEBGL: 14 | 15 | Demo: https://xem.github.io/mini3DPlatformer/webgl (3rd person camera) -------------------------------------------------------------------------------- /css3d/map.js: -------------------------------------------------------------------------------- 1 | // Map (made with https://xem.github.io/3Dmapeditor/) 2 | map = { 3 | w: 10, 4 | h: 10, 5 | layers: [ 6 | 7 | // Layer 0: 8 | [ 9 | '0000000000', 10 | '0000000000', 11 | '0000000000', 12 | '0000100000', 13 | '0000100000', 14 | '0011111000', 15 | '0000100000', 16 | '0000100000', 17 | '0000000000', 18 | '0000000000', 19 | ], 20 | 21 | // Layer 1: 22 | [ 23 | '0000000000', 24 | '0000000000', 25 | '0000000000', 26 | '0000000000', 27 | '0000000000', 28 | '0000100000', 29 | '0000000000', 30 | '0000000000', 31 | '0000000000', 32 | '0000000000', 33 | ], 34 | ] 35 | }; -------------------------------------------------------------------------------- /css3d/pieces.css: -------------------------------------------------------------------------------- 1 | /* Global */ 2 | .piece{pointer-events:none;position:absolute;width:200px;height:200px} 3 | .face{width:200px;height:200px;position:fixed;font-size:100px;transform-origin:50% 100%;backface-visibility:hidden} 4 | 5 | /* piece rotation */ 6 | .r1{transform:rotateZ(90deg)} 7 | .r2{transform:rotateZ(180deg)} 8 | .r3{transform:rotateZ(-90deg)} 9 | 10 | /* Cube */ 11 | .up{transform:translateZ(200px)} 12 | .left{transform:translate3D(-100px,-100px,0)rotateZ(90deg)rotateX(-90deg)} 13 | .right{transform:translate3D(100px,-100px,0)rotateZ(-90deg)rotateX(-90deg)} 14 | .front{transform:rotateX(-90deg)} 15 | .back{transform:translate3D(0,-200px,0)rotateZ(180deg)rotateX(-90deg)} 16 | .down{transform:rotateX(180deg)} 17 | 18 | /* textures */ 19 | .cube *{background:#bbb} 20 | .cube .front{background:#ddd} 21 | .cube .left, .cube .right{background:#999} 22 | 23 | #hero * {background:#fa0} 24 | #hero .front{background:#e92} 25 | #hero .left, #hero .right{background:#d70} 26 | #hero .front:before {display:block;width:200px;content:'👀';font-size:100px;text-align:center} 27 | 28 | /* plane, sprite */ 29 | .plane,.sprite{font-size:200px} 30 | .plane *,.sprite *{transform-origin:50% 100%;transform:translateY(-100px)rotateX(-90deg)} -------------------------------------------------------------------------------- /css3d/viewer.js: -------------------------------------------------------------------------------- 1 | // Globals 2 | var token = " ", 3 | rotation = 0, 4 | texture = 0, 5 | w = map.w, 6 | h = map.h, 7 | x = 0, 8 | y = 0, 9 | z = 0, 10 | rx = 45, 11 | rz = 45, 12 | 13 | // Move the scene 14 | moveScene = (rx, rz) => { 15 | scene.style.transformOrigin = `50% 50%`; 16 | scene.style.transform = `translate3D(-50%,-50%,-${Math.max(w*200,h*200)+z*200}px)rotateX(${rx}deg)rotateZ(${rz}deg)`; 17 | }, 18 | 19 | // Return HTML code for a cube, at the given coordinates 20 | drawCube = (x, y, z, id='') => { 21 | html = `
`; 22 | html += `
`; 23 | html += `
`; 24 | html += `
`; 25 | html += `
`; 26 | html += `
`; 27 | return html; 28 | }, 29 | 30 | // Draw scene 31 | drawScene = () => { 32 | for(Z in map.layers){ 33 | for(Y in map.layers[Z]){ 34 | for(X in map.layers[Z][Y]){ 35 | token = map.layers[Z][Y][X]; 36 | if(token == "1"){ // 1 = cube 37 | scene.insertAdjacentHTML("beforeEnd", drawCube(X,Y,Z)); 38 | } 39 | } 40 | } 41 | } 42 | } 43 | 44 | drawScene(); 45 | scene.style.width = floor.style.width = w * 200 + "px"; 46 | scene.style.height = floor.style.height = h * 200 + "px"; 47 | if(top.RX) RX.onchange = RX.onupdate = RX.oninput = RZ.onchange = RZ.onupdate = RZ.oninput = () => { moveScene(rx = +RX.value, rz = +RZ.value) } -------------------------------------------------------------------------------- /webgl/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /css3d/1/index.html: -------------------------------------------------------------------------------- 1 |

Mini 3D Platformer demo 1

2 | 3 | 4 | 5 |

Move with arrow keys or WASD or ZQSD, jump with Space 6 |

Source code 7 |

8 |

9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 |

Camera: 19 | 22 | 23 |

rx 24 | rz 25 | 26 | 27 | 28 | 29 | 224 | -------------------------------------------------------------------------------- /css3d/2/index.html: -------------------------------------------------------------------------------- 1 |

Mini 3D Platformer demo 2

2 | 3 | 4 | 5 |

Rotate with left/right (or A/D or Q/D), go front with up (or Z or W), go back with down (or S), jump with Space 6 |

Source code 7 |

8 |

9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 |

Camera: 19 | 22 | 23 |

rx 24 | rz 25 | 26 | 27 | 28 | 29 | 269 | -------------------------------------------------------------------------------- /css3d/3/index.html: -------------------------------------------------------------------------------- 1 |

Mini 3D Platformer demo 3

2 | 3 | 4 | 5 |

Rotate with left/right (or A/D or Q/D), go front with up (or Z or W), go back with down (or S), jump with Space 6 |

Source code 7 |

8 |

9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 265 | -------------------------------------------------------------------------------- /webgl/w.js: -------------------------------------------------------------------------------- 1 | // WebGL framework 2 | // =============== 3 | 4 | debug = 1; // Enable shader/program compilation logs (optional) 5 | 6 | W = { 7 | 8 | // List of 3D models that can be rendered by the framework 9 | // (See the end of the file for built-in models: plane, billboard, cube, pyramid...) 10 | models: {}, 11 | 12 | // List of custom renderers 13 | //renderers: {}, 14 | 15 | // Reset the framework 16 | // param: a element 17 | reset: canvas => { 18 | 19 | // Globals 20 | W.canvas = canvas; // canvas element 21 | W.objs = 0; // Object counter 22 | W.current = {}; // Objects current states 23 | W.next = {}; // Objects next states 24 | W.textures = {}; // Textures list 25 | 26 | // WebGL context 27 | W.gl = canvas.getContext('webgl2'); 28 | 29 | // Default blending method for transparent objects 30 | W.gl.blendFunc(770 /* SRC_ALPHA */, 771 /* ONE_MINUS_SRC_ALPHA */); 31 | 32 | // Enable texture 0 33 | W.gl.activeTexture(33984 /* TEXTURE0 */); 34 | 35 | // Create a WebGL program 36 | W.program = W.gl.createProgram(); 37 | 38 | // Hide polygons back-faces (optional) 39 | W.gl.enable(2884 /* CULL_FACE */); 40 | 41 | // Create a Vertex shader 42 | // (this GLSL program is called for every vertex of the scene) 43 | W.gl.shaderSource( 44 | 45 | t = W.gl.createShader(35633 /* VERTEX_SHADER */), 46 | 47 | `#version 300 es 48 | precision highp float; // Set default float precision 49 | in vec4 pos, col, uv, normal; // Vertex attributes: position, color, texture coordinates, normal (if any) 50 | uniform mat4 pv, eye, m, im; // Uniform transformation matrices: projection * view, eye, model, inverse model 51 | uniform vec4 bb; // If the current shape is a billboard: bb = [w, h, 1.0, 0.0] 52 | out vec4 v_pos, v_col, v_uv, v_normal; // Varyings sent to the fragment shader: position, color, texture coordinates, normal (if any) 53 | void main() { 54 | gl_Position = pv * ( // Set vertex position: p * v * v_pos 55 | v_pos = bb.z > 0. // Set v_pos varying: 56 | ? m[3] + eye * (pos * bb) // Billboards always face the camera: p * v * distance + eye * (position * [w, h, 1.0, 0.0]) 57 | : m * pos // Other objects rotate normally: p * v * m * position 58 | ); 59 | v_col = col; // Set varyings 60 | v_uv = uv; 61 | v_normal = transpose(inverse(m)) * normal; // recompute normals to match model thansformation 62 | }` 63 | ); 64 | 65 | // Compile the Vertex shader and attach it to the program 66 | W.gl.compileShader(t); 67 | W.gl.attachShader(W.program, t); 68 | if(debug) console.log('vertex shader:', W.gl.getShaderInfoLog(t) || 'OK'); 69 | 70 | // Create a Fragment shader 71 | // (This GLSL program is called for every fragment (pixel) of the scene) 72 | W.gl.shaderSource( 73 | 74 | t = W.gl.createShader(35632 /* FRAGMENT_SHADER */), 75 | 76 | `#version 300 es 77 | precision highp float; // Set default float precision 78 | in vec4 v_pos, v_col, v_uv, v_normal; // Varyings received from the vertex shader: position, color, texture coordinates, normal (if any) 79 | uniform vec3 light; // Uniform: light direction, smooth normals enabled 80 | uniform vec4 o; // options [smooth, shading enabled, ambient, mix] 81 | uniform sampler2D sampler; // Uniform: 2D texture 82 | out vec4 c; // Output: final fragment color 83 | 84 | // The code below displays colored / textured / shaded fragments 85 | void main() { 86 | c = mix(texture(sampler, v_uv.xy), v_col, o[3]); // base color (mix of texture and rgba) 87 | if(o[1] > 0.){ // if lighting/shading is enabled: 88 | c = vec4( // output = vec4(base color RGB * (directional shading + ambient light)), base color Alpha 89 | c.rgb * (max(0., dot(light, -normalize( // Directional shading: compute dot product of light direction and normal (0 if negative) 90 | o[0] > 0. // if smooth shading is enabled: 91 | ? vec3(v_normal.xyz) // use smooth normals passed as varying 92 | : cross(dFdx(v_pos.xyz), dFdy(v_pos.xyz)) // else, compute flat normal by making a cross-product with the current fragment and its x/y neighbours 93 | ))) 94 | + o[2]), // add ambient light passed as uniform 95 | c.a // use base color's alpha 96 | ); 97 | } 98 | }` 99 | ); 100 | 101 | // Compile the Fragment shader and attach it to the program 102 | W.gl.compileShader(t); 103 | W.gl.attachShader(W.program, t); 104 | if(debug) console.log('fragment shader:', W.gl.getShaderInfoLog(t) || 'OK'); 105 | 106 | // Compile the program 107 | W.gl.linkProgram(W.program); 108 | W.gl.useProgram(W.program); 109 | if(debug) console.log('program:', W.gl.getProgramInfoLog(W.program) || 'OK'); 110 | 111 | // Set the scene's background color (RGBA) 112 | W.gl.clearColor(1, 1, 1, 1); 113 | 114 | // Shortcut to set the clear color 115 | W.clearColor = c => W.gl.clearColor(...W.col(c)); 116 | W.clearColor("fff"); 117 | 118 | // Enable fragments depth sorting 119 | // (the fragments of close objects will automatically overlap the fragments of further objects) 120 | W.gl.enable(2929 /* DEPTH_TEST */); 121 | 122 | // When everything is loaded: set default light / camera 123 | W.light({y: -1}); 124 | W.camera({fov: 30}); 125 | 126 | // Draw the scene. Ignore the first frame because the default camera will probably be overwritten by the program 127 | setTimeout(W.draw, 16); 128 | }, 129 | 130 | // Set a state to an object 131 | setState: (state, type, texture, i, normal = [], A, B, C, Ai, Bi, Ci, AB, BC) => { 132 | 133 | // Custom name or default name ('o' + auto-increment) 134 | state.n ||= 'o' + W.objs++; 135 | 136 | // Size sets w, h and d at once (optional) 137 | if(state.size) state.w = state.h = state.d = state.size; 138 | 139 | // If a new texture is provided, build it and save it in W.textures 140 | if(state.t && state.t.width && !W.textures[state.t.id]){ 141 | texture = W.gl.createTexture(); 142 | W.gl.pixelStorei(37441 /* UNPACK_PREMULTIPLY_ALPHA_WEBGL */, true); 143 | W.gl.bindTexture(3553 /* TEXTURE_2D */, texture); 144 | W.gl.pixelStorei(37440 /* UNPACK_FLIP_Y_WEBGL */, 1); 145 | W.gl.texImage2D(3553 /* TEXTURE_2D */, 0, 6408 /* RGBA */, 6408 /* RGBA */, 5121 /* UNSIGNED_BYTE */, state.t); 146 | W.gl.generateMipmap(3553 /* TEXTURE_2D */); 147 | W.textures[state.t.id] = texture; 148 | } 149 | 150 | // Recompute the projection matrix if fov is set (near: 1, far: 1000, ratio: canvas ratio) 151 | if(state.fov){ 152 | W.projection = 153 | new DOMMatrix([ 154 | (1 / Math.tan(state.fov * Math.PI / 180)) / (W.canvas.width / W.canvas.height), 0, 0, 0, 155 | 0, (1 / Math.tan(state.fov * Math.PI / 180)), 0, 0, 156 | 0, 0, -1001 / 999, -1, 157 | 0, 0, -2002 / 999, 0 158 | ]); 159 | } 160 | 161 | // Save object's type, 162 | // merge previous state (or default state) with the new state passed in parameter, 163 | // and reset f (the animation timer) 164 | state = {type, ...(W.current[state.n] = W.next[state.n] || {w:1, h:1, d:1, x:0, y:0, z:0, rx:0, ry:0, rz:0, b:'888', mode:4, mix: 0}), ...state, f:0}; 165 | 166 | // Build the model's vertices buffer if it doesn't exist yet 167 | if(W.models[state.type]?.vertices && !W.models?.[state.type].verticesBuffer){ 168 | W.gl.bindBuffer(34962 /* ARRAY_BUFFER */, W.models[state.type].verticesBuffer = W.gl.createBuffer()); 169 | W.gl.bufferData(34962 /* ARRAY_BUFFER */, new Float32Array(W.models[state.type].vertices), 35044 /*STATIC_DRAW*/); 170 | 171 | // Compute smooth normals if they don't exist yet (optional) 172 | if(!W.models[state.type].normals && W.smooth) W.smooth(state); 173 | 174 | // Make a buffer from the smooth/custom normals (if any) 175 | if(W.models[state.type].normals){ 176 | W.gl.bindBuffer(34962 /* ARRAY_BUFFER */, W.models[state.type].normalsBuffer = W.gl.createBuffer()); 177 | W.gl.bufferData(34962 /* ARRAY_BUFFER */, new Float32Array(W.models[state.type].normals.flat()), 35044 /*STATIC_DRAW*/); 178 | } 179 | } 180 | 181 | // Build the model's uv buffer (if any) if it doesn't exist yet 182 | if(W.models[state.type]?.uv && !W.models[state.type].uvBuffer){ 183 | W.gl.bindBuffer(34962 /* ARRAY_BUFFER */, W.models[state.type].uvBuffer = W.gl.createBuffer()); 184 | W.gl.bufferData(34962 /* ARRAY_BUFFER */, new Float32Array(W.models[state.type].uv), 35044 /*STATIC_DRAW*/); 185 | } 186 | 187 | // Build the model's index buffer (if any) and smooth normals if they don't exist yet 188 | if(W.models[state.type]?.indices && !W.models[state.type].indicesBuffer){ 189 | W.gl.bindBuffer(34963 /* ELEMENT_ARRAY_BUFFER */, W.models[state.type].indicesBuffer = W.gl.createBuffer()); 190 | W.gl.bufferData(34963 /* ELEMENT_ARRAY_BUFFER */, new Uint16Array(W.models[state.type].indices), 35044 /* STATIC_DRAW */); 191 | } 192 | 193 | // Set mix to 1 if no texture is set 194 | if(!state.t){ 195 | state.mix = 1; 196 | } 197 | 198 | // set mix to 0 by default if a texture is set 199 | else if(state.t && !state.mix){ 200 | state.mix = 0; 201 | } 202 | 203 | // Save new state 204 | W.next[state.n] = state; 205 | }, 206 | 207 | // Draw the scene 208 | draw: (now, dt, v, i, transparent = []) => { 209 | 210 | // Loop and measure time delta between frames 211 | dt = now - W.lastFrame; 212 | W.lastFrame = now; 213 | requestAnimationFrame(W.draw); 214 | 215 | if(W.next.camera.g){ 216 | W.render(W.next[W.next.camera.g], dt, 1); 217 | } 218 | 219 | // Create a matrix called v containing the current camera transformation 220 | v = W.animation('camera'); 221 | 222 | // If the camera is in a group 223 | if(W.next?.camera?.g){ 224 | 225 | // premultiply the camera matrix by the group's model matrix. 226 | v.preMultiplySelf(W.next[W.next.camera.g].M || W.next[W.next.camera.g].m); 227 | } 228 | 229 | // Send it to the shaders as the Eye matrix 230 | W.gl.uniformMatrix4fv( 231 | W.gl.getUniformLocation(W.program, 'eye'), 232 | false, 233 | v.toFloat32Array() 234 | ); 235 | 236 | // Invert it to obtain the View matrix 237 | v.invertSelf(); 238 | 239 | // Premultiply it with the Perspective matrix to obtain a Projection-View matrix 240 | v.preMultiplySelf(W.projection); 241 | 242 | // send it to the shaders as the pv matrix 243 | W.gl.uniformMatrix4fv( 244 | W.gl.getUniformLocation(W.program, 'pv'), 245 | false, 246 | v.toFloat32Array() 247 | ); 248 | 249 | // Clear canvas 250 | W.gl.clear(16640 /* W.gl.COLOR_BUFFER_BIT | W.gl.DEPTH_BUFFER_BIT */); 251 | 252 | // Render all the objects in the scene 253 | for(i in W.next){ 254 | 255 | // Render the shapes with no texture and no transparency (RGB1 color) 256 | if(!W.next[i].t && W.col(W.next[i].b)[3] == 1){ 257 | W.render(W.next[i], dt); 258 | } 259 | 260 | // Add the objects with transparency (RGBA or texture) in an array 261 | else { 262 | transparent.push(W.next[i]); 263 | } 264 | } 265 | 266 | // Order transparent objects from back to front 267 | transparent.sort((a, b) => { 268 | // Return a value > 0 if b is closer to the camera than a 269 | // Return a value < 0 if a is closer to the camera than b 270 | return W.dist(b) - W.dist(a); 271 | }); 272 | 273 | // Enable alpha blending 274 | W.gl.enable(3042 /* BLEND */); 275 | 276 | // Render all transparent objects 277 | for(i of transparent){ 278 | 279 | // Disable depth buffer write if it's a plane or a billboard to allow transparent objects to intersect planes more easily 280 | if(["plane","billboard"].includes(i.type)) W.gl.depthMask(0); 281 | 282 | W.render(i, dt); 283 | 284 | W.gl.depthMask(1); 285 | } 286 | 287 | // Disable alpha blending for the next frame 288 | W.gl.disable(3042 /* BLEND */); 289 | 290 | // Transition the light's direction and send it to the shaders 291 | W.gl.uniform3f( 292 | W.gl.getUniformLocation(W.program, 'light'), 293 | W.lerp('light','x'), W.lerp('light','y'), W.lerp('light','z') 294 | ); 295 | }, 296 | 297 | // Render an object 298 | render: (object, dt, just_compute = ['camera','light','group'].includes(object.type), buffer) => { 299 | 300 | // If the object has a texture 301 | if(object.t) { 302 | 303 | // Set the texture's target (2D or cubemap) 304 | W.gl.bindTexture(3553 /* TEXTURE_2D */, W.textures[object.t.id]); 305 | 306 | // Pass texture 0 to the sampler 307 | W.gl.uniform1i(W.gl.getUniformLocation(W.program, 'sampler'), 0); 308 | } 309 | 310 | // If the object has an animation, increment its timer... 311 | if(object.f < object.a) object.f += dt; 312 | 313 | // ...but don't let it go over the animation duration. 314 | if(object.f > object.a) object.f = object.a; 315 | 316 | // Compose the model matrix from lerped transformations 317 | W.next[object.n].m = W.animation(object.n); 318 | 319 | // If the object is in a group: 320 | if(W.next[object.g]){ 321 | 322 | // premultiply the model matrix by the group's model matrix. 323 | W.next[object.n].m.preMultiplySelf(W.next[object.g].M || W.next[object.g].m); 324 | } 325 | 326 | // send the model matrix to the vertex shader 327 | W.gl.uniformMatrix4fv( 328 | W.gl.getUniformLocation(W.program, 'm'), 329 | false, 330 | (W.next[object.n].M || W.next[object.n].m).toFloat32Array() 331 | ); 332 | 333 | // send the inverse of the model matrix to the vertex shader 334 | W.gl.uniformMatrix4fv( 335 | W.gl.getUniformLocation(W.program, 'im'), 336 | false, 337 | (new DOMMatrix(W.next[object.n].M || W.next[object.n].m)).invertSelf().toFloat32Array() 338 | ); 339 | 340 | // Don't render invisible items (camera, light, groups, camera's parent) 341 | if(!just_compute){ 342 | 343 | // Set up the position buffer 344 | W.gl.bindBuffer(34962 /* ARRAY_BUFFER */, W.models[object.type].verticesBuffer); 345 | W.gl.vertexAttribPointer(buffer = W.gl.getAttribLocation(W.program, 'pos'), 3, 5126 /* FLOAT */, false, 0, 0) 346 | W.gl.enableVertexAttribArray(buffer); 347 | 348 | // Set up the texture coordinatess buffer (if any) 349 | if(W.models[object.type].uvBuffer){ 350 | W.gl.bindBuffer(34962 /* ARRAY_BUFFER */, W.models[object.type].uvBuffer); 351 | W.gl.vertexAttribPointer(buffer = W.gl.getAttribLocation(W.program, 'uv'), 2, 5126 /* FLOAT */, false, 0, 0); 352 | W.gl.enableVertexAttribArray(buffer); 353 | } 354 | 355 | // Set the normals buffer 356 | if((object.s || W.models[object.type].customNormals) && W.models[object.type].normalsBuffer){ 357 | W.gl.bindBuffer(34962 /* ARRAY_BUFFER */, W.models[object.type].normalsBuffer); 358 | W.gl.vertexAttribPointer(buffer = W.gl.getAttribLocation(W.program, 'normal'), 3, 5126 /* FLOAT */, false, 0, 0); 359 | W.gl.enableVertexAttribArray(buffer); 360 | } 361 | 362 | // Other options: [smooth, shading enabled, ambient light, texture/color mix] 363 | W.gl.uniform4f( 364 | 365 | W.gl.getUniformLocation(W.program, 'o'), 366 | 367 | // Enable smooth shading if "s" is true 368 | object.s, 369 | 370 | // Enable shading if in TRIANGLE* mode and object.ns disabled 371 | ((object.mode > 3) || (W.gl[object.mode] > 3)) && !object.ns ? 1 : 0, 372 | 373 | // Ambient light 374 | W.ambientLight || 0.2, 375 | 376 | // Texture/color mix (if a texture is present. 0: fully textured, 1: fully colored) 377 | object.mix 378 | ); 379 | 380 | // If the object is a billboard: send a specific uniform to the shaders: 381 | // [width, height, isBillboard = 1, 0] 382 | W.gl.uniform4f( 383 | W.gl.getUniformLocation(W.program, 'bb'), 384 | 385 | // Size 386 | object.w, 387 | object.h, 388 | 389 | // is a billboard 390 | object.type == 'billboard', 391 | 392 | // Reserved 393 | 0 394 | ); 395 | 396 | // Set up the indices (if any) 397 | if(W.models[object.type].indicesBuffer){ 398 | W.gl.bindBuffer(34963 /* ELEMENT_ARRAY_BUFFER */, W.models[object.type].indicesBuffer); 399 | } 400 | 401 | // Set the object's color 402 | W.gl.vertexAttrib4fv( 403 | W.gl.getAttribLocation(W.program, 'col'), 404 | W.col(object.b) 405 | ); 406 | 407 | // Draw 408 | // Both indexed and unindexed models are supported. 409 | // You can keep the "drawElements" only if all your models are indexed. 410 | if(W.models[object.type].indicesBuffer){ 411 | W.gl.drawElements(+object.mode || W.gl[object.mode], W.models[object.type].indices.length, 5123 /* UNSIGNED_SHORT */, 0); 412 | } 413 | else { 414 | W.gl.drawArrays(+object.mode || W.gl[object.mode], 0, W.models[object.type].vertices.length / 3); 415 | } 416 | } 417 | }, 418 | 419 | // Helpers 420 | // ------- 421 | 422 | // Interpolate a property between two values 423 | lerp: (item, property) => 424 | W.next[item]?.a 425 | ? W.current[item][property] + (W.next[item][property] - W.current[item][property]) * (W.next[item].f / W.next[item].a) 426 | : W.next[item][property], 427 | 428 | // Transition an item 429 | animation: (item, m = new DOMMatrix) => 430 | W.next[item] 431 | ? m 432 | .translateSelf(W.lerp(item, 'x'), W.lerp(item, 'y'), W.lerp(item, 'z')) 433 | .rotateSelf(W.lerp(item, 'rx'),W.lerp(item, 'ry'),W.lerp(item, 'rz')) 434 | .scaleSelf(W.lerp(item, 'w'),W.lerp(item, 'h'),W.lerp(item, 'd')) 435 | : m, 436 | 437 | // Compute the distance squared between two objects (useful for sorting transparent items) 438 | dist: (a, b = W.next.camera) => a?.m && b?.m ? (b.m.m41 - a.m.m41)**2 + (b.m.m42 - a.m.m42)**2 + (b.m.m43 - a.m.m43)**2 : 0, 439 | 440 | // Set the ambient light level (0 to 1) 441 | ambient: a => W.ambientLight = a, 442 | 443 | // Convert an rgb/rgba hex string into a vec4 444 | col: c => [...c.replace("#","").match(c.length < 5 ? /./g : /../g).map(a => ('0x' + a) / (c.length < 5 ? 15 : 255)), 1], // rgb / rgba / rrggbb / rrggbbaa 445 | 446 | // Add a new 3D model 447 | add: (name, objects) => { 448 | W.models[name] = objects; 449 | if(objects.normals){ 450 | W.models[name].customNormals = 1; 451 | } 452 | W[name] = settings => W.setState(settings, name); 453 | }, 454 | 455 | // Built-in objects 456 | // ---------------- 457 | 458 | group: t => W.setState(t, 'group'), 459 | 460 | move: (t, delay) => setTimeout(()=>{ W.setState(t) }, delay || 1), 461 | 462 | delete: (t, delay) => setTimeout(()=>{ delete W.next[t] }, delay || 1), 463 | 464 | camera: (t, delay) => setTimeout(()=>{ W.setState(t, t.n = 'camera') }, delay || 1), 465 | 466 | light: (t, delay) => delay ? setTimeout(()=>{ W.setState(t, t.n = 'light') }, delay) : W.setState(t, t.n = 'light'), 467 | }; 468 | 469 | // Smooth normals computation plug-in (optional) 470 | // ============================================= 471 | 472 | W.smooth = (state, dict = {}, vertices = [], iterate, iterateSwitch, i, j, A, B, C, Ai, Bi, Ci, normal) => { 473 | 474 | // Prepare smooth normals array 475 | W.models[state.type].normals = []; 476 | 477 | // Fill vertices array: [[x,y,z],[x,y,z]...] 478 | for(i = 0; i < W.models[state.type].vertices.length; i+=3){ 479 | vertices.push(W.models[state.type].vertices.slice(i, i+3)); 480 | } 481 | 482 | // Iterator 483 | if(iterate = W.models[state.type].indices) iterateSwitch = 1; 484 | else iterate = vertices, iterateSwitch = 0; 485 | 486 | // Iterate twice on the vertices 487 | // - 1st pass: compute normals of each triangle and accumulate them for each vertex 488 | // - 2nd pass: save the final smooth normals values 489 | for(i = 0; i < iterate.length * 2; i+=3){ 490 | j = i % iterate.length; 491 | A = vertices[Ai = iterateSwitch ? W.models[state.type].indices[j] : j]; 492 | B = vertices[Bi = iterateSwitch ? W.models[state.type].indices[j+1] : j+1]; 493 | C = vertices[Ci = iterateSwitch ? W.models[state.type].indices[j+2] : j+2]; 494 | AB = [B[0] - A[0], B[1] - A[1], B[2] - A[2]]; 495 | BC = [C[0] - B[0], C[1] - B[1], C[2] - B[2]]; 496 | normal = i > j ? [0,0,0] : [AB[1] * BC[2] - AB[2] * BC[1], AB[2] * BC[0] - AB[0] * BC[2], AB[0] * BC[1] - AB[1] * BC[0]]; 497 | dict[A[0]+"_"+A[1]+"_"+A[2]] ||= [0,0,0]; 498 | dict[B[0]+"_"+B[1]+"_"+B[2]] ||= [0,0,0]; 499 | dict[C[0]+"_"+C[1]+"_"+C[2]] ||= [0,0,0]; 500 | W.models[state.type].normals[Ai] = dict[A[0]+"_"+A[1]+"_"+A[2]] = dict[A[0]+"_"+A[1]+"_"+A[2]].map((a,i) => a + normal[i]); 501 | W.models[state.type].normals[Bi] = dict[B[0]+"_"+B[1]+"_"+B[2]] = dict[B[0]+"_"+B[1]+"_"+B[2]].map((a,i) => a + normal[i]); 502 | W.models[state.type].normals[Ci] = dict[C[0]+"_"+C[1]+"_"+C[2]] = dict[C[0]+"_"+C[1]+"_"+C[2]].map((a,i) => a + normal[i]); 503 | } 504 | } 505 | 506 | 507 | // 3D models 508 | // ========= 509 | 510 | // Each model has: 511 | // - A vertices array [x, y, z, x, y, z...] 512 | // - A uv array [u, v, u, v...] (optional. Allows texturing... if absent: RGBA coloring only) 513 | // - An indices array (optional, enables drawElements rendering... if absent: drawArrays is ised) 514 | // - A normals array [nx, ny, nz, nx, ny, nz...] (optional... if absent: hard/smooth normals are computed by the framework when they're needed) 515 | // The buffers (vertices, uv, indices) are built automatically when they're needed 516 | // All models are optional, you can remove the ones you don't need to save space 517 | // Custom models can be added from the same model, an OBJ importer is available on https://xem.github.io/WebGLFramework/obj2js/ 518 | 519 | // Plane / billboard 520 | // 521 | // v1------v0 522 | // | | 523 | // | x | 524 | // | | 525 | // v2------v3 526 | 527 | W.add("plane", { 528 | vertices: [ 529 | .5, .5, 0, -.5, .5, 0, -.5,-.5, 0, 530 | .5, .5, 0, -.5,-.5, 0, .5,-.5, 0 531 | ], 532 | 533 | uv: [ 534 | 1, 1, 0, 1, 0, 0, 535 | 1, 1, 0, 0, 1, 0 536 | ], 537 | }); 538 | W.add("billboard", W.models.plane); 539 | 540 | // Cube 541 | // 542 | // v6----- v5 543 | // /| /| 544 | // v1------v0| 545 | // | | x | | 546 | // | |v7---|-|v4 547 | // |/ |/ 548 | // v2------v3 549 | 550 | W.add("cube", { 551 | vertices: [ 552 | .5, .5, .5, -.5, .5, .5, -.5,-.5, .5, // front 553 | .5, .5, .5, -.5,-.5, .5, .5,-.5, .5, 554 | .5, .5,-.5, .5, .5, .5, .5,-.5, .5, // right 555 | .5, .5,-.5, .5,-.5, .5, .5,-.5,-.5, 556 | .5, .5,-.5, -.5, .5,-.5, -.5, .5, .5, // up 557 | .5, .5,-.5, -.5, .5, .5, .5, .5, .5, 558 | -.5, .5, .5, -.5, .5,-.5, -.5,-.5,-.5, // left 559 | -.5, .5, .5, -.5,-.5,-.5, -.5,-.5, .5, 560 | -.5, .5,-.5, .5, .5,-.5, .5,-.5,-.5, // back 561 | -.5, .5,-.5, .5,-.5,-.5, -.5,-.5,-.5, 562 | .5,-.5, .5, -.5,-.5, .5, -.5,-.5,-.5, // down 563 | .5,-.5, .5, -.5,-.5,-.5, .5,-.5,-.5 564 | ], 565 | uv: [ 566 | 1, 1, 0, 1, 0, 0, // front 567 | 1, 1, 0, 0, 1, 0, 568 | 1, 1, 0, 1, 0, 0, // right 569 | 1, 1, 0, 0, 1, 0, 570 | 1, 1, 0, 1, 0, 0, // up 571 | 1, 1, 0, 0, 1, 0, 572 | 1, 1, 0, 1, 0, 0, // left 573 | 1, 1, 0, 0, 1, 0, 574 | 1, 1, 0, 1, 0, 0, // back 575 | 1, 1, 0, 0, 1, 0, 576 | 1, 1, 0, 1, 0, 0, // down 577 | 1, 1, 0, 0, 1, 0 578 | ] 579 | }); 580 | W.cube = settings => W.setState(settings, 'cube'); 581 | 582 | // Pyramid 583 | // 584 | // ^ 585 | // /\\ 586 | // // \ \ 587 | // /+-x-\-+ 588 | // // \/ 589 | // +------+ 590 | 591 | W.add("pyramid", { 592 | vertices: [ 593 | -.5,-.5, .5, .5,-.5, .5, 0, .5, 0, // Front 594 | .5,-.5, .5, .5,-.5,-.5, 0, .5, 0, // Right 595 | .5,-.5,-.5, -.5,-.5,-.5, 0, .5, 0, // Back 596 | -.5,-.5,-.5, -.5,-.5, .5, 0, .5, 0, // Left 597 | .5,-.5, .5, -.5,-.5, .5, -.5,-.5,-.5, // down 598 | .5,-.5, .5, -.5,-.5,-.5, .5,-.5,-.5 599 | ], 600 | uv: [ 601 | 0, 0, 1, 0, .5, 1, // Front 602 | 0, 0, 1, 0, .5, 1, // Right 603 | 0, 0, 1, 0, .5, 1, // Back 604 | 0, 0, 1, 0, .5, 1, // Left 605 | 1, 1, 0, 1, 0, 0, // down 606 | 1, 1, 0, 0, 1, 0 607 | ] 608 | }); 609 | 610 | // Sphere 611 | // 612 | // = = 613 | // = = 614 | // = = 615 | // = x = 616 | // = = 617 | // = = 618 | // = = 619 | 620 | ((i, ai, j, aj, p1, p2, vertices = [], indices = [], uv = [], precision = 20) => { 621 | for(j = 0; j <= precision; j++){ 622 | aj = j * Math.PI / precision; 623 | for(i = 0; i <= precision; i++){ 624 | ai = i * 2 * Math.PI / precision; 625 | vertices.push(+(Math.sin(ai) * Math.sin(aj)/2).toFixed(6), +(Math.cos(aj)/2).toFixed(6), +(Math.cos(ai) * Math.sin(aj)/2).toFixed(6)); 626 | uv.push((Math.sin((i/precision))) * 3.5, -Math.sin(j/precision)) 627 | if(i < precision && j < precision){ 628 | indices.push(p1 = j * (precision + 1) + i, p2 = p1 + (precision + 1), (p1 + 1), (p1 + 1), p2, (p2 + 1)); 629 | } 630 | } 631 | } 632 | W.add("sphere", {vertices, uv, indices}); 633 | })(); -------------------------------------------------------------------------------- /webgl/mario.js: -------------------------------------------------------------------------------- 1 | W.add("mario", { 2 | vertices: [.01,.19,.15,.01,.17,.13,0,.17,.12,.02,.17,.12,-.02,.16,.12,.04,.16,.12,-.03,.18,.15,.05,.18,.15,-.04,.16,.13,.06,.16,.13,-.06,.16,.14,.08,.16,.14,-.07,.15,.14,.09,.15,.14,-.08,.16,.18,.1,.16,.18,-.04,.17,.19,.06,.17,.19,-.06,.16,.19,.08,.16,.19,-.09,.15,.17,.1,.15,.17,-.1,.14,.17,.12,.14,.17,-.11,.13,.19,.13,.13,.19,.01,.18,.18,-.02,.17,.18,.04,.17,.18,-.07,.15,.2,.09,.15,.2,-.09,.13,.21,.11,.13,.21,.2,-.05,.26,.21,-.06,.24,.22,-.05,.24,-.2,-.05,.24,-.19,-.06,.24,-.19,-.05,.26,.18,-.03,.15,.15,.01,.14,.19,-.03,.17,-.17,-.03,.17,-.13,.01,.14,-.16,-.03,.15,.15,-.04,.25,.18,-.02,.26,-.16,-.02,.26,-.13,-.04,.25,.13,-.03,.16,.18,-.05,.18,-.16,-.05,.18,-.11,-.03,.16,.2,-.05,.18,-.18,-.05,.18,.21,-.06,.21,-.19,-.06,.21,.14,-.05,.18,-.12,-.05,.18,.15,.02,.19,-.13,.02,.19,.17,-.03,.21,-.15,-.03,.21,.21,-.04,.2,-.19,-.04,.2,.21,-.03,.24,-.19,-.03,.24,.18,-.01,.25,-.17,-.01,.25,.16,0,.24,-.14,0,.24,-.04,.15,.12,.01,.16,.15,.01,.16,.11,.06,.15,.12,-.06,.15,.16,.08,.15,.16,-.1,.11,.13,.12,.11,.13,-.12,.11,.19,.14,.11,.19,.01,.15,.08,-.06,.11,.08,.08,.11,.08,.01,.15,.1,-.04,.16,.19,.06,.16,.19,-.06,.15,.19,.08,.15,.19,-.03,.12,.06,.05,.12,.06,.01,.12,.06,.07,-.15,.21,.01,-.13,.17,.09,-.13,.17,-.07,-.13,.17,-.05,-.15,.21,.08,-.15,.13,-.06,-.15,.13,.07,-.13,.1,-.05,-.13,.1,.03,-.16,.13,-.02,-.16,.13,.04,-.14,.1,-.02,-.14,.1,.01,-.06,.1,.05,-.06,.1,-.03,-.06,.1,.1,-.11,.1,-.08,-.11,.1,.12,-.12,.14,-.1,-.12,.14,.14,-.09,.11,-.12,-.09,.11,.15,-.1,.14,-.13,-.1,.14,.14,-.05,.18,-.12,-.05,.18,.14,-.09,.23,-.12,-.09,.23,.16,0,.24,.17,.02,.28,.15,-.04,.25,-.13,-.04,.25,-.15,.02,.28,-.14,0,.24,.17,.04,.2,-.15,.04,.2,.15,.02,.19,-.13,.02,.19,.16,.04,.18,-.14,.04,.18,.15,.01,.14,-.13,.01,.14,.15,.08,.17,-.13,.08,.17,.13,.07,.11,-.11,.07,.11,.12,.11,.13,-.1,.11,.13,.08,.11,.08,-.06,.11,.08,.1,.07,.08,-.08,.07,.08,.12,.01,.11,-.1,.01,.11,.11,-.03,.14,-.09,-.03,.14,.13,-.03,.16,-.11,-.03,.16,.1,.01,.09,-.08,.01,.09,.15,.06,.29,.13,.1,.26,.13,.11,.31,-.11,.11,.31,-.11,.1,.26,-.13,.06,.29,.15,.06,.26,-.13,.06,.26,.14,.08,.22,-.12,.08,.22,.14,.11,.19,-.12,.11,.19,.13,.1,.22,-.11,.1,.22,.01,.07,.05,.05,.12,.06,-.03,.12,.06,.01,-.15,.21,.01,.12,.06,-.16,0,.28,-.15,.02,.28,-.13,-.04,.25,-.12,-.09,.23,-.13,.06,.29,-.13,.07,.3,-.13,.15,.31,-.13,.16,.3,-.1,.21,.32,-.1,.21,.33,-.05,.24,.35,-.04,.24,.34,.01,.25,.35,.01,.25,.34,.01,.01,.48,-.05,-.01,.45,-.07,-.07,.41,.01,-.07,.41,-.05,-.14,.33,.01,-.14,.34,-.06,-.17,.32,.01,-.19,.33,-.11,-.06,.39,-.1,-.13,.32,-.1,.01,.44,-.06,.05,.48,-.07,-.18,.28,.01,-.2,.29,-.14,-.12,.29,-.17,-.04,.35,-.14,.04,.42,-.1,.08,.46,.01,.06,.49,-.06,.1,.48,-.07,-.17,.25,.01,-.19,.25,.01,.16,.46,-.06,.14,.44,.01,.11,.49,-.11,.11,.41,-.16,.06,.37,-.18,-.01,.31,-.14,-.1,.26,.01,.16,.42,-.05,.14,.37,-.09,.12,.35,-.05,-.15,.21,.01,.16,.38,.01,.14,.33,-.05,.13,.33,-.11,.11,.31,.13,.11,.31,.15,.16,.31,.15,.06,.29,.12,.21,.32,.07,.13,.33,.06,.24,.34,.07,.14,.37,.08,.1,.48,.08,.05,.48,.08,-.17,.32,.12,-.13,.32,.07,-.14,.33,.09,-.17,.25,.07,-.15,.21,.07,-.15,.21,.15,.15,.31,.12,.21,.33,.11,.12,.35,.15,.07,.3,.06,.24,.35,.16,-.1,.26,.14,-.09,.23,.2,-.01,.31,.18,0,.28,.18,.06,.37,.13,.11,.41,.08,.14,.44,.16,-.12,.29,.09,-.18,.28,.19,-.04,.35,.16,.04,.42,.12,.08,.46,.12,.01,.44,.13,-.06,.39,.07,-.01,.45,.09,-.07,.41,.17,.02,.28,.15,-.04,.25,.01,.22,.24,.05,.18,.22,.05,.21,.22,-.03,.21,.22,-.03,.18,.22,.01,.27,.19,.04,.26,.19,.01,.26,.17,-.02,.26,.19,.06,.16,.19,.01,.16,.15,.04,.18,.16,-.02,.18,.16,-.04,.16,.19,.01,.16,.15,.01,.18,.14,.07,.18,.19,.06,.16,.19,.04,.18,.16,-.02,.18,.16,-.04,.16,.19,-.05,.18,.19,.05,.23,.16,.01,.23,.15,-.03,.23,.16,.01,.21,.14,.05,.24,.22,.01,.24,.23,-.03,.24,.22,.01,.26,.21,.07,.23,.19,-.05,.23,.19,.07,.21,.19,-.05,.21,.19,.01,.19,.24,.01,.16,.23,.04,.14,.21,-.02,.14,.21,.05,.21,.16,-.03,.21,.16,.01,.18,.14,-.04,.14,.2,-.02,.14,.21,-.04,.16,.19,.06,.16,.19,.04,.14,.21,.06,.14,.2,-.01,.15,.25,.03,.15,.25,-.04,.14,.25,.06,.14,.25,-.04,.14,.29,.06,.14,.29,-.08,.11,.25,.1,.11,.25,-.07,.12,.28,.09,.12,.28,-.11,.1,.26,.13,.1,.26,-.11,.11,.31,.13,.11,.31,.01,.15,.29,-.05,.13,.33,.01,.14,.33,.07,.13,.33,-.02,.14,.28,.04,.14,.28,.01,.15,.25,-.06,.15,.19,.08,.15,.19,-.07,.12,.21,.09,.12,.21,-.12,.11,.19,.14,.11,.19,-.11,.1,.22,.13,.1,.22,.01,.16,.23,.14,-.04,-.01,.14,-.05,.05,.12,-.05,.05,-.1,-.05,.05,-.12,-.05,.05,-.12,-.04,-.01,.12,.05,.05,.11,.05,.05,.13,-.01,.08,-.11,-.01,.08,-.09,.05,.05,-.1,.05,.05,.1,-.01,.08,-.08,-.01,.08,.14,.05,.01,.15,.01,-.02,.13,.06,0,-.11,.06,0,-.13,.01,-.02,-.12,.05,.01,.16,.06,.05,-.14,.06,.05,.21,-.05,.05,.2,-.04,-.01,-.19,-.05,.05,-.19,-.04,-.01,.21,.05,.05,.21,.03,-.01,-.19,.03,-.01,-.19,.05,.05,.2,-.04,-.01,.14,-.04,-.01,-.12,-.04,-.01,-.19,-.04,-.01,.16,-.01,.08,.21,0,.08,-.19,0,.08,-.14,-.01,.08,.27,.06,.05,.28,.04,-.01,.22,.03,-.01,.22,.06,.05,-.2,.03,-.01,-.26,.04,-.01,-.25,.06,.05,-.2,.06,.05,.28,-.04,0,.22,-.04,-.01,-.26,-.04,-.01,-.2,-.04,-.01,.28,-.04,0,.28,-.05,.05,.22,-.06,.05,.22,-.04,-.01,-.2,-.06,.05,-.26,-.05,.05,-.26,-.04,-.01,-.2,-.04,-.01,.28,0,.08,.22,0,.08,-.2,0,.08,-.26,0,.08,.12,.1,0,.11,.05,.05,.13,.06,0,-.11,.06,0,-.09,.05,.05,-.1,.1,0,.1,.05,.07,.1,0,.09,.1,-.01,.08,-.08,-.01,.08,-.08,0,.09,-.08,.05,.07,.11,-.07,0,.12,-.05,.05,.1,-.06,.04,-.08,-.06,.04,-.1,-.05,.05,-.09,-.07,0,.14,-.04,-.01,-.12,-.04,-.01,.15,.01,-.02,.16,.02,-.06,-.14,.02,-.06,-.13,.01,-.02,.14,-.06,-.05,-.12,-.06,-.05,.1,-.01,.08,.1,0,.09,-.08,0,.09,-.08,-.01,.08,.15,.07,-.06,-.13,.07,-.06,.17,.02,-.06,-.15,.02,-.06,.14,.1,-.08,-.12,.1,-.08,.14,.09,-.16,.08,.11,-.2,.08,.14,-.18,-.06,.14,-.18,-.06,.11,-.2,-.12,.09,-.16,.09,.09,-.3,.09,.08,-.28,.15,.03,-.3,-.13,.03,-.3,-.07,.08,-.28,-.07,.09,-.3,.02,-.05,-.23,.02,.03,-.3,.02,-.04,-.3,0,-.04,-.3,0,.03,-.3,0,-.05,-.23,.02,.03,-.3,0,.03,-.3,.09,-.07,-.32,.09,-.06,-.3,-.07,-.06,-.3,-.07,-.07,-.32,.14,-.04,-.3,-.12,-.04,-.3,.15,.04,-.38,.08,.09,-.36,-.06,.09,-.36,-.13,.04,-.38,.14,-.05,-.39,-.12,-.05,-.39,.08,-.09,-.39,-.06,-.09,-.39,.02,-.05,-.39,0,-.05,-.39,.02,.04,-.38,0,.04,-.38,.02,.04,-.38,0,.04,-.38,.09,-.06,-.22,-.07,-.06,-.22,.14,-.04,-.2,-.12,-.04,-.2,.15,.02,-.19,-.13,.02,-.19,.14,.08,-.19,-.12,.08,-.19,.09,-.08,-.19,.01,-.07,-.21,-.07,-.08,-.19,.14,-.05,-.18,-.12,-.05,-.18,.16,.02,-.15,-.14,.02,-.15,.02,.09,-.22,0,.09,-.22,.06,-.1,-.13,.01,-.09,-.13,-.04,-.1,-.13,.14,-.06,-.13,-.12,-.06,-.13,.16,.02,-.11,-.14,.02,-.11,.14,.1,-.12,-.12,.1,-.12,.09,.15,-.12,-.07,.15,-.12,.01,.15,-.18,.01,.17,-.11,.01,.16,-.05,.09,.14,-.06,-.07,.14,-.06,.06,-.09,-.06,-.05,-.09,-.06,.01,-.08,-.06,.07,.12,.01,-.05,.12,.01,.05,.06,.08,-.03,.06,.08,.04,0,.1,-.02,0,.1,.05,-.08,-.01,-.03,-.08,-.01,.05,-.08,.03,-.03,-.08,.03,.05,-.05,.08,-.03,-.05,.08,.04,0,.1,-.02,0,.1,.01,.13,0,.01,.06,.09,.01,0,.1,.01,-.08,-.01,.01,-.09,.03,.01,-.05,.09,.01,0,.1,.01,.02,-.23,.01,.02,-.23,.01,.02,-.23,.01,.02,-.23,.08,.1,-.38,.02,.03,-.41,0,.03,-.41,-.06,.1,-.38,.16,.05,-.41,-.14,.05,-.41,.14,-.07,-.42,-.12,-.07,-.42,.02,.03,-.41,.02,-.07,-.43,0,-.07,-.43,0,.03,-.41,.07,-.09,-.42,-.05,-.09,-.42,.01,.09,-.22,.01,.02,-.23,.01,-.05,-.23,.01,.02,-.23,.16,.07,-.47,.14,-.06,-.45,.14,-.05,-.48,.16,.07,-.43,.16,.14,-.43,.15,.07,-.4,.13,.13,-.4,.09,.13,-.38,.09,.16,-.39,.05,.13,-.39,.02,.14,-.43,.03,.07,-.4,.01,.07,-.43,.03,-.05,-.42,.03,-.06,-.45,.09,-.08,-.45,.09,-.07,-.48,.09,.07,-.38,.09,-.07,-.42,.14,-.05,-.42,.09,.17,-.5,.02,.07,-.5,.03,.14,-.5,.09,-.07,-.5,.16,.07,-.5,.14,-.05,-.5,.03,-.05,-.48,.02,.07,-.47,.09,.18,-.44,.15,.15,-.47,.09,.17,-.47,.03,.14,-.47,.14,-.05,-.5,.09,-.07,-.48,.09,-.07,-.5,.14,-.05,-.48,.09,-.07,-.48,.03,-.05,-.5,.09,-.07,-.5,.03,-.05,-.48,.02,.07,-.5,.03,.14,-.47,.03,.14,-.5,.02,.07,-.47,.15,.15,-.47,.16,.07,-.5,.14,.15,-.5,.16,.07,-.47,.16,.07,-.5,.14,-.05,-.48,.14,-.05,-.5,.16,.07,-.47,.02,.07,-.5,.03,-.05,-.48,.02,.07,-.47,.03,-.05,-.5,.14,.15,-.5,.09,.17,-.47,.15,.15,-.47,.09,.17,-.5,.09,.17,-.5,.03,.14,-.47,.09,.17,-.47,.03,.14,-.5,.03,-.05,-.5,.09,-.07,-.48,.14,.15,-.5,0,.14,-.43,0,.07,-.47,-.01,.14,-.47,.01,.07,-.43,-.01,.07,-.4,-.01,-.05,-.42,-.07,-.07,-.42,-.07,-.08,-.45,-.12,-.05,-.42,-.12,-.06,-.45,-.14,.07,-.43,-.14,.07,-.47,-.14,.14,-.43,-.13,.15,-.47,-.07,.17,-.47,-.07,.18,-.44,-.07,.16,-.39,-.11,.13,-.4,-.07,.13,-.38,-.13,.07,-.4,-.07,.07,-.38,-.03,.13,-.39,-.07,-.07,-.48,-.01,-.06,-.45,-.01,-.05,-.48,-.07,.17,-.5,-.14,.07,-.5,-.12,.15,-.5,-.07,-.07,-.5,-.12,-.05,-.48,-.14,.07,-.5,-.12,-.05,-.5,-.14,.07,-.47,-.14,.07,-.5,-.13,.15,-.47,-.12,.15,-.5,-.14,.07,-.47,-.12,-.05,-.48,-.07,-.07,-.48,-.01,-.05,-.48,0,.07,-.5,0,.07,-.47,-.01,-.05,-.5,-.07,-.07,-.48,-.12,-.05,-.5,-.07,-.07,-.5,-.12,-.05,-.48,-.01,-.05,-.5,-.07,-.07,-.48,-.07,-.07,-.5,-.01,-.05,-.48,-.07,.17,-.5,-.13,.15,-.47,-.07,.17,-.47,-.12,.15,-.5,-.01,.14,-.5,-.07,.17,-.47,-.01,.14,-.47,-.07,.17,-.5,-.01,.14,-.47,0,.07,-.5,-.01,.14,-.5,0,.07,-.47,0,.07,-.5,-.01,.14,-.5,-.12,-.05,-.5,-.01,-.05,-.5,.4,-.06,.05,.43,-.04,.05,.44,-.07,.05,.41,-.03,.05,.35,-.03,-.01,.35,.01,-.01,.31,.04,-.01,.34,.05,-.02,.34,.07,-.01,.37,.07,-.02,.37,.1,-.01,.41,.07,-.01,.41,.09,-.02,.44,.08,0,.42,.11,0,.4,-.07,.09,.4,-.06,.05,.44,-.07,.05,.37,-.07,.08,.35,0,.09,.31,-.05,.05,.31,0,.08,.3,-.01,.09,.29,.07,.06,.27,.06,.05,.28,.04,-.01,.4,.04,.1,.48,0,.09,.48,.04,.09,.4,0,.1,.41,-.03,.1,.46,-.07,.08,.48,.04,.04,.47,.04,.09,.45,.04,.05,.51,.04,.06,.51,.05,.04,.5,.08,.06,.5,.06,.03,.48,.07,.04,.45,-.07,.03,.48,-.07,.02,.46,-.06,.01,.48,-.04,.03,.45,-.05,.02,.45,-.04,.03,.41,.01,.05,.45,.04,.05,.45,0,.05,.41,.04,.05,.38,.06,.01,.46,-.03,.03,.47,-.03,.08,.45,-.03,.05,.49,-.03,.02,.48,-.02,.01,.5,0,.02,.47,-.01,.01,.46,0,.03,.37,.08,.06,.4,.08,.09,.41,.08,.05,.34,.07,.07,.34,.09,.03,.31,.06,.05,.31,.04,-.01,.29,.04,-.02,.48,0,.03,.45,0,.05,.51,0,.03,.5,.01,.01,.51,.04,.03,.49,.02,.01,.48,.04,.03,.34,.07,-.01,.37,.11,.01,.4,.09,.03,.43,.08,.03,.38,.06,.01,.41,.06,.02,.31,-.04,0,.35,-.07,.01,.3,-.07,.06,.28,0,.08,.41,-.03,.05,.46,-.04,.08,.43,-.04,.05,.46,0,.03,.45,-.03,.05,.44,0,.05,.46,-.03,.03,.47,-.01,.01,.48,-.02,.01,.41,.01,.05,.47,0,.08,.44,0,.05,.47,.08,.09,.45,.07,.05,.48,.04,.03,.48,0,.03,.49,.02,.01,.5,.01,.01,.45,-.07,.03,.45,-.05,.02,.46,-.06,.01,.45,-.04,.03,.41,.04,.05,.45,.04,.05,.48,.04,.04,.5,.06,.03,.51,.05,.04,.48,.07,.04,.45,.07,.05,.29,-.06,-.01,.28,-.05,.05,.44,.06,.01,.41,.06,.02,.4,.07,.03,.41,.08,.05,.35,-.07,.01,.31,-.04,0,.29,-.06,-.01,.4,.07,.03,.44,.06,.01,.44,.08,0,.45,.04,.05,.37,.11,.01,.29,.04,-.02,.28,-.04,0,.42,.11,0,.28,-.04,0,.28,.04,-.01,-.46,-.04,.03,-.41,-.04,.05,-.43,-.04,.03,-.44,-.04,.08,-.44,-.07,.08,-.39,-.03,.1,-.39,-.07,.09,-.33,0,.09,-.35,-.07,.08,-.29,-.05,.05,-.33,-.07,.01,-.29,-.04,0,-.38,.08,.09,-.39,.08,.05,-.43,.07,.05,-.35,.08,.06,-.32,.07,.07,-.32,.09,.03,-.29,.06,.05,-.29,.04,-.01,-.27,.07,.05,-.27,.04,-.02,-.25,.06,.05,-.26,.04,-.01,-.27,-.06,-.01,-.26,.04,-.01,-.26,-.04,-.01,-.27,.04,-.02,-.29,-.04,0,-.29,.04,-.01,-.33,-.03,-.01,-.33,.01,-.01,-.39,-.03,.05,-.39,.01,.05,-.29,0,.08,-.28,-.01,.09,-.28,-.07,.06,-.26,-.05,.05,-.26,-.04,-.01,-.35,.11,.01,-.39,.09,-.02,-.4,.11,0,-.35,.1,-.01,-.32,.07,-.01,-.35,.07,-.02,-.32,.05,-.02,-.36,.06,.01,-.39,0,.1,-.43,0,.05,-.39,.01,.05,-.46,0,.09,-.39,.04,.1,-.46,.04,.09,-.39,.04,.05,-.43,.04,.05,-.43,.04,.05,-.45,.04,.09,-.45,.08,.09,-.48,.08,.06,-.46,.07,.04,-.48,.06,.03,-.48,0,.02,-.43,0,.05,-.44,0,.02,-.45,0,.08,-.45,-.03,.08,-.49,.05,.04,-.49,.04,.06,-.46,.04,.04,-.42,.08,0,-.39,.07,-.01,-.39,.06,.02,-.35,.11,.01,-.38,.09,.03,-.41,.08,.03,-.4,.11,0,-.42,.08,0,-.27,-.06,-.01,-.38,.07,.03,-.39,.06,.02,-.36,.06,.01,-.39,.04,.05,-.38,.07,.03,-.39,.08,.05,-.43,.07,.05,-.38,-.06,.05,-.33,-.07,.01,-.46,0,.03,-.49,0,.03,-.49,.04,.03,-.42,-.07,.05,-.43,-.07,.03,-.38,-.06,.05,-.43,-.03,.05,-.44,-.03,.03,-.39,-.03,.05,-.26,0,.08,-.47,.02,.01,-.46,.04,.03,-.48,.01,.01,-.43,-.04,.03,-.42,-.07,.05,-.43,-.07,.03,-.41,-.04,.05,-.44,-.05,.02,-.45,-.06,.01,-.43,.04,.05,-.46,.04,.04,-.46,.04,.03,-.43,0,.05,-.46,0,.03,-.43,.04,.05,-.32,.07,-.01,-.46,-.07,.02,-.48,.06,.03,-.49,.05,.04,-.46,.07,.04,-.45,-.01,.01,-.46,-.02,.01,-.47,-.03,.02,-.43,0,.05,-.43,-.03,.05,-.44,0,.02,-.44,-.03,.03,-.45,-.01,.01,-.46,-.02,.01,-.42,.06,.01,-.44,-.05,.02,-.45,-.06,.01,-.42,.06,.01,-.47,.02,.01,-.48,.01,.01], 3 | uv: [.78,.77,.79,.73,.82,.73,.82,.73,.85,.75,.85,.75,.85,.79,.85,.79,.88,.77,.88,.77,.91,.78,.91,.78,.93,.8,.93,.8,.93,.85,.93,.85,.86,.84,.86,.84,.89,.86,.89,.86,.95,.84,.95,.84,.97,.85,.97,.85,.98,.88,.98,.88,.77,.8,.82,.82,.82,.82,.91,.87,.91,.87,.94,.9,.94,.9,.31,.12,.34,.13,.33,.12,.33,.12,.34,.13,.31,.12,.4,.08,.42,.03,.39,.08,.39,.08,.42,.03,.4,.08,.29,.12,.31,.09,.31,.09,.29,.12,.45,.07,.4,.12,.4,.12,.45,.07,.39,.11,.39,.11,.36,.12,.36,.12,.4,.15,.4,.15,.34,.03,.34,.03,.34,.07,.34,.07,.36,.1,.36,.1,.32,.1,.32,.1,.31,.07,.31,.07,.31,.05,.31,.05,.63,.68,.56,.71,.56,.67,.63,.68,.65,.72,.65,.72,.71,.7,.71,.7,.72,.76,.72,.76,.56,.64,.65,.65,.65,.65,.56,.66,.62,.75,.62,.75,.66,.75,.66,.75,.6,.63,.6,.63,.56,.62,.88,.99,.89,.97,.84,.96,.84,.96,.88,.99,.86,.94,.86,.94,.86,.91,.86,.91,.89,.94,.89,.94,.89,.92,.89,.92,.91,.89,.86,.89,.86,.89,.84,.9,.84,.9,.83,.93,.83,.93,.8,.9,.8,.9,.8,.92,.8,.92,.76,.92,.76,.92,.78,.99,.78,.99,.66,.96,.62,.98,.72,.98,.72,.98,.62,.98,.66,.96,.63,.91,.63,.91,.66,.91,.66,.91,.63,.89,.63,.89,.69,.85,.69,.85,.6,.87,.6,.87,.61,.82,.61,.82,.54,.82,.54,.82,.54,.77,.54,.77,.63,.8,.63,.8,.7,.83,.7,.83,.78,.88,.78,.88,.74,.88,.74,.88,.71,.82,.71,.82,.58,.98,.55,.94,.53,.98,.53,.98,.55,.94,.58,.98,.59,.95,.59,.95,.58,.91,.58,.91,.55,.87,.55,.87,.55,.91,.55,.91,.72,.8,.56,.75,.56,.75,.88,.99,.56,.75,.98,.22,.99,.19,1,.27,.99,.3,.98,.1,.96,.11,.94,.07,.95,.06,.91,.04,.91,.05,.84,.03,.84,.03,.76,.02,.77,.02,.77,.21,.85,.22,.87,.26,.77,.26,.85,.3,.77,.3,.85,.33,.77,.32,.91,.25,.9,.3,.91,.21,.85,.19,.86,.34,.77,.34,.93,.3,.93,.23,.92,.18,.89,.16,.77,.19,.86,.16,.88,.35,.77,.36,.76,.14,.86,.13,.77,.17,.92,.13,.95,.15,.96,.23,.96,.3,.76,.1,.84,.07,.91,.1,.86,.37,.76,.07,.77,.01,.86,.02,.95,.05,.95,.05,.95,.06,.98,.1,.91,.04,.86,.02,.84,.03,.84,.07,.86,.16,.85,.19,.85,.33,.9,.3,.85,.3,.88,.35,.86,.37,.77,.37,.94,.07,.91,.05,.91,.1,.96,.11,.84,.03,.96,.3,.99,.3,.96,.23,.98,.22,.95,.15,.92,.13,.86,.13,.93,.3,.86,.34,.93,.23,.92,.18,.89,.16,.91,.21,.91,.25,.85,.22,.87,.26,.99,.19,1,.27,.59,.58,.65,.58,.64,.56,.64,.56,.65,.58,.59,.53,.61,.53,.59,.51,.61,.53,.71,.53,.67,.47,.66,.49,.66,.49,.71,.53,.59,.45,.67,.47,.69,.53,.71,.53,.66,.49,.66,.49,.71,.53,.69,.53,.63,.51,.59,.49,.63,.51,.59,.47,.62,.55,.59,.56,.62,.55,.59,.54,.64,.53,.64,.53,.67,.53,.67,.53,.59,.59,.59,.6,.71,.58,.71,.58,.65,.5,.65,.5,.59,.46,.84,.42,.8,.44,.83,.41,.83,.41,.8,.44,.84,.42,.77,.51,.77,.51,.83,.51,.83,.51,.84,.58,.84,.58,.91,.52,.91,.52,.89,.58,.89,.58,.98,.54,.98,.54,.98,.63,.98,.63,.74,.59,.86,.65,.74,.65,.86,.65,.79,.57,.79,.57,.74,.52,.88,.41,.88,.41,.89,.44,.89,.44,.98,.41,.98,.41,.98,.46,.98,.46,.74,.46,.26,.31,.3,.32,.3,.37,.3,.37,.3,.32,.26,.31,.38,.33,.38,.37,.35,.32,.35,.32,.38,.37,.38,.33,.34,.37,.34,.37,.42,.33,.46,.33,.43,.37,.43,.37,.46,.33,.42,.33,.39,.3,.39,.3,.29,.25,.26,.26,.29,.25,.26,.26,.4,.25,.44,.26,.44,.26,.4,.25,.49,.26,.49,.31,.49,.31,.49,.26,.35,.28,.35,.25,.35,.25,.35,.28,.4,.17,.45,.17,.45,.24,.4,.23,.45,.24,.45,.17,.4,.17,.4,.23,.49,.17,.49,.24,.49,.17,.49,.24,.26,.17,.3,.17,.3,.23,.26,.24,.3,.23,.3,.17,.26,.17,.26,.24,.34,.17,.34,.23,.34,.23,.34,.17,.18,.84,.19,.91,.22,.84,.22,.84,.19,.91,.18,.84,.18,.92,.19,.98,.23,.96,.23,.96,.19,.98,.18,.92,.39,.85,.34,.9,.39,.93,.39,.93,.34,.9,.39,.85,.34,.82,.34,.82,.29,.82,.28,.78,.28,.78,.29,.82,.36,.78,.36,.78,.35,.95,.37,.97,.37,.97,.35,.95,.23,.78,.23,.78,.28,.77,.28,.77,.2,.75,.2,.75,.2,.66,.14,.61,.14,.65,.14,.65,.14,.61,.2,.66,.15,.51,.14,.54,.21,.51,.21,.51,.14,.54,.15,.51,.49,.58,.55,.51,.48,.51,.48,.51,.55,.51,.49,.58,.04,.51,.04,.51,.42,.49,.42,.51,.42,.51,.42,.49,.37,.51,.37,.51,.21,.42,.14,.42,.14,.42,.21,.42,.34,.42,.34,.42,.43,.42,.43,.42,.49,.42,.49,.42,.56,.42,.56,.42,.04,.42,.04,.42,.42,.6,.42,.6,.37,.62,.37,.62,.27,.63,.27,.63,.2,.63,.2,.63,.42,.65,.5,.64,.42,.65,.37,.64,.37,.64,.28,.68,.28,.68,.04,.59,.04,.59,.45,.71,.5,.72,.45,.71,.36,.7,.36,.7,.28,.72,.28,.72,.2,.7,.2,.7,.15,.71,.15,.71,.03,.64,.03,.71,.03,.78,.14,.76,.14,.76,.45,.77,.45,.77,.5,.77,.11,.85,.11,.85,.11,.94,.11,.94,.11,.99,.11,.99,.46,.82,.46,.82,.46,.89,.46,.89,.45,.97,.45,.97,.44,.99,.44,.99,.02,.85,.02,.96,.03,1,.5,.82,.5,.9,.48,.98,.47,.99,.56,.58,.56,.58,.01,.55,.01,.55,.14,.39,.03,.39,.03,.39,.14,.39,.2,.39,.2,.39,.37,.39,.37,.39,.56,.39,.48,.39,.48,.39,.56,.39,.44,.39,.44,.39,.03,.6,.01,.56,.5,.59,.55,.59,.23,.21,.2,.05,.22,.04,.22,.21,.2,.3,.19,.21,.17,.29,.13,.27,.13,.3,.17,.29,.2,.3,.19,.21,.22,.21,.19,.07,.2,.05,.13,.03,.13,.01,.13,.22,.13,.06,.19,.07,.12,.36,0,.22,.03,.33,.12,.01,0,.22,.05,.03,.22,.04,.23,.21,.13,.33,.22,.33,.13,.36,.22,.33,0,.35,.12,.37,.12,.35,0,.37,0,.37,.12,.35,0,.35,.12,.37,0,.35,.12,.37,.12,.35,0,.37,0,.37,.12,.35,0,.35,.12,.37,0,.35,.12,.37,.12,.35,0,.37,.12,.35,0,.37,.12,.37,0,.35,.12,.35,0,.37,.12,.37,0,.35,.12,.35,0,.37,.12,.37,0,.35,.05,.03,.13,.01,.03,.33,.2,-.7,.23,-.79,.22,-.67,.22,-.79,.19,-.79,.19,-.93,.13,-.94,.13,-.97,.19,-.93,.2,-.95,.22,-.79,.23,-.79,.2,-.7,.22,-.67,.13,-.64,.13,-.67,.13,-.7,.17,-.71,.13,-.73,.19,-.79,.13,-.78,.17,-.71,.13,-.99,.2,-.95,.22,-.96,.12,-.64,0,-.78,.03,-.67,.12,-.99,.12,-.63,0,-.65,.12,-.65,0,-.63,.12,-.65,0,-.63,0,-.65,.12,-.63,.22,-.96,.13,-.99,0,-.63,.12,-.65,.12,-.63,0,-.65,.12,-.63,0,-.65,.12,-.65,0,-.63,.12,-.65,0,-.63,0,-.65,.12,-.63,0,-.65,.12,-.63,0,-.63,.12,-.65,0,-.65,.12,-.63,0,-.63,.12,-.65,.12,-.63,0,-.65,.12,-.65,0,-.63,0,-.78,.03,-.67,.05,-.97,.05,-.97,.63,.17,.67,.15,.67,.18,.63,.14,.58,.14,.57,.11,.54,.08,.56,.06,.56,.05,.6,.05,.59,.03,.64,.04,.63,.02,.66,.01,.63,0,.63,.37,.63,.36,.67,.37,.6,.37,.58,.29,.54,.34,.55,.3,.53,.3,.53,.23,.51,.24,.51,.26,.64,.26,.69,.3,.69,.26,.64,.3,.63,.33,.67,.37,.72,.26,.69,.26,.68,.26,.73,.26,.74,.25,.72,.22,.74,.24,.72,.22,.71,.37,.71,.36,.72,.35,.71,.34,.72,.34,.71,.34,.63,.11,.68,.08,.68,.11,.63,.08,.61,.06,.72,.33,.68,.33,.68,.33,.72,.33,.74,.32,.72,.3,.74,.31,.73,.3,.6,.22,.63,.22,.64,.22,.58,.23,.57,.21,.55,.24,.54,.26,.53,.26,.73,.3,.69,.3,.73,.3,.75,.29,.73,.26,.75,.27,.73,.26,.56,.23,.6,.19,.62,.2,.66,.2,.61,.24,.65,.22,.54,.34,.57,.36,.53,.36,.51,.3,.64,.33,.67,.34,.67,.34,.72,.12,.68,.15,.68,.11,.72,.15,.73,.12,.73,.14,.64,.29,.68,.3,.68,.3,.69,.22,.69,.23,.72,.08,.72,.11,.74,.09,.74,.1,.7,.18,.72,.16,.72,.17,.7,.15,.64,.26,.69,.26,.72,.08,.73,.06,.74,.07,.72,.05,.68,.05,.53,.35,.51,.35,.67,.02,.65,.04,.62,.04,.63,.04,.57,.17,.54,.15,.53,.16,.63,.22,.67,.2,.67,.19,.68,.08,.59,.02,.53,.07,.51,.15,.64,.18,.51,.34,.51,.08,.7,.34,.66,.34,.7,.34,.66,.34,.66,.36,.63,.33,.62,.36,.58,.29,.59,.37,.54,.34,.57,.36,.54,.34,.63,.22,.63,.22,.68,.23,.6,.22,.57,.23,.56,.21,.54,.24,.54,.26,.53,.23,.53,.26,.51,.24,.51,.26,.53,.16,.51,.08,.51,.15,.53,.07,.54,.15,.54,.08,.57,.14,.57,.11,.63,.14,.63,.11,.54,.3,.53,.3,.53,.36,.51,.35,.51,.34,.59,.02,.63,.02,.63,.01,.59,.03,.56,.05,.59,.05,.56,.06,.6,.06,.63,.3,.68,.3,.63,.29,.68,.3,.63,.26,.68,.26,.63,.26,.68,.26,.67,.26,.68,.26,.68,.22,.71,.22,.71,.22,.73,.24,.71,.3,.67,.3,.71,.3,.67,.3,.67,.33,.73,.25,.71,.26,.71,.26,.65,.01,.63,.04,.64,.04,.59,.19,.62,.2,.65,.2,.63,.18,.66,.19,.53,.35,.62,.22,.64,.22,.6,.24,.63,.08,.62,.04,.63,.05,.67,.05,.62,.17,.57,.17,.72,.29,.72,.29,.72,.26,.66,.37,.7,.36,.62,.36,.67,.33,.71,.33,.63,.33,.51,.3,.73,.27,.72,.26,.73,.29,.69,.15,.66,.18,.69,.18,.66,.15,.71,.34,.71,.35,.67,.08,.71,.08,.71,.08,.67,.11,.71,.11,.67,.08,.56,.23,.7,.36,.72,.06,.72,.07,.71,.05,.73,.31,.73,.32,.71,.33,.67,.12,.67,.15,.71,.12,.71,.15,.72,.12,.72,.14,.66,.2,.71,.16,.7,.17,.66,.02,.73,.09,.73,.1], 4 | indices: [0,1,2,1,0,3,4,0,2,3,0,5,0,4,6,5,0,7,8,6,4,5,7,9,6,8,10,11,9,7,10,12,6,7,13,11,14,6,12,13,7,15,6,14,16,17,15,7,18,16,14,15,17,19,12,20,14,15,21,13,22,14,20,21,15,23,14,22,24,25,23,15,0,6,26,7,0,26,27,26,6,7,26,28,18,14,29,30,15,19,14,31,29,30,32,15,6,16,27,28,17,7,24,31,14,15,32,25,16,8,27,28,9,17,8,16,10,11,17,9,18,10,16,17,11,19,18,12,10,11,13,19,12,18,20,21,19,13,29,20,18,19,21,30,29,22,20,21,23,30,22,29,24,25,30,23,29,31,24,25,32,30,8,4,27,28,5,9,4,2,27,28,3,5,27,2,26,26,3,28,2,1,26,26,1,3,33,34,35,36,37,38,39,40,41,42,43,44,45,33,46,47,38,48,49,39,50,51,44,52,39,49,40,43,52,44,53,50,39,44,51,54,50,53,55,56,54,51,34,45,57,58,48,37,45,34,33,38,37,48,40,59,41,42,60,43,61,41,59,60,42,62,41,61,63,64,62,42,34,55,35,36,56,37,55,34,50,51,37,56,50,34,57,58,37,51,50,57,49,52,58,51,61,65,63,64,66,62,65,61,67,68,62,66,59,67,61,62,68,60,67,59,69,70,60,68,41,53,39,44,54,42,53,41,55,56,42,54,63,55,41,42,56,64,55,63,35,36,64,56,65,35,63,64,36,66,35,65,33,38,66,36,67,33,65,66,38,68,33,67,46,47,68,38,69,46,67,68,47,70,46,69,45,48,70,47,71,72,73,73,72,74,72,71,75,76,74,72,77,75,71,74,76,78,75,77,79,80,78,76,71,81,82,83,81,74,81,71,84,74,81,84,73,84,71,74,84,73,75,85,72,72,86,76,85,75,87,88,76,86,79,87,75,76,88,80,81,89,82,90,81,83,77,71,82,83,74,78,89,81,91,91,81,90,92,93,94,95,93,96,94,93,97,98,93,95,94,97,99,100,98,95,101,99,97,98,100,102,99,101,103,104,102,100,105,103,101,102,104,105,103,105,99,100,105,104,106,99,105,105,100,107,99,106,94,95,107,100,108,94,106,107,95,109,94,108,110,111,109,95,112,110,108,109,111,113,110,112,114,115,113,111,116,114,112,113,115,117,114,116,94,95,117,115,118,94,116,117,95,119,94,118,92,96,119,95,120,121,122,123,124,125,121,120,126,127,125,124,128,126,120,125,127,129,126,128,130,131,129,127,132,130,128,129,131,133,130,132,134,135,133,131,136,134,132,133,135,137,134,136,138,139,137,135,140,138,136,137,139,141,136,142,140,141,143,137,142,136,144,145,137,143,132,144,136,137,145,133,144,132,146,147,133,145,148,146,132,133,147,149,146,148,116,117,149,147,144,150,142,143,151,145,150,144,106,107,145,151,146,106,144,145,107,147,106,146,112,113,147,107,116,112,146,147,113,117,152,153,154,155,156,157,153,152,158,159,157,156,121,158,152,157,159,124,158,121,160,161,124,159,162,134,138,139,135,163,134,162,160,161,163,135,164,160,162,163,161,165,160,164,153,156,165,161,160,130,134,135,131,161,130,160,126,127,161,131,121,126,160,161,127,124,93,101,97,98,102,93,101,93,105,105,93,102,142,166,140,141,166,143,166,142,150,151,143,166,166,167,140,141,168,166,150,105,166,166,105,151,105,150,106,107,151,105,116,122,118,119,123,117,114,94,110,111,95,115,153,158,160,161,159,156,106,112,108,109,113,107,169,93,92,96,93,169,170,167,166,166,168,170,171,172,173,171,173,174,175,172,171,175,171,176,175,176,177,175,177,178,179,178,177,179,177,180,181,182,179,181,179,180,183,184,182,183,182,181,185,186,187,185,187,188,189,190,188,189,188,187,189,191,192,189,192,190,189,187,193,189,193,194,186,195,193,186,193,187,196,195,186,196,186,185,191,197,198,191,198,192,191,194,199,191,199,197,194,193,200,194,200,199,193,195,201,193,201,200,195,196,202,195,202,201,203,204,202,203,202,196,198,197,205,198,205,206,207,208,204,207,204,209,204,208,210,204,210,202,201,202,210,201,210,211,200,201,211,200,211,212,200,212,213,200,213,199,197,199,213,197,213,205,207,214,215,207,215,208,208,215,216,208,216,210,211,210,216,211,216,176,171,212,211,171,211,176,174,213,212,174,212,171,217,205,213,217,213,174,181,215,218,181,218,183,181,180,216,181,216,215,216,180,177,216,177,176,217,206,205,189,194,191,185,203,196,203,209,204,218,215,214,184,219,182,220,182,219,182,220,179,221,179,220,179,221,178,175,178,221,222,223,224,223,222,225,226,225,222,225,226,227,219,227,226,227,219,184,214,228,218,229,209,203,230,203,185,231,232,233,234,206,235,236,206,217,237,238,239,237,239,240,239,238,241,239,241,228,218,228,241,218,241,183,242,234,235,242,235,243,244,242,243,244,243,245,246,244,245,246,245,240,239,247,246,239,246,240,239,228,248,239,248,247,207,248,228,207,228,214,242,249,250,242,250,234,242,244,251,242,251,249,246,252,251,246,251,244,247,253,252,247,252,246,247,248,229,247,229,253,207,209,229,207,229,248,234,250,198,234,198,206,253,229,203,253,203,230,253,230,254,253,254,252,252,254,255,252,255,251,251,255,232,251,232,249,249,232,231,249,231,250,198,250,231,198,231,192,256,254,230,256,230,185,255,254,256,255,256,257,255,257,233,255,233,232,192,231,233,192,233,190,188,190,233,188,233,257,257,256,185,257,185,188,227,184,183,227,183,241,225,227,241,225,241,238,237,223,225,237,225,238,237,240,224,237,224,223,224,240,245,224,245,258,245,243,259,245,259,258,260,261,262,263,264,260,265,266,267,267,268,265,269,270,271,272,270,273,271,274,275,275,274,272,276,277,278,279,280,281,282,283,267,267,283,284,283,282,285,285,284,283,286,287,260,260,287,288,287,286,289,289,288,287,266,282,267,267,284,268,282,266,290,291,268,284,261,292,262,263,293,264,286,262,292,293,263,288,262,286,260,260,288,263,260,294,261,264,294,260,295,261,294,294,264,295,261,295,296,297,295,264,296,277,261,264,280,297,276,261,277,280,264,281,261,276,292,293,281,264,278,292,276,281,293,279,292,278,298,299,279,293,265,289,266,268,289,265,286,266,289,289,268,288,266,286,290,291,288,268,292,290,286,288,291,293,290,292,282,284,293,291,298,282,292,293,284,299,282,298,285,285,299,284,278,285,298,299,285,279,285,278,300,300,279,285,301,302,303,304,305,306,302,301,307,308,306,305,307,301,309,310,306,308,307,309,311,312,310,308,313,311,309,310,312,314,311,313,315,316,314,312,317,315,313,314,316,318,315,317,319,320,318,316,321,322,323,323,324,321,322,321,311,312,321,324,325,311,321,321,312,326,311,325,307,308,326,312,321,307,325,326,308,321,307,321,327,327,321,308,328,301,303,304,306,329,301,328,330,331,329,306,332,330,328,329,331,333,330,332,334,335,333,331,336,307,327,327,308,336,307,336,302,305,336,308,301,313,309,310,314,306,313,301,330,331,306,314,315,322,311,312,324,316,322,315,319,320,316,324,313,334,317,318,335,314,334,313,330,331,314,335,337,338,339,340,341,342,343,344,345,346,347,348,349,345,344,347,346,350,345,349,339,340,350,346,351,352,353,354,355,356,353,343,351,356,348,354,343,353,344,347,354,348,351,343,357,358,348,356,359,338,337,359,337,360,342,341,361,342,361,362,363,364,352,363,352,351,355,365,366,355,366,356,364,367,368,364,368,352,369,370,365,369,365,355,371,372,363,371,363,357,366,373,374,366,374,358,359,372,371,359,371,338,374,373,361,374,361,341,357,363,351,356,366,358,375,376,377,375,377,378,379,380,381,379,381,382,377,376,383,377,383,384,385,380,379,385,379,386,387,388,389,387,389,390,391,392,393,391,393,394,395,396,389,395,389,388,391,397,398,391,398,392,375,378,396,375,396,395,397,382,381,397,381,398,378,377,364,378,364,363,365,379,382,365,382,366,378,363,372,378,372,396,373,366,382,373,382,397,396,372,359,396,359,389,361,373,397,361,397,391,389,359,360,389,360,390,362,361,391,362,391,394,364,377,384,364,384,367,386,379,365,386,365,370,343,345,371,343,371,357,374,346,348,374,348,358,339,338,371,339,371,345,374,341,340,374,340,346,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,412,411,417,418,416,415,419,420,401,402,421,422,420,419,417,418,422,421,417,423,420,421,424,418,423,417,411,416,418,424,400,405,407,408,410,403,405,400,399,404,403,410,413,425,426,427,428,414,425,413,412,415,414,428,420,399,401,402,404,421,399,420,429,430,421,404,431,429,420,421,430,432,429,431,433,434,432,430,433,399,429,430,404,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,442,441,446,445,454,431,420,423,424,421,432,455,456,449,450,457,458,456,455,459,460,458,457,443,461,462,443,462,441,463,464,444,463,444,446,443,459,465,443,465,461,466,460,444,466,444,464,465,459,455,465,455,467,458,460,466,458,466,468,467,455,449,467,449,469,450,458,468,450,468,470,449,448,471,449,471,469,472,451,450,472,450,470,441,462,473,441,473,453,474,463,446,474,446,454,475,447,449,475,449,456,450,452,476,450,476,457,475,456,459,475,459,477,460,457,476,460,476,478,479,477,459,479,459,443,460,478,480,460,480,444,481,479,443,481,443,442,444,480,482,444,482,445,483,484,447,483,447,475,452,484,485,452,485,476,483,475,477,483,477,486,478,476,485,478,485,487,488,486,477,488,477,479,478,487,489,478,489,480,488,479,481,488,481,435,482,480,489,482,489,440,481,442,436,481,436,435,439,445,482,439,482,440,436,442,453,436,453,490,454,445,439,454,439,491,492,493,484,492,484,483,484,493,494,484,494,485,495,492,483,495,483,486,485,494,496,485,496,487,495,486,488,495,488,497,489,487,496,489,496,498,488,435,499,488,499,497,500,440,489,500,489,498,435,437,501,435,501,499,502,438,440,502,440,500,436,490,503,436,503,437,503,491,439,503,439,438,501,437,503,501,503,504,503,438,502,503,502,504,501,504,505,501,505,506,505,504,502,505,502,507,501,506,433,501,433,499,434,507,502,434,502,500,433,431,497,433,497,499,498,432,434,498,434,500,423,495,497,423,497,431,498,496,424,498,424,432,508,492,495,508,495,423,496,494,509,496,509,424,508,510,493,508,493,492,493,510,509,493,509,494,399,433,506,399,506,511,507,434,404,507,404,512,399,511,513,399,513,405,514,512,404,514,404,410,405,513,515,405,515,406,516,514,410,516,410,409,517,508,423,517,423,411,424,509,518,424,518,416,517,411,413,517,413,519,414,416,518,414,518,520,426,521,519,426,519,413,520,522,427,520,427,414,426,523,521,522,524,427,506,505,525,506,525,511,525,505,507,525,507,512,513,511,525,513,525,526,525,512,514,525,514,526,515,513,526,515,526,527,526,514,516,526,516,527,508,517,528,508,528,510,528,518,509,528,509,510,517,519,529,517,529,528,529,520,518,529,518,528,519,521,530,519,530,529,530,522,520,530,520,529,523,531,530,523,530,521,530,531,524,530,524,522,447,532,448,451,533,452,534,490,453,454,491,535,536,537,473,536,473,462,474,538,539,474,539,463,462,461,540,462,540,536,541,464,463,541,463,539,540,461,465,540,465,542,466,464,541,466,541,543,544,545,469,544,469,471,470,546,547,470,547,472,467,469,545,467,545,548,546,470,468,546,468,549,542,465,467,542,467,548,468,466,543,468,543,549,490,550,503,503,550,491,490,534,551,490,551,550,551,535,491,551,491,550,484,552,447,452,552,484,447,552,553,447,553,532,553,552,452,553,452,533,554,555,556,555,554,557,557,554,558,557,558,559,560,559,558,559,560,561,562,561,560,561,562,563,564,563,562,563,564,565,566,565,564,565,566,567,568,567,566,567,568,569,570,569,568,569,570,555,565,561,563,561,565,571,572,571,565,571,572,559,573,559,572,559,573,557,555,557,573,574,575,576,575,574,577,578,577,574,577,578,579,568,580,570,580,568,581,566,581,568,581,566,564,562,582,564,582,562,558,560,558,562,558,554,583,558,583,582,584,582,583,564,585,581,585,564,584,582,584,564,586,587,588,587,586,589,590,591,592,591,590,593,594,595,596,595,594,597,598,599,600,598,601,599,602,603,604,602,605,603,606,607,608,607,606,609,573,569,555,569,573,572,572,567,569,567,572,565,610,611,612,611,610,613,614,615,616,615,614,617,577,618,575,561,571,559,619,556,555,620,578,574,621,622,623,622,621,624,624,621,625,624,625,626,627,626,625,626,627,628,629,628,627,628,629,630,631,630,629,630,631,632,633,632,631,632,633,634,635,634,633,633,636,635,636,633,637,638,637,633,637,638,639,640,639,638,639,640,641,627,641,640,641,627,625,637,621,636,621,637,642,639,642,637,642,639,625,641,625,639,643,628,630,628,643,644,645,644,643,644,645,622,644,626,628,626,644,624,622,624,644,646,647,648,647,646,649,650,651,652,651,650,653,654,655,656,655,654,657,630,658,659,658,630,632,660,661,662,661,660,663,664,665,666,665,664,667,668,669,670,669,668,671,672,673,674,673,672,675,676,677,678,677,676,679,636,621,623,636,623,635,680,681,682,681,680,683,684,646,685,646,684,649,633,640,638,640,633,631,629,640,631,640,629,627,649,686,647,684,687,649,625,621,642,688,689,690,689,688,691,691,688,692,691,692,693,694,693,692,693,694,695,696,695,694,695,696,697,698,697,696,697,698,699,700,699,698,699,700,701,702,701,700,703,704,705,704,703,706,707,706,703,706,707,708,709,708,707,708,709,710,711,710,709,710,711,712,713,712,711,714,715,716,715,714,717,707,717,714,717,707,718,703,718,707,718,703,719,705,719,703,720,721,722,721,720,723,724,723,720,723,724,725,726,725,724,725,726,727,728,719,705,719,728,729,730,729,728,729,730,731,732,731,730,731,732,733,734,735,736,735,734,737,693,737,734,737,693,738,695,738,693,738,695,697,739,740,741,740,739,742,743,742,739,742,743,744,745,744,743,744,745,746,747,748,749,748,747,750,751,750,747,750,751,752,753,752,751,752,753,754,755,715,756,715,755,757,758,757,755,757,758,759,760,759,758,759,760,761,751,762,753,762,751,763,764,763,751,763,764,765,766,765,764,765,766,767,708,768,769,768,708,770,710,770,708,770,710,771,712,771,710,772,773,774,773,772,718,741,718,772,718,741,740,775,776,777,776,775,778,779,778,775,778,779,780,781,782,783,782,781,717,756,717,781,717,756,715,784,714,721,714,784,748,785,748,784,748,785,749,786,736,735,736,786,787,788,787,786,787,788,789,790,791,792,791,790,793,690,793,790,793,690,689,794,716,795,716,794,714,722,714,794,714,722,721,731,719,729,719,731,773,774,773,731,744,740,742,740,744,782,783,782,744,759,715,757,715,759,716,795,716,759,796,797,798,797,796,799,800,799,796,752,707,750,707,752,709,711,709,752,770,801,768,801,770,802,771,802,770,725,721,723,721,725,784,784,727,785,727,784,725,803,699,701,699,803,804,804,697,699,697,804,738,769,704,706,769,706,708,737,805,806,805,737,738,740,717,718,717,740,782,692,688,807,692,807,808,808,694,692,694,808,809,734,691,693,691,734,777,747,764,751,764,747,810,811,765,767,765,811,812,748,707,714,707,748,750,737,800,813,800,737,806,814,698,696,698,814,702,754,711,752,711,754,713,809,815,694,815,809,816,763,812,817,812,763,765,759,761,795,796,813,800,776,691,777,731,733,774,744,746,783,802,818,801,747,749,810,700,698,702,816,819,815,719,773,718,764,810,766,820,821,822,821,820,823,823,820,824,823,824,825,826,825,824,825,826,827,828,827,826,827,828,829,830,829,828,829,830,831,832,833,834,833,832,835,836,835,832,835,836,837,838,837,836,837,838,839,840,839,838,839,840,841,842,841,840,841,842,843,844,845,846,845,844,847,848,847,844,847,848,849,850,849,848,849,850,851,852,851,850,851,852,853,827,836,832,836,827,838,854,838,827,838,854,855,856,855,854,855,856,857,858,857,856,859,860,861,860,859,862,863,862,859,862,863,864,865,864,863,864,865,866,851,866,865,867,868,869,868,867,870,871,870,867,870,871,872,873,872,871,872,873,874,871,875,873,875,871,876,877,876,871,876,877,878,879,878,877,878,879,880,881,882,883,882,881,884,885,884,881,884,885,867,825,867,885,867,825,827,886,878,880,878,886,887,888,887,886,887,888,876,875,876,888,860,889,861,889,860,890,864,890,860,890,864,891,866,891,864,877,834,879,834,877,832,871,832,877,832,871,827,867,827,871,892,893,837,893,892,894,895,894,892,894,895,896,829,854,827,854,829,856,897,856,829,856,897,858,898,899,900,899,898,893,835,893,898,893,835,837,901,902,866,902,901,903,904,903,901,850,905,852,905,850,906,848,906,850,870,907,868,907,870,908,909,908,870,910,824,911,824,910,826,912,826,910,913,885,914,885,913,825,915,825,913,855,840,838,840,855,916,857,916,855,917,909,918,909,917,919,920,921,922,921,920,923,923,905,921,905,923,852,924,820,822,820,924,925,919,908,909,908,919,907,828,912,830,912,828,826,926,904,901,904,926,927,928,929,930,929,928,931,931,853,929,853,931,901,823,915,821,915,823,825,872,909,870,909,872,874,932,837,839,837,932,892,824,820,933,824,933,911,934,927,935,927,934,936,937,881,883,881,937,938,938,939,881,939,938,914,940,852,941,852,940,853,942,941,943,941,942,940,944,943,945,943,944,942,933,820,925,933,925,911,901,851,853,851,901,866,939,885,881,885,939,914,884,869,882,869,884,867,946,894,896,894,946,899,947,922,948,922,947,920,890,949,889,949,890,891,930,950,928,950,930,951,849,865,863,865,849,851,874,918,909,927,936,904,893,894,899,878,887,876,898,833,835,916,842,840,829,831,897,860,862,864] 5 | }); -------------------------------------------------------------------------------- /webgl/mariotexture.js: -------------------------------------------------------------------------------- 1 | document.write(''); --------------------------------------------------------------------------------