Hey folks! I’m trying to render a large number of sprites to the screen using custom shaders, and I’m wondering how best to approach it. (OpenFL Next, by the way.)
The goal is at least 200-400 sprites arranged in a scene larger than the display resolution (user can pan to see other regions of the scene). The sprites will have custom shaders attached for lighting purposes, and ideally, be able to support arbitrary rotations. This is part of a larger HaxeFlixel game prototype, but I’m looking at OpenFL because it exposes more OpenGL (and particularly shader) features.
Here’s a screen of a scene I’m currently prototyping:
http://bluebottlegames.com/main/node/4940
And here’s a pared-down code sample of how I got that effect:
It’s a combo of openfl-samples’s SimpleOpenGLView demo with some normal-mapping/lighting shaders from elsewhere, rendered beneath a HaxeFlixel camera. It’s pretty crude, however, and a performance hog. I’m sure I’m doing it “wrong,” but I’m unsure how to do it right. (Probably starting with not rendering each sprite per-frame with lots of overdraw.)
openfl-samples/SimpleOpenGLView
As I mention above, I’ve got something working that was derived from this demo. Since SimpleOpenGLView performs raw GL instructions, I was able to add my own vertex and fragment shaders, and pass the required uniforms, attributes, etc. into the renderer.
The down side here, however, is that it’s easy to do non-optimized (and non-cross-platform) stuff, since I’m bypassing OpenFL and HaxeFlixel rendering pipelines.
openfl-samples/HerokuShaders
I think this is a similar approach to SimpleOpenGLView, above.
openfl.display.Sprite.shader
This approach was my initial attempt, and it was super easy to use. Just assign a shader to any sprite!
However, I soon discovered that the vertex shader this uses lacks some transform info (namely, the rotation of the sprite). At least, by default. I wasn’t sure if there was a way to override/modify that vertex shader to add this uniform (for normal-map TBN calcs).
openfl-samples/BunnyMark
BunnyMark seems to use a combo of Tilemap and TilemapLayer to send thousands (even tens of thousands!) of sprites around the screen. However, it seems to assume a zero rotation and no shader support.
HaxeFlixel Shaders
HaxeFlixel 4.0.0 also seems to have some shader support. However, this appears to be limited to those applied to a whole camera, not just certain sprites.
Suggestions?
It’s possible that one or more of the above do what I’m thinking, and I just don’t realize it yet. Maybe I need to just render all my sprites to some textures, and then run shaders on those? Maybe layer some FlxCameras in HaxeFlixel?
I just wanted to ask some experts for their input on how they would approach this.