////////////////////////////////////////////////
//
// particle shaders
//
////////////////////////////////////////////////

// wobbles the vertices of an explosion sphere
// and generates all texcoords 
// and blends the edge color
// and modulates the texture
explosionshader = [
    shader 0 $arg1 [
        //:fog
        attribute vec4 vvertex, vcolor;
        uniform mat4 explosionmatrix;
        uniform vec3 center;
        uniform float millis;
        attribute vec2 vtexcoord0;
        uniform vec4 texgenS, texgenT;
        @(? (>= (strstr $arg1 "soft") 0) [
            uniform vec2 lineardepthscale;
            varying float lineardepth;
        ])
        varying vec4 color;
        varying vec2 texcoord0, texcoord1, texcoord2;
        void main(void)
        {
            vec4 wobble = vec4(vvertex.xyz*(1.0 + 0.5*abs(fract(dot(vvertex.xyz, center) + millis*2.0) - 0.5)), vvertex.w);
            gl_Position = explosionmatrix * wobble;
            @(? (>= (strstr $arg1 "soft") 0) [
                lineardepth = dot(lineardepthscale, gl_Position.zw);
            ])

            color = vcolor;

            texcoord0 = vtexcoord0; 
            vec2 texgen = vec2(dot(texgenS, vvertex), dot(texgenT, vvertex)); 
            texcoord1 = texgen;
            texcoord2 = 0.5*texgen - millis*0.5;
        }
    ] [
        @(if (>= (strstr $arg1 "soft") 0) [result [
            @(gfetchdefs tex2)
            uniform vec3 softparams;
            varying float lineardepth;
        ]])
        varying vec4 color;
        varying vec2 texcoord0, texcoord1, texcoord2;
        uniform sampler2D tex0;
        uniform vec2 blendparams;
        fragdata(0) vec4 fragcolor;
        void main(void)
        {
            vec2 dtc = texcoord0 + texture2D(tex0, texcoord2).xy*0.1; // use color texture as noise to distort texcoords
            vec4 diffuse = texture2D(tex0, dtc);
            float blend = max(pow(clamp(1.0 - dot(texcoord1, texcoord1), 0.0, 1.0), blendparams.x), blendparams.y);
            diffuse *= blend*4.0; // dup alpha into RGB channels + intensify and over saturate
            diffuse.b += 0.5 - blend*0.5; // blue tint 

            @(if (>= (strstr $arg1 "soft") 0) [result [
                fragcolor.rgb = diffuse.rgb * color.rgb;

                @(gdepthunpack depth [gfetch(tex2, gl_FragCoord.xy)])
                fragcolor.a = diffuse.a * max(clamp((depth - lineardepth)*softparams.x - softparams.y, 0.0, 1.0) * color.a, softparams.z);
            ]] [result [
                fragcolor = diffuse * color;
            ]])
        }
    ]
]

explosionshader "explosion"
explosionshader "explosionsoft"

shader 0 "particlenotexture" [
    //:fog
    attribute vec4 vvertex, vcolor;
    uniform mat4 camprojmatrix;
    uniform vec4 colorscale;
    varying vec4 color;
    void main(void)
    {
        gl_Position = camprojmatrix * vvertex;
        color = vcolor * colorscale;
    }
] [
    varying vec4 color;
    fragdata(0) vec4 fragcolor;
    void main(void)
    {
        fragcolor = color;
    }
]

shader 0 "particletext" [
    //:fog
    attribute vec4 vvertex, vcolor;
    attribute vec2 vtexcoord0;
    uniform mat4 camprojmatrix;
    uniform float ldrscale;
    varying vec4 color;
    varying vec2 texcoord0;
    void main(void)
    {
        gl_Position = camprojmatrix * vvertex;
        texcoord0 = vtexcoord0;
        color = vec4(vcolor.rgb * ldrscale, vcolor.a);
    }
] [
    uniform vec4 textparams;
    uniform sampler2D tex0;
    varying vec4 color;
    varying vec2 texcoord0;
    fragdata(0) vec4 fragcolor;
    void main(void)
    {
        float dist = texture2D(tex0, texcoord0).r;
        float border = smoothstep(textparams.x, textparams.y, dist);
        float outline = smoothstep(textparams.z, textparams.w, dist);
        fragcolor = vec4(color.rgb * outline, color.a * border);
    }
]

particleshader = [
    shader 0 $arg1 [
        //:fog
        attribute vec4 vvertex, vcolor;
        attribute vec2 vtexcoord0;
        uniform mat4 camprojmatrix;
        uniform vec4 colorscale;
        varying vec4 color;
        varying vec2 texcoord0;
        @(? (>= (strstr $arg1 "soft") 0) [
            uniform vec2 lineardepthscale;
            varying float lineardepth;
            varying vec2 surface;
        ])
        void main(void)
        {
            gl_Position = camprojmatrix * vvertex;
            texcoord0 = vtexcoord0; 
            color = vcolor * colorscale; 

            @(? (>= (strstr $arg1 "soft") 0) [
                lineardepth = dot(lineardepthscale, gl_Position.zw);
                surface = vtexcoord0.xy*2.82842712474619 - 1.4142135623731;
            ])
        }
    ] [
        @(if (>= (strstr $arg1 "soft") 0) [result [
            @(gfetchdefs tex2)
            uniform vec3 softparams;
            varying float lineardepth;
            varying vec2 surface;
        ]])
        uniform sampler2D tex0;
        varying vec4 color;
        varying vec2 texcoord0;
        fragdata(0) vec4 fragcolor;
        void main(void)
        {
            vec4 diffuse = texture2D(tex0, texcoord0);

            @(if (>= (strstr $arg1 "soft") 0) [result [
                @(gdepthunpack depth [gfetch(tex2, gl_FragCoord.xy)])
                diffuse.a *= clamp((depth - lineardepth)*softparams.x - softparams.y - dot(surface, surface), 0.0, 1.0);
            ]])

            fragcolor = diffuse * color;
        }
    ]
]

particleshader "particle"
particleshader "particlesoft"

