New gl.UnitShape is less useful

New gl.UnitShape is less useful

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

Post Reply
Google_Frog
Moderator
Posts: 2464
Joined: 12 Oct 2007, 09:24

New gl.UnitShape is less useful

Post by Google_Frog »

The new gl.UnitShape is less useful than it was in 100.0. I have figured out the arguments required to make gl.UnitShape draw something but the translucent version is much too translucent and I do not want a fully opaque unit. Also there are cases where it was useful to change the other colours of gl.UnitShape, for example a red tinge could be used to indicate an illegal location.

I have going to have to use gl.UnitShapeTextures alongside every instance of gl.UnitShape. However I do not know how to use gl.UnitShapeTextures. It does not have a return value so it must be loading a texture. But it does not seem to load a texture either. Could someone provide an example of gl.UnitShapeTextures doing something?

The new gl.UnitShape would be an improvement over the old one if it took color arguments.
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: New gl.UnitShape is less useful

Post by Kloot »

Code: Select all

local function SetupWorldUnitShape()
	gl.MatrixMode(GL.MODELVIEW)
	gl.PushMatrix()
	gl.LoadIdentity()
end
local function ResetWorldUnitShape()
	gl.MatrixMode(GL.MODELVIEW)
	gl.PopMatrix()
end

local function glUnitShapeWorld(unitDef)
	SetupWorldUnitShape()

	gl.Translate(1.0, 2.0, 3.0)
	gl.UnitShapeTextures(unitDef.id, true)
	gl.UnitShape(unitDef.id, 0, true) -- UST needs rawState
	gl.UnitShapeTextures(unitDef.id, false)
	
	ResetWorldUnitShape()
end
Whenever you find yourself thinking "color", mentally reprogram that thought to say "shader".
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: New gl.UnitShape is less useful

Post by gajop »

Here's an example:

Code: Select all

local teamID = 0
local unitDefName = "tawf114"
local unitDefID = UnitDefNames[unitDefName].id
local shaderObj
function widget:DrawWorld()
    if not shaderObj then
        InitShader()
    end
    local x, y = Spring.GetMouseState()
    local result, coords = Spring.TraceScreenRay(x, y, true)
    if result == "ground" then
        gl.PushMatrix()
        gl.DepthTest(GL.LEQUAL)
        gl.DepthMask(true)
        gl.UseShader(shaderObj.shader)
        gl.Uniform(shaderObj.teamColorID, Spring.GetTeamColor(teamID))

        gl.Translate(coords[1], coords[2], coords[3])
        gl.UnitShapeTextures(unitDefID, true)
        gl.UnitShape(unitDefID, teamID, true)
        gl.UnitShapeTextures(unitDefID, false)
        gl.UseShader(0)
        gl.PopMatrix()
    end
end

function InitShader()
    shaderFragStr =
