Howdy, Stranger!

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

Text outline shader

edited January 2014 in Shaders Posts: 1,595

I was toying around with a glowing method and tried it on some text, it didn't work out great so I condensed it and turned it black to create a smooth text outline which has IMO a nice effect.
The down side is you need to setContext to an image and put it on a mesh.


--# Main -- TextOutline -- Use this function to perform your initial setup function setup() m = mesh() r = m:addRect(WIDTH/2,HEIGHT/2,300,300) txtre = image(300,300) setContext(txtre) pushStyle() fill(50,255,0) fontSize(50) font("AmericanTypewriter") textWrapWidth(280) textMode(CENTER) text("Text Outline! abcdefghijklmnopqrstuvwxyz",150,150) popStyle() setContext() m.texture = txtre m.shader = shader(shadr.vS,shadr.fS) end -- This function gets called once every frame function draw() -- This sets a dark background color background(131, 131, 190, 255) -- This sets the line thickness strokeWidth(5) -- Do your drawing here m:draw() 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 = [[ uniform sampler2D texture; varying highp vec2 vTexCoord; void main() { highp float radius = 0.01; mediump vec4 ot = vec4(0.0); mediump vec4 normal = vec4(0.0); mediump float x = 0.0; mediump float y = 0.0; normal = texture2D(texture, vec2(vTexCoord.s,vTexCoord.t)); for(int i=1;i<5; i++){ x+=0.1; y+=0.1; ot += texture2D(texture, vec2(vTexCoord.s-radius*x, vTexCoord.t-radius*y)); ot += texture2D(texture, vec2(vTexCoord.s+radius*x, vTexCoord.t-radius*y)); ot += texture2D(texture, vec2(vTexCoord.s+radius*x, vTexCoord.t+radius*y)); ot += texture2D(texture, vec2(vTexCoord.s-radius*x, vTexCoord.t+radius*y)); } ot *= 1.0; ot.rgb = vec3(0,0,0); //accum.a = 1.0; normal = (ot * (1.0-normal.a)) + (normal * normal.a); gl_FragColor = normal; } ]] }

Comments

  • Very nice job :)

    also, I got a little question about shaders, since you know alot about them, every shader only works with a mesh...? or not...?

  • Posts: 1,595

    I know far from a lot! Just experimenting with the fragment shader mostly. You can only set a shader to a mesh though.

  • edited January 2014 Posts: 1,595

    Little update made it smoother and added width:


    --# Main -- TextOutline -- Use this function to perform your initial setup function setup() m = mesh() r = m:addRect(WIDTH/2,HEIGHT/2,300,300) txtre = image(400,400) setContext(txtre) pushStyle() fill(255, 248, 0, 255) fontSize(50) font("Noteworthy-Bold") textWrapWidth(350) textMode(CENTER) text("Text Outline! ABCDFGHIJKLMNOPQRSTUVWXYZ?",200,200) fill(0,0) strokeWidth(2) stroke(0,255) rect(0,0,400,400) popStyle() setContext() m.texture = txtre m.shader = shader(shadr.vS,shadr.fS) m.shader.width = 2 end -- This function gets called once every frame function draw() -- This sets a dark background color background(131, 131, 190, 255) -- This sets the line thickness strokeWidth(5) -- Do your drawing here m:draw() 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 = [[ uniform sampler2D texture; varying highp vec2 vTexCoord; uniform highp float width; void main() { highp float radius = 0.01; mediump vec4 ot = vec4(0.0); mediump vec4 normal = vec4(0.0); mediump float x = 0.0; mediump float y = 0.0; normal = texture2D(texture, vec2(vTexCoord.s,vTexCoord.t)); for(int i=1;i<12; i++){ x=sin(float(i)*0.5)*width*0.3; y=cos(float(i)*0.5)*width*0.3; ot += texture2D(texture, vec2(vTexCoord.s-radius*x, vTexCoord.t-radius*y)); ot += texture2D(texture, vec2(vTexCoord.s+radius*x, vTexCoord.t-radius*y)); ot += texture2D(texture, vec2(vTexCoord.s+radius*x, vTexCoord.t+radius*y)); ot += texture2D(texture, vec2(vTexCoord.s-radius*x, vTexCoord.t+radius*y)); } ot *= 0.4; ot.rgb = vec3(0,0,0); //accum.a = 1.0; normal = (ot * (1.0-normal.a)) + (normal * normal.a); gl_FragColor = normal; } ]] }
  • Posts: 2,820

    I'll have to try this. Thanks!

  • Posts: 1,595

    It's works better than expected, even on fontsizes of 10 with a width of .5 to make it look more noticeable.

  • edited January 2014 Posts: 2,820

    You need to replace m.shader = shader("Documents:OutlineGlow") with m.shader = shader(shadr.vS,shadr.fS).

  • edited January 2014 Posts: 1,595

    Oops, sorry! Fixed.

  • Jmv38Jmv38 Mod
    Posts: 3,295

    Doesnt work for me. The previous one did. Dont know what is wrong.

  • @Jmv38 same here, I'm on ipad3

  • Posts: 2,820

    It's not working for me (I assumed it was an issue with the beta).

  • Posts: 1,595

    sorry if its not working guys I'll take a look when I get back home.

  • Posts: 257

    very great, i like it. just first version works on ipad 2 32Go.

  • Posts: 1,595

    thanks, I'm not able to fix the second one at the moment as I'm not at home for a while, I will edit the post with what I think is the fix now but I can't promise anything!

  • @Luatee yes it works now, looking good ;)

  • Posts: 1,595

    @Stevon8ter thanks bud, I think theres a small problem when using the shader on sprites when the direction is true south and east, it stops blending making it look flat on the side but this isnt the case with text I don't think

Sign In or Register to comment.