Howdy, Stranger!

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

Making fire

in Shaders Posts: 237

Does anyone have anything (shader or code) to make fire? I mean with animation. I'm also talking about very simple fire, like the one on this rocket right here. Thanks in advance.



  • Posts: 505
    The most simple solution would be to draw the flames 2x (1x yellow, 1x red) both with an offset from the rocket, just like in the picture. Then at random time blend out both or just the furthest one. This will create a blinking burn effect. Combined wirh some sound that makes for a beleaveable illusion.

    Another solution would be to animate the flame in asesprite or photoshop and use the resulting spritesheet to play the whole animation in a loop. To make an animation from a spritesheet you can use one of the scripts from this discussion:

    The third solution involves making your own particle engine. John did a generic one here:
  • Posts: 455

    Here's one I made that offloads all the heavy lifting into a shader:

  • Posts: 237

    @spacemonkey I have a lot of different particle engines, I don't know how to make them look good for what I am aiming for

    @se24vad I was gonna approach it the same way you did, except I can't find any good images and I can get vertices to work on my mesh, can anybody share som code, it would really be appreciated. Thanks!

  • edited March 2017 Posts: 631

    I found this, i cannot remember who wrote it.....

    --# Main
    function setup()
        --screen = image(WIDTH,HEIGHT)
        cap = image(100,100)
                local mp = 255/100
                for i=1,400 do
        m = mesh()
        m.texture = cap
        part = {}
        parameter.color("colour",color(255,60,0,80),function() m:setColors(colour) end)
        emitpos = vec2(WIDTH/2,HEIGHT/2-200)
    function draw()
        if i <= 400 then 
            i = i + 1
            part[i] = {}
            part[i].pos = vec2(WIDTH/2,HEIGHT/2)
            part[i].vel = vec2(math.random(-2,2)*2,math.random(-2,2))
            part[i].time = 0.5
            part[i].size = math.random(20,40)+size
            part[i].r = m:addRect(WIDTH/2,HEIGHT/2,1,1)
        background(77, 70, 70, 255)
        for i=1,#part do
            local p = part[i].pos
            part[i].pos = p+part[i].vel
            p = part[i].pos
            part[i].vel = part[i].vel+vec2((emitpos.x-p.x)/300-part[i].vel.x/15,0.005*part[i].size)
            part[i].time = part[i].time-0.01
            local t = part[i].time
            if t<=0 then
                part[i].pos = vec2(WIDTH/2,HEIGHT/2)
                part[i].vel = vec2(math.random(-2,2),math.random(-2,2))
                part[i].time = 0.5
                part[i].size = math.random(20,40)+size
    function touched(t)
        emitpos = emitpos + vec2(t.deltaX,t.deltaY)
    end -- cartoon fire
  • edited March 2017 Posts: 505

    If you try to go route (2) I described, you can use my Procreate-To-Codea-Animation-Tool mentioned here:

    And here are two tweets showing the process..
    As you can tell, it doesn't matter if you can draw or not, you just need at least two frames of animation for it to work. (I did three)

  • Posts: 237

    @se24vad that looks really good, but also really difficult.

    @piinthesky i think I might use that one, I have made one of my own, now I have to decide which one is better.

    Thank you both!

  • edited March 2017 Posts: 455

    Here is some fire I found on the internet and ported in. Alpha blending doesn't seem to work so I hard push it down to black, probably just something I'm rusty on.

    From here:

    You'll need this image to load in the setup:

    -- Fire
    -- Use this function to perform your initial setup
    function setup()
        flameTexture = readImage("Dropbox:flame")
        fireMesh = mesh()
        fireMesh:addRect(WIDTH/2, HEIGHT/2, 100, 200)
        fireMesh:setRectTex(1 , 0,1,1,-1.0)
        fireMesh.texture = flameTexture
        fireMesh.shader = shader(fireShader.vertexShader, fireShader.fragmentShader)
    -- This function gets called once every frame
    function draw()
        fireMesh.shader.time = ElapsedTime
    fireShader = {
    vertexShader = [[
    // A basic vertex shader
    //This is the current model * view * projection matrix
    // Codea sets it automatically
    uniform mat4 modelViewProjection;
    //This is the current mesh vertex position, color and tex coord
    // Set automatically
    attribute vec4 position;
    attribute vec2 texCoord;
    //This is an output variable that will be passed to the fragment shader
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
    void main()
        vTexCoord = texCoord;
        //Multiply the vertex position by our combined transform
        gl_Position = modelViewProjection * position;
    fragmentShader = [[
    // A basic fragment shader
    //Default precision qualifier
    precision highp float;
    //This represents the current texture on the mesh
    uniform highp sampler2D texture;
    uniform highp float time;
    //The interpolated texture coordinate for this fragment
    varying highp vec2 vTexCoord;
    void main()
        //Generate noisy x value
        vec2 n0uv = vec2(vTexCoord.x*1.4 + 0.01, vTexCoord.y + time*0.69);
        vec2 n1uv = vec2(vTexCoord.x*0.5 - 0.033, vTexCoord.y * 2.0 + time*0.12);
        vec2 n2uv = vec2(vTexCoord.x*0.94 + 0.02, vTexCoord.y * 3.0 + time*0.61);
        float n0 = (texture2D( texture, n0uv).w-0.5)*2.0;
        float n1 = (texture2D( texture, n1uv).w-0.5)*2.0;
        float n2 = (texture2D( texture, n2uv).w-0.5)*2.0;
        float noiseA = clamp(n0 + n1 + n2, -1.0, 1.0);
        //Generate noisy y value
        vec2 n0uvB = vec2(vTexCoord.x*0.7 - 0.01, vTexCoord.y + time*0.27);
        vec2 n1uvB = vec2(vTexCoord.x*0.45 + 0.033, vTexCoord.y * 1.9 + time*0.61);
        vec2 n2uvB = vec2(vTexCoord.x*0.8 - 0.02, vTexCoord.y * 2.5 + time*0.51);
        float n0B = (texture2D( texture, n0uvB).w-0.5)*2.0;
        float n1B = (texture2D( texture, n1uvB).w-0.5)*2.0;
        float n2B = (texture2D( texture, n2uvB).w-0.5)*2.0;
        float noiseB = clamp(n0B + n1B + n2B, -1.0, 1.0);
        vec2 finalNoise = vec2(noiseA, noiseB);
        float perturb = (1.0 - vTexCoord.y)*0.35 + 0.02;
        finalNoise = (finalNoise * perturb) + vTexCoord - 0.02;
        vec4 color = texture2D(texture, finalNoise);
        color = vec4(color.x*2.0, color.y*0.9, (color.y/color.x)*0.2, 1.0);
        finalNoise = clamp(finalNoise, 0.0, 1.0);
        color.a = texture2D(texture, finalNoise).a * 4.0;
        color.a = color.a*texture2D(texture, vec2(vTexCoord.x, 0.95 - vTexCoord.y)).z * 4.0;
        //for some reason alpha isn't merging so just drop the overall color
        color = color * color.a;
        gl_FragColor = color;
  • Posts: 237

    @spacemonkey Wow! This is amazing! You gotta teach me how you make your shaders, they are really great! Thank you so much!

  • Posts: 455

    I can't take credit, my process is:
    1. google for something cool
    2. copy it into Codea
    3. poke it randomly till it works


Sign In or Register to comment.