[[
//#define use_normalmapping
//#define flip_normalmap
//#define use_shadows
//#define flipAlpha
//#define tex1Alpha

  uniform sampler2D textureS3o1;
  uniform sampler2D textureS3o2;
  uniform samplerCube specularTex;
  uniform samplerCube reflectTex;

  uniform vec3 sunDir;
  uniform vec3 sunDiffuse;
  uniform vec3 sunAmbient;

#ifdef use_shadows
  uniform sampler2DShadow shadowTex;
  uniform float shadowDensity;
#endif

  uniform vec4 teamColor;
  uniform float alphaPass;

  varying vec4 vertexWorldPos;
  varying vec3 cameraDir;
  varying float fogFactor;

#ifdef use_normalmapping
  uniform sampler2D normalMap;
  varying mat3 tbnMatrix;
#else
  varying vec3 normalv;
#endif

float GetShadowCoeff(vec4 shadowCoors)
{
	#ifdef use_shadows
	float coeff = shadow2DProj(shadowTex, shadowCoors).r;

	coeff  = (1.0 - coeff);
	coeff *= shadowDensity;
	return (1.0 - coeff);
	#else
	return 1.0;
	#endif
}

void main(void)
{
#ifdef use_normalmapping
	vec2 tc = gl_TexCoord[0].st;
	#ifdef flip_normalmap
		tc.t = 1.0 - tc.t;
	#endif
	vec3 nvTS  = normalize((texture2D(normalMap, tc).xyz - 0.5) * 2.0);
	vec3 normal = tbnMatrix * nvTS;
#else
	vec3 normal = normalize(normalv);
#endif

	vec3 light = max(dot(normal, sunDir), 0.0) * sunDiffuse + sunAmbient;

	vec4 diffuse     = texture2D(textureS3o1, gl_TexCoord[0].st);
	vec4 extraColor  = texture2D(textureS3o2, gl_TexCoord[0].st);

	vec3 reflectDir = reflect(cameraDir, normal);
	vec3 specular   = textureCube(specularTex, reflectDir).rgb * extraColor.g * 4.0;
	vec3 reflection = textureCube(reflectTex,  reflectDir).rgb;

	float shadow = GetShadowCoeff(gl_TexCoord[1] + vec4(0.0, 0.0, -0.00005, 0.0));

	// no highlights if in shadow; decrease light to ambient level
	specular *= shadow;
	light = mix(sunAmbient, light, shadow);


	reflection  = mix(light, reflection, extraColor.g); // reflection
	reflection += extraColor.rrr; // self-illum

	gl_FragColor     = diffuse;
	gl_FragColor.rgb = mix(gl_FragColor.rgb, teamColor.rgb, gl_FragColor.a); // teamcolor
	gl_FragColor.rgb = gl_FragColor.rgb * reflection + specular;

	//gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, fogFactor); // fog
	gl_FragColor.a   = extraColor.a * teamColor.a;
}

]]
    local shaderTemplate = {
        fragment = shaderFragStr,
        uniformInt = {
            textureS3o1 = 0,
            textureS3o2 = 1,
            shadowTex   = 2,
            specularTex = 3,
            reflectTex  = 4,
            normalMap   = 5,
            --detailMap   = 6,
        },
        uniform = {
            sunPos = {gl.GetSun("pos")},
            sunAmbient = {gl.GetSun("ambient", "unit")},
            sunDiffuse = {gl.GetSun("diffuse", "unit")},
            shadowDensity = {gl.GetSun("shadowDensity" ,"unit")},
            shadowParams  = {gl.GetShadowMapParams()},
        },
        uniformMatrix = {
            shadowMatrix = {gl.GetMatrixData("shadow")},
        }
    }

    local shader = gl.CreateShader(shaderTemplate)
    local errors = gl.GetShaderLog(shader)
    if errors ~= "" then
        Spring.Echo(errors)
        return
    end
    shaderObj = {
        shader = shader,
        teamColorID = gl.GetUniformLocation(shader, "teamColor")
    }
end
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: New gl.UnitShape is less useful

Post by zwzsg »

Shader may be much more powerful, but also much less friendly, than Spring's Lua OpenGL Api.
User avatar
Shadowfury333
Posts: 55
Joined: 25 Sep 2006, 00:32

Re: New gl.UnitShape is less useful

Post by Shadowfury333 »

Why not just have it default to use the basecontent Model*Prog.glsl shaders with a uniform added for tint/alpha, while keeping this custom shader setup if one is explicitly pointed to in whatever is calling gl.UnitShape()?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: New gl.UnitShape is less useful

Post by Kloot »

Questions that start with "why not just" should be an automatic disqualifier for participating in engine code discussions.
Shader may be much more powerful, but also much less friendly
With increased power comes increased complexity.

Modern rendering also isn't obligated to be noob-friendly, and shaders have been around (in games) for ~15 years now so it's time people got with the program.
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: New gl.UnitShape is less useful

Post by Silentwings »

Split generic discussion of custom shaders versus inbuilt shaders to viewtopic.php?f=14&t=34419
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: New gl.UnitShape is less useful

Post by Silentwings »

I didn't have any success at controlling the alpha of gl.UnitShape with gl.Color or gl.Blending (although I can get fully opaque and 0.5 alpha using the fifth arg of UnitShape), and I have a use case where a model should fade out gently, so...

gajop: I tried using your code above, with just copypasta and add widget:info, but it doesn't render right for me. It looks like light/dark are partially swapped somehow. The same issue occurs when trying it with BA, so I don't think its related to any of BARs shaders.

edit: After testing some more, the extent to which the white/dark balance is off varies with camera height if advunitshading is on, and independent of camera height if advunitshading is off.

Image
Attachments
screen00638.jpg
(365.74 KiB) Not downloaded yet
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: New gl.UnitShape is less useful

Post by Kloot »

a use case where a model should fade out gently
1) pass in desired alpha as a shader uniform
2) write value of said uniform to fragment alphas
3) profit
controlling the alpha of gl.UnitShape with gl.Color or gl.Blending
If you're drawing with raw=false, Color will not work at all and there is no way to influence the alpha.

