Screen fade using stencil buffers

I wanted to try improve my stencil buffer fades in my game, but thought it’d be easier/better to create a small demo/playground for this.

This is nothing new under the sun, I just tried to gather the info from this forum post into a working example. Here is also a video to explain this further.

HTML5 Demo (more demos)
Source

Note that the actual fade screen textures are quite poor, I didn’t spend any time making them nice.

If you produce some nice fade texture, feel free to share it with the community here in this topic ^^

14 Likes

Brilliant! Thanks for sharing!

2 Likes

Awesome! Tested a few more transitions! Just took images from that other demo.

I noticed that just by existing some of the transition files can cause permanent distortions in all of the others? Maybe a config I didn’t set right? I deleted the offending ones to record the gif above.

5 Likes

Testing two more mosaic / noise. It would be better to generate the stencil textures by code so they can be random though.

The “not fully transitioning with a speck left” thing in the gif is only due to the recording software.

2 Likes

Nice!

I don’t think you got any configs wrong, since they’re basically non existent :slight_smile:
The main issue I think is that they all are active at the same time. Ideally, I’d like to be able to disable the model components, or be able to change the model component texture on the fly.

2 Likes

Friend got inspired and made a version for Monkey

We could do the same thing with Defold. Load your next screen, and then transition to it with this kind of effect!

2 Likes

We can do
Fade In with effect thanks to Jcash
load collection/level
when loaded is finish
fade out

Dunno if defold current engine could let use preload other collection

Yes, you can async pre-load other collection without turning it on first.

yes but when you init it and render it you render it on the buffer that is show
we need to have as the same time the 2 collections loaded and rendered in 2 buffer to have a transition

That’s true, you would have to do it based on unique materials and render targets maybe.

Yes this could be a nice solution.

I’d say that calls for a feature request. :slight_smile: Separating by material in that case would work, but would also be really annoying and messy in practice.

1 Like

How would you phrase the feature request? Maybe you should post it so it’s most practical to implement. :smile:

@JCash
After the changes in version 1.2.94 fading example does not work correctly.
I made the pull request, can check it Pls: https://github.com/JCash/stencilfade/pull/1

in accordance with Defold 1.2.94 has been released

2 Likes

Thanks for reporting! I’ve merged your pull request and I also fixed the build error.

2 Likes

@Pkeod can you please add the classic fade effect ? I mean just alpha black screen from 0 to 100% alpha.
the current effects are more suitable with oldschool pixel art games.

There can be something like this in DefFx perhaps?

1 Like

For that you can just use a sprite or GUI node covering the whole screen and animate its opacity.

1 Like

Animate something like this on the layer you want fading to happen.

-- This overlay will fill the screen with a solid color
-- Use it below popups or pause screens to overlay the game screen or lower z level menus

function toggle_fade(self)
	if self.faded == false then
		self.faded = true
		msg.post("main:/transition","fade_in")
	else
		self.faded = false
		msg.post("main:/transition","fade_out")
	end
end

function fade_out(self)
	self.fading = true
	self.fading_timer = 100
	self.fading_out = true
	self.pre_fade_color = gui.get_color(self.shade)
end

function fade_in(self)
	self.fading = true
	self.fading_timer = 0
	self.fading_in = true
	self.pre_fade_color = gui.get_color(self.shade)
end

function init(self)
	
	local color = vmath.vector4(0,0,0,1)
	
	local width, height = gui.get_width(), gui.get_height()
	local position = vmath.vector3(width / 2, height / 2, 0)
	local size = vmath.vector3(width * 1, height * 1, 0)
	local shade = gui.new_box_node(position,size)
	-- todo have a gui layer sorting stack or something
	gui.set_render_order(10)
	gui.set_adjust_mode(shade, gui.ADJUST_ZOOM)
	gui.set_color(shade,color)
	self.shade = shade
	
	self.faded = false
	self.fading = false
	self.fading_out = false
	self.fading_in = false
	self.fading_timer = 0
	self.color_mod = vmath.vector4(0,0,0,1)
	
	fade_out(self)
end



function final(self)
	
end

function update(self, dt)
	if (self.fading_timer < 0.1 and self.fading_timer > 0) or (self.fading_timer < 0) and self.fading_out == true then
		self.fading_timer = 0
		self.fading_out = false
		self.fading = false
		self.color_mod.w = 0
		gui.set_color(self.shade, self.color_mod)		
	end
	if self.fading_timer > 0 and self.fading_out == true then
		self.color_mod = self.pre_fade_color
		self.color_mod.w = self.fading_timer * 0.01
		
		gui.set_color(self.shade, self.color_mod)
		--gui.set_color(self.shade, self.pre_fade_color * vmath.vector4(1,1,1,self.fading_timer*0.01))
		
		self.fading_timer = self.fading_timer - 60 * dt - (100 - self.fading_timer) / 6
	end
	
	if (self.fading_timer > 99.9 and self.fading_timer < 100) or (self.fading_timer > 100) and self.fading_in == true then
		self.fading_timer = 100
		self.fading_in = false
		self.fading = false
		self.color_mod.w = 1
		gui.set_color(self.shade, self.color_mod)
	end
	if self.fading_timer < 100 and self.fading_in == true then
		self.color_mod = self.pre_fade_color
		self.color_mod.w = self.fading_timer * 0.01
		
		gui.set_color(self.shade, self.color_mod)
		--gui.set_color(self.shade, self.pre_fade_color * vmath.vector4(1,1,1,self.fading_timer*0.01))
		
		self.fading_timer = self.fading_timer + 60 * dt + (100 - self.fading_timer) / 6
	end	
	
end

function on_message(self, message_id, message, sender)
	if message_id == hash("toggle_fade") and self.fading == false then toggle_fade(self) end
	if message_id == hash("fade_in") and self.fading == false then
		fade_in(self)
	elseif message_id == hash("fade_out") and self.fading == false then
		fade_out(self)
	end
end

function on_input(self, action_id, action)
	-- Add input-handling code here
	-- Remove this function if not needed
end

function on_reload(self)
	-- Add input-handling code here
	-- Remove this function if not needed
end

9 Likes

Thanks a lot! that’s what I need!

1 Like