Page 1 of 1

Apply PixelEffect to 'shapes'

Posted: Wed Sep 04, 2013 11:14 am
by codinghands
I'm trying to apply a PixelEffect to both a ParticleSystem and a raw 'shape' (a love.graphics.line). However, whilst the ParticleSystem's pixels are being affected as expected, the drawn shape exhibits some strange behaviour. My shader is below:

Code: Select all

makePurple = love.graphics.newPixelEffect [[
    extern vec2 p;
    extern vec2 q;
    extern vec2 r;
    extern vec3 replaceColor;
    
    float det(vec2 v1, vec2 v2){
        return v1.x*v2.y-v2.x*v1.y;
    }

    vec4 effect ( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ) {
        
        vec2 pr = vec2(r.x - p.x, r.y - p.y);
        vec2 pq = vec2(q.x - p.x, q.y - p.y);
        vec2 pa = vec2(screen_coords.x - p.x, screen_coords.y - p.y);
        
        float d = det(pq, pr);

        if (0.0 <= -det(pa, pq)/d && -det(pa, pq)/d <= 1.0 && 0.0 <= det(pa, pr)/d && det(pa, pr)/d <= 1.0)
            return Texel(texture, texture_coords)*vec4(replaceColor.r,replaceColor.g,replaceColor.b,color.a);
        return Texel(texture, texture_coords)*vec4(color.r,color.g,color.b,color.a);
    }
]]
p, q and r are 3 points of a parallelogram, whilst replaceColor is the color to replace with if a point is in the area bounded by that parallelogram. These are sent on draw.

My Lua code is:

Code: Select all

    love.graphics.setStencil(self.emitterMask.stencil)
    -- Y coords of screen_coord in pixel effect are inverted
    -- TODO: remove these hardcoded numbers. set to the default resolution
    makePurple:send("p", {self.box.pos.tr.x, 720-self.box.pos.tr.y})
    makePurple:send("q", {self.box.pos.tl.x, 720-self.box.pos.tl.y})
    makePurple:send("r", {self.box.pos.br.x, 720-self.box.pos.br.y})
    makePurple:send("replaceColor", {self.bg.color.r/255, self.bg.color.g/255, self.bg.color.b/255})
    
    love.graphics.setPixelEffect(makePurple)
    self.wave:draw() -- just a line
    love.graphics.draw(self.emitter, self.bg.pos.br.x+25, self.bg.pos.br.y-10) -- adjust to 'center' the PS vertically - ROUGH
    love.graphics.draw(love.graphics.newImage("gfx/pulseWord.png"), 800, 200) -- for testing only
    love.graphics.setPixelEffect()
    love.graphics.setStencil()
When this runs, the emitter is correctly masked (by the stencil) and colors changed (by the shader). The 'pulseWord' image is also correctly color adjusted if any point is in the parallelogram. However, the line drawn (self.wave:draw()) either appears very faint (if draw is called before the ParticleSystem), or not at all (if draw is called after drawing the ParticleSystem).

I can't for the life of me figure this out. Do PixelEffects operate differently on primitive shapes?

Re: Apply PixelEffect to 'shapes'

Posted: Wed Sep 04, 2013 11:33 am
by vrld
These lines are the culprit:

Code: Select all

        if (0.0 <= -det(pa, pq)/d && -det(pa, pq)/d <= 1.0 && 0.0 <= det(pa, pr)/d && det(pa, pr)/d <= 1.0)
            return Texel(texture, texture_coords)*vec4(replaceColor.r,replaceColor.g,replaceColor.b,color.a);
        return Texel(texture, texture_coords)*vec4(color.r,color.g,color.b,color.a);
You can only get texels of image(like) objects, but not of the graphic primitives - because they have no texture.

Re: Apply PixelEffect to 'shapes'

Posted: Wed Sep 04, 2013 11:39 am
by codinghands
Ah ha. That makes sense, along with showing gaping holes in my knowledge of GLSL. Is there any way to achieve what I'm after in a similar manner?