I'm working on a WebGL application that works similarly to video compositing programs like After Effects.
The application takes textures and stacks them like layers. This can be as simple as drawing one texture on top of the other or using common blend modes like the screen to combine several layers.
Each layer can be individually scaled/rotated/translated via an API call, and altogether the application forms a basic compositing software.
Now my question, doing all this in a single WebGL canvas is a lot to keep track of.
// Start webgl rant
The application won't know how many layers there are ahead of time, and so textures coordinate planes and shaders will need to be made dynamically.
Blending the layers together would require writing out the math for each type of blend mode. Transforming vertex coordinates requires matrix math and just doing things in WebGL, in general, requires lots of code being a low-level API.
// End webgl rant
However, this could be easily solved by making a new canvas element for each layer. Each WebGL canvas will have a texture drawn onto it, and then I can scale/move/blend the layers using simple CSS code.
At the surface, it seems like the performance hit won't be that bad, because even if I did combine everything into a single context each layer would still need its own texture and coordinate system. So the number of textures and coordinates stays the same, just spread across multiple contexts.
However deep inside I know somehow this is horribly wrong, and my computer's going to catch fire if I even try. I just can't figure out why.
With a goal of being able to support, ~4 layers at a time would using multiple canvases be a valid option? Besides worrying about browsers having a max number of active WebGL context's are there any other limitations to be aware of?
Related
Has anyone tried accelerating collision detection via GPU? I thought about passing position+radius for a simple sphere intersection, rendering all intersecting triangle indices to a texture.
Using the GPU
I'm not sure if this is an good idea at all, but the math doesn't seem to be costly for this in vertex shader. It wouldn't resolve anything, just fetching the face indices to indicate which faces are relevant. It's also only supposed for the terrain.
Using the octree
The terrain is generated via dual contouring, and in it's highest lod several thousand nodes can be required, storing face indices based on the dual cells or connecting them to their octree nodes are costly in terms of memory and cpu. It already required a lot optimizations and needs to run multi-threaded, i'd like to avoid additional steps on this side.
It might work using the octree and the density function on the boundaries and trilinear interpolating the surface, but it requires to pass the nodes from the worker, or position to worker. Anyway this wouldn't completely match the polygons of a cell, but at least smooth out the error.
Using the density function
While required octree-nodes and their polygons are adaptive, their size are varying much, so a collision based on the density field function won't always fit the actual underlying geometry, surface can be far below or above the geometry.
Any suggestions?
I am trying to write a layout extension and have already looked at the examples provided both from the existing extensions (e.g. arbor, cola, cose-bilkent, etc.) and the scaffolding here. The place where I am hung up is with the webGL renderer. In all of the examples, this is handled by the core (for canvas), if I am not mistaken. Is it possible to use a webGL renderer through three.js? If so, is it as simple as just creating/attaching the required webGL elements in the extension (e.g. scene, cameras, light-sources, etc.)?
The reason for the webGL push is that I want to implement a 3D adjacency matrix (I cannot remember where I found the paper, but someone had implemented this in a desktop application with subject, predicate, and object being the X,Y, and Z axes) and don't see another way to do that efficiently for large result sets on the order of 10-25K nodes/edges.
Cytoscape supports multiple renderers, but it does not support 3D co-ordinates. Positions are defined as (x, y).
You could add a 3D renderer if you like, but you'd have to use a data property for the z position, because the position object doesn't support z.
It's a lot of work to write a renderer, especially one that's performant and fully-featured. If you were to write a 2D renderer, you could reuse all the existing hittests, gestures/interaction, events, etc -- so you could focus on drawing tech. To write a 3D renderer, you'll have to do all the rendering logic from scratch.
If your data requires 3D (e.g. representing 3D atomic bonds or 3D protein structures), then writing a 3D renderer may be a good idea. If it's just to have a neat 3D effect, it's probably not worth it -- as 3D is much harder for users to navigate and understand.
I have a webgl application, I've written using threejs. But the FPS is not good enough on some of my test machines. I've tried to profile my application using Chrome's about:tracing with the help from this article : http://www.html5rocks.com/en/tutorials/games/abouttracing/
It appears that the gpu is being overloaded. I also found out that my FPS falls drastically when I have my entire scene in the camera's view. The scene contains about 17 meshes and a single directional light source. Its not really a heavy scene. I've seen much heavier scenes get render flawlessly on the same GPU.
So, what changes can I make in the scene to make it less heavy, without completely changing it? I've already tried removing the textures? But that doesn't seem to fix the problem.
Is there a way to figure out what computation threejs is pushing on to the GPU? Or would this be breaking the basic abstraction threejs gives?
What are general tips for profiling GPU webgl-threejs apps?
There are various things to try.
Are you draw bound?
Change your canvas to 1x1 pixel big. Does your framerate go way up? If so you're drawing too many pixels or your fragment shaders are too complex.
To see if simplifying your fragment shader would help use a simpler shader. I don't know three.js that well. Maybe the Basic Material?
Do you have shadows? Turn them off. Does it go faster? Can you use simpler shadows? For example the shadows in this sample are fake. They are just planes with a circle texture.
Are you using any postprocessing effects? Post processing effects are expensive, specially on mobile GPUs.
Are you drawing lots of opaque stuff? If so can you sort your drawing order so you draw front to back (close to far). Not sure if three.js has an option to do this or not. I know it can sort transparent stuff back to front so it should be simple to reverse the test. This will make rendering go quicker assuming you're drawing with the depth test on because pixels in the back will be rejected by the DEPTH_TEST and so won't have the fragment shader run for them.
Another thing you can do to save bandwidth is draw to a smaller canvas and have it be stretched using CSS to cover the area you want it to appear. Lots of games do this.
Are you geometry bound?
You say you're only drawing 17 meshes but how big are those meshes? 17 12 triangle cubes or 17 one million triangle meshes?
If you're geometry bound can use simplify? If the geometry goes far into the distance can you split it and use lods? see lod sample.
I'm building a game in HTML5. I have hundreds of images that look similar to this:
And at certain points in the game I want to draw an outline around them. Like this:
I want to do different tracing colors at different times and don't want to end up with [number of sprites] * [number of colors] of additional images for memory and bandwidth reasons so I'm looking at vector drawings.
What I need to come to a solution on are really two separate things:
Calculate a vector path for each frame in a spritesheet. This can be either dynamically or ahead of time and stored.
Draw the vector path
The engine I'm using for the game is ImpactJS. It doesn't have any support for vector operations. The author of the game engine I'm using did his own vector drawing manually by exporting the vectors from Illustrator for a particular image, then using an online converter tool to change them to HTML5 syntax. This isn't the best method for hundreds of images so I thought I'd see what information others of you have.
I would like to still draw the images using ImpactJS since this game is already pretty far along, and just do a second-pass drawing of the outline of the image when necessary.
Thank you for any help!
I'm working on displaying interactive map in html5.
I have created zones of map as array of numbers (representing coordinates)
like:
Zone1=[{x=3,y=4}, {x=8,y=5}]
and I have also created a map which is an array of zones
like:
map=[zone1, zone2....]
I have no problem drawing the zones in the canvas using context.lineTo() function, the same way I'm able to capture the mouse position on click and determine on which zone a user has clicked using point in polygon algorithm.
My difficulty arises when I want to fill color of of the zone when it is clicked at.
Anybody have ideas?
PS:
The shapes I made are irregular
I'm not in to using JavaScript libraries like jQuery or anything else
HTML5 Canvas does not know of notion of shapes of objects which you can manipulate. You have two options in your situation:
Use SVG to draw what you need (check examples on W3Schools)
Use some JS canvas library which adds abstraction to provide notion of shapes (check out EasleJS)
Write your own abstraction over canvas to provide shapes
You should know however, that even with such libraries, "shapes" are getting fully redrawn. Possibly, entire scenes are redrawn. SVG alleviates this, it's performance decreases as number of shapes/objects grows.
You can't. The shapes you created are not variables or referenceable in any way once they are added to the canvas. You could redraw the shape with a new colour over the old one, but I think your best bet would be to use a library to handle this for you.
Since I have used it myself, my own suggestion would be Kinetic.js, but there are a plenty to chose from.