Not logged inOpenClonk Forum
Up Topic Development / Developer's Corner / Completing lights branch - issues (locked)
1 2 Previous Next  
- - Date 2014-10-12 10:16
Parent - - By Newton [de] Date 2014-10-12 10:16 Edited 2014-11-17 18:58
1. rays are seemingly not casted in 45°(,135°,225°,315°). See this screenshot.
Fixed.
Parent - - By Newton [de] Date 2014-11-16 19:43
Progress!
Parent - By Zapper [de] Date 2014-11-17 00:36
Very cool!
Parent - By ala [de] Date 2014-11-17 11:46
awesome!
Parent - - By PeterW [de] Date 2014-11-17 12:51
Nice. Hm, how did you handle when the end-points don't match up? Also why did you put four triangles into the lower-bottom hole? Wouldn't one be enough?
Parent - - By Newton [de] Date 2014-11-17 17:51
I pulled up the code for calculation of the intermediate fade points as well as the rendering into C4FoWLight (and a new class C4FoWDrawStrategy). So the C4FoWLightSection simply return their list of calculated fan and fade points, C4FoWLight then concatenates this list of all the four directions and runs the intermediate fade point calculation algorithm on the concatenated list. This algorithm iterates through the list as if it were a ring (because it is).

>Also why did you put four triangles into the lower-bottom hole


I don't know exactly what you mean, but I removed a few "do I really need to render this or that triangle" checks in the process of the refactor. It just bloated up the code and effect on render performance is questionable.
Parent - - By PeterW [de] Date 2014-11-17 19:40
Ah, smart. But I don't remember the code being too bloated - it was just checking whether the triangles were zero, right? You could generalise that, I think.
Parent - By Newton [de] Date 2014-11-17 19:56

>it was just checking whether the triangles were zero, right?


Yes, so that is probably not what you meant.
Parent - - By Newton [de] Date 2014-10-12 10:17 Edited 2014-11-19 21:59
2. display for changes to the landscape only update every second or so. See this screenshot
Fixed.
Parent - By Clonk-Karl [us] Date 2014-11-18 21:59
Fixed
Parent - By PeterW [de] Date 2014-11-19 10:25
... this was actually completely my fault (spot DoRelights going missing!). Sorry for the confusion.
Parent - - By Newton [de] Date 2014-10-12 10:18 Edited 2014-11-23 22:42
3. the brightness of "explored" areas does not reset to 0. See Screenshot
fixed
Parent - - By Newton [de] Date 2014-10-12 10:19 Edited 2014-10-12 15:18
fixed.
Parent - - By PeterW [de] Date 2014-10-12 11:30 Edited 2014-10-12 11:44
You have introduced a fade out bias towards top-left normals. After thinking about it - this probably "fixes" the problem because extreme top-left normals are normally not illuminated very heavily. But that's really not the right way to do this.

Maybe try to do another fade out blit that's actually subtractive? Have you checked at what value we actually get stuck? If it's just RGB(1,256/3,256/3) or something, we just need to subtract RGB(-1,0,0) once in a while. You can check that by putting something like "gl_FragColor = rgba(light.rgb,1.0);" at the end of the landscape shader - that allows you to see directly what the light texture contains.
Parent - - By Newton [de] Date 2014-10-12 11:55
Probably I haven't quite understood C4FoWRegion then. I thought these values are for the color of the blending. I have to admit I did very little in OpenGL, so I might get the one or the other thing wrong. I understood it this way:

Line 121:
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

Clear to color rgb(0,0,0)

Line 154:
glBlendFunc(GL_ONE, GL_ZERO);
...
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

Actually draw the illumination texture

Line 171:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.0f,0.0f, 0.0f, 1.0f/16.0f+iAdd*1.0f/256.0f ); 

