-
Notifications
You must be signed in to change notification settings - Fork 2
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
Transparency #589
base: master
Are you sure you want to change the base?
Transparency #589
Conversation
looks good. I tried to make these yellow things in the gamescenario transparent but it didn't work. What did I do wrong? |
nothing, seems to work for me. note you edited the gamescenario (the big battle) and not the frozen one. |
Is that a freaking transparent cockpit on the mox? wooooha! |
void main() { | ||
vec4 opaque = texture(color, v_uv) + texture(bloom, v_uv); | ||
vec4 accumulated = texture(transparencyAcc, v_uv); | ||
accumulated.a = texture(transparencyCnt, v_uv).z; // Why is Acc.a always 1?! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could use some input with this:
Even though I switched the textures to RGBA the alpha value always returns 1. It's no problem because I have space in the count buffer, but why?
I don't know the limitations of weighted average, but would it be possible to make a whole planet or maybe at least the yellow enemies (-> frozengamescenario) appear transparent? Currently the planet turns almost white and the enemies appear transparent only from some angles. |
because all voxels are rendred those on the outer edge appear more transparent from some angles, because there are only 2 transparent layers rather than the >4 everywhere else, is that what you mean? |
That's probably it. We should use multiple layers of transparent voxels then, I guess. |
The performance impact from the trancparency is constant (well, the number of transparent pixels might have some impact), the perfomance drop must result from splitdetection. |
I flew through the planet via freecam, so no splitdetection. Are there ifs only triggered on transparency in the shaders? Sometimes they are evil. :D |
} | ||
if (transparentPass == 0 && f_color.a < 0.9999) { | ||
discard; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are ifs, I don't see how we can get around these though...
And indeed the game spends 90% in nvogl.dll when in the planet
Weighted average is one of the faster algorithms, so yes, it's not perfect, especially with many layers of transparent pixels. But if you don't start making whole ships or objects transparent, I think it does the job quite well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why there is a performance difference with transparent voxels though. The scene is rendered twice, any fragment passes either trough the first if in the first run or the second if in the second run. This means any fragment passes the part below the ifs once per frame.
I can't explain it via Z-Buffer either because the z test is applied after the fragment shader has run. Can blending be the problem? With many transparent fragments on one pixel, the GPU has to blend a lot
GTX460 video load in the transparency2_perf branch (without moving the camera, shader doesn't discard anything): |
Need some less euphoria? Crashes on my bp-pc
|
Probably because glClearNamedBufferDataEXT isnt set by glewInit.... |
glBlendFunc(GL_ONE, GL_ONE); | ||
CheckGLError(); | ||
drawGame(camera, true); | ||
//drawGameAlpha(camera); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove may 🐝 ?
Not quite done yet, I need to think about splitting the particleengine a bit, but so far it looks pretty good. |
vec4 accumulated = texture(transparencyAcc, v_uv); | ||
// HACK: actually accumulated.a should be the accumulation of the a values | ||
// It seems to always be 1, while using the count-buffer's z for the same purpose works | ||
accumulated.a = texture(transparencyCnt, v_uv).z; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open to ideas... I didn't try cnt.a, don't the textures have alpha? The framebuffer creates them with
texture->image2D(0, GL_RGBA, m_resolution.x, m_resolution.y, 0, GL_RGBA, GL_FLOAT, nullptr);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't look but you have enabled GL_BLEND? Otherwise I wouldn't be surprised if OpenGL optimizes values out that aren't explicitely set (as is the case for the alpha value of the color)
vec3 rgbColor = voxelFragmentColor(f_color.rgb, f_emissiveness, f_normal, f_modelposition); | ||
fragColor = vec4(rgbColor * f_color.a, f_color.a); | ||
emissiveness = voxelFragmentEmissiveness(f_color.xyz, f_emissiveness); | ||
if(transparentPass) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about
normalz = (1-transparentPass) * voxelFragmenNormalZ(f_normal);?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ifs are evil, I have been told, as we need voxelFragmenNormalZ() in most cases (=most of the pixels won't be transparent), this should be better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so long as this operation is properly defined with bool, I'm on. Will try
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you will probably need to cast to float explicitely
@@ -23,6 +24,7 @@ namespace { | |||
"NormalZ", | |||
"Emissisiveness", | |||
"BlurTmp", | |||
"Bloom", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be considered premature optimization... and its a bit confusing as well. And what is the pupose to name a buffer "Emissiveness" if it is used for something else as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the use still is only Emissiveness == Bloom. Since they are the same buffer now it could be named bloom. Otherwise it's not an optimization but was needed to get two more buffers (limit is 8 on most GPUs)
When I run the PirateScenario and fly through the enginetrail of the normandy, I suffer slowdowns. Can you reproduce this? |
my load goes from 33% without significant transparent voxels up to 80% when the entire screen is filled with transparent voxels. |
Well, it's definitely to much of a drop for that few particles there, that definitely needs to be fixed somehow. Or we have to forbid transparent particles |
note the performance critical part is screen coverage (pixels), not particle count. with a bad perspective, you probably can mess up any scenario by overlapping n transparent surfaces and filling the entire screen with it. I agree though, we'll have to find some solution. Maybe a performance setting (so HD4000's don't have it but GTX780 players may enjoy it) |
I have problems to believe this. Even my HD5830 has a pixelfillrate of 200Mio/Frame. That's each pixel 100 times in HD. And I am not even running the game in HD! http://techreport.com/review/18521/amd-radeon-hd-5830-graphics-card/5 |
I know too few about GPUs to argue. |
We should have done this earlier....
Here comes Order Independent Transparency using Weighted Average
Because we use instancing etc it was not possible to directly use the glow implementation, but most is stolen from there.
With two render passes and one additional render target, you get transparency for any Voxel in a VoxelCluster and any Particle
Please try this ASAP and be blown by the awesomeness 😄