Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust PSM distortion to use entire SM texture #12166

Merged
merged 12 commits into from
Apr 7, 2022

Conversation

x2048
Copy link
Contributor

@x2048 x2048 commented Apr 3, 2022

This PR aims to improve quality and visible distance of the dynamic shadows.

What's done:

  • Passing camera/player position to all the relevant shaders
  • New distortion function that is tied to the position of the player
  • Adjusted light frustum to render more area in front of the player
  • Adjusted filter radius to get more crisp shadows.

To do

This PR is Ready for Review.

How to test

  1. Enable dynamic shadows and choose one of the presets
  2. Start a game that supports shadows (devtest)
  3. Shadows should look better than earlier
  4. Performance should be the same or better

For example, Medium preset should have decent shadow quality and support viewing distance up to 200 nodes.

@Andrey2470T
Copy link
Contributor

Andrey2470T commented Apr 3, 2022

No shadows casted at all (neither from map nodes nor from objects):
Снимок экрана от 2022-04-03 13-53-07

The enabled preset in the settings is High.

@Andrey2470T
Copy link
Contributor

Also checked in all other presets: none of them the shadows are not rendered. Except that, I noticed the performance doesn't change at all when switching between presets (FPS hesitates within 59-60 ). That is, the engine just refuses to render them for some reason, this is not a result of e.g. the shadows color is transparent and therefore invisible.

@NathanSalapat
Copy link
Contributor

@Andrey2470T I don't believe MTG supports shadows currently, you'll need to use a recent version of devtest, and possibly have to enable shadows within the game, via chat command, to see them.

@x2048
Copy link
Contributor Author

x2048 commented Apr 3, 2022

@Andrey2470T currently only devtest game supports dynamic shadows. You need to type /set_lighting 0.4 to turn the shadows on.

@x2048
Copy link
Contributor Author

x2048 commented Apr 3, 2022

@Andrey2470T Also #12157 will enable shadows by default and change the command to /set_shadow

@x2048 x2048 requested a review from lhofhansl April 3, 2022 14:03
@Andrey2470T
Copy link
Contributor

I discovered the artifacts of the netty shadow and the self-shadowing on the player model:
Снимок экрана от 2022-04-03 20-24-15

Снимок экрана от 2022-04-03 20-25-34

Also, the frequency of the shadow map update is enough low. It is even noticeable when a player just walks around (his shadow falls behind at half-second).

@lhofhansl
Copy link
Contributor

lhofhansl commented Apr 3, 2022

I can confirm that the shadow quality is (much) better with the same settings.

I found that shadows vanish:
screenshot_20220403_113401

screenshot_20220403_113403

Both at the same time with just slightly different view angles. Probably due to blocks behind the player not being rendered (and hence casting no shadows).

Note that happens also without this change. (Although it seems to be less.)

@lhofhansl
Copy link
Contributor

On the code I'll mostly trust you. Seems to all make sense, but I didn't time to reason through the changes formulas and changed constants.

@x2048
Copy link
Contributor Author

x2048 commented Apr 3, 2022

@Andrey2470T

I discovered the artifacts of the netty shadow and the self-shadowing on the player model

Can you describe the netty shadow? Does it disappear when you disable the filtering?
Self-shadowing of entities is a known prior problem.

@lhofhansl

found that shadows vanish

Yeah, shadow draw list is still generated with an old algorithm which does not account for the new light frustum. I'll fix it and let's see if it causes problems for @Andrey2470T :)

@Andrey2470T
Copy link
Contributor

Does it disappear when you disable the filtering? Self-shadowing of entities is a known prior problem.

No. I disabled the poisson filtering in the settings and it didn't disappear.

@x2048
Copy link
Contributor Author

x2048 commented Apr 3, 2022

@Andrey2470T

Also, the frequency of the shadow map update is enough low. It is even noticeable when a player just walks around (his shadow falls behind at half-second).

This is only specific to devtest. MCL2 and MTG do not have the lag problem.

Use non-perspective frustum culling (direction + radius)
Remove occlusion culling
Copy link
Contributor

@lhofhansl lhofhansl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great! Nothing stands out with the code.

See the few comments I left.

src/client/clientmap.cpp Show resolved Hide resolved
src/client/clientmap.cpp Show resolved Hide resolved
src/client/shadows/dynamicshadowsrender.cpp Show resolved Hide resolved
src/client/shadows/dynamicshadowsrender.cpp Show resolved Hide resolved
@Andrey2470T
Copy link
Contributor

Unfortunately, the last commit didn't fix those bugs which I reported about. I looked into a bit deeper the conditions on which they happen: first off, I want to say there are no the self-shadowing and the ripple on the model in the master branch. So maybe did your PR break something in the code? And what I noticed is the self-shadowing appears only during walking and only when the sun is behind of you. The last condition also relates to the ripple bug. However, nothing of that happens on first world startup until how the sun passes over the zenith point.

Other bug that I already mentioned in the previous comment is the shadow falls back for updating its location somewhere at half-second interval when a player is walking. Also, could you please fix the waving artifact around the edges of the shadows?

@Andrey2470T
Copy link
Contributor

I am unsure whether this has a direct relation to this PR, but I noticed the item entities don't darken themselves in the dark places as if they are not affected by the lighting:
Снимок экрана от 2022-04-06 00-44-17
Снимок экрана от 2022-04-06 00-44-33
It happens in your branch and also in the master branch.

@lhofhansl
Copy link
Contributor

@Andrey2470T I have not observed the issues you see. I definitely do not see the shadow "falling behind".
MCL2 does not enabled shadows (as of the last sync from the master branch).

@lhofhansl
Copy link
Contributor

