Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use DOM background layer with keyframe animations and Canvas layer for a physic engine

In my next game I'm planning to mix a DOM background layer with the canvas(es) on top of it. I would like to move non-interactive background animations to that DOM layer, and use keyframe animations for transformations and opacity changes, like moving clouds around, air-planes etc.

As for me there are 2 pros for this:

  1. Simple keyframe animations are much easier to create. imho

  2. The most interesting point - it should improve performance:

    • transform and opacity animations can be GPU accelerated and performed on separate thread.
    • we do not perform those animations in our render frames, so we save here some milliseconds.

Or am I wrong? Perhaps browsers need much more time to make the composition of those layers, or are there some other caveats?

The biggest contrary for this technique is, that we can use it mostly for the decoration animations, and not for our game-play, as to control those animations is the hard task.

Does anybody have an experience with such layering?

Thank you in advance.

like image 956
tenbits Avatar asked May 03 '17 19:05

tenbits


1 Answers

I started off in much the same boat you are and have travelled many avenues of webgl, canvas, and my new go-to: svg.

SVG provides much of what you want out of your elements, but it's still within a graphical rendering engine, so you can still add a bunch of filters and effects, but the layers are more static, like you said you wanted. ( not rendering every tick ).

In my current app, the three.js engine has been stripped down, and no longer does image textures ( those are 3d transformed html elements ). I have a pure html+react scene, and a three.js scene which match perfectly ( either perspective camera or orthogonal ). It was a very long (fun) process to get them all to match.

Anyway, I only use three.js for some 3d decorations ( like handles to grab onto to resize elements ). It's an animation app by the way, so like a 3d editor in ways. I am debating whether to remove the threejs rendering completely ( I still will use three.js to have a scene structure, and call localToWorld on stuff, then render it on an svg overlay-- but I won't call render on the three scene [I have to manually call updateMatrixWorld() on everything, but its like 20x faster than rendering the scene] )

For real-time rendering, if the character moves for a while, then stands still, and you're trying to save time on those moments in time when the background doesn't move, I dunno if that's right thinking. Do you want lag when he is moving far enough to scroll the background?

That being said, caveats aside, it could be faster. Three.js has to load big textures into memory. If you're doing certain filters onto the background, then changing the background image in and out of a texture buffer would be pretty dang slow, but there are also webgl ways to do it all without changing the texture.

I probably wouldn't recommend doing a hybrid system unless you have exhausted your options and are just looking to try something new.

I definitely recommend using and learning svg.

I'm pretty sure there are hacks within webl that would probably prove to be more maintainable in the long run ( maintaining two engines is a bit mentally taxing ). It's not terrible, and I actually like my html engine much better than my three.js one.. but hmm..

Have you considered an all html 3d engine? It took me a long time to figure out a heirarchy, and until I was confortable using a ton of html elements ( and not trying to conserve them -- its fast with a lot )

My html elements are 0 based (i always translate 50%, 50%, working from the center of an element, like three.js does, it's much easier on the brain than doing top,left orientation) container anchor mesh children This is what I went with. The mesh is usually an img or an svg. Actually now most of my elements are 0x0. Only mesh has a width, usually. Originally I was doing a weird stuff, but now it's pretty much like a three.js scene, except with html elements, and I was using the CSS3dRenderer originally, but my own is just as good and more maintable ( everything is a react component )

Each "thing" is a class and it creates those 4 html elements. It also creates three.js elements ( for doing mouse intersections, raycasting, converting between coordinate systems, etc ).

Getting everything into and out of redux in a sane way was also interesting.

SVG meshes have children too ( the svg elements ).

You might enjoy doing some project with react and nested html elements, 3d transformed, and using svg for the elements + animations.. cuz I know I do.

You could pre-process the meshes and use a gif instead of an image or svg.

I dunno. You seem to want to do something weird, so imo, making a game in react with svg seems weird. I bet you'd get free press because people will up-vote anything with react in it.

Another thing I'll say is that after learning react + redux + immutable, my whole mind is different. My three.js engine for updating props is 10000% different. It's much lazier. You might find that just learning a new system of handling data + updating props will make you see your engine in a new way. I recommend learning react + redux + immutable, and perhaps even learning to apply them to three.js.

Another thing you could do would be multiple webgl scenes, and then just not need to render the background layer unless it's moving.

Also, if you look into doing the svg route, note that using css transform is different than using the attribute transform(built for svg elements). Firefox and IE can't handle svg elements ( like rect, path, circle, etc) being css transformed, but it does work if you use the attribute.

Also, css animations aren't faster than javascript animations.. not really. Using transform with a 3d translation or rotation or whatever, that's all you need to activate the video card. If you even do something like transform: translateZ(0), it'll activate the video card. You don't need to write css, you can use javascript, and most tween libraries just use javascript. You still will have performance things to work out, but it's also good to do your transitions in js, so things don't get out of sync.

If I were to send you on a vision quest, I'd tell you to write a 3d game in react + redux + immutable. And you'd get like 1000 upvotes on programmer websites.

like image 122
dansch Avatar answered Nov 15 '22 14:11

dansch