Jump to content


grandhighgamer

Member Since 07 Sep 2004
Offline Last Active Mar 28 2016 09:14 PM

Topics I've Started

[Experiment] Draw_Set_Blend_Mode And Speed

02 March 2014 - 01:27 AM

Having read through Mark Alexander's knowledge base article, 'Optimising Your Games', the segment on changing the blend mode and its effect on speed stood out to me.

The crux of it being that Game Maker: Studio automatically batches together draw calls whenever possible, but as a matter of function it cannot do this when the blend mode needs to be changed. And in the case of instances with different blending, each object ends up as its own draw call, slowing things down considerably.

 

This made me think of possibility of sticking all objects of a specific blend mode on a specific depth and then placing objects on the depths below and above it in order to set and reset the blend mode and speed up rendering. I then wondered if this was even necessary, or if GM simply compared the current blend mode state to the desired one when executing the 'draw_set_blend_mode' function, thus rendering my optimisation useless.

This called for a test...
 

The Test Outline:

'obj_control' generates 4000 instances of 'obj_sprite' at random positions in its creation code.

It also records the maximum fps in a global variable for viewing in the debug window. Recording the minimum FPS would also have been prudent, but that would have required addtional work to have it only begin updating after the game has bypassed the initial few seconds of start-up lag.

 

'obj_sprite' draws itself, and depending on the sub-test, applies a set or random blend mode first.

 

'obj_block' fufills the purpose of setting the blend mode once for all instances of 'obj_sprite', potentially allowing for faster drawing.

It also blocks off the top right of the screen so that the debug info remains visible (consider that a small gripe). That in turn means there's a few duplicate instances of it, but since we have 4000 instances of 'obj_sprite' that's a few drops in the ocean.

 

I then tested the program in various configurations, and made a note of the maximum fps returned. Some varation existed between different runs of the exact same code, so consider the results accurate to around 10fps lower.


Download It:
SpeedTest.gmz

The Results (w/4000 objects):

Spoiler

 
Conclusions:
Switching blend modes is indeed 'slow as all heck', breaking any kind of batching on the part of the game. Interestingly setting the blend mode to the existing blend mode drops the fps by a fifth, but is still sigificantly faster than switching the blend mode. Is this the result of the way GM queries the blend mode before changing? I can only assume GM is checking first before making that chance, hence the huge FPS boost.

My original idea of using two objects acting as buffers between different depth ranges, allowing those ranges to always be set to a specific blend mode still appears to have merit. Which, honestly, is a bit disappointing. It's a pretty cumbersome system to use. But it is also by a margin the fastest.

As you might have already thought, using 'with(obj_sprite) draw_self();' after having set the desired blend mode was also an option, however it only resulted in an fps of 305. This is an improvement, and if you're opposed to using special blend mode setting objects, having a control object is certainly a step up. However it still remains marginally slower, which might make the difference for games that need to be heavily optimised to run well on the target system.

TL;DR: Whatever you choose to do, keep objects with blend modes grouped at the same depths or FACE THE WRATH OF TERRIBLE SLOWDOWN.


Super Cheapo Gaussian Blur

05 September 2013 - 06:35 PM

This is just a super cheapo port of a nice and simple gaussian blur shader found at: http://www.gamerende...-filter-shader/

This is simplest implementation of gaussian blur (for bloom, etc) I could find. It consists of two shaders that handle the horizontal and vertical component of the blurs respectively. You blur the source image horizontally, and the blur that blurred image vertically for the final 'composite' blur. It doesn't allow you to change the level of blur with a uniform or variable so you'll need to modify it if you have need of it (or be lazy and do multiple passthroughs with the surfaces).

 

Since it is a modified version of the code found above you should give credit to the website if you do use it as a matter of courtesy.

 

Screenshot (yes that is just a random Minecraft screenshot used as a background):

Spoiler

 

shaderBlurHorizontal fragment shader:

 

Spoiler

 

shaderBlurVertical fragment shader:

 

Spoiler

 

Example use code:

 

Spoiler

 

Pre-made Example GMZ:

 

http://host-a.net/u/...oBlurShader.gmz