Repository navigation
Conversation
|
Just a note: When I worked on an underwater shader, I noticed the same problem with free-camera. But a ray from the player, who can be very distant, may not cause a correct intersection. So I implemented state tracking, where the camera always starts above water on game load. and then it tracks intersections between pos and last pos. This makes it independent from player state too. |
This is pretty much what current implementation already does in case of free-camera. Yet still, complete solution that works is practically impossible and we have to relay on various heuristics. |
| if(pl!=nullptr && pl->isSwim()) { | ||
| inWater = (angles.x < -8.f); | ||
| // The swimmer stays at the surface while the orbit camera can dip below it at any pitch. | ||
| inWater = physic.waterRay(origin, 0.f).hasCol; |
There was a problem hiding this comment.
Can be OK as complementary heuristics, alongside angle one.
Why you not using physic.cameraRay ? It also reports hit-count water mesh, what make sit more general.
There was a problem hiding this comment.
I tried cameraRay(origin, pl->cameraBone(true)), but that version regressed while moving: the swimming animation dips the head below the surface while the camera stays above, so it incorrectly enables underwater shading and produces black bands. Standing still hides the problem. The orbit target can be submerged too, so neither is a reliable above-water reference.
Reverted to the direct waterRay(origin, 0.f).hasCol query and included diving, which previously used persistent crossing tracking. The camera-position query handled the reproduction correctly, including when both camera and head were underwater. It also keeps the cave-occlusion check. The angle fallback is removed.
|
Water has another issue. I have a local fix, but it even touches water shader. Let me know if you want to this 3e534ef as a PR. |
|
Is the water surface gone in the second screenshot or is it just a different angle? In case it's gone, correct way should look like this: |
|
Just slightly different angle. Water surface is still there. I was fixing blue water tint. |
443180a to
4a061d1
Compare
|
Tested your version on both cases:
Found one more case: swimming close to the overhang at the cave entrance with the camera dipping under the rock. The ray stops at the rock, finds no water, and the camera renders as above water (streaky surface seen from below). Pushed a fallback for that: if the ray finds no water, the camera still counts as underwater when it's below the swimmer's surface and the line from the hero to the camera crosses no rock and no water surface. 9/9 placements at that spot are correct now, waterfall results unchanged, diving untouched. |
Can you please share screenshoot? I think I see what case is it, just to be extra sure. |







While swimming, the camera counted as underwater only when it looked up by more than 8 degrees. The orbit camera can dip below the surface at a shallower pitch, so water got rendered with above-water shading from below, which shows up as vertical streaks over the surface.
The camera now uses
waterRay(origin, 0.f).hasColto classify its current position while swimming or diving. This avoids relying on an animated head or orbit target as an above-water reference and retains the water query's cave-occlusion handling. There is no angle fallback.Before:

After:
