Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Glowing line shader

edited January 2014 in Shaders Posts: 1,595

As some of you might know I added a little glow effect to the physgun in my game for when objects are being held, well as fewer of you may know it doesn't perform too well with big objects, so I thought I would take a basic line shader and add the glowing effect I was looking for, this time it actually glows which is what I was aiming for the first time.
Here's the code:


--# GLine GLine = class() function GLine:init(ent,width) -- you can accept and set parameters here self.m = mesh() self.r = {} local pos1 = nil local pos2 = nil for i=1,4 do if i == 1 then pos1 = ent.points[i] pos2 = ent.points[4] else pos1 = ent.points[i] pos2 = ent.points[i-1] end local d = (pos1-pos2) self.r[i] = self.m:addRect(pos1.x-d.x/2,pos1.y-d.y/2,d:len(),width*5,angleOfPoint(d)/mp) end self.m.shader = shader(shadr.vS,shadr.fS) self.m.shader.color = vec4(0,1,2,1) self.m.shader.len = (ent.points[1]-ent.position):len()/45 self.width = width end function GLine:setPositions(ent) local pos1,pos2 for i=1,4 do if i == 1 then pos1 = ent.points[i]:rotate(ent.angle/mp) pos2 = ent.points[4]:rotate(ent.angle/mp) else pos1 = ent.points[i]:rotate(ent.angle/mp) pos2 = ent.points[i-1]:rotate(ent.angle/mp) end local d = (pos1-pos2) self.m:setRect(self.r[i],ent.x+pos1.x-d.x/2,ent.y+pos1.y-d.y/2,d:len(),self.width*5,angleOfPoint(d)/mp) end self.m.shader.len = (ent.points[1]-ent.position):len()/45 end function GLine:draw() self.m.shader.time = ElapsedTime*2 self.m:draw() end function GLine:touched(touch) -- Codea does not automatically call this method end shadr = {vS = [[ uniform mat4 modelViewProjection; attribute vec4 position; attribute vec4 color; attribute vec2 texCoord; varying lowp vec4 vColor; varying highp vec2 vTexCoord; void main() { //Pass the mesh color to the fragment shader vColor = color; vTexCoord = texCoord; //Multiply the vertex position by our combined transform gl_Position = modelViewProjection * position; } ]], fS = [[ varying highp vec2 vTexCoord; uniform lowp vec4 color; uniform highp float time; uniform highp float len; void main() { highp float mp = sin(time*4.0+(25.0*vTexCoord.x)*0.03*len)* sin(time*10.0+25.0*vTexCoord.x*0.055*len)*1.9+3.0; mediump vec2 vTexCoordn = 1.0-2.0*vec2(vTexCoord.x,vTexCoord.y); lowp float dist = sqrt(vTexCoordn.x*vTexCoordn.x+vTexCoordn.y*vTexCoordn.y); vTexCoordn.x = 0.0; //Premult gl_FragColor = color*(1.4-length(vTexCoordn)*0.7*mp-dist); } ]]} -- Codea does not automatically call this method --# GStroke GStroke = class() function GStroke:init(pos1,pos2,width) -- you can accept and set parameters here self.pos1 = pos1 self.pos2 = pos2 self.m = mesh() self.m.shader = shader(shadr.vS,shadr.fS) self.m.shader.color = vec4(0,1,2,0.8) local d = (pos1-pos2) self.m.shader.len = d:len()/5 self.r = self.m:addRect(pos1.x-d.x/2,pos1.y-d.y/2,d:len(),width*5,angleOfPoint(d)/mp) self.width = width end function GStroke:setPositions(pos1,pos2) self.pos1 = pos1 self.pos2 = pos2 local d = (pos1-pos2) self.m.shader.len = d:len()/5 self.m:setRect(self.r,pos1.x-d.x/2,pos1.y-d.y/2,d:len(),self.width*5,angleOfPoint(d)/mp) end function GStroke:draw() self.m.shader.time = ElapsedTime*5 self.m:draw() end function GStroke:touched(touch) -- Codea does not automatically call this method end --# Main mp = (180/math.pi) function angleOfPoint( pt ) local ang = math.atan2(pt.y,pt.x)*(180/math.pi) if ang < 0 then ang = 360+ang elseif ang > 360 then ang = 0+(ang-360) end return ang end function setup() pos = vec2(WIDTH/2,HEIGHT/2) body = physics.body(POLYGON,vec2(-40,-40),vec2(-40,40),vec2(40,40),vec2(40,-40)) body.position = pos lines = GLine(body,5) lines.m.shader.color = vec4(2,1,0,1) floor = physics.body(POLYGON,vec2(-WIDTH/2,-5),vec2(-WIDTH/2,5),vec2(WIDTH/2,5),vec2(WIDTH/2,-5)) floor.position = vec2(WIDTH/2,5) flines = GLine(floor,4) flines.m.shader.color = vec4(1,1,1,1) floor.type = STATIC holding = nil tline = nil end function draw() background(50,255) flines:setPositions(floor) flines:draw() lines:setPositions(body) lines:draw() if holding then local dist = vec2(holding.x,holding.y):dist(body.position) body:applyForce((vec2(holding.x,holding.y)-body.position)*(dist/250)-body.linearVelocity/10) tline:setPositions(body.position,vec2(holding.x,holding.y)) tline:draw() end text(1/DeltaTime,200,100) end function touched(t) if t.state == BEGAN and body:testPoint(vec2(t.x,t.y)) then holding = t tline = GStroke(body.position,vec2(t.x,t.y),5) end if holding ~= nil then holding = t end if t.state == ENDED then holding = nil tline = nil end end

