Simple Real-Time lighting (example code)

Simple Real-Time lighting (example code)

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

Moderator: Moderators

User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Simple Real-Time lighting (example code)

Post by Argh »

Here's a very simple vertex shader for doing realtime lighting:

Code: Select all

function widget:GetInfo()
  return {
    name      = "GLSL Lightmap",
    desc      = "The P.U.R.E. GLSL Realtime lighting implementation.",
    author    = "Argh",
    date      = "October 30, 2008",
    license   = "Public Domain, or the least-restrictive rights in your country of residence",
    layer     = 0,
    --handler   = true,
    enabled  = true -- loaded by default?
  }
end

local UseShader = 0

function widget:Initialize()
GLSL_LIGHT_Shader = gl.CreateShader({
    vertex = [[
	void main() {
	
		vec3 normal, lightDir;
		vec4 diffuse;
		float NdotL;
		
		normal = normalize(gl_NormalMatrix * gl_Normal);
		
		lightDir = normalize(vec3(gl_LightSource[0].position));
		
		NdotL = max(dot(normal, lightDir), 0.0);
		diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
		
		gl_FrontColor =  NdotL * diffuse;
		
		gl_Position = ftransform();
	}

]],
	fragment = [[
	void main()
	{
		gl_FragColor = gl_Color;
	}
    ]],
})

	if (GLSL_LIGHT_Shader == nil) then
		Spring.Echo("GLSL Light Shader Failed"..gl.GetShaderLog())
		return false
	else
		Spring.Echo("GLSL Light Shader Succeeded")
		UseShader = 1;
	end
end

function widget:DrawWorld()
	if UseShader == 1 then
	local myIDList = Spring.GetVisibleUnits(-1,3000,false)
		if myIDList[1] ~= nil then
			for _,myID in ipairs(myIDList) do
				if (Spring.IsUnitVisible(myID)) then
					gl.DepthTest(GL.LEQUAL)
					gl.Culling(GL.BACK)
					gl.Blending(true)
					gl.Lighting(true)
					gl.Light(0,GL.POSITION,-10000,100,-10000)
					gl.Material({diffuse = {1.0, 1.0, 0.0, 1.0},})
					gl.UseShader(GLSL_LIGHT_Shader)
					gl.PolygonOffset(-2,-2)
					gl.Unit(myID,true)

					gl.PolygonOffset(0,0)
					gl.ResetState()
					gl.Lighting(false)
				end
			end
		end
	end	
end
Now, before we get all excited about it... there is one major problem (besides hooking up the attenuation constant at some point for falloff). I want to see about building a mesh based on the heightmap and rendering that as well, so that the ground can be lit... and I'd like to explore ways to make the whole thing relatively efficient and to hook more capabilities into it. But it's here and easy to test and it works all right, and it's such basic code that I thought it'd be nice to just put it out there.
Last edited by Argh on 04 Nov 2008, 09:50, edited 1 time in total.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Simple Real-Time lighting shader

Post by Tobi »

This looks pretty much exactly like the standard lighting Spring already does: the light position is fixed (the sun) and there is only one light (light 0).

Real interesting dynamic lighting only starts when you design algorithms to allow for a multitude of moving light source (e.g. explosions), and still manage to keep decent performance.

Deferred shading could be a way to do this, since it only has approximate complexity O(num lights + num fragments) instead of O(num lights * num fragments).

This is good as sample to get used with OpenGL lighting in Spring tho :-)
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Simple Real-Time lighting shader

Post by jK »

I am already thinking about a way to integrate Deferred Shading/Lighting, but it would make Lua OpenGL rendering very complicated, and then there are the issues with DS itself. :?
But Dynamic Lighting for free is a huge pro :-)

And btw Spring's unit shaders in GLSL are:

s3o

Code: Select all

