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

Clip posteffect color to respective nodes #15055

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Desour
Copy link
Member

@Desour Desour commented Aug 25, 2024

Screenshots

black_ceiling
waving_water
water_and_black
flowing_water
flowing_water_below
flowing_water_down
If there's no backface:
no_backface
Posteffect fullscreen plus shaped:
overlap
A thin line between:
pxlline1
pxlline2
Torch triggers different triangulation of water (not new in this PR. but PR needs to take this into account):
torch_next_to_water

How it works

In master

For comparison, in master, the camera position is used to determine node whose post effect color should be used. Then a rectangle is drawn over the whole screen. It is drawn after the 3D scene and after the wield hand.

In PR

For PR, imagine how the near plane lies in the world. Because it is small, it will only intersect with nodes in a 2x2x2 block around the camera pos.
If the near plane intersects with a node, the respective are on the screen is inside the node, and needs posteffect. We want to draw a shape with the posteffect color for this area.

Wieldhand

If we drew the wieldhand before the posteffect shapes, the wieldhand would often be partly covered by such a shape, which is ugly. This is why the wieldhand is rendered after the posteffect step.
To color the wield hand appropriately, there's a new uniform for the object shader (used for wieldhand).
If the whole screen is filled with one posteffect color, it looks exactly like in master.
If shaders are off, the node light color is abused. It looks different. But shaders off support will be dropped soonish anyways.

How the shapes are determined

Imagine a node with drawtype normal for now, it is just a cube. More generally it is a convex polytope. A convex polytope is just an intersection of a bunch of half spaces, given via oriented planes, which are represented by 4D vectors.
These planes are transformed to clip space, and the intersection with the near plane (an oriented 2D line) is gotten (see clip_polygon_by_objsp_plane()).
To get the shape, we start with a rectangle filling the whole screen, and then cut off parts of it with one of the oriented 2D lines from above (see ConvexPolygon::clip()). The result (and all steps in between) are a convex polygon.
In the general case, we have more than one convex polytope for a node, and end up with multiple convex polygons.

A note about liquids

Liquids (e.g. water) can wave. The vertices at the top are moved up and down. It's still just two convex polygons. We cut the node by it's top face quad diagonal, which depends on lighting. There's also flowing liquid. Most of the changed lines outside of clientmap.cpp are devoted to either exposing the necessary information for this, or to coloring the wieldhand.

Other drawtypes

For the sake of backwards compatibility, other drawtypes than flowing liquid, liquid source, and normal still work similar as in master: They fill the whole screen and are only drawn if and only if the camera is inside the node.
This means that multiple post effect polygons can overlap. Check out the screenshots to see how this looks like.

Known issues

  • There's sometimes a 1 pixel or so thick line between the posteffect shape and the node face. (See screenshots.)
  • The wield shading doesn't work correctly without shaders. We no longer support the fixed function pipeline.
  • In cases where Waving water animation is laggy depending on Y coordinate #14159 appears, the posteffect shape doesn't behave like the buggy water.
  • Far out in the map, waving may also be broken, near /teleport 30140 0 10 for example. (Idk why.)
  • Extreme water wave parameters don't work.
  • If you're in a node that has backface culling, it can look a bit weird, because you can see the border of the node without seeing the face. But imo it looks correct, and is fine. (See screenshots.)

Possible future PRs

  • Add API for nodes to define convex polytopes to use for the posteffect.

To do

This PR is ready for review.

How to test

  • Fly inside a node, then disable noclip. Or in case of water, just fly into it.
  • Settings to try: enable_shaders, enable_waving_water, water_wave_*, 3d_mode, noclip, smooth_lighting, camera mode (1st pers, 2nd pers, 3rd pers), video_driver
  • Try at different positions in the world.
  • Try with different nodes / node combinations, including solid next to liquid (e.g. so it doesn't wave below), node with fullscreen posteffect color, and waving liquid.
  • Place a light source to trigger different triangulation of liquid top. (See screenshots.)
  • Go underwater and take a screenshot of the wieldhand. Compare colors to master.
  • Here's a mod for an allfaces node with opaque green posteffect color: https://codeberg.org/Desour/test_tmp/src/branch/posteffect_green (notice the branch)

@Desour Desour added Bugfix 🐛 PRs that fix a bug Feature ✨ PRs that add or enhance a feature @ Client rendering labels Aug 25, 2024
@Desour Desour marked this pull request as ready for review August 27, 2024 13:25
@Desour
Copy link
Member Author

Desour commented Aug 27, 2024

PR is ready for review now!

@Desour
Copy link
Member Author

Desour commented Aug 30, 2024

Squashed and rebased.

@cx384 cx384 self-assigned this Sep 1, 2024
@Desour
Copy link
Member Author

Desour commented Sep 24, 2024

Rebased.

I noticed the polygons aren't drawn with the "opengl3" video driver, because it has no draw2DVertexPrimitiveList. Will have to fix.

@Desour
Copy link
Member Author

Desour commented Oct 10, 2024

I noticed the polygons aren't drawn with the "opengl3" video driver, because it has no draw2DVertexPrimitiveList. Will have to fix.

Fixed.
(Implementing draw2DVertexPrimitiveList in the opengl3 driver turned out to be too annoying (something something screensize projection matrix) and too big of a change (would blow up PR, with difficult code, making it harder to review), so I'm using the 3D draw function now. (Edit: Tried in this commit: aa9db75))

(Also, trivially rebased.)

@cx384 cx384 removed their assignment Oct 10, 2024
@Desour Desour added this to the 5.11.0 milestone Nov 6, 2024
@Desour
Copy link
Member Author

Desour commented Nov 15, 2024

Trivially rebased, and removed the no-shader workaround, thanks to #15421.

@sfan5
Copy link
Collaborator

sfan5 commented Nov 16, 2024

(Implementing draw2DVertexPrimitiveList in the opengl3 driver turned out to be too annoying (something something screensize projection matrix)

FWIW if someone were to work on batching all the 2D drawcalls we have, this function would have to be implemented anyway.

@Desour
Copy link
Member Author

Desour commented Dec 13, 2024

Rebased.

FWIW if someone were to work on batching all the 2D drawcalls we have, this function would have to be implemented anyway.

(I'm still not doing that in this PR, fyi, for complexity reasons, and because the current method used here works.)

@Zughy
Copy link
Contributor

Zughy commented Dec 29, 2024

@Desour rebase needed

@Zughy Zughy added the Rebase needed The PR needs to be rebased by its author label Dec 29, 2024
@Desour
Copy link
Member Author

Desour commented Dec 29, 2024

Thanks for the notification!

Rebased.

@Desour Desour removed the Rebase needed The PR needs to be rebased by its author label Dec 29, 2024
@Desour
Copy link
Member Author

Desour commented Jan 12, 2025

Rebased.

@appgurueu
Copy link
Contributor

(disregard me mentioning this PR, it's unrelated, I was too hasty)

@Desour Desour modified the milestones: 5.11.0, 5.12.0 Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bugfix 🐛 PRs that fix a bug @ Client rendering Feature ✨ PRs that add or enhance a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Seeing through blocks glitch near_plane behaves poorly with nodes with post_effect_color (ie. water)
5 participants