Forum

[FTE]Directional dynamic light implementation

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

[FTE]Directional dynamic light implementation

Postby toneddu2000 » Mon Jan 08, 2018 10:28 am

Hi guys! It's been quite a while that I'm struggling with the same question: would it be too hard to implement directional dynamic lights (aka sun light) in FTE with openGL? I read some papers here and here that explains that it wouldn't be a super hard task but the problem is..FTE code it's too complex. I don't even know where to start. I'd like to "simply" add a static directional light (even with hard coded inclination would be ok, not ideal, but ok) in openGL that works at least in client (read only-csqc games: yes in FTE you can create a only-csqc game!) but I cannot understand where FTE starts to draw lights. I tried gl/gllight.c and took a quick look at R_RenderDlights(), but I didn't find anything useful.

Anyone could please guide me in the right direction?

Thanks in advance guys!!
toneddu2000
 
Posts: 1215
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE]Directional dynamic light implementation

Postby Spike » Tue Jan 09, 2018 3:08 am

'directional' light is just such a vague term.
there are 3 'basic' types of rtlight.
1) omni-lights that cast light in every direction from a central spot (something like a cubemap).
2) spot-lights that cast light in a single direction from a 'central' spot (pretty much just a single face of the aforementioned cubemap).
3) parallel lights that have no central spot, but instead project from one side of its logical cuboid to the other.

(there's actually many different ways an engine could implement the above. deferred, forward, forward+, etc. then there's different ways to do shadows. stencil, cubemaps, dual-paraboloid, etc... but I'm ignoring that stuff for now, and focusing on just FTE's forward rendering.)

What you're asking for is the third type, but FTE only supports the first two right now.
parallel lights are interesting in that they're just weird. Logically, they're just a really (infinitely) far away omni light. except that this means that you might as well treat them like a spot light without the spot filter. and their infinite-distance nature means that they should use an orthographic projection matrix instead of the frustum-based projection matrix that a spot light or omniface would use.
orthographic matricies have no single point of origin, which makes pvs checks really messy (you'd have to scan for all leafs that contain an entire bounded plane), or just disable pvs checks... *shrug*.
so yeah, if you take the spot-light code, change the shadow generation to use an ortho matrix (the Matrix4x4_CM_Projection_Far line in Sh_GenShadowMap), change the projection glsl to use an ortho matrix (this is messy, the matrix is passed via a simple vec4 and transformed weirdly in the glsl for the benefit of omni lights), somehow define a non-axial cuboid for your light's volume that encompasses all visible geometry for your light to project over (or just use the worldmodel's bounds, if you're lazy), and disable all pvs checks when generating the shadows (beware of lights inside walls!), then you should have something close to what you're after.
getting it to work without breaking spotlights in the process is a bit more of a challenge... bonus points if you can
note that many implementations of such lights actually define multiple cuboids, with multiple shadowmaps, as a way to avoid depth precision issues on large maps. terrain systems might need it, but if your map is small or you're willing to fade the effects of the sun's shadows with distance then its probably overkill. Note how this stuff is all kinda special-casey, which is why I never sought to address this stuff - the idea of lights emitting from an entire plane that is actually inside a wall kinda put me off.
Spike
 
Posts: 2853
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: [FTE]Directional dynamic light implementation

Postby toneddu2000 » Tue Jan 09, 2018 7:50 am

Thanks Spike for the detailed reply. Instead of modifying spot light code, would it be possible to:
1. Removing light decay from omni light(I know it would be always an omni light, but at least there wouldn't be any attenuation from center of light)?
2. Using spot light with cubemaps with just one cube face as "hole" where to project light(again, lame solution, but..)?
3. There's the possibility to "lengthen" shadow computation with very far omni lights? Because, when I use a distant omni light (say [0,0, 1024]) with a big radius (like 8000), shadows didn't reach ground perfectly, they're like very low detailed. Once, I touched engine code to increase shadowmap to 8192 px but it was idiotic, I admit.

If these 3 options are (probably) lame or not feasible, could you tell me where's the portion of code that manages spot light?

On a side note, in CSQC, which is the method to use spotlight? Is it perhaps the 5th argument of dynamiclight_add() func? Where it says "optional string cubemapname"? So, filling that with cubemap, will it transform omni light in spot light? And, which would be the "orientation" of light cubemaps?

Just to know, are you planning to add parallel light support in future versions of FTE or it's not one of your prerogatives? Because if not, I'll try to tinker with spotlights code on my own but I don't guarantee any results! :biggrin:

Thanks again
toneddu2000
 
Posts: 1215
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTE]Directional dynamic light implementation

Postby Spike » Tue Jan 09, 2018 9:46 am

float light = dynamiclight_add(...);
dynamiclight_set(light, LFIELD_ANGLES, self.v_angle);
dynamiclight_set(light, LFIELD_FOV, 90.0);
will add a spotlight with a 90-degree cone. larger values will be distorted, 180+ will bug out completely, much like the fov cvar.

that's the theory anyway. they don't get tested enough - they might be completely bugged right now... have fun...
Spike
 
Posts: 2853
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: [FTE]Directional dynamic light implementation

Postby toneddu2000 » Tue Jan 09, 2018 12:56 pm

Spike wrote:float light = dynamiclight_add(...);
dynamiclight_set(light, LFIELD_ANGLES, self.v_angle);
dynamiclight_set(light, LFIELD_FOV, 90.0);
will add a spotlight with a 90-degree cone. larger values will be distorted, 180+ will bug out completely, much like the fov cvar.

that's the theory anyway. they don't get tested enough - they might be completely bugged right now... have fun...

Well, I had fun! :biggrin: It works pretty well, I might say. It's not buggy at all, plus I didn't know dynamiclight_add could be tied to a float to get retrieved later for editing..cool..

But still I'm wondering.. there's a solution for very distant omni lights shadows resolution? Because, in that case, I could use a super huge omni light (which, to be finicky, it's what sun is! :mrgreen: ) and set its origin WAYYYYY more up and its enormous radius should cover a decent terrain portion (something like 4096 x 4096), which could be ok
toneddu2000
 
Posts: 1215
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 2 guests