{
  vertex = [[
//#define use_shadow
    uniform mat4 camera;   //ViewMatrix (gl_ModelViewMatrix is ModelMatrix!)
    uniform vec3 cameraPos;
    uniform vec3 sunPos;
    uniform vec3 sunDiffuse;
    uniform vec3 sunAmbient;
  #ifdef use_shadow
    uniform mat4 shadowMatrix;
    uniform vec4 shadowParams;
  #endif

    varying vec3 normal;
    varying vec3 cameraDir;
    varying vec3 teamColor;
    varying vec3 light;


    void main(void)
    {
      gl_TexCoord[0].st = gl_MultiTexCoord0.st;

      vec4 worldPos = gl_ModelViewMatrix * gl_Vertex;

      normal    = normalize(gl_NormalMatrix * gl_Normal);
      cameraDir = worldPos.xyz - cameraPos;

      teamColor = gl_TextureEnvColor[0].rgb;

      float a = max( dot(normal, sunPos), 0.0);
      light   = a * sunDiffuse + sunAmbient;

     #ifdef use_shadow
      gl_TexCoord[1] = shadowMatrix * worldPos;
      gl_TexCoord[1].st = gl_TexCoord[1].st * (inversesqrt( abs(gl_TexCoord[1].st) + shadowParams.z) + shadowParams.w) + shadowParams.xy;
     #endif

      gl_Position = gl_ProjectionMatrix * camera * gl_ModelViewMatrix * gl_Vertex;
    }
  ]],
  fragment = [[
//#define use_shadow
    uniform sampler2D textureS3o1;
    uniform sampler2D textureS3o2;
    uniform samplerCube specularMap;
    uniform samplerCube reflectMap;

    uniform sampler2D detailMap;

  #ifdef use_shadow
    uniform sampler2DShadow shadowMap;
    uniform float shadowDensity;
    uniform vec3 sunAmbient;
  #endif

    varying vec3 normal;
    varying vec3 cameraDir;
    varying vec3 teamColor;
    varying vec3 light;

    void main(void)
    {
       gl_FragColor    = texture2D(textureS3o1, gl_TexCoord[0].st);
       vec4 extraColor = texture2D(textureS3o2, gl_TexCoord[0].st);

       vec3 reflectDir = reflect(cameraDir, normalize(normal));
       vec3 specular   = textureCube(specularMap, reflectDir).rgb * 4.0 * max(extraColor.g,0.7);
       vec3 reflection = textureCube(reflectMap,  reflectDir).rgb;

     #ifdef use_shadow
       float shadow = shadow2DProj(shadowMap, gl_TexCoord[1]).r;
       shadow      = 1.0 - (1.0 - shadow) * shadowDensity;
       vec3 shade  = mix(sunAmbient, light, shadow);
       reflection  = mix(shade, reflection, extraColor.g);
       reflection += extraColor.r;
       specular   *= shadow;
     #else
       reflection  = mix(light, reflection, extraColor.g);
       reflection += extraColor.rrr;
     #endif

       gl_FragColor.rgb = mix(gl_FragColor.rgb, teamColor, gl_FragColor.a); //teamcolor
       gl_FragColor.rgb = gl_FragColor.rgb * reflection + specular;
       gl_FragColor.a   = extraColor.a;
    }
  ]],
  uniformInt = {
    textureS3o1 = 0,
    textureS3o2 = 1,
    shadowMap   = 2,
    specularMap = 3,
    reflectMap  = 4,
  },
  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")},
  },
}
3do

Code: Select all