Draw rgb(0,0,0) with alpha of 1.0f/16.0f+iAdd*1.0f/256.0f above it (making previously illuminated areas black again)
Parent - - By PeterW [de] Date 2014-10-12 11:59 Edited 2014-10-12 12:04
Well, yes, they are. But colours in the lights texture mean very specific things. The red channel is the strength of illumination, the green channel is the x component of the light direction, while the blue channel has the y component (the z component is assumed fixed at 1). As I am explaining somewhere else in a comment, the "zero point" of the signed arithmetic is at 1.0/3, which means that "zero" for our lights is actually rgb(0,1.0f/3,1.0f/3). Hence blending rgb(0,0,0) on top of it means pulling normals towards top-left.

Edit: See this screenshot. Green means the light comes from the left, blue that it comes from the top.
Parent - By Newton [de] Date 2014-10-12 12:04
Ah, I see. Yeah I haven't gotten around to read (, understand and document) the core stuff yet - the stuff in C4FoWLightSection::Render / Update. If I had, I would have probably understood that the channels are used differently there.
Parent - By Newton [de] Date 2014-10-12 22:24 Edited 2014-10-12 22:32
So the problem is not in the shader again.

texture2D(lightTex, gl_TexCoord[1].st)

already has some alpha at those locations (but no light direction, thats why it looks so flat).
Parent - - By Newton [de] Date 2014-10-14 20:04
Having found the problem and seeing that I probably will not find a good solution for now, let me describe what is the problem. I want my work on the lights branch be very transparent, that is why most of the stuff I have done so far was simply documenting the code:

All the light from the lights (=the result of all the complicated calculations) on the screen are rendered as a texture into a framebuffer each frame. The channels have a certain meaning: R=strength of light, G=x-light-direction, B=y-light-direction. After that, to have a fadeout effect of areas that were once lighted and now not anymore, an area is blended over this texture with R=0, GB=neutral light direction and A=1/16. This makes the lighted areas (quickly) fade out as the strength of light is multiplied by (1-1/16) each frame.

However, even though OpenGL seemingly works with floats, actually behind it there is an integer that ranges from 0..255 for every color channel. The blending is rounded. so when R <= 8, R*15/16 always gets rounded to 8 again. A solution is to subtract every few frames an absolute value of R, but I tested that and it kinda doesn't look good. Maybe with a little bit of fiddling around with values, but still it is a hacky solution.

According to Peter, this best solution would be to simply use a shader to do the blending at that position. We need a new_r = min(r-1,r*15/16) or something similar. That is simply not doable with glBlendFunc and glBlendEquation. With shaders it is, but I have to admit that this solution is simply out of my competence right now.
Parent - - By Clonk-Karl [us] Date 2014-10-15 14:49

> With shaders it is, but I have to admit that this solution is simply out of my competence right now.


Is it? As far as I know, blending is not part of the programmable pipeline. It might be possible if you are rendering into a texture.
Parent - By Newton [de] Date 2014-10-15 21:28
At that point we are rendering into a texture, into the lightText that is used later in the landscape shader. Was I unclear about that?
Parent - - By PeterW [de] Date 2014-10-15 23:19
Btw, it might be an idea to switch around the order here. Right now we copy the old state, then fade it out 15/16, then draw our stuff over it with 1/16 intensity. Instead, we could first clear the texture, then draw over it with full intensity, and finally do an alpha blit of the old state with 15/16 weight. This might actually have a chance of resolving the stair artefacts in water. Not quite sure why I haven't done this from the start - possibly just because I wanted to use glBlitFramebuffer (which can't do blending).
Parent - By Newton [de] Date 2014-10-15 23:31
Yes I tried that. I don't know why, but the result was extremely dark. I don't know, perhaps I did something wrong.
Parent - By Newton [de] Date 2014-10-15 23:54

>, then fade it out 15/16


where?
Parent - - By Newton [de] Date 2014-11-23 19:09
Can I interest you in fixing this bug?
Parent - By PeterW [de] Date 2014-11-23 19:28
Which one? I already implemented the drawing flip-around. Not quite sure how to implement darkness ending up at zero - hm, given that we actually can't make productive use of these last few percents it might actually make sense to just have the shader ignore it?
Parent - By Newton [de] Date 2014-11-23 22:41
Even though he declared it as an intermediate solution Peter's fix is absolutely fine. (brightness lower than X is treated as 100% dark)
Parent - - By Newton [de] Date 2014-10-12 10:18 Edited 2015-01-01 16:11
4. normal maps for blasted areas are seemingly messed up
Parent - By Newton [de] Date 2014-10-12 20:34
So the problem is not in the shader.

texture2D(landscapeTex[0], texCoo).yz

is already wrong. The area in the screenshot and similar areas in tests have their normals slightly shifted to the upperleft.

Where are the normals of landscapeTex constructed?
Parent - By Newton [de] Date 2015-01-01 16:11
Fixed
Parent - - By Newton [de] Date 2014-10-18 22:08 Edited 2014-11-23 22:51
5. Found a minor bug. (Here I display only the brightness, not the landscape):
Attachment: raysinviewport.jpg (69k)
Parent - By Newton [de] Date 2014-11-23 22:51
Can't reproduce anymore.
Parent - - By Clonk-Karl [us] Date 2014-11-17 17:04 Edited 2014-11-20 23:47
6. When zooming in or out quickly, and maybe also when the viewport is moving, some areas that should not be visible become visible for a short amount of time. It looks like when the new light texture is blitted over the old one, they are offset relative to each other because they were generated at different zoom levels. In that case, we should transform the old light map to the new coordinates when blitting, and maybe start with zero intensity for regions that were outside the viewport before. When zooming out, this would lead to newly uncovered areas to slowly fade in from black to the actual light value.
fixed
Parent - - By PeterW [de] Date 2014-11-20 21:51
Could be better now. Possibly. We'll probably have to put some more thought into what we want to do with off-screen areas. One solution here might be to increase the area we are computing light for...
Parent - By Clonk-Karl [us] Date 2014-11-20 23:13
Yeah, much better. It does not seem to be an issue anymore, not even when large previously off-screen areas come into view. I would consider it fixed.
Parent - - By Newton [de] Date 2014-11-17 23:13 Edited 2014-11-20 23:52
7. Found another bug. (what you see is a shader that displays the light direction - white = from the screen/camera, black = ortogonal to the screen)
Sometimes single triangles in the fan are not rendered. This is in the range of my competence and likely my fault. Will investigate.

