From ccf9693877a649ccb9c2b891b37b36b54d04ffbb Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Thu, 18 Jul 2024 02:57:41 +0300 Subject: [PATCH] Shadergen: More lighting work --- include/PICA/pica_frag_uniforms.hpp | 23 ++++++++++++++++++- include/PICA/shader_gen.hpp | 1 + src/core/PICA/shader_gen_glsl.cpp | 34 ++++++++++++++++++++++++---- src/core/renderer_gl/renderer_gl.cpp | 4 ++++ 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/include/PICA/pica_frag_uniforms.hpp b/include/PICA/pica_frag_uniforms.hpp index 332acd4e..0122ae93 100644 --- a/include/PICA/pica_frag_uniforms.hpp +++ b/include/PICA/pica_frag_uniforms.hpp @@ -1,12 +1,27 @@ #pragma once #include +#include #include #include "helpers.hpp" namespace PICA { - struct FragmentUniforms { + struct LightUniform { using vec3 = std::array; + + // std140 requires vec3s be aligned to 16 bytes + alignas(16) vec3 specular0; + alignas(16) vec3 specular1; + alignas(16) vec3 diffuse; + alignas(16) vec3 ambient; + alignas(16) vec3 position; + alignas(16) vec3 spotlightDirection; + + float distAttenuationBias; + float distanceAttenuationScale; + }; + + struct FragmentUniforms { using vec4 = std::array; static constexpr usize tevStageCount = 6; @@ -17,5 +32,11 @@ namespace PICA { alignas(16) vec4 constantColors[tevStageCount]; alignas(16) vec4 tevBufferColor; alignas(16) vec4 clipCoords; + + // NOTE: THIS MUST BE LAST so that if lighting is disabled we can potentially omit uploading it + LightUniform lightUniforms[8]; }; + + // Assert that lightUniforms is the last member of the structure + static_assert(offsetof(FragmentUniforms, lightUniforms) + 8 * sizeof(LightUniform) == sizeof(FragmentUniforms)); } // namespace PICA \ No newline at end of file diff --git a/include/PICA/shader_gen.hpp b/include/PICA/shader_gen.hpp index 0a6bca8e..21d85d98 100644 --- a/include/PICA/shader_gen.hpp +++ b/include/PICA/shader_gen.hpp @@ -26,6 +26,7 @@ namespace PICA::ShaderGen { void getAlphaOperation(std::string& shader, PICA::TexEnvConfig::Operation op); void applyAlphaTest(std::string& shader, const PICARegs& regs); + void compileLights(std::string& shader, const PICA::FragmentConfig& config); u32 textureConfig = 0; diff --git a/src/core/PICA/shader_gen_glsl.cpp b/src/core/PICA/shader_gen_glsl.cpp index 5dbc3b81..9c319780 100644 --- a/src/core/PICA/shader_gen_glsl.cpp +++ b/src/core/PICA/shader_gen_glsl.cpp @@ -3,6 +3,17 @@ using namespace PICA; using namespace PICA::ShaderGen; static constexpr const char* uniformDefinition = R"( + struct LightSource { + vec3 specular0; + vec3 specular1; + vec3 diffuse; + vec3 ambient; + vec3 position; + vec3 spotlightDirection; + float distanceAttenuationBias; + float distanceAttenuationScale; + }; + layout(std140) uniform FragmentUniforms { int alphaReference; float depthScale; @@ -11,6 +22,8 @@ static constexpr const char* uniformDefinition = R"( vec4 constantColors[6]; vec4 tevBufferColor; vec4 clipCoords; + + LightSource lightSources[8]; }; )"; @@ -128,7 +141,7 @@ std::string FragmentGenerator::generate(const PICARegs& regs, const FragmentConf uniform sampler2D u_tex2; // GLES doesn't support sampler1DArray, as such we'll have to change how we handle lighting later #ifndef USING_GLES - uniform sampler1DArray u_tex_lighting_lut; + uniform sampler2D u_tex_lighting_lut; #endif )"; @@ -140,9 +153,14 @@ std::string FragmentGenerator::generate(const PICARegs& regs, const FragmentConf void main() { vec4 combinerOutput = v_colour; vec4 previousBuffer = vec4(0.0); - vec4 tevNextPreviousBuffer = tevBufferColor; + vec4 tevNextPreviousBuffer = tevBufferColor; + + vec4 primaryColor = vec4(0.0); + vec4 secondaryColor = vec4(0.0); )"; + compileLights(ret, config); + ret += R"( vec3 colorOp1 = vec3(0.0); vec3 colorOp2 = vec3(0.0); @@ -353,8 +371,8 @@ void FragmentGenerator::getSource(std::string& shader, TexEnvConfig::Source sour case TexEnvConfig::Source::PreviousBuffer: shader += "previousBuffer"; break; // Lighting - case TexEnvConfig::Source::PrimaryFragmentColor: - case TexEnvConfig::Source::SecondaryFragmentColor: shader += "vec4(1.0, 1.0, 1.0, 1.0)"; break; + case TexEnvConfig::Source::PrimaryFragmentColor: shader += "primaryColor"; break; + case TexEnvConfig::Source::SecondaryFragmentColor: shader += "secondaryColor"; break; default: Helpers::warn("Unimplemented TEV source: %d", static_cast(source)); @@ -430,3 +448,11 @@ void FragmentGenerator::applyAlphaTest(std::string& shader, const PICARegs& regs shader += ") { discard; }\n"; } + +void FragmentGenerator::compileLights(std::string& shader, const PICA::FragmentConfig& config) { + if (!config.lighting.enable) { + return; + } + + +} \ No newline at end of file diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index b85e7689..34ed0d22 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -875,6 +875,10 @@ OpenGL::Program& RendererGL::getSpecializedShader() { vec[3] = float((color >> 24) & 0xFF) / 255.0f; } + // Append lighting uniforms + if (fsConfig.lighting.enable) { + } + gl.bindUBO(programEntry.uboBinding); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PICA::FragmentUniforms), &uniforms);