sort order with shader

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
borr
Prole
Posts: 42
Joined: Wed Oct 16, 2019 7:39 pm

sort order with shader

Post by borr »

Code: Select all

extern float depth;
    varying vec4 vpos;
    
    #ifdef VERTEX
    vec4 position(mat4 transform_projection, vec4 vertex_position)
    {
        vpos = transform_projection * vertex_position;
        vpos.z = depth;
        return vpos;
    }
    #endif
    #ifdef PIXEL

    vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
    {
        // texture_coords += vec2(vpos.x, vpos.y);
        vec4 texcolor = Texel(tex, texture_coords);
        return texcolor * color;
    }
    #endif
i'm trying draw sort with shader
but i have problem with alpha color. with this shader there is no reaction to changing the alpha for the color
Attachments
alpha_problem.jpg
alpha_problem.jpg (3.36 KiB) Viewed 6647 times
main.lua
(1.46 KiB) Downloaded 120 times
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: sort order with shader

Post by ReFreezed »

When you draw half-transparent objects you must draw them from back to front for alpha blending to work properly, as the depth buffer only contains the distance to the closest object, no matter how "transparent" that object is (i.e. you cannot draw "behind" objects as the GPU has no concept of what's been drawn before).
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
borr
Prole
Posts: 42
Joined: Wed Oct 16, 2019 7:39 pm

Re: sort order with shader

Post by borr »

thanks for your reply.
both rectangles with alpha less than one.
if i change the alpha of the color of the second rectangle to one - it doesn't help

Code: Select all

function love.draw()
	
	love.graphics.clear()
        love.graphics.setCanvas({ renderTarget1, depthstencil = depthBuffer })
	love.graphics.clear(0.4, 0.4, 1.0, 0.0)
	
	love.graphics.setShader(shader)
	shader:send("depth", 1.0)
	love.graphics.setDepthMode("less", true)
	
	shader:send("depth", 0.5)
	love.graphics.setColor(1.0, 0.0, 0.0, 0.5)
	love.graphics.rectangle("fill", 200, 200, 100, 100)
	
	shader:send("depth", 0.8)
	love.graphics.setColor(0.0, 1.0, 0.0, 0.5)
	love.graphics.rectangle("fill", 250, 250, 100, 100)
	
	love.graphics.reset()
	
	love.graphics.draw(renderTarget1)
	love.graphics.draw(depthBuffer, 0, 0, 0, 0.1, 0.1)
end
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: sort order with shader

Post by ReFreezed »

Draw the rectangles in the opposite order...
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
borr
Prole
Posts: 42
Joined: Wed Oct 16, 2019 7:39 pm

Re: sort order with shader

Post by borr »

it works thanks. except for the layer with the greatest depth

Code: Select all

	love.graphics.clear(0.4, 0.4, 1.0, 0.0)
	
	love.graphics.setShader(shader)
	shader:send("depth", 1.0)
	love.graphics.setDepthMode("less", true)
	
	shader:send("depth", -0.5)
	love.graphics.setColor(1.0, 0.0, 0.0, 0.5)
	love.graphics.rectangle("fill", 200, 200, 100, 100)
	
	shader:send("depth", -0.8)
	love.graphics.setColor(0.0, 1.0, 0.0, 0.5)
	love.graphics.rectangle("fill", 250, 250, 100, 100)
	
	--love.graphics.reset()
	
	love.graphics.draw(renderTarget1)
Attachments
alpha_problem_2.jpg
alpha_problem_2.jpg (3.33 KiB) Viewed 6559 times
borr
Prole
Posts: 42
Joined: Wed Oct 16, 2019 7:39 pm

Re: sort order with shader

Post by borr »

Is there a way to change the draw order using a shader. with full functionality (stencil, color etc)?
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: sort order with shader

Post by ReFreezed »

borr wrote: Wed Oct 19, 2022 5:01 pm it works thanks. except for the layer with the greatest depth
I'm not sure what you mean. That image looks correct. A green see-through rectangle, on top of a red see-through rectangle, on top of the blue background.

Note that shader:send("depth",1.0) doesn't do anything since you don't draw anything before you send a new value for 'depth'.
borr wrote: Wed Oct 19, 2022 5:22 pm Is there a way to change the draw order using a shader. with full functionality (stencil, color etc)?
The only thing you can change in the shader that affects the depth is the z position of the vertices, like you're currently doing. I don't think you can use both a depth buffer and a stencil at the same time (oops, I forgot about the depth24stencil8/depth32fstencil8 canvas formats), but you can implement you own stencil-like functionality using an extern Image and the 'discard' keyword.

Code: Select all

    extern Image mask;
    vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
    {
        if (Texel(mask, screen_coords/love_ScreenSize.xy).a == 0)  discard; // something like this
        vec4 texcolor = Texel(tex, texture_coords);
        return texcolor * color;
    }
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
borr
Prole
Posts: 42
Joined: Wed Oct 16, 2019 7:39 pm

Re: sort order with shader

Post by borr »

>I'm not sure what you mean. That image looks correct
red rectangle drawn with wrong alpha(other than 0.5) - love.graphics.setColor(1.0, 0.0, 0.0, 0.5)

looks like the right solution for draw-drawing is
https://love2d.org/wiki/Tutorial:Drawing_Order

I don't like it because you need to sort the array
User avatar
slime
Solid Snayke
Posts: 3166
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: sort order with shader

Post by slime »

Every game that uses alpha blending with semitransparency (regardless of what engine is being used) needs to sort objects back-to-front to make sure they're blended correctly.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: sort order with shader

Post by ReFreezed »

borr wrote: Wed Oct 19, 2022 6:21 pm >I'm not sure what you mean. That image looks correct
red rectangle drawn with wrong alpha(other than 0.5) - love.graphics.setColor(1.0, 0.0, 0.0, 0.5)
I'm still not sure what you mean, but maybe it has something to do with the way the canvas is drawn to the screen. You ought to use premultiplied alpha. (See the note at the top of https://love2d.org/wiki/Canvas.)

Code: Select all

	love.graphics.setBlendMode("alpha", "premultiplied")
	love.graphics.draw(renderTarget1)
	love.graphics.setBlendMode("alpha")
borr wrote: Wed Oct 19, 2022 6:21 pm looks like the right solution for draw-drawing is
https://love2d.org/wiki/Tutorial:Drawing_Order
I don't like it because you need to sort the array
It's only really going to be an issue if you have way too many objects in the array you're sorting. Also, you only have to sort objects with half-transparency. Opaque objects can be drawn in any order.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 7 guests