-
Notifications
You must be signed in to change notification settings - Fork 60
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
Implement alphaGen portal #1022
Conversation
8fb9a74
to
d6a8a32
Compare
When I apply #1019 I see the portal map being blended with distance, though it is upside down and it is not blended over the portal but over itself, but this is promising. At least the “fade with distance” compute is right or not totally wrong. |
I think I've identified the issue there, hopefully should be fixed soon. |
d6a8a32
to
94304e6
Compare
I believe this is because of how we render portals now. The portal surfaces themselves are not rendered with the other surfaces, but alphagen portal uses Render_portal() which seems to be a really old function. I assume that's a relic of the fixed function pipeline where it had to be drawn in multiple passes. We can just pass the alphagen parameters and texture to the shader now and blend it there. |
Yeah, ioq3 apply |
We should too, we can use gl_FragDepth with a uniform passing in the alphagen value. Might need to get the linear depth since I assume that's what alphagen portal is supposed to use. |
You might need to add Tess_Begin() and rb_surfaceTable() or equivalent. I think the reason we're getting incorrect rendering here might be because the portals are rendered as follows:
That last one does a Tess_Begin(), rb_surfaceTable() and a Tess_End(), while Render_portal() just does Tess_DrawElements(), which would then have incorrect data (presumably Render_portal() would be called after FinalisePortalCommand). |
Current state is:
|
a719bd5
to
d767259
Compare
Not sure what that means.
Isn't that the crrect behaviour? I'm pretty sure trem works like that too (it also just makes sense, what's the point of a portal that you can't really see?). |
You should see the portal surface (the scene from the camera) when close, but the fallback image when far, with the fallback image fading from transparent to opaque while increasing the distance. The idea is that the portal is only rendered when close with an image rendered instead when far. |
Oh, so it's just backwards, right? I think just changing |
OK, now two things are missing:
|
I also noticed that while it fades in the right direction, it doesn't really fade to black. Example of test scene: map |
It should be fading to an image though, rather than black? |
Incorrect might be because alpha channel is not set and/or because of the blend functions. |
It should be fading to the image from the distant camera. I assume fading to black is expected when blending is not working yet. |
Blending is fixed now.
What you're seeing on nova is because the game doesn't render the portal at all from this position. |
This also happens on 0.54.1, so at least it's not a regression (or not a recent one). |
dbc0eed
to
f0969a9
Compare
Excellent!
Yes. The expected behavior of such surface is that when the view position is out of range, the surface always renders the textures, so what should be disabled is not the whole material, but only the portal rendering, with the texture being displayed. |
Doing this “fixes” it: diff --git a/src/engine/renderer/tr_main.cpp b/src/engine/renderer/tr_main.cpp
index 061baee51..f19166508 100644
--- a/src/engine/renderer/tr_main.cpp
+++ b/src/engine/renderer/tr_main.cpp
@@ -1587,7 +1587,7 @@ static bool SurfBoxIsOffscreen(const drawSurf_t *drawSurf, screenRect_t& surfRec
if (shortest > (shader->portalRange * shader->portalRange))
{
- return true;
+// return true;
}
return false;
@@ -1741,7 +1741,7 @@ static bool SurfIsOffscreen( const drawSurf_t *drawSurf, screenRect_t& surfRect
if ( shortest > ( tess.surfaceShader->portalRange * tess.surfaceShader->portalRange ) )
{
- return true;
+// return true;
}
return false; But this is wrong, it defeats the portalRange, meaning the portals are always rendered. What we need is to never disable the surface when out of range, but to disable the portal rendering when out of range. |
I tried doing this: --- a/src/engine/renderer/tr_main.cpp
+++ b/src/engine/renderer/tr_main.cpp
@@ -1585,10 +1585,7 @@ static bool SurfBoxIsOffscreen(const drawSurf_t *drawSurf, screenRect_t& surfRec
return false;
}
- if (shortest > (shader->portalRange * shader->portalRange))
- {
- return true;
- }
+ shader->isPortalOutOfRange |= shortest > (shader->portalRange * shader->portalRange);
return false;
}
@@ -1739,10 +1736,7 @@ static bool SurfIsOffscreen( const drawSurf_t *drawSurf, screenRect_t& surfRect
return false;
}
- if ( shortest > ( tess.surfaceShader->portalRange * tess.surfaceShader->portalRange ) )
- {
- return true;
- }
+ shader->isPortalOutOfRange |= shortest > ( tess.surfaceShader->portalRange * tess.surfaceShader->portalRange );
return false;
} Now I'm looking for a place to do: if ( shader->isPortalOutOfRange )
{
return;
} To avoid rendering the related portal surface when out of range, but without disabling the surface itself. |
Perhaps in an else block here? Daemon/src/engine/renderer/tr_main.cpp Lines 2094 to 2101 in e522be8
|
a4b1120
to
7187a15
Compare
6624552
to
46389f9
Compare
LGTM |
I don't claim it is working, but we need this to make it work.
We can notice the current code computes the distance to portal in fragment shader, but ioq3 does it in vertex shader, and it's probably faster to do it once per vertex than once per pixel, but this is a good start.
I'm not sure the existing GLSL code is correct, but the GLSL code will not run without those patches anyway.
The ioq3 code also does the range compute in the
generic
shader and at some point we may want to do the same as there may be other needs for doing blend operations according to distance, but yet again, we can look small and do small steps after small steps.