If you're drawing with raw=true, Color is mutually exclusive with custom shaders as used in gajop's example.

Blending is not what you want in either case, it only controls the function with which pixels are combined (not the translucency level).

doesn't render right for me. It looks like light/dark are partially swapped
That shader needs different / more inputs to produce correct results, 'sunPos' should be 'sunDir' and the vertex component is completely missing for some reason. You've not exactly been served A-grade copypasta from the looks of it.
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: New gl.UnitShape is less useful

Post by gajop »

Kloot wrote:You've not exactly been served A-grade copypasta from the looks of it.
This. I'll try to fix it during the weekend, but the thing I provided was poorly written (mostly a slightly adjusted copy of the engine shader). I know there are quite a few issues with it, but I just didn't have time to address them.
User avatar
Shadowfury333
Posts: 55
Joined: 25 Sep 2006, 00:32

Re: New gl.UnitShape is less useful

Post by Shadowfury333 »

Yeah, I tried using this with the engine shaders copied into it to add the vertex component, and it doesn't work for ATI cards, though I've had to do my testing second-hand.

Code: Select all

 [f=0000660] Vertex shader failed to compile with the following errors:
ERROR: 0:16: error(#164) l-value required: assign "gl_Vertex" (can't modify an input)
ERROR: 0:17: error(#164) l-value required: assign "gl_Vertex" (can't modify an input)
ERROR: 0:30: error(#162) Wrong operand types: no operation "&&" exists that takes a left-hand operand of type "uniform highp float" and a right operand of type "uniform highp float" (or there is no acceptable conversion)
ERROR: error(#273) 3 compilation errors.  No code generate
Weird errors, though, since the engine ModelVertProg.glsl doesn't even have "&&" used in the code, and never tries to modify gl_Vertex (it uses it for gl_Position calculation, but that's about it).

As a side note, is the engine getting set up for uniform Model(View(Projection)) matrices instead of the old matrix stack and VBOs with attributes to replace display lists?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: New gl.UnitShape is less useful

Post by Kloot »

uniform matrices are planned, but I want to kill off the FFP path (/advmodelshading 0) before switching over. No ETA since that involves the always-fun politics surrounding Intel support.

The engine already renders models with VBO's (introduced in 92.0), it just compiles all bind and client-state calls into the static piece display lists. Unfortunately the Spring.{Unit,Feature}Rendering API is also list-based, which makes it harder to get rid of them (you may have noticed Lua GL lacks VBO access).

re ATI error debugging: start with a blank shader that only writes gl_Position and gl_FragColor, add lines until you trip the compiler.
User avatar
Shadowfury333
Posts: 55
Joined: 25 Sep 2006, 00:32

Re: New gl.UnitShape is less useful

Post by Shadowfury333 »

Kloot wrote:uniform matrices are planned, but I want to kill off the FFP path (/advmodelshading 0) before switching over. No ETA since that involves the always-fun politics surrounding Intel support.
Yay! Though I know what you mean about the politics
Kloot wrote:The engine already renders models with VBO's (introduced in 92.0), it just compiles all bind and client-state calls into the static piece display lists. Unfortunately the Spring.{Unit,Feature}Rendering API is also list-based, which makes it harder to get rid of them (you may have noticed Lua GL lacks VBO access).
Great about the engine stuff, but I have noticed the LuaGL has no VBO access, which I find odd. Other than the boilerplate setup code for different buffers VBOs are much simpler, but I guess it's just a matter of priorities and time.
Kloot wrote:re ATI error debugging: start with a blank shader that only writes gl_Position and gl_FragColor, add lines until you trip the compiler.
Good point. I hope KingRaptor is comfortable staying up for a while.
aeonios
Posts: 202
Joined: 03 Feb 2015, 14:27

Re: New gl.UnitShape is less useful

Post by aeonios »

Intel cards have supported GLSL for a while now, so that's a moot point. 0ad runs fine under intel, and apparently it has fewer bugs with reflective/refractive water than nvidia cards do (which are still better than ati, go figure). VAOs have been standard since GL2.0.

I guess I could take a look at that shader, but there may be issues with using transparency when using deferred rendering. (if gl.UnitShape uses the deferred path then transparency wouldn't be possible, you'd have to use a custom forward shader after the deferred rendering phase)
Post Reply

Return to “Engine”