Spring.SetMapShader questions

Spring.SetMapShader questions

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

Moderator: Moderators

Post Reply
User avatar
eronoobos
Posts: 73
Joined: 27 Mar 2015, 20:25

Spring.SetMapShader questions

Post by eronoobos »

(moved from viewtopic.php?f=81&t=34710 )
gajop wrote:Custom map shaders are pretty powerful and not terribly hard to write, see https://www.youtube.com/watch?v=2IgBvSH7Kqs
the custom map shader in the video is super cool! could you provide the source code?

I can't figure out how to preserve the map texturing when giving a vertex shader to Spring.SetMapShader. I get a black map if I don't set gl_FrontColor, and if I set it to gl_Color, then I get a white map. Do I need to re-implement the engine's vertex shader? https://github.com/spring/spring/blob/5 ... tProg.glsl I've tried to do this, and any vertex shader with

Code: Select all

gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
fails to compile, with no errors in the log.

Do I need to completely recreate the engine's vertex and fragment shaders? If I leave out a fragment shader, will the engine's be used? How do I just transform the positions of vertices, and pass through everything else (texturing, lighting, etc)?

Why does this

Code: Select all

local testWormShader = [[
void main(void)
{
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
	gl_TexCoord[0] = gl_MultiTexCoord0;
}       
]]

function widget:Initialize()
	wormShaderID = glCreateShader({vertex = testWormShader})
	spEcho("wormShaderID", wormShaderID)
	local errors = gl.GetShaderLog(wormShaderID)
	spEcho(errors)
	spSetMapShader(wormShaderID, 0)
end
result in this?
Image
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Spring.SetMapShader questions

Post by gajop »

I'm posting my widget + shader below. Hopefully you'll be able to analyze it yourself and apply it to your problem.
It's important to note that it doesn't do sun lighting or SSMF. It's unfortunate, but someone will have to create the custom map shader framework (or extend the existing CUSF), and I don't have the time to do so this month. That said, you can still get the effects I achieved in the video, and try hacking in things one at a time as you need them.
Please ask if you have any further questions about the code below.

Code: Select all

function widget:GetInfo()
	return {
		name      = "MapShader",
		desc      = "MapShader demo",
		author    = "gajop",
		date      = "",
		license   = "",
		layer     = 0,
		enabled   = true,
	}
end

local shader, timeID, pointsID, pointsSizeID

local MAX_POINTS = 10
local points = {}

function widget:Initialize()
    local vertexShader = [[
        #define SMF_TEXSQR_SIZE 1024.0

        uniform ivec2 texSquare;
        varying vec2 texCoors;

        varying vec4 colorChange;

        uniform float time;
        uniform float points[MAX_POINTS];
        uniform int pointSize;

        void main(void) {
            texCoors = (floor(gl_Vertex.xz) / SMF_TEXSQR_SIZE) - vec2(texSquare);

            vec4 pos = gl_Vertex;
            colorChange = vec4(0, 0, 0, 1);
            for (int i = 0; i < pointSize; i++) {
                float d = distance(vec2(points[i*3], points[i*3+1]), pos.xz);
                float dtime = time - points[i*3+2];

                float timeFalloff = pow(dtime, 3) + 1;
                float rangeFalloff = pow(d/400, 2) + 1;
                float rangeFrequency = sin(d/1000 + 1);
                pos.y += sin(dtime*10) * 200 / rangeFalloff * rangeFrequency / timeFalloff;

                colorChange += vec4(sin(dtime*10) * 200 / rangeFalloff * rangeFrequency / timeFalloff) / 1000;
            }
            gl_Position = gl_ModelViewProjectionMatrix * pos;
        }
    ]]
    vertexShader = vertexShader:gsub("MAX_POINTS", tostring(MAX_POINTS*3))
    shader = gl.CreateShader({
        vertex = vertexShader,

        fragment = [[
            uniform sampler2D texSampler;

            varying vec2 texCoors;

            varying vec4 colorChange;

            void main(void) {
                gl_FragColor = texture2D(texSampler, texCoors);
                gl_FragColor += colorChange;
            }
        ]],

        uniformInt = {
            texSampler = 0,
            pointSize  = 0,
        },
        uniformFloat = {
            time = 0,
        },
    })

    local errors = gl.GetShaderLog(shader)
    if errors ~= "" then
        Spring.Log("MapShaders", LOG.ERROR, errors)
    end
    Spring.SetMapShader(shader, 0)
