From 7e480e35ece212277f44844c26b5f628b156b514 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Thu, 18 Jul 2024 03:37:11 +0300 Subject: [PATCH] Shadergen: Upload light uniforms --- include/PICA/pica_frag_uniforms.hpp | 5 +++- include/PICA/regs.hpp | 13 +++++++++- src/core/PICA/shader_gen_glsl.cpp | 2 ++ src/core/renderer_gl/renderer_gl.cpp | 38 ++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/PICA/pica_frag_uniforms.hpp b/include/PICA/pica_frag_uniforms.hpp index 0122ae93..09722d61 100644 --- a/include/PICA/pica_frag_uniforms.hpp +++ b/include/PICA/pica_frag_uniforms.hpp @@ -17,11 +17,12 @@ namespace PICA { alignas(16) vec3 position; alignas(16) vec3 spotlightDirection; - float distAttenuationBias; + float distanceAttenuationBias; float distanceAttenuationScale; }; struct FragmentUniforms { + using vec3 = std::array; using vec4 = std::array; static constexpr usize tevStageCount = 6; @@ -33,6 +34,8 @@ namespace PICA { alignas(16) vec4 tevBufferColor; alignas(16) vec4 clipCoords; + // Note: We upload this as a u32 and decode on GPU + u32 globalAmbientLight; // NOTE: THIS MUST BE LAST so that if lighting is disabled we can potentially omit uploading it LightUniform lightUniforms[8]; }; diff --git a/include/PICA/regs.hpp b/include/PICA/regs.hpp index 312ac78b..bd1f823e 100644 --- a/include/PICA/regs.hpp +++ b/include/PICA/regs.hpp @@ -67,9 +67,20 @@ namespace PICA { ColourBufferLoc = 0x11D, FramebufferSize = 0x11E, - // Lighting registers LightingEnable = 0x8F, + Light0Specular0 = 0x140, + Light0Specular1 = 0x141, + Light0Diffuse = 0x142, + Light0Ambient = 0x143, + Light0XY = 0x144, + Light0Z = 0x145, + Light0SpotlightXY = 0x146, + Light0SpotlightZ = 0x147, + Light0AttenuationBias = 0x14A, + Light0AttenuationScale = 0x14B, + + LightGlobalAmbient = 0x1C0, LightNumber = 0x1C2, LightConfig0 = 0x1C3, LightConfig1 = 0x1C4, diff --git a/src/core/PICA/shader_gen_glsl.cpp b/src/core/PICA/shader_gen_glsl.cpp index 9c319780..98a10bca 100644 --- a/src/core/PICA/shader_gen_glsl.cpp +++ b/src/core/PICA/shader_gen_glsl.cpp @@ -23,6 +23,8 @@ static constexpr const char* uniformDefinition = R"( vec4 tevBufferColor; vec4 clipCoords; + // Note: We upload this as a u32 and decode on GPU + uint globalAmbientLight; LightSource lightSources[8]; }; )"; diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 34ed0d22..5f599e9c 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -877,6 +877,44 @@ OpenGL::Program& RendererGL::getSpecializedShader() { // Append lighting uniforms if (fsConfig.lighting.enable) { + uniforms.globalAmbientLight = regs[InternalRegs::LightGlobalAmbient]; + for (int i = 0; i < 8; i++) { + auto& light = uniforms.lightUniforms[i]; + const u32 specular0 = regs[InternalRegs::Light0Specular0 + i * 0x10]; + const u32 specular1 = regs[InternalRegs::Light0Specular1 + i * 0x10]; + const u32 diffuse = regs[InternalRegs::Light0Diffuse + i * 0x10]; + const u32 ambient = regs[InternalRegs::Light0Ambient + i * 0x10]; + const u32 lightXY = regs[InternalRegs::Light0XY + i * 0x10]; + const u32 lightZ = regs[InternalRegs::Light0Z + i * 0x10]; + + const u32 spotlightXY = regs[InternalRegs::Light0SpotlightXY + i * 0x10]; + const u32 spotlightZ = regs[InternalRegs::Light0SpotlightZ + i * 0x10]; + const u32 attenuationBias = regs[InternalRegs::Light0AttenuationBias + i * 0x10]; + const u32 attenuationScale = regs[InternalRegs::Light0AttenuationScale + i * 0x10]; + +#define lightColorToVec3(value) \ + { \ + float(Helpers::getBits<20, 8>(value)) / 255.0f, \ + float(Helpers::getBits<10, 8>(value)) / 255.0f, \ + float(Helpers::getBits<0, 8>(value)) / 255.0f, \ + } + light.specular0 = lightColorToVec3(specular0); + light.specular1 = lightColorToVec3(specular1); + light.diffuse = lightColorToVec3(diffuse); + light.ambient = lightColorToVec3(ambient); + light.position[0] = Floats::f16::fromRaw(u16(lightXY)).toFloat32(); + light.position[1] = Floats::f16::fromRaw(u16(lightXY >> 16)).toFloat32(); + light.position[2] = Floats::f16::fromRaw(u16(lightXY)).toFloat32(); + + // Fixed point 1.11.1 to float, without negation + light.spotlightDirection[0] = float(s32(spotlightXY & 0x1FFF) << 19 >> 19) / 2047.0; + light.spotlightDirection[1] = float(s32((spotlightXY >> 16) & 0x1FFF) << 19 >> 19) / 2047.0; + light.spotlightDirection[2] = float(s32(spotlightZ & 0x1FFF) << 19 >> 19) / 2047.0; + + light.distanceAttenuationBias = Floats::f20::fromRaw(attenuationBias & 0xFFFFF).toFloat32(); + light.distanceAttenuationScale = Floats::f20::fromRaw(attenuationScale & 0xFFFFF).toFloat32(); +#undef lightColorToVec3 + } } gl.bindUBO(programEntry.uboBinding);