lhofhansl commented Apr 5, 2022

Also dev-test is special here in how the player is rendered. I do see the shadow lag of one frame there, but IMHO we do not need to fix that as dev-test is so special... Same with self-shadowing of the 2d player model.

Edit: Spelling

@Andrey2470T
Copy link
Contributor

@Andrey2470T I have not observed the issues you see. I definitely do not see the shadow "falling behind". MCL2 does not enabled shadows (as of the last sync from the master branch).

That's what I mean:

shadow_fall_behind.mp4

As you see on this short video, at a high speed the shadow casted from the player is a bit falling behind in that moment. Maybe does this happen of the shadowmap is got updated after somewhere a half-second, not so often as the main rendering?

@x2048
Copy link
Contributor Author

x2048 commented Apr 6, 2022

@Andrey2470T @lhofhansl I hacked shadows into MCL2 and MTG and checked that there is no lag for the player shadow, so it is devtest-specific.

@lhofhansl
Copy link
Contributor

I maintain my "One Approval". If we feel devtest is a significant problem I propose fixing that in a different PR.

@lhofhansl
Copy link
Contributor

lhofhansl commented Apr 6, 2022

The filtering with zoom seems off:
screenshot_20220406_131221

Probably related the shadow bias. Does not block this PR (still maintaining the One Approval), but thought I'd mention it.

Perhaps related:
Unzoomed, but closer:
screenshot_20220406_132942

Same zoomed (see how blurry this is, probably due to the larger radius, so maybe not much one can do...):
screenshot_20220406_132944

Again, not to block this PR from being merged.

@x2048
Copy link
Contributor Author

x2048 commented Apr 7, 2022

@lhofhansl Filtering and biases/offsets are known to be off and are on my list of things to fix.

Zoom is changes the scale of the shadow map, making SM texels and filter radius larger. I an only see this being solved by non-square SM texture or cascaded shadow maps.

I will merge this PR now.

@x2048
Copy link
Contributor Author

x2048 commented Apr 7, 2022

@Andrey2470T

item entities don't darken themselves

May I ask you to file a bug for this, so we do not forget?

@x2048 x2048 added the Roadmap The change matches an item on the current roadmap. label Apr 7, 2022
@x2048 x2048 merged commit 48f7c56 into minetest:master Apr 7, 2022
@x2048 x2048 deleted the shadow_distortion branch April 7, 2022 20:13
x2048 added a commit that referenced this pull request Apr 7, 2022
@x2048
Copy link
Contributor Author

x2048 commented Apr 7, 2022

@Andrey2470T

Unfortunately, the last commit didn't fix those bugs which I reported about. I looked into a bit deeper the conditions on which they happen: first off, I want to say there are no the self-shadowing and the ripple on the model in the master branch. So maybe did your PR break something in the code?

Yes, the offset parameters to avoid self-shadowing are now wrong because of a different distortion function for the shadows. Tuning these parameters is the next task on my list, and after that I will optimize filtering.

And what I noticed is the self-shadowing appears only during walking and only when the sun is behind of you. The last condition also relates to the ripple bug. However, nothing of that happens on first world startup until how the sun passes over the zenith point.

This is a good insight, thank you. I will take a look when fixing self-shadowing.

Other bug that I already mentioned in the previous comment is the shadow falls back for updating its location somewhere at half-second interval when a player is walking.

Also, could you please fix the waving artifact around the edges of the shadows?

"Waving artiact" happens due two reasons:

  • Projection aliasing, you can read more here. This can be addressed by (a) using a larger texture with shadow_map_texture_size parameter, (b) reducing the viewing range and (c) filtering the shadows, which I plan to fix soon.
  • Light direction changing due to movement of sun. You can reduce time_speed parameter to make the days longer and reduce dancing of the shadows.

@x2048 x2048 mentioned this pull request Apr 12, 2022
2 tasks
@x2048
Copy link
Contributor Author

x2048 commented Apr 14, 2022

A few words on how the new distortion function works and why it is needed.

The background is that the previous implementation could not use much of the shadow map because center of the light frustum was placed close to the player:

image

Red color shows camera frustum (what the player sees), grey is the texture surface, and circle shows the 'horizon' of the original distortion function (where shadows have the worst quality).

Ideally, we want to render as many shadows as possible in the camera frustum (visible to the player), meaning moving the player away from the light frustum center:
image

Distortion function also needs to be changed to have high-quality shadows close to the player, and the trick is to perform distortion in camera-relative space.

In the light space, both camera (player) position and vertex positions are expressed relative to the light frustum center:
image

The trick is to transform the vertex position into coordinates relative to the camera before applying the distortion function:
image

Given v is the vertex position in light space (-1 .. 1) and c is the camera (player) position, the following transformations apply:

  • if v.x > c.x then l.x = (v.x - c.x) / (1 - c.x) and the result is from 0 to 1
  • if v.x < c.x then l.x = (v.x - c.x) / (c.x - (-1)) = (v.x - c.x) / (1 + c.x) and the result from -1 to 0

The same transformation applies to y axis and can be simplified to:

l = (v - c) / (1 - s * c) (1)

Where v is the vertex position in light space, c is the camera position in light space, s is the sign of (v-c).

Perspective transformation is done the same as before:

  1. Perspective factor is f = a * length(l) + b where a and b are bias parameters
  2. Transformed relative coordinate is l' = l / f

Then the vertex is mapped back into the light-space: v' = l' * (1 - s * c) + c, which is the inverse of formula (1)

@x2048 x2048 mentioned this pull request Apr 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@ Client / Audiovisuals Roadmap The change matches an item on the current roadmap. Shaders >= Two approvals ✅ ✅
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants