Shader problem

Shader problem

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Shader problem

Post by PicassoCT »

Hi,
i have a small problem.

I have a working shader - with this code:

Code: Select all

function gadget:GetInfo()
    return {
        name = "HeatDeathShader",
        desc = "Dead Vehicles glow while dead",
        author = "me",
        date = "Sep. 20014",
        license = "GPL 3.141",
        layer = 256,
        enabled = true, --until the problem of all units having the shader applied is fixed
    }
end

if (gadgetHandler:IsSyncedCode()) then
    WreckageIs = {
        [UnitDefNames["gcvehiccorpsemini"].id] = true,
        [UnitDefNames["gcvehiccorpse"].id] = true,

    }

    burningUnits = {}
    TIME_BURNING = 900

    function gadget:UnitCreated(unitID, unitDefID, unitTeam, damage, paralyzer, weaponDefID, attackerID, attackerDefID, attackerTeam)
        if WreckageIs[unitDefID] then
            burningUnits[unitID] = TIME_BURNING
            SendToUnsynced("glowing_heatDeathShader_Start", unitID)
        end
    end

    function gadget:GameFrame(frame)
        if frame % 30 == 0 then
            for id, frames in pairs(burningUnits) do
                burningUnits[id] = frames - 30
                if frames - 30 < 0 then
                    SendToUnsynced("glowing_heatDeathShader_End", id)
                    burningUnits[id] = nil
                end
            end
        end
    end

else --UNSYNCED
    --shaderCode
    --- [[----------------------------------------------------------------------------
    local fragmentShaderSource = [[
uniform float time;
varying vec3 fNormal;

vec3 hit= vec3(1.0,0.8,0.3 );

vec3 glowing= vec3(0.9,0.3,0.1);

vec3 cooldown= vec3(0.4,0.1,0.05);

vec3 wreck=vec3(0.185,0.155,0.155);

vec3 currColor;
float averageShadow;
float PI=3.14159;

float totalTime=1.0;
float percenTage=0.0;
vec3 emptyVec = vec3(0.0,0.0,0.0);

vec3 clampAfter(vec3 x, float Time, float TimeLimit)
{
    return (Time < TimeLimit ? x :emptyVec);
}

vec3 openEnded(vec3 x, float Time, float TimeLimit, vec3 deFault)
{
    return Time < TimeLimit ? x :deFault;
}

void main()
{
    percenTage= (mod((time),totalTime))/totalTime*PI;

    averageShadow=(fNormal.x*fNormal.x+fNormal.y*fNormal.y+fNormal.z+fNormal.z)/3.25;

    currColor=(

     (percenTage < 0.5*PI ?  hit*cos(percenTage)*2.0 :emptyVec)

    + (percenTage < PI ? glowing*sin(percenTage)*2.5 :emptyVec)

    + (percenTage < PI*2.0 ? cooldown*sin(PI+percenTage)*2.0 :emptyVec)

    +openEnded(wreck*abs(sin(PI+percenTage)),PI+percenTage,PI*2.0,abs(wreck*0.3))
    );

  gl_FragColor = vec4(currColor*(1.0-averageShadow), 1);
}

]]

    local vertexShaderSource = [[
    uniform float time;
  	varying vec3  pos;

    const vec4 centerPos = vec4(0.0,0.0,0.0,1.0);

    varying vec3 fNormal;
    varying float changeRate;


    float PI_HALF= 3.14159/2.0;
    float PI =3.14159;

void main() {
    fNormal = normalize(gl_NormalMatrix * gl_Normal);

    float sigNum=1.0;

    //melting process - a inverse cosinus rising
    float molten = abs(1.0-cos((time)*PI_HALF));

    //percentage we scale the vector out or inwards
    float percentage= (sqrt(abs(fNormal.y)/(abs(fNormal.x)+abs(fNormal.z) +0.01)))/50.0; // /50

    sigNum=(fNormal.y >= 0.0)  ? -1.41  : 1.0;

    //computate the total melting and end it at max where the molten metall gets hadr
    //keep Constant Change
    changeRate= time < 0.5  ?
        mix(0.0, percentage * sigNum*molten, time / 0.5 ):
        percentage* sigNum* molten;


    // move the position along the normal and transform it
    vec3 newPosition = gl_Vertex + fNormal * changeRate;
    gl_Position =  gl_ModelViewProjectionMatrix * vec4( newPosition, 1.0  );

}
    ]]

    local shaderTable = {
        vertex = vertexShaderSource,
        fragment = fragmentShaderSource,
        uniformInt = {},
        uniform = {
            time = 0,
        },
    }
    --]]--------------------------------------------------------------------------

    --variables for the task ahead
    local shaderProgram
    local glUseShader = gl.UseShader

    local redHotUnits = {}
    glowTime = 900

    --Transfers the Data to the shader
    local function glowing_heatDeathShader_Start(callname, id)
        --Forge values in which to store the Holes Data


        if not redHotUnits[id] then
            redHotUnits[id] = Spring.GetGameFrame()
        end
        Spring.UnitRendering.SetUnitLuaDraw(id, true)
    end

    --Transfers the Data to the shader
    local function glowing_heatDeathShader_End(callname, id)
        --Forge values in which to store the Holes Data

        if redHotUnits[id] then
            redHotUnits[id] = nil
        end
        Spring.UnitRendering.SetUnitLuaDraw(id, false)
    end

    local timer = 0

    function gadget:Initialize()

        if gl.CreateShader then

            shaderProgram = gl.CreateShader(shaderTable)
            if shaderProgram == nil then
                Spring.Echo("HeatDeathShader" .. gl.GetShaderLog())
            end
            -- This associate the messages with the functions
            -- So that when the synced sends a message "f" it calls the function f in unsynced
            gadgetHandler:AddSyncAction("glowing_heatDeathShader_Start", glowing_heatDeathShader_Start)
            gadgetHandler:AddSyncAction("glowing_heatDeathShader_End", glowing_heatDeathShader_End)
            timer = gl.GetUniformLocation(shaderProgram, 'time')
        else
            Spring.Echo("<HeatDeath-Shader>: GLSL not supported.")
        end
    end


    local function getTime(startFrame)
        totalTime = Spring.GetGameFrame() - startFrame
         times= math.min(0.95, math.max(totalTime / glowTime, 0.0001))
        return times
    end

    function gadget:DrawUnit(unitID, drawMode)
        if shaderProgram then
            if redHotUnits[unitID] then
                glUseShader(shaderProgram)
				Spring.Echo("Shader active for:"..unitID)
                gl.Uniform(timer, getTime(redHotUnits[unitID]))
				--glUseShader(0)       
				end
        end
     end

        function gadget:Finalize()
            if (gl.DeleteShader) then
                gl.DeleteShader(shaderProgram)
            end
        end
  

end
The problem?
A this is not correct code - --glUseShader(0) should not be commented out. But if im commenting it in- the unit is simply not drawn.
Now - interestingly the shader has also bugs - meaning that at a certain zoom level - unfaced units will be drawn with the shader.
Attachments
screen00000.jpg
(303.88 KiB) Not downloaded yet
Post Reply

Return to “Lua Scripts”