end

function widget:Shutdown()
    Spring.SetMapShader(0, 0)
end

function widget:DrawWorld()
    gl.UseShader(shader)
    if not timeID then
        timeID         = gl.GetUniformLocation(shader, "time")
        pointsID       = gl.GetUniformLocation(shader, "points")
        pointSizeID    = gl.GetUniformLocation(shader, "pointSize")
    end
    gl.Uniform(     timeID,       os.clock())
    gl.UniformInt(  pointSizeID,  #points/3)
    gl.UniformArray(pointsID,     1, points)
    gl.UseShader(0)
end

function widget:MousePress(x, y, button)
    local time = os.clock()
    if button == 1 or button == 3 then
        local result, coords = Spring.TraceScreenRay(x, y, true)
        if result == "ground" then
            if #points >= MAX_POINTS * 3 then
                table.remove(points, 1)
                table.remove(points, 1)
                table.remove(points, 1)
            end
            table.insert(points, coords[1])
            table.insert(points, coords[3])
            table.insert(points, time)
        end
    end
end
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Spring.SetMapShader questions

Post by PicassoCT »

Okay, i have a lot of questions..

1) How to incooperate the default map rendering behavior in a map shading framework so that additional shaders may render on top?
?) More to come
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Spring.SetMapShader questions

Post by gajop »

1) Difficult. Basically you'd need to create some sort of Lua map shader framework that will wire up the shader to engine environment values (lighting, sun position/dir, etc.) and mapinfo SSMF textures (specular, normal, dnts, etc.), depending on what is available.
I kinda want to do that. Are you willing to collaborate?
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Spring.SetMapShader questions

Post by PicassoCT »

Yes i am.. the target is to get something like the UnitShaderFramework with a distribution Map?

To be honest, i contemplated on working on something like this allready.

https://github.com/PicassoCT/springMap_ ... ui/widgets

It is not much at the moment. It loads fragments and vertexelements. I decided to load uniform and uniform update code from a seperate file.
Im interested in how you would approach this.

The trouble i see is rebuilding the engine rendering process in Lua.

https://github.com/spring/spring/tree/d ... aders/GLSL

My suggestion is to build a small working version that works upon a distribution texture.
Then integrate the engines mapshaders one by one, measuring every step on frame drops.
Used resources of the engine shaders should be available to another shader?
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Spring.SetMapShader questions

Post by gajop »

The end goal is to get a shader framework for maps and also units and features (after modernizing the approach). This would be a repository hosted under spring/shader_framework and therefore less likely to become outdated.

I want to modularize shaders into four elements:
1) Shader framework. The framework itself will handle material assignment, update shader uniforms as engine values change, and it will provide an API for other elements.
2) Shader specification. Defines the shader with its inputs and outputs.
3) Shader instancing. Assigns certain values to a shader and creates an instance out of it. This would involve assigning actual textures, uniforms and similar (depending on the inputs given in the shader specification). The reason I'd like to move it out from the shader specification is because this would allow us to have multiple instances of the same shader with different values.
4) Shader-object linking. Enabling the shader for specific units, features or the map. This should be moved from the shader specification or shader framework because this logic can be arbitrarily complex.

I would also like for this to be data driven (or rather, specified clearly with some tables), so it's possible to read and assign things through editors (because I'd like SpringBoard to provide support for shader editing).

As you've noticed, right now there seem to be some ongoing changes in the engine rendering and I was advised by hokomoko to delay creating any shader framework until GL4 transition is finalized -> so this adventure of ours may have to wait.

In the end, I would like to create and modernize the existing shader framework, and then I'd like to have you test it with some ideas you might have.

I think it might be worth it to create a "default" shader (to mimic the engine shader), but in the end we should aim for people writing their shaders from scratch, without thinking about SSMF.
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Spring.SetMapShader questions

Post by PicassoCT »

May i suggest to signal the engine rewritting party our existence so that the various requirements of our endavour can be accommodated
Post Reply

Return to “Lua Scripts”