Not logged inOpenClonk Forum
Up Topic Development / Developer's Corner / Project to complete and merge the lights branch
1 2 3 Previous Next
- - By Newton [de] Date 2014-10-11 17:01 Edited 2014-11-01 20:06
Some of you might have noticed when I talked about it in IRC already, but here is an official announcement for it in the forum.

The lights branch


I will be taking on the development of the fog of war a.k.a lights branch. The lights branch is built on top of PeterW's high resolution landscape shader which scales up the landscape x4. Its goal was to add dynamic lighting to the landscape rendering, which makes the landscape look even more stunning and three-dimensional. This also effectively adds fog of war to the game again since areas that are not lighted by the clonk appear as black.

The lights branch was originally developed by PeterW about three years ago. Unfortunately, work on it stopped over two years ago, so it can safely be declared as dead now. His original plans with this feature were quite aspiring. Global lighting by the sun and preliminary optimization seemed to have been the thing he ultimately failed on.

Rescueing the light branch


In my opinion, this project is too valuable and in a too advanced stage to give up, so my plan is to turn this into a team effort to "rescue" the work he has done so far into the master branch. I want to strive for a minimal solution here: No global light, no colored light, no multiple lights (lamps, torches). Just the current state minus the bugs and an option to turn if off, which it is by default.

Talking about aspiring, for me this is an utterly aspiring project. I am braced to try this project alone, but I'd love for that to be a team effort. Be it that you volunteer to get aboard this ship and help steer it back to master, be it that you can help with one task or even just give tips on how to solve the one or the other issue. In any case, I can use any help I get.

The plan


His work so far involves about 1500 lines of code, the very most being in C4FoW.cpp and a few lines in the shader itself. So actually, alone from the amount of code, this is perhaps not that of a big undertaking.
I plan to split the work in 3 phases:

1. understand, accustom, document and refactor the current code - with focus on phase 2

2. fix the known issues

3. implement the missing feature to reach a releasable state:

  - add a scenario option AmbientLight = height1, height2. Only if it is defined, the shader should darken the landscape, otherwise 100% of the light is ambient light. The ambient light portion of the light dims down from height1 (100%) to height2 (0%).
 
  - make fow affect objects as well
Attachment: 1second.jpg (35k)
Attachment: darkness.jpg (69k)
Attachment: normalmap.jpg (61k)
Attachment: rays.jpg (62k)
Parent - - By Newton [de] Date 2014-10-11 17:49

> 1. understand, accustom, document and refactor the current code - with focus on phase 2

Parent - By Newton [de] Date 2014-10-11 18:05
- Merged master a few days ago.

- Currently trying to understand the structure. Put all the classes in C4FoW.cpp in own files (not committed yet)
Parent - By Newton [de] Date 2014-10-11 23:34
Put all classes in C4FoW.cpp into own files.

Actually, a big part of the mentioned 1500 lines of code is pretty forward object oriented code that just needed a little bit of documentation to understand better. In a nutshell:

C4FoWRegion - Extension of the Viewport, renders the whole stuff to the screen
C4FoW - Keeps a list of lights (C4FoWLight)
C4FoWLight - Associated with one object. Has a size, and a section (C4FoWLightSection) for each direction
C4FoWLightSection - Keeps a list of beams and handles the mathematics
C4FoWRay - represents one beam

C4FoWLightSection then contains 1000 lines of the heavy mathematical stuff in spagetthi functions.
Parent - - By Maikel Date 2014-10-11 19:07
Great to see some progress on this branch! Good luck, most of all. I really like how the tunnel texture looks in these screenshots.
Parent - By PeterW [de] Date 2014-10-11 20:05
Just for the record - this is simply what I got when I ran CrazyBump over the tunnel texture. We might want to find a better method in future...
Parent - - By PeterW [de] Date 2014-10-11 19:30 Edited 2014-10-11 19:50
Two years already? Time sure flies...