This is a little example of what it can be used for, hope you enjoy it, I was looking for one of these for 2D for ages! But I thought I might as well try and write my own, the performance is much better!

Comments

  • Posts: 2,820

    By reading the code, it looks interesting, but I can't try it right now. Thanks!

  • Posts: 1,595

    @Zoyt GLine outlines any polygon with 4 vertices, could have done it based on the point count but I only needed it for a box on my game and GStroke is a line from point a to point b, thanks.

  • Jmv38Jmv38 Mod
    Posts: 3,295

    @luatee very nice! Runs 60hz on ipad1 too =D>

  • edited January 2014 Posts: 1,595

    @Jmv38 Thanks, 60Fps really? As I said it completely outweighs the other method in terms of speed and at the same time has many more applications. Didn't think it was that good though ;)

  • Posts: 2,820

    Finally got a chance to try it. It's sweet! May I have permission to use it in StackIt? I was literally looking for something like this 2 days ago.
    Thanks!

  • Posts: 1,595

    Sure go for it! Glad you like it, it's more like plasma than a glow though.

  • Posts: 2,820

    @Luatee - It's actually a better effect than I was looking for. Thanks!

  • It looks so sexy...

  • Posts: 1,976

    @TheRogueBatcher There are children on here...

  • Posts: 1,595

    @SkyTheCoder kids as young as 5 are being taught about that sort of education if you don't want to use the word.

  • Posts: 1,976

    @Luatee I don't understand, what sort of education?

    I just think that it's stupid to say something that looks cool is "sexy."

  • Posts: 1,595

    Sexual education, and I agree but it's his choice of words, I can't argue with that.

  • Posts: 835

    I hate to agree, Kids are learning words that are just pointless! Swag being the worst! At least use Swagger, its a real word thats existed for hundreds of years!

  • Posts: 1,976

    School isn't helping at all, either...

  • With 150 physics bodies on the screen, it draws at 20fps on my ipad 3

    Very nice job @Luatee!

    I wonder if I can use this as the basic graphics of a game I'm working on? (ofcourse I'd give credits!)

  • Posts: 2,820

    Nice @stevon8ter.

  • Posts: 1,595

    Wow thanks I didn't test it thoroughly. You could only for lines though, I'm trying to figure out how to make a fast enough circle glow all the ones I've come up with are too slow, using just math no conditionals and it's still slow.

  • edited January 2014 Posts: 547

    @Luatee I'm far from a shader expert (well I actually never used it) but I could take a look at the math behind it if you want me to

    Also, my game would be all about cubic shapes so yeah ;)

    And note that the physics probably also slows the program down, so my guess is that 150 squares without physics would run around 30fps...

  • Posts: 2,820

    @Luatee - I'm on an iPhone, so my shot at a solution might not be too clear, but here we go: You you basically take the normal shader, then add this at the end to move the x position to cos(pixelX/totalX*6.28+circleDist) and do the same with the y. I actually don't know that much about how it works, so if I have a bit of extra time, I'll take a peak.

  • Posts: 1,595

    I know what the problem is its not the math, it's the amount of pixels in the shader texture that's slowing it down. And on my game I get 30fps with 100 boxes with physics, but I only use the glow when holding one box so I don't know about it on all of them, I hope the new version of codea will have some noticeable speed differences.

  • Posts: 1,595

    @Zoyt that's blurred a bit though when the ball is about 20 times larger!

  • @Luatee yes I'm hoping for those speed improvements ;)

    and the test I did was 150 objects with physics, all glowing at the same time

    It runs at 20 fps, the glowing itself slows a little bit down tho, but nothing than that, and I don't mind them slowing down a bit

  • Posts: 1,595

    @stevon8ter depending on the width you'll get different speeds, if you use a width of 20 for all boxes it will be a lot slower.

  • @Luatee I noticed that, but there was a very small (and yes very small) slow down when using either 1 or 150 bodies

    But I could have been misstaken at that time xD

  • Posts: 1,595

    Haha well I'm gonna see if I can improve it a bit tomorrow anyway hopefully make it a bit faster

  • Posts: 2,820

    It looks amazing in my app, and doesn't bring down the FPS at all (I'm drawing around 20-30 settings the position every frame).

  • Posts: 1,595

    Which app is this on? And thanks, good to know it runs smoothly!

  • Posts: 2,820

    StackIt.

  • edited January 2014 Posts: 1,595

    I look forward to seeing what you do with it :)

  • Posts: 2,042

    @Luatee, now I'm just guessing here, but I'm pretty sure he is using it to outline the falling shapes.

  • Posts: 1,595

    @JakAttak you think? I was thinking a power up of sorts

  • Posts: 2,820

    It's for the "glue" power up. I call it glue, but it's really not. It's much more fun.

  • @Luatee i would like to make heavy use of your glowline shader in my app, it looks and works great. Is that okay? I will add you in the credits if it ever goes further than my ipad.

    Did you succeed to make a circle glowline shader? if so, I would be interested to play with it, even if it is slow.

  • Posts: 1,595

    @piinthesky sure, I have another one where the glow comes from the middle outwards, I forget if I edited the OP with that version or not, I made a few circle glow line shaders, some a bit faster than others but never the speed I'm looking for, I'd be happy to put it on they're all free for use

  • Posts: 2,820

    Cool. I forgot to put you in the credits. Whoops!

  • Posts: 1,595

    You're bad, I still haven't managed to see what it looks like because of the errors on start up

  • Posts: 2,820

    @Luatee - Sadly, I won't have access to a computer for 2 weeks, so I'll post a video for you.

  • Posts: 372

    A little late, but that looks really awesome! Thanks for sharing it...

  • Posts: 1,595

    @Zoyt great, thanks! @Saurabh thanks bud.

  • @Luatee ' OP with that version...' what does OP mean?!

    Don't forget the glow circle shader! :)

  • Posts: 1,595

    @piinthesky Original Post (1st post) and I will post them tonight when I get my iPad back!

  • Posts: 2,042

    @Luatee, this is amazing, may I use it in a game of mine? Also, I was wondering if you think it's possible to achieve a similar effect for text.

  • edited January 2014 Posts: 1,595

    Yes of course @JakAttak it's here for everyone to use as they like, I was toying with outlining text but I only got a solid black outline, and that's by making passes of the image in a 1 pixel circle. I'm not sure how I'd do it with glow, I'm going to look in to that a bit more later on.

    @piinthesky plug this fragment shader in to the shader lab:

    //
    // A basic fragment shader
    //
    uniform lowp vec4 color;
    uniform highp float time;
    uniform mediump float len;
    uniform mediump float width;
    
    //Default precision qualifier
    precision highp float;
    
    //The interpolated vertex color for this fragment
    varying lowp vec4 vColor;
    
    //The interpolated texture coordinate for this fragment
    varying highp vec2 vTexCoord;
    
    void main()
    {
        mediump vec2 tn = -1.0+2.0*vTexCoord;
        mediump float dist = sqrt(tn.x*tn.x+tn.y*tn.y);
        if(dist<0.7) discard;
        highp float add = atan(tn.y,tn.x);
        mediump float mp = cos(add*3.0+time*10.0)*(cos(add*3.0)*0.7);
        highp vec4 col = color*len*(-cos(sin(dist*(1.8+mp*0.05))*
        (4.72+width*0.01))*
        (-10.0+width*0.1+(mp)));
        //Set the output color to the texture color
        gl_FragColor = col;
    }
    

    It's not very glow like yet, I have another one rooted around somewhere.

  • Posts: 2,820

    @Luatee - It still needs some perfection, but here's an early video of what I have:
    One thing I plan to do is so not every object is showing a line to every other object.
    Thanks!

  • Posts: 2,042

    @Zoyt, video unavailable on mobile...

  • Posts: 1,595

    I like it, it looks a bit messy though when all of them are connected, is there a way you can make a polygon surrounding those bodies and glow that up, that might not be what you’re going for though.

  • Posts: 2,820

    @Luatee - That's my plan. When I initially made it, it was just a test and I was going to change it later, but I was on a timeframe to release the beta (because I wouldn't have a computer for a while) and I never got a chance to fix it.
    @JakAttak - You might of tried to view it while it was still processing. Try it again.

  • Posts: 2,042

    @Zoyt, either way, I've seen it in action.

Sign In or Register to comment.