Skip to content

Commit 755d205

Browse files
committed
bugfix(bgfx): Sample the scene composite the right way up on GLES
The composite pass reads the scene render target back to the swapchain with a fullscreen triangle. Render targets are bottom-left origin on GLES and WebGL but top-left on DX11 and Metal, and nothing accounted for that: the vertex shader built one fixed set of texture coordinates and the backend passed a hardcoded 0 where the flip flag belongs. So everything that goes through the composite - the whole 3D scene - came out vertically mirrored on those renderers, while the UI, which draws straight to the swapchain, stayed upright. That reads as "the game is upside down but the menus are not". Carry the flag in u_postTexelSize.z again, from bgfx's originBottomLeft cap, and flip V in the vertex shader when it is set. DX11 and Metal report false and pass 0.0, so they are byte-for-byte unaffected.
1 parent 156e7a2 commit 755d205

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

Core/Libraries/Source/WWVegas/WW3D2/BgfxBackend.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4045,10 +4045,15 @@ static void SubmitSceneComposite()
40454045
// Texel size of the (supersampled) scene color the composite samples.
40464046
const float texW = g_device.sceneRenderWidth > 0 ? static_cast<float>(g_device.sceneRenderWidth) : static_cast<float>(g_device.width);
40474047
const float texH = g_device.sceneRenderHeight > 0 ? static_cast<float>(g_device.sceneRenderHeight) : static_cast<float>(g_device.height);
4048+
// TheSuperHackers @bugfix githubawn 30/07/2026 .z carries the V-flip flag for the
4049+
// composite. Render targets are bottom-left origin on GLES and WebGL but top-left on
4050+
// DX11 and Metal, so without it the whole 3D scene comes out of this pass upside down
4051+
// on those renderers, while the UI - drawn straight to the backbuffer - stays the right
4052+
// way up. The cap decides it, so DX11 and Metal pass 0.0 and are unaffected.
40484053
const float postTexelSize[4] = {
40494054
1.0f / texW,
40504055
1.0f / texH,
4051-
0.0f,
4056+
bgfx::getCaps()->originBottomLeft ? 1.0f : 0.0f,
40524057
0.0f
40534058
};
40544059
if (bgfx::isValid(g_uniforms.uPostParams))

Core/Libraries/Source/WWVegas/WW3D2/shaders/vs_scene_composite.sc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,21 @@ $output v_texcoord0
77

88
#include <bgfx_shader.sh>
99

10+
// TheSuperHackers @bugfix githubawn 30/07/2026 u_postTexelSize.z carries a V-flip flag
11+
// (1.0 on bottom-left-origin renderers like GLES and WebGL, 0.0 on DX11 and Metal) so the
12+
// scene render target is sampled the right way up. Without it this pass hands back a
13+
// vertically mirrored scene on those renderers - the UI draws straight to the swapchain and
14+
// looks correct, which makes it read as "the game is upside down but the menus are not".
15+
uniform vec4 u_postTexelSize;
16+
1017
void main()
1118
{
1219
gl_Position = vec4(a_position, 1.0);
13-
v_texcoord0 = vec2(a_position.x * 0.5 + 0.5, 0.5 - a_position.y * 0.5);
20+
float u = a_position.x * 0.5 + 0.5;
21+
float v = 0.5 - a_position.y * 0.5;
22+
if (u_postTexelSize.z > 0.5)
23+
{
24+
v = 1.0 - v;
25+
}
26+
v_texcoord0 = vec2(u, v);
1427
}

0 commit comments

Comments
 (0)