Progress update: Material animation & more


#1

Hi again, it’s time for a new progress update! Special thanks to all my patrons for supporting the project so far - and if you aren’t a patron yet please consider becoming one, it really helps me out a lot. (Visit Patreon here)

Work is progressing on the new particle system, things are really shaping up and I’ll be doing more updates on it later. For now I wanted to talk about a few new features available on the master branch right now:

  • SpriteTexture animation
  • Material property animation
  • Built-in renderer profiler

SpriteTexture animation
I’ve added support for general purpose sprite sheet animation through the SpriteTexture class. This isn’t the most advanced feature out there but I believe the way it integrates into bsf is a bit more unique than other engines.

Up until this point SpriteTexture class was used only for referencing a sub-section of a larger texture (or rather, an atlas). It was pretty much exclusively used by the GUI system which makes use of texture atlases to optimize rendering.

I’ve extended the concept to support animation. Its simple enough to define the sprite sheet grid, number of frames in the animation and FPS.

SpriteSheetGridAnimation anim;
anim.numColumns = 3;
anim.numRows = 3;
anim.count = 8;
anim.fps = 8;

HSpriteTexture spriteTexture = ...;
spriteTexture->setAnimation(anim);
spriteTexture->setAnimationPlayback(SpriteAnimationPlayback::Loop);

An example sprite sheet the above code might be used for:
SpriteSheet

What makes it unique is that sprite textures can now be used in a variety of in-engine systems and they will ‘just work’. For now these systems include the brand new particle system, as well as general purpose material animation (talked about below). I will also be soon doing an update that will allow animated GUI elements!

See it in action with the particle system:
AnimatedParticles

Material animation
What makes bsf’s SpriteTexture unique is that you can now assign it on an arbitrary Material. Anywhere you could plugin in a normal texture, you can now set a sprite texture instead! Most (all?) other engines would require you to write specialized code and/or shaders to support the functionality.

HMaterial material = ...;
material->setSpriteTexture("gAlbedoTex", spriteTexture);

I can imagine this being used to create futuristic or organic looking environments/characters, as well as being used to complement the particle system when creating special effects. Here’s a (really) un-inspired example using the sprite sheet from above.

AnimatedTexture

I’ve also decided to extend this concept a bit and allow parameters like numbers or colors to be animated as well. Therefore anywhere on a Material you can now specify animation curves where you would normally set a static (non-vector) value, or color gradients where you would normally specify a static color.

An example that assigns an animation curve to a ‘float’ parameter:

// Create an animation curve with three keys:
// [0] - Value 1 at time 0.0s
// [1] - Value 2 at time 0.5s
// [2] - Value 1 at time 1.0s
// The curve starts at value of 1, goes to 2 and then back to 1, in the duration of one second.
// (Middle two values of each keyframe represent tangents that allow finer control
// of the curve, be you can leave them at zero)
Vector<TKeyframe<float>> keyframes = 
{
	{ 1.0f, 0.0f, 0.0f, 0.0f },
	{ 2.0f, 0.0f, 0.0f, 0.5f },
	{ 1.0f, 0.0f, 0.0f, 1.0f }
};

TAnimationCurve<float> curve(keyframes);
material->setFloatCurve("gScale", curve);

An example that assigns a color gradient to a ‘color’ parameter:

// Create a color gradient with three keys
// [0] - Red color at time 0.0s
// [1] - Blue color at time 2.5s
// [2] - Red color at time 5.0s
// The gradient starts with red color, interpolates towards blue and then back to red,
// in the duration of five seconds.
ColorGradient gradient;
gradient.setKeys(
	{
		ColorGradientKey(Color::Red, 0.0f),
		ColorGradientKey(Color::Blue, 2.5f),
		ColorGradientKey(Color::Red, 5.0f)
	});

material->setColorGradient("gTint", Color::White);

ColorGradient

Renderer profiler
Finally, I’ve added profiling blocks to the majority of the renderer. Luckily with the render compositor/render material system in place it was pretty straightforward to insert the profiling code. Now you can get GPU timings for all the rendering effects through the profiler interface, or through the profiler overlay. Profiler overlay has been improved and is now easily available through the Application class.

// Shows the profiler overlay on the 'Main' camera (or provide your own camera)
gApplication().showProfilerOverlay(ProfilerOverlayType::GPUSamples);

As time goes on I will be making improvements to the overlay by adding graphs and organizing things more neatly, as well as improving CPU profiling coverage.

That’s it for now, stay tuned for more. Next update will likely be focusing on new features added to the particle system.