Most things on your list should be manageable, with the notable exception of "light applies to objects" (also particles, PXS, text, lines...?). That's probably going to touch a *lot* of code all over the engine. I consider it the main blocker to lights at this point.

I'm obviously available on IRC if there's questions (it's not exactly trivial code). If you plan to understand how I come up with the final mesh it might be a good idea to take a look at the sketches I made when coming up with it (attached). Note that the calculation of intermediate fade points (Y in the sketches) has changed quite a bit as I tried to come up with something that actually looks good.
Attachment: Lights.pdf - Sketch of how soft shadows work (64k)
Parent - By Newton [de] Date 2014-10-11 21:47
Thanks a lot!
Parent - By PeterW [de] Date 2014-10-11 20:03

> no multiple lights (lamps, torches).


And btw - that should work already. Just haven't tested it yet, so it might look bad in some way.
Parent - By Sven2 [de] Date 2014-10-11 20:42
Looks great! I like the high contrast on material borders. It makes them a lot more visible and might also allow us to have more structure on materials.
Parent - By Newton [de] Date 2014-10-12 00:37

>   - the brightness of "explored" areas does not reset to 0


By pure chance, found the bug. Fixed :-)
Parent - - By Newton [de] Date 2014-10-12 10:16

> 2. fix the known issues

Parent - Date 2014-10-12 10:16
Parent - - By Maikel Date 2014-10-12 10:26
How did you merge master into lights? I get tons of script errors and a black landscape when I play some scenario on lights.
Parent - - By Newton [de] Date 2014-10-12 10:49
That's odd. I had a look at the diff between current master and current lights after the merge and all the changes seemed related to FoW.

