How to fix shadow mapping problems - resolution, shadow swimming, sawtooth (OpenGL) - opengl

Im experimenting with rendering by trying to make a minecraft-like voxel engine. I want nice visuals, so I implemented basic shadow mapping. On a basic level it works, I do have shadows, and I have already accounted for shadow acne. But I am still encountering weird artifacts and problems which make the scene look rubbish.
This is what I had to begin with
I am guessing that the sawtooth shadow pattern on straight edges is basically a projection of the individual shadow map pixels, so I tried increasing the resolution of the shadow map to a massive 8192x8192 and it did indeed make the sawtooth much finer (though still perfectly visible)
I changed from GL_NEAREST to GL_LINEAR filtering and added Poisson sampling in my shader like this
void main()
{
float visibility = 0.6;
for (int i=0;i<4;i++){
visibility+=0.1*texture( depth_buffer_texture, vec3(shadowCoord.xy + poissonDisk[i]/14000.0,shadowCoord.z-0.0002));
}
fragColor = texture(texture_sampler, outTexCoord)*visibility;
}
(I also tried changing to sampler2DShadow but that did literally nothing)
the result looks better but still has some problems, namely the sawtooth is stiill visible both on the casting surface and on the shadow itself
This does look a lot better but I can still see the following problems:
I have an 8192x8192 shadow map which does not seem reasonable (though I'm not sure, it does still run at a comfortable fps even without any optimisations at this point, so, maybe, in this case it is ok?)
The shadow edges are still not smooth both on the casting surface and on the surface the shadow falls on
As this is an 'infinite' voxel world, the light source, while using a constant ortho projection, has to follow the player arround, and when the source moves with the player the shadow edges move around and flicker in a most annoying way. With the large texture and smoothing it is almost ok but gets worse fast with a smaller texture size. I believe its called shadow swimming but could not find the proper way to fix this
There is an annoying Moire-like pattern on the farther hill. While it is present without the shadows it is made considerably worse by them and I can't seem to find what its called and, therfore can't really search how to fix it
If anyone can help me fix these problems or even just point me in the right direction I would be very grateful. Thanks in advance!

Related

openGL simple 2d light

I am making a simple pixel top-down game. And I want to add some simple lights there, but I don't know what the best way to do that. This image is an example of light what I want to realise.
http://imgur.com/a/PpYiR
When I googled that task, I saw only solutions for that kind of light.
https://www.youtube.com/watch?v=mVlYsGOkkyM
But I need to increase a brightness of the texture part when the light source is near. How can I do this if I am using textures with GL_QUADS without UV?
Ok, my response may not totally answer you question, but it will lead you down the right path.
It appears you are using immediate mode, this is now depreciated and changing to VBOs (vertex buffer objects) will make you life easier.
The lighting in the picture appears to be hand drawn. You cannot create that style of lighting exactly with even the best algorithm.
You really have two options to solve your problem, and both of them will require texture coordinates and shaders.
You could go with lightmaps, which use a pre generated texture multiplied over the texture of a quad. This is extremely fast, but requires some sort of tool to generate the lightmaps which might be a bit over your head at the moment.
Instead, learn shader based lighting. Many tutorials exist for 3d lighting but the principles remain the same for 2D.
Some Googling will get you the resources you need to implement shaders.
A basic distance based lighting algorithm will look like this:
GL_Color = texturecolor * 1.0/distance(light_position,world_position);
It multiplies the color of the texel by how far away the texel is from the light position. There are tutorials that go more into depth on this.
If you want to make the lighting look "retro" like in the first image,you can downsample the colors in a postprocesing step.

Diffuse light/shadow

I just implemented a light system in my engine. In the following screenshot you can see a light (the yellow square) in action:
Take into account that on top of the light illuminating the scenario, its also implemented a FOV which will occlude anything outside your field of view. Thats why the left part of the shadow seems so off.
As you can see the light's shadows are pretty "hard", as they won't even illuminate one bit of the area outside its direct reach.
In order to make the lights look better, I applied a filter to them, which pretty much limits the range to be illuminated, and also iluminate the area slightly within this limit:
In the big yellow circle you can see how the area is illuminated even if no direct light reaches it.
This solution however comes with some undesirable side effects. As you can see in the following screenshot, even if no light at all reaches an area, it will be illuminated if its too close to the light source:
I was wondering if there is any way to achieve what im trying to do by using shaders properly.
The main problem that I encounter comes from how I draw these shadows.
1) First I take the structures within the light's range.
At this point, I'm working with vertex, as they define the area of the shadow casting items:
2) Then, for each of these objects, I calculate the shadow they cast individually:
The shadow they cast is done by the CPU, by calpulating projections for each vertex of the body.
3) Then the GPU draws these shapes into a texture to compose the final shadow:
The problem I find is that making this difuse shadow effect, I need the final shadow. If I were to calculate the diffused shadows in step 2), a gap of light would appear between solids B and C.
But if I difuse the shadows in step 3, I no longer have the vertex information, as all the info I have are the 3 local textures added up together in one final texture.
So, is there anyway to achieve this? My first idea would be to pass a varying to the fragmentshader to calculate how much light comes into the dark area, but since I'll be processing this info on the final shadow, which has no vertex information, I'm completely lost about what approach I should use to make this.
I might be completely wrong on this approach, since I have very very limited experience with shaders.
Here is an example of what I have right now, and what I desire:
What I have: Plain illumination withing the light radius (which causes the light to clip through walls.
What I want: Shadow is more intense the farther away it is from where the light ends.
I think that no matter what you do, you're going to have to calculate the light falloff differently for the areas of the scene that don't have direct visibility to the original light source. I'm not sure how you're actually applying the shadow volume to the scene, but you might be able to do something like classify the edges as you're generating the shadow volume (i.e. did they come from a wall or from the line from the light to a corner?), and treat them accordingly.
In short I don't think there's any clever shader-specific trick you can pull off to fix this problem. It's a limitation of the algorithm you're using, so you need to improve the algorithm to take into account the different nature of the edges in your shadow volume.
--- Edit ---
Ok I think your best bet is going to be to create two shadow volumes (or rather shadow areas since we're working in 2D). One will be exactly as you have now, the other will be smaller -- you'll want to exclude the areas that are in "soft" shadow. Then you'll have three categories in your fragment shader: total shadow, soft shadow, and unshadowed.
To create the second shadow map, I think you'll want to do something like add a fixed angle to the edges that are created by the light shining around a corner.
--- Edit #2 ---
I think you can solve the problem of the gap between objects B and C by taking the silhouette of the shadow areas and the outer box of the scene. So for each of your shadow areas, you'd find the two outermost points that intersect the outer box, then throw out all the line segments in between and replace them with that portion of the box. I feel like I should be able to name that algorithm but it escapes me at the moment...
Original Scene:
Individual "hard" shadows:
Now union the shadows together:
Finally, trace around the shadows, keeping to the edges of the box. The corners you want to identify are the ones in yellow. As you are tracing around the perimeter of the shadows, you want to cut across the edge of the box until you reach the opposite corner. Not the easiest thing to code but if you've gotten this far I think you can figure it out :)
Alternatively, it might be easier to simply consider the lit areas. For example, you could do something like take the difference of the scene box and the unioned shadowed area This will usually give you multiple polygons; discard everything except the one that contains the light because the rest are the false gaps.

Can not find a proper shadow mapping depth bias?

Hello there fellow programmers, I have found yet an other obstacle in improving shadow mapping.
The question is that I am doing some shadow mapping, and can not find any suitable depth biases for it. Some time ago in my XNA project when I was doing it for the first time, I could set it up quite nicely on a terrain, and could find a suitable bias in no time, because, if no bias was set, such acne occured:
I was adjusting the bias until the shadows looked fine, that is the basic idea behind it as far as I could understand. This is the result what I am aiming for.
Now moved on to DirectX 11, and set up a little scene later, and done some PCF shadow mapping. Then, when setting no bias, there were no such acne, but the shadows were disconnected, such as this (sorry for ugly texturing):
It should have acne on the ground, and the shadow of the box connect to the box's edge, but instead it is disconnected. When lowering bias (to a negative), the gap starts to decrease, but soon the whole shadow map darkens before reaching optimal gap distance.
I am using the same shader code (only extended by pcf filtering) as on XNA, so I am assuming it is more to do with the api. Checking out the xna code, I can not even see what the render-to texture formats are, because they are hidden (I guess).
If anyone ever had this problem before, please help me achieve the shadow acne with a zero bias.
UPDATE: This image shows the uneven shadowing on a plain flat quad (the acne should be even across the whole quad, as it is on the terrain in XNA):
UPDATE2: I tried switching culling mode to cull out front-facing faces during the depth render pass, that way the shadows ccan be adjusted a little better, because there is no floor rendered that would darken if bias is modified, but the shadows are still very uneven. Individual meshes' shadows can be adjusted to look good, but then the others get messed up.
Somehow, I think, the depth buffer distribution is very uneven, because objects closer to the far plane get better results. Not even my clipping distances are bad, I think. The Shadow Projection is set to 1-2000 depth distribution (in my scene, 1 meter is approximately 200 units), but somehow, accuracy is way off.
I have tried depth texture formats of R32_FLOAT and D24_S8_UNORM.
I've seen a similar issue when not setting the 'SlopeScaledDepthBias' property appropriately (also part of the D3D11_RASTERIZER_DESC).
As is explained here, the SlopeScaledDepthBias is an important part of the depth bias calculation, make sure it's initialized to something that makes sense.
OK, slope scaled bias is a solution to self-shadowing acne, but was not the correct solution for my problem.
I have found out I had my viewport set up faulty. All this time I have filled out the description for its depth to 0.1f near depth and 1.0f far depth, because I had not known what it was for exactly and worked ok, but the depth buffer was uneven, getting more precision near the shadow eye and losing precision going further.
I changed the viewport description for the shadow map rendering depth stencil view to 0.0f on the near plane and finally it worked, so now the whole scene is getting depth information evenly, like previously in XNA.

Voxel Cone Traced Soft Shadows

I have recently implemented soft shadows using voxel cone tracing in OpenGL 4.3 by tracing a cone in the direction of the light and accumulating opacity values.
The key thing that I am trying to resolve or hide is the very voxelized shadowing effect as the occluded surface gets closer to the occluder, as well as hide the clear spots in the shadow due to surface voxelization. I am using low resolution voxels 64x64x64; however, even if I use higher resolution voxels, some of the low-res voxels at a higher mip-map level are still captured in the trace.
So here's what my first idea is: I want to be able to keep the softest parts of the shadow that is furthest away and replace the parts of the shadow that is closer to the occluder with a shadow map. The shadow map will fade as it is further away from each occluder and I will somehow blend it into with the cone traced shadows.
Can anyone think of a way to fade a shadow away based on distance from each object for a shadow-map and then have it blend smoothly into the cone-traced shadow?
Another idea I have would be to somehow ray-trace shadows onto surfaces that are closer to an occluder, but this would probably be too expensive.
Alternatively, I would welcome any other ideas to help improve my soft shadow algorithm.
I've also put up a video to show it in motion:
https://www.youtube.com/watch?v=SUiUlRojBpM
Still haven't found a way to resolve the shadowing issue.
I'm guessing the "clear spot" artifacts are occurring due to large voxel sizes only being partially filled with geometry: "accumulating opacity values.". How many samples are you taking when converting from rasterized pixels to voxels? If the sample volume/voxel volume is small then there could be issues with correctly rendering transparency - there will be noise indicated by lighter areas.
Also, are your voxels' transparency direction dependent? Based on the author's original paper. Directional dependence is important to ensure semi-opaque voxels are rendered correctly.
A quick picture to explain
"for a shadow-map and then have it blend smoothly into the cone-traced shadow?"
This seems like you are kind of shooting yourself in the foot. You get an even larger performance hit and get the disadvantages of both shadow mapping and voxel cone tracing. Voxel cone tracing is expensive but can give nice soft shadows and do global illumination. Shadow mapping is better at doing hard shadows and is faster for smaller scenes, but as you add more geometry you end up redrawing the same stuff multiple times, at least once for each light.
Great work btw. I came across your problem while doing preliminary research for my own DirectX implementation of voxel cone tracing.
[Edit]
I realized that I made a typo in the picture. The picture on the right should be 4/64, rather than 4/16. I forgot about the Z dimension.
Well, in this case you can do it by adding more lights. You can add more lights closer to the original one and then compose the shadow of a light with the shadows of a bunch of closer lights. That is the 'area light' effect.

Headlight or understanding of way the light works

I'm developing a project of 3D maze with OpenGL. Despite my poor knowledge of programming, I managed to build it, add textures and steering with mouse and keyboard (stolen from net in most part, though). Now I'm stuck with lighting.
My idea (similar to famous game SCP-087) was to make a headlight, with a short range of light. I've read a lot about lighting in OpenGL and normals, but light still acts odd and kind of randomly.
I have the functions, that move (translate) my world around the camera. I understand, that if I place my light0 on the beginning of code, before translations in Render() function, that light should be "still placed" with camera, and world shall move around them - that sounds simple. But it doesn't seem to work. Most of walls are lit when I'm standing sideways to them (and completely dark when I turn to them with other side).
My other problem are normals. I'm pretty sure, that my normals aren't specified well, but have no idea how they should look like. I'm using triangle strips for walls (theoretically for improved efficiency, but practically it's just my caprice) and I could nowhere find a solution how normals should be specified for straight walls made of triangle strips (how to attach normals for faces, when I have only two vertices definign a single face, actually). Making one wall of simple quads and attaching four perpendicular, lenght of one unit vectors for one face also didn't make any improvement.
I can neither handle properly parameters of OpenGL state machine, especially attenuation - no changes in code seems to affect final lighting.
I have currently no idea, where to search and what to read about lighting in OpenGL. I would like to make it supersimple, with no additional libraries (except glu.h). Can you give me a hand with this problem or refer me to any useful source of knowledge (simple examples needed...)?