{
  vertex = [[
#define use_shadow
    uniform mat4 camera;   //ViewMatrix (gl_ModelViewMatrix is ModelMatrix!)
    uniform vec3 cameraPos;
    uniform vec3 sunPos;
    uniform vec3 sunDiffuse;
    uniform vec3 sunAmbient;
  #ifdef use_shadow
    uniform mat4 shadowMatrix;
    uniform vec4 shadowParams;
  #endif

    varying vec3 normal;
    varying vec3 cameraDir;
    varying vec3 teamColor;
    varying vec3 light;

    void main(void)
    {
      gl_TexCoord[0].st  = gl_MultiTexCoord0.st;

      vec4 worldPos = gl_ModelViewMatrix * gl_Vertex;

      normal    = normalize(gl_NormalMatrix * gl_Normal);
      cameraDir = worldPos.xyz - cameraPos;

      teamColor = gl_TextureEnvColor[0].rgb;

      float a = max( dot(normal, sunPos), 0.0);
      light   = a * sunDiffuse + sunAmbient;

     #ifdef use_shadow
      gl_TexCoord[1] = shadowMatrix * worldPos;
      gl_TexCoord[1].st = gl_TexCoord[1].st * (inversesqrt( abs(gl_TexCoord[1].st) + shadowParams.z) + shadowParams.w) + shadowParams.xy;
     #endif

      gl_Position = gl_ProjectionMatrix * camera * gl_ModelViewMatrix * gl_Vertex;
    }
  ]],
  fragment = [[
#define use_shadow
    uniform sampler2D texture3do;
    uniform samplerCube specularMap;
    uniform samplerCube reflectMap;

    uniform sampler2D detailMap;

  #ifdef use_shadow
    uniform sampler2DShadow shadowMap;
    uniform float shadowDensity;
    uniform vec3 sunAmbient;
  #endif

    varying vec3 normal;
    varying vec3 cameraDir;
    varying vec3 teamColor;
    varying vec3 light;

    void main(void)
    {
       gl_FragColor = texture2D(texture3do, gl_TexCoord[0].st);

       vec3 reflectDir = reflect(cameraDir, normalize(normal));
       vec3 specular   = textureCube(specularMap, reflectDir).rgb * 4.0 * gl_FragColor.a;
       vec3 reflection = textureCube(reflectMap,  reflectDir).rgb;
     #ifdef use_shadow
       float shadow = shadow2DProj(shadowMap, gl_TexCoord[1]).r;
       shadow      = 1.0 - (1.0 - shadow) * shadowDensity;
       vec3 shade  = mix(sunAmbient, light, shadow);
       reflection  = mix(shade, reflection, gl_FragColor.a);
       specular   *= shadow;
     #else
       reflection  = mix(light, reflection, gl_FragColor.a);
     #endif

       gl_FragColor.rgb = gl_FragColor.rgb * reflection + specular;
       gl_FragColor.a   = 1.0;
    }
  ]],
  uniformInt = {
    texture3do  = 0,
    shadowMap   = 2,
    specularMap = 3,
    reflectMap  = 4,
  },
  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")},
  },
}
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Simple Real-Time lighting shader

Post by Tobi »

Ah nice you actually ported/rewrote them in GLSL?
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting shader

Post by Argh »

I was planning to put all of the lights into a "set" based on which lights are available, since it's always going to be best to light everything at once, and modify the lights over time based on some parameters, so that you'd have two lists, basically- lights within x,z of the camera FOV (so that lights off-screen can participate to some degree) and the list of objects to be lit, then run for each object --> light list --> final result. The only issue I'm having with that is that I think that there has to be an absolute limit on how many lights can be in a scene, but I think that's something where performance requirements are going to be a big deal anyhow- this isn't something that we'll want to throw around willy-nilly.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Re: Simple Real-Time lighting shader

Post by KDR_11k »

You can have at most 8 lights in OpenGL and using those already drops the framerate a lot. Professional games use only a small number of lights but move them depending on where the model is so there's e.g. one light that's always at the closest torch, one that's always the sun and one that's always at the closest explosion or muzzle flare...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting shader

Post by Argh »

I was thinking of keeping the limit down to 4- I've done some tests, and that's about where performance is slow enough that I don't think it's practical to go further.

Anybody know a fast way of establishing which 4 lights are closest to a given Unit, and using them to light a scene, with some sort of practical frustrum culling that culls them if they are more than x,z away from the edges of the screen?
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Re: Simple Real-Time lighting shader

Post by KDR_11k »

Why the hell would you cull lights when they are offscreen?
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting shader

Post by Argh »

If they're > some distance away, their attenuation value should be high enough that there's no point wasting cycles rendering them.
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Re: Simple Real-Time lighting shader

Post by Zpock »

I always thought it would be a good idea to do lights only for special effects like explosions or weaponfireing, and limit it to 1-2 per unit and only within a short distance of the unit. So there would be many lights but only for short times effecting small parts of the entire scene.

You could start off simple and have a unit lit just itself by it's muzzle flare, easy to do. That's were I think the most significant effect of lighting would be in relevance to typical spring stuff anyway.

Going further I would probably try to tag units that there was an effect with light involved close to them so they would individually be rendered with this light, maybe using the getunitsinradiusp(). Since LUA is completly disconnected from what weapons are doing you might have trouble finding out were weapons hit tough, except for them hitting units. The idea is that you only need to do the check once, not per frame, when the effect starts.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting shader

Post by Argh »

The idea is that you only need to do the check once, not per frame, when the effect starts.
Can't get around that beyond a certain point, because everything's moving. Could limit the checks to X frames, etc.

I've already planned out (in my head, mind ye) a simple implementation of Unit lighting for unit-specific stuff, like muzzle flashes. I think that should be easy enough to do- get the worldspace location of a given Piece for the location of the light, pass some parameters, and voila, the Unit lights itself. However, I think that the Unit will need to call every few frames or so to other nearby Units via GetUnitsInSphere() and update them in a table somewhere, to light them as well, and there's the additional problem of lighting the ground, which I still haven't come up with a fast method of solving.
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Re: Simple Real-Time lighting shader

Post by Zpock »

To light the ground it's obviously best to use the groundflash trick or similar...

If you must have permament lights using the above method would be best to update it every x seconds yes... but for flashes you don't need to since their going to be quick (and static). Just take the shortcuts and don't worry about having it perfect, it's just fickle eye candy. Lighting is in my opinion what's easiest to 'do wrong' and still look good, more > accurate.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting shader

Post by Argh »

Meh, I know, but I want it to be really nice, effective eye-candy, if I'm going to spend the time to integrate it into P.U.R.E. ;)

Seriously though... first, attached lights, no lighting of objects around it... then... if the performance isn't too bloody awful (which, thus far, appears to be the case, so long as one isn't lighting gigantic numbers of polygons)... I'll make it fancier.

Should have a basic demo done here in a bit, since it appears I'm not going to solve the problems associated with a new shadowmap method today, probably because I'm overlooking something basic in my quest to find a workable solution :P
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting shader

Post by Argh »

Ok... this took waaaaay longer than I thought it would, but it's all working now.

Here's the Lua:

Code: Select all

function gadget:GetInfo()
  return {
    name      = "GLSL Lighting",
    desc      = "The P.U.R.E. GLSL Realtime lighting implementation.",
    author    = "Argh",
    date      = "November 4, 2008",
    license   = "Public Domain, or the least-restrictive rights in your country of residence",
    layer     = 0,
    --handler   = true,
    enabled  = true -- loaded by default?
  }
end

if (gadgetHandler:IsSyncedCode()) then
----------------------------------------------------------------------------------------------------------SYNCED
local function CreateLightMe(u, ud, team, p, r, g, b, a)
	p = Spring.GetUnitScriptPiece(u,p)
	SendToUnsynced("CreateLight",u, ud, team, p, r, g, b, a)
end

local function DestroyLightMe(u, ud, team)
	SendToUnsynced("DestroyLight",u, ud, team)
end

function gadget:Initialize()
	gadgetHandler:RegisterGlobal("CreateLightMe", CreateLightMe)
	gadgetHandler:RegisterGlobal("DestroyLightMe", DestroyLightMe)
end

function gadget:UnitDestroyed(u,ud,team)
	SendToUnsynced("DestroyLight",u, ud, team)
end

----------------------------------------------------------------------------------------------------------END SYNCED
else
----------------------------------------------------------------------------------------------------------UNSYNCED
local UseShader = 0
local LP

function gadget:Initialize()
GLSL_LIGHT_Shader = gl.CreateShader({
    vertex = [[
   void main() {
   
      vec3 normal, lightDir;
      vec4 diffuse;
      float NdotL;
      
      normal = normalize(gl_NormalMatrix * gl_Normal);
      lightDir = normalize(gl_LightSource[0].position);
      
      NdotL = max(dot(normal, lightDir), 0.0);
      diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
      
      gl_FrontColor =  NdotL * diffuse;
      
      gl_Position = ftransform();
   }

]],
   fragment = [[
   void main()
   {
      gl_FragColor = gl_Color;
   }
    ]],
})

	if (GLSL_LIGHT_Shader == nil) then
		Spring.Echo("GLSL Light Shader Failed"..gl.GetShaderLog())
		return false
	else
		Spring.Echo("GLSL Light Shader Succeeded")

		UseShader = 1;
	end
end

local tinsert = table.insert
local tremove = table.remove
local LightList = {unit, piece, red, green, blue, alpha}
local GetUnitPiecePosDir = Spring.GetUnitPiecePosDir

function gadget:RecvFromSynced(name, u, ud, team, p, r, g, b, a)
	if name == "CreateLight" then
		for k, v in ipairs (LightList) do
			if v.unit == u then 
				tremove (LightList,k)
			end
		end
		tinsert (LightList,{unit = u, piece = p, red = r, green = g, blue = b, alpha = a})
	elseif name == "DestroyLight" then
		for k, v in ipairs (LightList) do
			if v.unit == u then 
				tremove (LightList,k)
			end
		end
	end
end

function gadget:DrawWorld()
	if UseShader == 1 and LightList[1] ~nil then
	local myIDList = Spring.GetVisibleUnits(-1,3000,false)
		if myIDList[1] ~= nil then
			for _,myID in ipairs(myIDList) do
				if (Spring.IsUnitVisible(myID)) then
					for _,id in ipairs(LightList) do
						if id.unit == myID then
							gl.DepthTest(GL.LEQUAL)
							gl.Culling(GL.BACK)
							gl.Blending(true)
							gl.Lighting(true)
							local x,y,z = Spring.GetUnitPiecePosition(id.unit,id.piece)

							--Spring.Echo(id.unit,id.piece,x,y,z)
							gl.Light(0,GL.POSITION,-x,y,z)
							gl.Material({diffuse = {id.red, id.green, id.blue, id.alpha},})
							gl.UseShader(GLSL_LIGHT_Shader)
							gl.PolygonOffset(-2,-2)
							gl.Unit(myID,true)
							
							gl.Light(0,false)
							gl.PolygonOffset(0,0)
							gl.ResetState()
							gl.Lighting(false)
						end
					end
				end
			end
		end
	end	
end
----------------------------------------------------------------------------------------------------------END
end
Then in BOS, just feed it:

call-script lua_CreateLightMe(light, 0, 1, 0, 1);

And voila:

Image

And the best part is that it's nearly free- the hit CPU-wise is low, and the hit on the GPU is practically nil (of course, if the light list gets big enough, that will change, but meh, there's always a cost somewhere).

I'm going to expand this to include multiple lights here in a bit, after doing some cleanup, adding integer conversions for the light colors and speedups. But it's really quite cheap and very effective, and you can try it out now :-)
dizekat
Posts: 438
Joined: 07 Dec 2007, 12:10

Re: Simple Real-Time lighting (example code)

Post by dizekat »

"And the best part is that it's nearly free- the hit CPU-wise is low, and the hit on the GPU is practically nil (of course, if the light list gets big enough, that will change, but meh, there's always a cost somewhere)."
Doesn't your code infact handle only precisely 1 directional light, without any distance attenuation, same way as spring engine does?
edit: ahh, it just renders every unit multiple times with different lights and somehow that gets added together. I don't see it setting correct blend function for that though, dunno, maybe something else that runs earlier already sets that.

I suppose you got generated glsl code from some program.
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Re: Simple Real-Time lighting (example code)

Post by Zpock »

Well yeah needs work but a good start I guess.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting (example code)

Post by Argh »

1. It's not a directional light, it's a point light, with the position treated as the vector for the resulting rays, per vertex.

2. Yes, it handles exactly one light at present, but I'm still deciding how to go about additive stuff efficiently. I don't suppose you have a magic solution for that?

3. The GLSL shader is based on the basic vertex shader from Typhoon Labs' GLSL course, Chapter 3, and is pretty much used verbatim, except for one little thing which I did that you can figure out yourselves by comparing sources- it's not like it's a lot of code or anything ;)

Lastly... doing attenuation or a dramatically more complex lighting model on the fragments seems pretty pointless to me (although you are more than free to implement one if you want to, this code is easily extended), given the distances that this will likely get used at, and the fact that I think I'll just use the good ol' ground-scar trick for the ground lighting. Why make it more complicated and use more math than it needs to, when its primary uses are muzzle flashes, explosions, and dynamic event stuff where merely altering the RGBA values over time should present players with enough visual interest?

I mean... hello... it's a dynamic lightsource that moves with the Unit, and that I can change the RGBA and relative position parameters with on the fly, using BOS... if you guys can't see what you can do with that, meh, just wait, it'll be in RC4 ;)

Keep in mind that in that example, I'm using an alpha level of 1.0, to make it bloody obvious that it's working at a basic level- I guess I should have spent more time on the Rest Of It before presenting it, but it's not really my problem if people lack enough imagination to understand what this can be used for.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Re: Simple Real-Time lighting (example code)

Post by AF »

Remember lua<->cob is expensive just like cpu<->gpu, it would server you better in the long run to run to keep as much as possible in lua regarding lights, and keeping things nice and asynchronous

As a side note it might be worth defining a set grid of lights at regular intervals. This way your lights are in predefined set locations, thus giving you a preset to optimize for. When placing lights move them to the nearest point and combine the lights together prior to rendering. Thus a unit should only ever have 4 active lights maximum. Lighting effects that are larger than the grid resolution can be split into multiple lights of varying intensity in a circular pattern. This also minimizes the number of lights by blending light sin similar positions together before doing the work.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Simple Real-Time lighting (example code)

Post by Argh »

Remember lua<->cob is expensive just like cpu<->gpu, it would server you better in the long run to run to keep as much as possible in lua regarding lights, and keeping things nice and asynchronous
It already works like that. We're talking about one COB-->Lua interaction when a light is turned on, or when we want to change the state of the light (change color or alpha values). Otherwise, once turned on, it's all on the Lua end. And all the COB --> Lua does is give Lua enough information to make a table with.

Oh... and before I go take care of RL stuff for a bit... I'd like to get texture2's green value read into the fragment shader. I was thinking that using that as a float would provide a quick n' sloppy way to make the light feel a little more detailed, without eating up too much performance.

Trouble is, on the unsync side, I keep getting errors when I attempt to get UnitDefs[ud[model[textures]]].texture2 :P

I know I must be structuring that wrong, or something, anybody have a clue? I'm too tired to puzzle it out any more. Sorry, I know that probably sounds stupid, but I've tried several different ways of phrasing that over the last hour, and none of it worked. Just another reminder of why I hate tables :P
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: Simple Real-Time lighting (example code)

Post by lurker »

Think of [] as parentheses.
UnitDefs[ud[model[textures]]].texture2
UnitDefs[ud[value1]].texture2
UnitDefs[value2].texture2
value3.texture2
value4
Post Reply

Return to “Lua Scripts”