fixed.
Attachment: lightdir.png (199k)
Attachment: lightdir2.png (187k)
Parent - By Newton [de] Date 2014-11-19 23:23
This can only happen if the last (or first) triangle in the triangle fan is not drawn. I might have fixed this in my last commit.
Parent - - By Newton [de] Date 2014-11-17 23:17 Edited 2014-11-23 21:24
8. Clipping error, very likely not caused by my recent clipping implementation during rendering. This is only reproducable if you got a viewport and move the edge of the viewport past the light source. Then it still render right, but if you move your Clonk, then it displays like this. So the render clipping code is fine, only when the beams are raycast anew, the clipping is wrong. Will also investigate but since this may not be in my code, will take longer.
Attachment: lightoutofviewport.png - (don't mind the sky) (496k)
Parent - By Newton [de] Date 2014-11-23 21:24
Pow!
Parent - - By Newton [de] Date 2014-11-17 23:31 Edited 2014-11-20 23:52
9. There are sometimes really hard borders in the fadeout. I have an idea about this - during refactor I removed some lines of seemingly unnecessary code from Peters code. Lets see what happens if I reintroduce it.
fixed
Parent - - By Anonymous [de] Date 2014-11-20 10:34
I'm on it. (Newton)
Parent - By PeterW [de] Date 2014-11-20 11:54
Btw, what I told you yesterday was wrong - the purpose of that loop is simply to access the pre-transformed ray coordinates. We need those because the transformations might reduce the fan's "base" to 0 (fanL == fanR), at which point find_cross would fail.
Parent - - By Newton [de] Date 2014-11-20 23:53
So, this is how it looks now. Left: before I reintroduced the code, right: after.
Parent - - By PeterW [de] Date 2014-11-21 10:47 Edited 2014-11-21 10:55
Well, looks better. However your change to find_cross looks seriously awkward - even if you can make it to not divide by zero, that doesn't mean it makes sense. A point and a line don't cross, period. I mean, given that we are dealing with floating point numbers here we might well get something like 0.0001 at some point, and all of sudden points will be all over the place.

I feel this *really* should be solved by making sure that the line points can never get too close to each other in the first place. My version solved this by looking up the original beam. I think in your case this could be done simply by retaining a pointer to the original beam in your "triangle", then use the left and right end points for finding the cross point.

An alternate solution could be to take the distance of the inner fade point (left for ascending, right for descending, as usual) and construct a point on the mx/my-line that has the same distance to the light. That might even be more stable. After all, my "all over the place" argument still applies here somewhat - even if we have a minimum of 1px distance between the line points, this can still make the line jump around quite a bit.
Parent - - By Newton [de] Date 2014-11-21 12:05 Edited 2014-11-21 12:13

> I think in your case this could be done simply by retaining a pointer to the original beam in your "triangle"


Won't work for 45° angles. pBeam->isRight does not work in that coordinate system.

I made sure that the lines are not zero by removing all triangles of the fan where fanR == fanL (zero size).... for now. But I noticed that by that, I effectively made another part of your code defunct - C4FoWLightSection.cpp line 588 - 620 - cause it adds new triangles of zero size. But I didn't really understand what it does... other than,... well, roughly the same as what the intermediate fade triangles should do. That is why I wanted to talk with you yesterday evening.

But I think there is another solution that is actually simpler: light source S to midpoint M is a line segment. Make that line segment advance to a length of the total reach of light (reach + fadeout). The end point I is the point we look for:

dist = total reach of light / (M-S)
I = S + dist * (M-S)
Parent - - By PeterW [de] Date 2014-11-21 12:24 Edited 2014-11-21 12:31

> Won't work for 45° angles. pBeam->isRight does not work in that coordinate system.


Hm? That's why I said to save the pointer in the triangle. The loop is for jumping over beams that have been eliminated in the meantime, it's a bit hack-ish. You would get that for free. You would have to re-transform the beam coordinates though.

> I made sure that the lines are not zero by removing all triangles of the fan where fanR == fanL (zero size)


What? That's wrong. That breaks descend collisions, check the sketches - it's the situation where light shines through a hole but the light is large enough that it doesn't reach the bottom of the hole at 100% intensity. Keep in mind that even if the "beam" itself has been reduced to zero width, this still has an effect on the final triangle fan, as it fills the "holes" between the beams.

If it's not needed, could we then remove the extra cases from find_cross, or put assertions into them? Sorry, I really don't think it's a good idea to have the function attempt to be "smart" in undefined cases. Things like "just return any point" sound like a recipe for hard-to-reproduce bugs.

> Make that line segment advance to a length of the total reach of light (reach + fadeout).


What's the "total reach of light" here? I think that's pretty much what I proposed, with "total reach" being the distance of the lower fan point. Also I would propose fadeout/2.
Parent - By Newton [de] Date 2014-11-21 18:26
total reach of light is light reach plus fadeout of the light.
Parent - - By Newton [de] Date 2014-11-23 19:12 Edited 2014-11-23 19:26
10. some beams do not extend towards max range on first frame. They "wander" outwards in a total duration of perhaps 1-10 frames until they hit solid material. This produces ugly effects that are only covered up by the (too) smooth fading of the whole lighting texture.  Here is a screenshot of where the beam did not reach solid material yet. The error must lie in the raytracing algorithm.
Parent - By Newton [de] Date 2014-11-23 19:29
This seems to occur always at 45° angles. So it seems of each section the last (or first?) beam has a problem.
Up Topic Development / Developer's Corner / Completing lights branch - issues (locked)
1 2 Previous Next  

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill