-
-
Notifications
You must be signed in to change notification settings - Fork 21k
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
Alpha blending works incorrectly in 3D + Vulkan #82879
Comments
This is likely due to sRGB/linear conversion, and may be done by design. Forward+ and Mobile render 3D in HDR (with Mobile having more limited dynamic range), while Compatibility renders in LDR with sRGB for performance and compatibility reasons. 2D rendering is LDR + sRGB in all rendering methods by default, but you can opt into HDR since 4.2 when using Forward+ or mobile. |
This is indeed the difference between blending in linear space and sRGB/gamma space. The compatibility renderer always uses sRGB and the 2D renderer uses sRGB. The 3D renderers for mobile and Forward+ blend in linear space. Neither is more correct than the other, you have to design your assets based on which one you will be using. |
If it is the case, is there an easy way to achieve old behavior in 3d? Or at least have a predictable color (e.g. exact mixing formula), to adjust accordingly? We have 2.5d game and do most of concepting and texture rendering in 2d image editors. So I expect that RGB(0, 0, 0) + RGBA(1, 1, 1, 0.5) will produce RGB(0.5, 0.5, 0.5). |
Well, than i just have to figure out how to configure Photoshop/Procreate to work with linear color space. And maybe it should be mentioned (or even highlighted) in docs. |
Conversion routines: float toSRGB( float x )
{
if( x <= 0.0031308f )
return 12.92f * x;
else
return 1.055f * powf( x, ( 1.0f / 2.4f ) ) - 0.055f;
}
//-----------------------------------------------------------------------------------
float fromSRGB( float x )
{
if( x <= 0.040449907f )
return x / 12.92f;
else
return powf( ( x + 0.055f ) / 1.055f, 2.4f );
} These routines work in range [0; 1], so you can call toSRGB( 128.0f / 255.0f ) to get the value you want to generate 0x80. Note that internally Godot F+/Mobile works in RGB10A2 so there may be some rounding error (I suspect that's why in 2D you get 7F vs 80 in Compatibility).
There's plenty of guides for that 😄 |
Yeap, I've already configured it. But thanks for the formulas, good to have it in one place :) And for the mentioning of rgb10a2, I looked that up too. I guess, issue can be closed now? |
Godot version
Godot v4.1.stable
System information
Godot v4.1.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3080 Ti (NVIDIA; 31.0.15.3742) - 12th Gen Intel(R) Core(TM) i7-12700 (20 Threads)
Issue description
3d blending with Forward+ renderer works incorrectly (or at least in an unexpected way). 3d blending with Compatibility renderer and 2d blending in BOTH renderers work as expected.
3d
2d
Steps to reproduce
In 3d scene just add quad with semitransparent texture or set semitransparent albedo_color, set unshaded mode for clean test enviroment. Blended color will be different from what is expected in Forward+ rendered.
Or just run attached project.
Minimal reproduction project
blend_problems.zip
2d_blend.tscn - 2d blending works almost the same way in both Compatibility/Forward+ renderers. Final RGB color differs by 1, possibly due to rounding errors.
3d_blend.tscn - 3d blending works differently for Compatibility and Forward+, resulting in quite visible colors discrepancy.
The text was updated successfully, but these errors were encountered: