Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Low level APIs using three.js

3c557c6103a4addc52f7b76ffd0a0f27?s=47 yomotsu
June 06, 2015

Low level APIs using three.js

my talk at Tokyo WebGL Meetup #2
http://tokyowebglmeetup.github.io/2/

3c557c6103a4addc52f7b76ffd0a0f27?s=128

yomotsu

June 06, 2015
Tweet

Transcript

  1. Low level APIs
 using three.js Presented by Akihiro Oyamada (@yomotsu)

    Jul 6, 2015
  2. Frontend Engineer at PixelGrid, Inc. @yomotsu recent works • http://yomotsu.github.io/walkthrough/

    • http://yomotsu.github.io/xmas2014/ Akihiro Oyamada
  3. three.js makes WebGL easier

  4. • Too lengthy initialization of WebGL • Shaders in GLSL

    • Math: Linear algebra, physics, etc and others. *USFEVDFT
  5. You may think that’s all?

  6. You can also use
 low level APIs,
 like pure WebGL.

  7. THREE.BufferGeometry
 for attributes

  8. THREE.ShaderMaterial and
 THREE.RawShaderMaterial
 for uniforms
 and shaders in GLSL

  9. sorry for a CHEAP figure, ive been having a cold…

  10. var width = window.innerWidth; var height = window.innerHeight; var clock

    = new THREE.Clock(); var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 60, width / height, .1, 100 ); camera.position.set( 0, 0, 2 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); ! ! var indices = new Uint16Array( [ 0, 1, 2, 3, 4, 5 ] ); ! var vertices = new Float32Array( [ -1, -1, 0, 1, -1, 0, -1, 1, 0, !
  11. ! ! var indices = new Uint16Array( [ 0, 1,

    2, 3, 4, 5 ] ); ! var vertices = new Float32Array( [ -1, -1, 0, 1, -1, 0, -1, 1, 0, ! -1, 1, 0, 1, -1, 0, 1, 1, 0 ] ); ! var uvs = new Float32Array( [ 0, 1, 1, 1, 0, 0, ! 0, 0,
  12. ! ! var indexBuffer = new THREE.BufferAttribute( indices, 1 );

    var vertexBuffer = new THREE.BufferAttribute( vertices, 3 ); var uvBuffer = new THREE.BufferAttribute( uvs, 2 ); ! ! var geometry = new THREE.BufferGeometry(); geometry.addAttribute( 'index', indexBuffer ); geometry.addAttribute( 'position', vertexBuffer ); geometry.addAttribute( 'uv', uvBuffer ); ! ! // // You don't need to put following uniforms. // modelMatrix is automatically linked to `mesh.matrixWorld` // viewMatrix is automatically linked to `camera.matrixWorldInverse` // projectionMatrix is automatically linked to `camera.projectionMatrix` // var uniforms = { // modelMatrix : { type: 'm4', value: new THREE.Matrix4() }, // viewMatrix : { type: 'm4', value: new THREE.Matrix4() }, // projectionMatrix : { type: 'm4', value: new THREE.Matrix4() },
  13. ! // // You don't need to put following uniforms.

    // modelMatrix is automatically linked to `mesh.matrixWorld` // viewMatrix is automatically linked to `camera.matrixWorldInverse` // projectionMatrix is automatically linked to `camera.projectionMatrix` // var uniforms = { // modelMatrix : { type: 'm4', value: new THREE.Matrix4() }, // viewMatrix : { type: 'm4', value: new THREE.Matrix4() }, // projectionMatrix : { type: 'm4', value: new THREE.Matrix4() }, diffuse : { type: "t", value: THREE.ImageUtils.loadTexture( 'uv.png' ) } }; ! var vertexShader = [ ! 'attribute vec3 position;', 'attribute vec2 uv;', ! 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat4 modelMatrix;', !
  14. ! var vertexShader = [ ! 'attribute vec3 position;', 'attribute

    vec2 uv;', ! 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat4 modelMatrix;', ! 'varying vec2 vUv;', ! 'void main() {', ! ' gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 );', ' vUv = uv;', ! '}' ! ].join( "\n" ); ! !
  15. ! ! var fragmentShader = [ ! 'precision mediump float;',

    ! 'uniform sampler2D diffuse;', ! 'varying vec2 vUv;', ! 'void main() {', ! 'vec4 diffuseColor = texture2D( diffuse, vUv );', 'gl_FragColor = diffuseColor;', // 'gl_FragColor = vec4( 1 );', ! '}', ! ].join( "\n" ); ! ! var material = new THREE.RawShaderMaterial( { vertexShader : vertexShader, fragmentShader : fragmentShader,
  16. ! ! var material = new THREE.RawShaderMaterial( { vertexShader :

    vertexShader, fragmentShader : fragmentShader, attributes : { // if you put custom attributes except // positions, indices, normals, colors and UVs // you need to declare those like // // vertexOpacity: { type: 'f', value: [] } }, uniforms : uniforms, defines : {} } ); ! var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); ! ! ( function animate () { ! requestAnimationFrame( animate ); !
  17. ! var mesh = new THREE.Mesh( geometry, material ); scene.add(

    mesh ); ! ! ( function animate () { ! requestAnimationFrame( animate ); ! var theta = clock.getElapsedTime(); mesh.rotation.set( 0, theta, 0 ); ! renderer.render( scene, camera ); ! } )();
  18. 18

  19. None
  20. A gas-ish fluid object in a MMO game

  21. 21 https://github.com/yomotsu/VolumetricFire Fire in three.js using
 THREE.BufferGeometry and THREE.RawShaderMaterial

  22. Extended build-in shades

  23. None
  24. In a MMO game what I play… Similar to THREE.MeshPhongMaterial,

    but edge of the model is different. It seems, normal directions make it…
  25. 25 https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderLib.js

  26. You can use THREE.ShaderChank
 in your custom shader

  27. var uniforms = THREE.UniformsUtils.merge( [ ! THREE.UniformsLib[ "common" ], THREE.UniformsLib[

    "bump" ], THREE.UniformsLib[ "normalmap" ], THREE.UniformsLib[ "fog" ], THREE.UniformsLib[ "lights" ], THREE.UniformsLib[ "shadowmap" ], ! { "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) }, "specular" : { type: "c", value: new THREE.Color( 0x111111 ) }, "shininess": { type: "f", value: 30 }, "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } }, ! { // ADDED UNIFROMS The same as actual code of
 build-in PhongMaterial
  28. "shininess": { type: "f", value: 30 }, "wrapRGB" : {

    type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } }, ! { // ADDED UNIFROMS glowColor : { type: "c", value: new THREE.Color( 0x84ccff ) }, viewVector: { type: "v3", value: new THREE.Vector3() }, viewMatrixInverse : { type: 'm4', value: new THREE.Matrix4() } }, ! ] ); ! var vertexShader = [ ! "#define PHONG", ! "varying vec3 vViewPosition;", ! "#ifndef FLAT_SHADED", The same as actual code of
 build-in PhongMaterial
  29. ! var vertexShader = [ ! "#define PHONG", ! "varying

    vec3 vViewPosition;", ! "#ifndef FLAT_SHADED", ! " varying vec3 vNormal;", ! "#endif", ! THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "map_pars_vertex" ], THREE.ShaderChunk[ "lightmap_pars_vertex" ], THREE.ShaderChunk[ "envmap_pars_vertex" ], THREE.ShaderChunk[ "lights_phong_pars_vertex" ], THREE.ShaderChunk[ "color_pars_vertex" ], THREE.ShaderChunk[ "morphtarget_pars_vertex" ], The same as actual code of
 build-in PhongMaterial
  30. THREE.ShaderChunk[ "skinning_pars_vertex" ], THREE.ShaderChunk[ "shadowmap_pars_vertex" ], THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], !

    ! 'uniform mat4 viewMatrixInverse;', //ADDED 'uniform vec3 viewVector;', //ADDED 'varying float vIntensity;', //ADDED ! "void main() {", ! THREE.ShaderChunk[ "map_vertex" ], THREE.ShaderChunk[ "lightmap_vertex" ], THREE.ShaderChunk[ "color_vertex" ], ! THREE.ShaderChunk[ "morphnormal_vertex" ], THREE.ShaderChunk[ "skinbase_vertex" ], THREE.ShaderChunk[ "skinnormal_vertex" ], THREE.ShaderChunk[ "defaultnormal_vertex" ], ! The same as actual code of
 build-in PhongMaterial
  31. ! ! var fragmentShader = [ ! "#define PHONG", !

    "uniform vec3 diffuse;", "uniform vec3 emissive;", "uniform vec3 specular;", "uniform float shininess;", "uniform float opacity;", ! "uniform vec3 glowColor;", //ADDED 'varying float vIntensity;', //ADDED ! THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "color_pars_fragment" ], THREE.ShaderChunk[ "map_pars_fragment" ], THREE.ShaderChunk[ "alphamap_pars_fragment" ], THREE.ShaderChunk[ "lightmap_pars_fragment" ], The same as actual code of
 build-in PhongMaterial
  32. this should be pre-multiplied to allow for bright highlights on

    very transparent objects // 'gl_FragColor = vec4( outgoingLight, diffuseColor.a );', // REMOVED ! 'vec3 glow = glowColor * vIntensity;', 'gl_FragColor = vec4(', // 'glow,', 'outgoingLight + glow,', 'diffuseColor.a', ');', ! "}" ! ].join( "\n" ); ! ! ! var material = new THREE.ShaderMaterial( { vertexShader : vertexShader,
  33. ! ! var material = new THREE.ShaderMaterial( { vertexShader :

    vertexShader, fragmentShader: fragmentShader, attributes: {}, uniforms: uniforms, defines: {}, ! fog: true, lights: true, // side: THREE.FrontSide, // blending: THREE.AdditiveBlending, skinning: true, transparent: true, // depthWrite: false // wireframe: true } ); ! material.uniforms.map = { type: 't', value: texture }
  34. // side: THREE.FrontSide, // blending: THREE.AdditiveBlending, skinning: true, transparent: true,

    // depthWrite: false // wireframe: true } ); ! material.uniforms.map = { type: 't', value: texture } material.defines.USE_MAP = '';
  35. build in shader custom shader

  36. Conclusion

  37. Three.js is not only high level APIs,
 but also it

    provides low level APIs
  38. • THREE.BufferAttribute • THREE.BufferGeometry • THREE.ShaderMaterial • THREE.RawShaderMaterial "WBJMBCMFGFBUVSFTJOUISFFKT

  39. Three.js is a
 flexible and extensible library

  40. gl.finish(); @yomotsu