You sure you Pulled and Updated? Also, with which scenario for example do you have problems? I only tested in Tutorial01.ocs the last days.
Parent - By Maikel Date 2014-10-12 13:01
Never mind, forgot to pull ...
Parent - - By Pyrit Date 2014-10-12 13:15
Can someone upload the engine from the lights branch? (I'm too stupid to build myself)
Parent - By Pyrit Date 2014-10-12 13:48
Oh, I didn't know that, thanks!
Parent - By Newton [de] Date 2014-10-12 19:51 Edited 2014-10-12 19:57
wrote a shader for debugging light directions. Put this at the end of LandscapeShader.c


  // uncomment the following lines for debugging light directions:
  // yellow: light up, blue: light down, turqoise: light right, pink: light left, opacity: light strength
  float lightYDir = lightPx.b - 1.0/3.0;
  float lightXDir = lightPx.g - 1.0/3.0;
  float lightStrength = lightPx.r;
  gl_FragColor = vec4(
    1.0-1.5*(max(0.0, lightYDir) + max(0.0,lightXDir)),
    1.0-1.5*(max(0.0, lightYDir) + max(0.0,-lightXDir)),
    1.0-1.5*max(0.0, -lightYDir),
    lightStrength);


Attachment: debuglightdirection.jpg (49k)
Parent - - By Newton [de] Date 2014-11-13 14:10
Looking at the speed at which Clonk-Karl implemented the shading for sprites, particles, pxs and meshes, I just want to note down here that I am restructuring large parts of the algorithm that finally renders the light texture (C4FoWLightSection::Render), so please talk with me if you (Clonk-Karl) intend to change something there.
Parent - - By Newton [de] Date 2014-11-13 14:15
Also, two questions about the Clonk C++ code:

* is the std::list considered harmful or something? I only see homebrew pointer-based lists in the (Peter's) code. I am in the process of replacing those with the std::list for proper OO but stopped because perhaps there a a good reason for not using the standard list?

* is there really no general simple point/coordinate class in the project yet? I feel dumb if I introduce something like that now.
Parent - By Sven2 Date 2014-11-13 14:56

> * is the std::list considered harmful or something? I only see homebrew pointer-based lists in the (Peter's) code. I am in the process of replacing those with the std::list for proper OO but stopped because perhaps there a a good reason for not using the standard list?


I've used it in new code as well. Just make sure that you don't introduce memory leaks or pointer errors because suddenly some pointers change when the objects are added to the list. Also make sure if classes are copied that this works. Stuff that breaks commonly if such assumptions are violated is e.g. loading of scenario sections (LoadScenarioSection()) or reloading of definitions (ReloadDef()).

And make sure stuff still works with StdCompiler. (For savegames, runtime joins, etc.).
Parent - By Clonk-Karl Date 2014-11-13 15:36
In addition to what Sven said, you might want to consider whether std::vector is more appropriate in certain situations.
Reply
Parent - - By PeterW [de] Date 2014-11-15 00:49 Edited 2014-11-15 00:52
The idea is to stay consistent, mainly. I find it neither particularly harder to write nor to read, so why not stay with it?

But on the other hand I am the same guy that would also object to both using STL having anything to do with OO, or OO being that much of a good idea in the first place... Comes with the field, I suppose.
Parent - By Sven2 [de] Date 2014-11-16 21:11

> The idea is to stay consistent, mainly. I find it neither particularly harder to write nor to read, so why not stay with it?


I don't really care for lists either. But once you need slightly more advanced stuff, like sorted lists or hash maps, you need to write a lot of boring code that is introduces potential bugs.
Parent - - By Clonk-Karl [de] Date 2014-12-28 12:28

>  I find it neither particularly harder to write nor to read, so why not stay with it?


Cough... :)
Reply
Parent - By PeterW [de] Date 2015-01-01 16:56
Oops :)
Parent - - By Clonk-Karl Date 2014-11-13 15:40
Do you intend to fix any of the known problems with the restructuring? I won't touch the light texture generation, there's enough other stuff to do (e.g. particle shading or adding an ambient light component).
Reply
Parent - - By Newton [de] Date 2014-11-13 16:04
Yes, the reason for the restructuring is the issue with the fadeout of 45° edges not being rendered.

>an ambient light component


That would be awesome if you could busy yourself with that! It fits quite nice because that part has nothing to do with the actual light texture generation, more with the shaders.
The simplest solution would be to generate a 1D-8-bit-Array from the scenario options and put this as an uniform into the shader calculation. Do you aim for that?
Parent - - By Clonk-Karl Date 2014-11-13 22:41 Edited 2014-11-13 22:47

> The simplest solution would be to generate a 1D-8-bit-Array from the scenario options and put this as an uniform into the shader calculation. Do you aim for that?


If all you have in mind is the two numbers mentioned in your initial post, then probably only those numbers are all that's needed in the shader. But I wonder whether there are better methods for example for scenarios like dark castle where there is a hill and basically you want everything bright outside the underground and dark when you go underground. So basically it would be nice to have some measure for how far a pixel is away from the sky, but I don't have a good idea yet how to calculate or approximate that.

Another question is how to combine the ambient part with the diffuse part of the light (for example you do want the ambient part to get darkened when light intensity is low, so that they disappear in the FoW, but you don't want them to be brightened when the light source is near, since at daylight the ambient part should dominate. This can probably be easily figured out with some experimentation.
Reply
Parent - - By Newton [de] Date 2014-11-13 23:06 Edited 2014-11-13 23:08

> Another question is how to combine the ambient part with the diffuse part of the light (for example you do want the ambient part to get darkened when light intensity is low, so that they disappear in the FoW, but you don't want them to be brightened when the light source is near, since at daylight the ambient part should dominate. This can probably be easily figured out with some experimentation.


My initial suggestion was/is:
ambientLightStrength = 0..1 (depending on how deep you are/the px is)
lightAtPositionFromLightmap = 0..1
lightAtPosition = ambientLightStrength + (1-ambientLightStrength) * lightAtPositionFromLightmap
The same with the direction of the light.

So, in daylight, you will see no effect from the lighting shader.
Parent - - By Clonk-Karl Date 2014-11-14 15:10
And you would apply this also to the Landscape shader itself? This would basically mean that if you have for example a sky island, it would always be completely illuminated, or also hills like in Dark castle?

At the moment I tend to a solution where I would create a sort of "ambient light map", where the ambient light strength of each pixel would be determined by how many sky pixels are around it in a given radius. This would basically have to be computed only once at game start, since in a typical game the sky/tunnel (IFT) of pixels do not change. Also, it would probably be good enough if this light map was computed only for the unzoomed map, and then interpolated between pixels. This would have the advantage that the ambient lighting adapts itself to the landscape, and allows the scenario designer additional options (for example, put some small sky patches here and there in tunnels to get some extra light in). We could even allow custom ambient light maps (Ambient.bmp in addition to Map.bmp) for scenario designer who want full control of the ambient lighting themselves. What do you think?
Reply
Parent - By Newton [de] Date 2014-11-14 17:37
Certainly a nicer solution and would remove the need for an extra scenario parameter. But, on first sight the more complex one.

This ambient light map could be of very low resolution, e.g. one px every 100 landscape px or so and then simply scaled to apply. E.g. you take a box of 100x100px of the landscape and the shade of grey the ambient light px for this box has is (number of sky px in this box / (100*100)).
Parent - - By PeterW [de] Date 2014-11-15 00:58 Edited 2014-11-15 01:00

> the simplest solution would be to generate a 1D-8-bit-Array


I'd say the simplest solution would be to just brighten up the light texture? If we flip around how the frame buffer gets updated we need to clear it anyway - we'd just use a fade then instead of solid (0,1/3,1/3). If we put the "scenario ambient map" ck proposed into a texture, this could just become a blit.
Parent - - By Clonk-Karl [us] Date 2014-11-15 03:24

> I'd say the simplest solution would be to just brighten up the light texture?


The problem with this is that the light would then still have a direction, and faces of meshes pointing away from the light source would not be illuminated. This is one thing that I would want to fix with the ambient lighting, so that for example trees at daylight are not super dark on one side and super bright on the other, whereas at night, or underground, they would look much more like in the screenshots I have posted in the other thread. So basically I think it would be good to have the ambient and diffuse light strength separately from each other. Of course we could encode this information for example in the alpha channel of the light texture as well...

> If we put the "scenario ambient map" ck proposed into a texture, this could just become a blit.


Yes, I was thinking about that anyway, so that the landscape and object pixel shaders can access the ambient light at each individual pixel.
Reply
Parent - - By PeterW [de] Date 2014-11-15 09:49
Hm, good point. On the other hand, are we sure we couldn't get a similar effect by just introducing some ambience into the light equation? Something like "intensity * (0.5 + dot product / 2)"? I am not quite sure we would want the back sides of underground objects to be solid black either...
Parent - - By Clonk-Karl [us] Date 2014-11-15 14:22

> Something like "intensity * (0.5 + dot product / 2)"?


Yeah, this is already similar to what Newton proposed... ambient + (1-ambient) * dot product

> I am not quite sure we would want the back sides of underground objects to be solid black either...


Indeed. We should be able to take care of this by generating the ambient map such that the lowest ambient value is never 0.0 but maybe 0.25 even in the darkest cave.
Reply
Parent - - By PeterW [de] Date 2014-11-15 14:39
Well, no, the idea would be to have "intensity" being the light strength. So what I mean is that everywhere the light reaches we have some illumination, no matter whether the normal matches the light direction or not. I'd be against having ambient light everywhere - we don't want to have people turn up their brightness in order to find out in what direction to dig in order to find gold.
Parent - - By Clonk-Karl [us] Date 2014-11-15 15:23
I was thinking something along the lines of

min(intensity, 1) * (ambient + (1-ambient) * max(intensity, 1) * dot(...))

such that the light intensity also affects the regions with ambient light. Now I understand your proposal would be to do

ambient + (1-ambient) * intensity * (0.5 + 0.5 * dot(...))

I suppose the difference would be that with the first option, sky would only be visible when in light of sight of the clonk, while with the second one, sky (and the edges to material) would always be visible. Yeah, I actually might like the second option more...
Reply
Parent - - By PeterW [de] Date 2014-11-15 18:54 Edited 2014-11-15 18:56
My proposal was to not have an explicit "ambient" in the equation in the first place, and instead put it into the light map (intensity) just like all other light sources. So I suppose in your notation this would make it

  (intensity + ambient) * (0.5 + 0.5 * dot(...))

No idea, we'll have to see what looks good. I'd just be reluctant to involve yet another texture unit or uniform for an effect that is just a variant of what we have already.
Parent - - By Clonk-Karl [us] Date 2014-11-15 21:14
Yeah, it probably needs some experimentation to get a good result. I'll try to get to a workable state...

Worrying about the number of uniforms or texture units at the moment seems a bit like premature optimization to me at this stage. If these turn out to be an issue, we can still think about optimizations later.
Reply
Parent - By PeterW [de] Date 2014-11-16 00:21
Uhm. What I'm suggesting comes down to a single blend in the frame buffer update, a dozen lines tops. That is not an "optimisation", I'm simply suggesting to try the easy solution first before we invest into something that is both more complicated and costly.
Parent - - By Zapper [de] Date 2014-11-13 17:13
Depending on the amount of work it would be, it might potentially be really cool to allow custom shaders for particles, too
Parent - - By Newton [de] Date 2014-11-13 20:16
This would be breathtaking. Imagine how the "air burst" effect could look like. Or heat effects from lava,...

But this is really something for when the lights branch is merged into master IMO. Lets really do the shortest route to master here.
Parent - By Maikel Date 2014-11-13 20:24
And the safest (bug-free) and least laggy route!
Parent - - By Clonk-Karl [us] Date 2014-11-17 16:51

> ambient light component


I have committed something into the lights branch. The ambient map is generated from the landscape, and then used as an additional texture unit in the shaders. The effect is that every sky portion and what is close to it (the fade radius is 50 pixels at the moment) is visible, and only underground areas are covered with FoW.

The ambient light intensity is not just added to the intensity of the light texture, so that the ambient light and the light from other light sources can have different directions. For example, when a tree is on the surface, it is illuminated somewhat uniform, while if it is underground, it is illuminated from the direction of the light source. For meshes and the landscape, I did not actually use a fully ambient light in the sense that it is completely independent from the normal vectors, since this makes everything on the surface look very "flat", for example the gold idol does not even have a texture and would appear with only a single color. Instead, the light direction is fixed to "from the front" (meshes) or "from the top" (landscape), which corresponds to the same behaviour as in the master branch for stuff that is not underground. Things can certainly be tweaked more here!
Reply
Parent - By Matthias [de] Date 2014-11-17 17:19
Random suggestion: One could maybe perform a Closing (http://en.wikipedia.org/wiki/Closing_(morphology)) on the ambient light map, so that small obstacles like the pillar on the first screenshot stay lit. it looks a bit odd against the bright background.
Reply
Parent - - By Newton [de] Date 2014-11-17 17:43
Wow, very cool! Very cool. This looks so good already that I'd like to suggest to move on to the other things that block the merge to master first before tweaking around some more.

The ambient light texture you generate, is that a 1:1 32bit texture for the whole map?
Parent - - By Clonk-Karl [us] Date 2014-11-17 18:42 Edited 2014-11-17 18:45

> Wow, very cool! Very cool. This looks so good already that I'd like to suggest to move on to the other things that block the merge to master first before tweaking around some more.


Thanks ;) -- Do you consider everything in the "issues" topic to be a blocker?

> The ambient light texture you generate, is that a 1:1 32bit texture for the whole map?


It is 1:10, and it only has one color channel (red), representing the ambient intensity. I don't know 100% how OpenGL internally stores it, but I think it is 8 bits per channel, and therefore 8 bits per pixel.
Reply
Up Topic Development / Developer's Corner / Project to complete and merge the lights branch
1 2 3 Previous Next

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill