Shadergen: More lighting work

This commit is contained in:
wheremyfoodat 2024-07-18 02:57:41 +03:00
parent ed00ddc805
commit ccf9693877
4 changed files with 57 additions and 5 deletions

View file

@ -1,12 +1,27 @@
#pragma once #pragma once
#include <array> #include <array>
#include <cstddef>
#include <type_traits> #include <type_traits>
#include "helpers.hpp" #include "helpers.hpp"
namespace PICA { namespace PICA {
struct FragmentUniforms { struct LightUniform {
using vec3 = std::array<float, 3>; using vec3 = std::array<float, 3>;
// 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<float, 4>; using vec4 = std::array<float, 4>;
static constexpr usize tevStageCount = 6; static constexpr usize tevStageCount = 6;
@ -17,5 +32,11 @@ namespace PICA {
alignas(16) vec4 constantColors[tevStageCount]; alignas(16) vec4 constantColors[tevStageCount];
alignas(16) vec4 tevBufferColor; alignas(16) vec4 tevBufferColor;
alignas(16) vec4 clipCoords; 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 } // namespace PICA

View file

@ -26,6 +26,7 @@ namespace PICA::ShaderGen {
void getAlphaOperation(std::string& shader, PICA::TexEnvConfig::Operation op); void getAlphaOperation(std::string& shader, PICA::TexEnvConfig::Operation op);
void applyAlphaTest(std::string& shader, const PICARegs& regs); void applyAlphaTest(std::string& shader, const PICARegs& regs);
void compileLights(std::string& shader, const PICA::FragmentConfig& config);
u32 textureConfig = 0; u32 textureConfig = 0;

View file

@ -3,6 +3,17 @@ using namespace PICA;
using namespace PICA::ShaderGen; using namespace PICA::ShaderGen;
static constexpr const char* uniformDefinition = R"( 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 { layout(std140) uniform FragmentUniforms {
int alphaReference; int alphaReference;
float depthScale; float depthScale;
@ -11,6 +22,8 @@ static constexpr const char* uniformDefinition = R"(
vec4 constantColors[6]; vec4 constantColors[6];
vec4 tevBufferColor; vec4 tevBufferColor;
vec4 clipCoords; vec4 clipCoords;
LightSource lightSources[8];
}; };
)"; )";
@ -128,7 +141,7 @@ std::string FragmentGenerator::generate(const PICARegs& regs, const FragmentConf
uniform sampler2D u_tex2; uniform sampler2D u_tex2;
// GLES doesn't support sampler1DArray, as such we'll have to change how we handle lighting later // GLES doesn't support sampler1DArray, as such we'll have to change how we handle lighting later
#ifndef USING_GLES #ifndef USING_GLES
uniform sampler1DArray u_tex_lighting_lut; uniform sampler2D u_tex_lighting_lut;
#endif #endif
)"; )";
@ -140,9 +153,14 @@ std::string FragmentGenerator::generate(const PICARegs& regs, const FragmentConf
void main() { void main() {
vec4 combinerOutput = v_colour; vec4 combinerOutput = v_colour;
vec4 previousBuffer = vec4(0.0); 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"( ret += R"(
vec3 colorOp1 = vec3(0.0); vec3 colorOp1 = vec3(0.0);
vec3 colorOp2 = 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; case TexEnvConfig::Source::PreviousBuffer: shader += "previousBuffer"; break;
// Lighting // Lighting
case TexEnvConfig::Source::PrimaryFragmentColor: case TexEnvConfig::Source::PrimaryFragmentColor: shader += "primaryColor"; break;
case TexEnvConfig::Source::SecondaryFragmentColor: shader += "vec4(1.0, 1.0, 1.0, 1.0)"; break; case TexEnvConfig::Source::SecondaryFragmentColor: shader += "secondaryColor"; break;
default: default:
Helpers::warn("Unimplemented TEV source: %d", static_cast<int>(source)); Helpers::warn("Unimplemented TEV source: %d", static_cast<int>(source));
@ -430,3 +448,11 @@ void FragmentGenerator::applyAlphaTest(std::string& shader, const PICARegs& regs
shader += ") { discard; }\n"; shader += ") { discard; }\n";
} }
void FragmentGenerator::compileLights(std::string& shader, const PICA::FragmentConfig& config) {
if (!config.lighting.enable) {
return;
}
}

View file

@ -875,6 +875,10 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
vec[3] = float((color >> 24) & 0xFF) / 255.0f; vec[3] = float((color >> 24) & 0xFF) / 255.0f;
} }
// Append lighting uniforms
if (fsConfig.lighting.enable) {
}
gl.bindUBO(programEntry.uboBinding); gl.bindUBO(programEntry.uboBinding);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PICA::FragmentUniforms), &uniforms); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PICA::FragmentUniforms), &uniforms);