UNPKG

dreemgl

Version:

DreemGL is an open-source multi-screen prototyping framework for mediated environments, with a visual editor and shader styling for webGL and DALi runtimes written in JavaScript. As a toolkit for gpu-accelerated multiscreen development, DreemGL includes

148 lines (136 loc) 5.12 kB
/* DreemGL is a collaboration between Teeming Society & Samsung Electronics, sponsored by Samsung and others. Copyright 2015-2016 Teeming Society. Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ define.class("$server/composition",function(require, $ui$, screen, view) { this.render = function() { return [screen({ clearcolor:'black' }, view({ flex:1, bgcolor:'red', mousepos:vec2(0,0), pointermove:function(event){ this.mousepos = event.value }, hardrect:{ color:function(){ //return 'red' if(mesh.depth>13.){ var len = min(pow(1.5-length(mesh.pos),8.),1.) if(mesh.isberry>0.){ // render a berry //var len = min(pow(1.5-length(mesh.pos),8.)*0.15,1.) return mycolor*len } else{ // render a leaf return mycolor*len } } // render a branch return mix('brown',mycolor,mesh.depth/12)*sin(mesh.pos.y*PI) }, // the geometry structure, position, path (a power of 2 float mask) and depth of the rect // also note we are only using 'floats' for this data, videocards dont really like other types mesh:define.struct({ pos:vec2, path:float, depth:float, isberry:float }).array(), position:function(){ var mainscale = vec2(30,30) var mainoffset = vec2(300,400) var mousepos = (view.mousepos - mainoffset) / mainscale // the path is a set of float 'bits' that can be walked to go left or right var path = mesh.path // cumulative position of the tree branch or leaf var pos = vec2(0,0) // cumulative scale var scale = vec2(1,1) // the direction vector is rotated as we go var dir = vec2(0,-0.8) // the turbulence factor var turbulence =3. // the depth of the rectangle we are processing var depth = int(mesh.depth) var swoosh = mod(view.time, mesh.depth) // run over the whole depth, note we don't use i < depth because thats not allowed in webGL, has to be fixed number for(var i = 0; i < 14; i++){ if(i >= depth) break // this is like path&1 binary arithmetic done using floats var right = mod(path, 2.) // its the right branch var angle = 25.*math.DEG+0.01*turbulence*sin(view.time) if(right>0.){ angle = -1.*angle } // rotate by mouse position var dist = max(50.-10.*length(mousepos - pos)-sin(view.time),0.) angle -= dist*0.01 dir = math.rotate2d(dir,angle) // accumulate position scale pos += (dir * scale)*1.9 scale = scale * vec2(0.85,0.85) // this is like path = path >>1 in float path = floor(path / 2.) } // our colornoise varying colornoise = 0. // the leaves have a different scale/center than the branches so make it tweakable var vscale = vec2(1.,.5) var vcen = vec2(-.8,-.4) // we are a leaf or berry if(depth > 13){ var noise = noise.noise3d(vec3(pos.x*.1,pos.y*.1,0.5*view.time)) * turbulence colornoise = noise // only rotate the leaves if(mesh.isberry > 0.){ mycolor = 'blue' scale *= vec2(0.5,0.5) } else{ dir = math.rotate2d(dir, -50.*math.DEG*noise) mycolor = pal.pal5(0.1*colornoise+0.1*view.time) } scale *= vec2(1,4.) vscale = vec2(3.,.5) vcen = vec2(0.8,0.) } else{ mycolor = pal.pal5(0.1*colornoise + mesh.pos.y+mesh.depth/14+0.1*view.time) } // compute the final position var p = (math.rotate2d((mesh.pos*vscale+vcen)*scale, atan(dir.y,dir.x)) + pos) * mainscale + mainoffset return vec4(p, 0, 1) * view.totalmatrix * view.viewmatrix }, update:function(){ var mesh = this.mesh = this.mesh.struct.array() // first triangle function recur(path, depth){ var isberry = 0 // probabilistically spread the berries through the tree if(depth > 13 && Math.random()<0.1) isberry = 1 // we push plain rectangles in the geometry buffer with just the path + depth added mesh.pushQuad( -1,-1, path, depth, isberry, 1,-1, path, depth, isberry, -1,1, path, depth, isberry, 1,1, path, depth, isberry ) // bail when at level 14 if(depth>13)return // recur left and right, encode the 'right' with a power of 2 'flag' in the path boolean recur(path, depth+1) recur(path + Math.pow(2, depth), depth+1) } recur(0,0) } } }) )] } })