feat: post-effects array parameters & add gfx.posteffects.set_array & make shadows opacity depending on clouds opacity

This commit is contained in:
MihailRis
2025-06-14 20:06:05 +03:00
parent 02a91e0b72
commit 436a89b066
14 changed files with 223 additions and 78 deletions
+72 -17
View File
@@ -2,11 +2,14 @@
#include "Shader.hpp"
#include "data/dv_util.hpp"
#include "debug/Logger.hpp"
static debug::Logger logger("post-effect");
PostEffect::Param::Param() : type(Type::FLOAT) {}
PostEffect::Param::Param(Type type, Value defValue)
: type(type), defValue(defValue), value(defValue) {
PostEffect::Param::Param(Type type, Value defValue, bool array)
: type(type), defValue(defValue), value(defValue), array(array) {
}
PostEffect::PostEffect(
@@ -24,21 +27,53 @@ Shader& PostEffect::use() {
if (!param.dirty) {
continue;
}
switch (param.type) {
case Param::Type::FLOAT:
shader->uniform1f(name, std::get<float>(param.value));
break;
case Param::Type::VEC2:
shader->uniform2f(name, std::get<glm::vec2>(param.value));
break;
case Param::Type::VEC3:
shader->uniform3f(name, std::get<glm::vec3>(param.value));
break;
case Param::Type::VEC4:
shader->uniform4f(name, std::get<glm::vec4>(param.value));
break;
default:
assert(false);
if (param.array) {
const auto& found = arrayValues.find(name);
if (found == arrayValues.end()) {
continue;
}
size_t size = found->second.size();
auto ibuffer = reinterpret_cast<const int*>(found->second.data());
auto fbuffer = reinterpret_cast<const float*>(found->second.data());
switch (param.type) {
case Param::Type::INT:
shader->uniform1v(name, size / sizeof(int), ibuffer);
break;
case Param::Type::FLOAT:
shader->uniform1v(name, size / sizeof(float), fbuffer);
break;
case Param::Type::VEC2:
shader->uniform2v(name, size / sizeof(glm::vec2), fbuffer);
break;
case Param::Type::VEC3:
shader->uniform3v(name, size / sizeof(glm::vec3), fbuffer);
break;
case Param::Type::VEC4:
shader->uniform4v(name, size / sizeof(glm::vec4), fbuffer);
break;
default:
assert(false);
}
} else {
switch (param.type) {
case Param::Type::INT:
shader->uniform1i(name, std::get<int>(param.value));
break;
case Param::Type::FLOAT:
shader->uniform1f(name, std::get<float>(param.value));
break;
case Param::Type::VEC2:
shader->uniform2f(name, std::get<glm::vec2>(param.value));
break;
case Param::Type::VEC3:
shader->uniform3f(name, std::get<glm::vec3>(param.value));
break;
case Param::Type::VEC4:
shader->uniform4f(name, std::get<glm::vec4>(param.value));
break;
default:
assert(false);
}
}
param.dirty = false;
}
@@ -67,6 +102,9 @@ void PostEffect::setParam(const std::string& name, const dv::value& value) {
}
auto& param = found->second;
switch (param.type) {
case Param::Type::INT:
param.value = static_cast<int>(value.asInteger());
break;
case Param::Type::FLOAT:
param.value = static_cast<float>(value.asNumber());
break;
@@ -82,3 +120,20 @@ void PostEffect::setParam(const std::string& name, const dv::value& value) {
}
param.dirty = true;
}
void PostEffect::setArray(const std::string& name, std::vector<ubyte>&& values) {
const auto& found = params.find(name);
if (found == params.end()) {
return;
}
auto& param = found->second;
if (!param.array) {
logger.warning() << "set_array is used on non-array effect parameter";
if (!values.empty()) {
setParam(name, values[0]);
}
return;
}
param.dirty = true;
arrayValues[name] = std::move(values);
}
+10 -3
View File
@@ -1,11 +1,13 @@
#pragma once
#include <vector>
#include <memory>
#include <string>
#include <variant>
#include <unordered_map>
#include <glm/glm.hpp>
#include "typedefs.hpp"
#include "data/dv_fwd.hpp"
#include "util/EnumMetadata.hpp"
@@ -14,24 +16,26 @@ class Shader;
class PostEffect {
public:
struct Param {
enum class Type { FLOAT, VEC2, VEC3, VEC4 };
enum class Type { INT, FLOAT, VEC2, VEC3, VEC4 };
VC_ENUM_METADATA(Type)
{"int", Type::INT},
{"float", Type::FLOAT},
{"vec2", Type::VEC2},
{"vec3", Type::VEC3},
{"vec4", Type::VEC4},
VC_ENUM_END
using Value = std::variant<float, glm::vec2, glm::vec3, glm::vec4>;
using Value = std::variant<int, float, glm::vec2, glm::vec3, glm::vec4>;
Type type;
Value defValue;
Value value;
bool array = false;
bool dirty = true;
Param();
Param(Type type, Value defValue);
Param(Type type, Value defValue, bool array);
};
PostEffect(
@@ -49,6 +53,8 @@ public:
void setParam(const std::string& name, const dv::value& value);
void setArray(const std::string& name, std::vector<ubyte>&& values);
bool isAdvanced() const {
return advanced;
}
@@ -60,5 +66,6 @@ private:
bool advanced = false;
std::shared_ptr<Shader> shader;
std::unordered_map<std::string, Param> params;
std::unordered_map<std::string, std::vector<ubyte>> arrayValues;
float intensity = 0.0f;
};
+3 -25
View File
@@ -43,20 +43,6 @@ PostProcessing::PostProcessing(size_t effectSlotsCount)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, 0);
std::uniform_real_distribution<float> randomFloats(0.0, 1.0);
std::default_random_engine generator;
for (unsigned int i = 0; i < 64; ++i)
{
glm::vec3 sample(
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator)
);
sample = glm::normalize(sample);
sample *= randomFloats(generator);
ssaoKernel.push_back(sample);
}
}
PostProcessing::~PostProcessing() = default;
@@ -90,21 +76,13 @@ void PostProcessing::refreshFbos(uint width, uint height) {
void PostProcessing::configureEffect(
const DrawContext& context,
PostEffect& effect,
Shader& shader,
float timer,
const Camera& camera,
uint shadowMap
) {
const auto& viewport = context.getViewport();
bool ssaoConfigured = false;
if (!ssaoConfigured) {
for (unsigned int i = 0; i < 64; ++i) {
auto name = "u_ssaoSamples["+ std::to_string(i) + "]";
shader.uniform3f(name, ssaoKernel[i]);
}
ssaoConfigured = true;
}
shader.uniform1i("u_screen", 0);
if (gbuffer) {
shader.uniform1i("u_position", 1);
@@ -156,7 +134,7 @@ void PostProcessing::render(
if (totalPasses == 0) {
auto& effect = assets.require<PostEffect>("default");
auto& shader = effect.use();
configureEffect(context, shader, timer, camera, shadowMap);
configureEffect(context, effect, shader, timer, camera, shadowMap);
quadMesh->draw();
return;
}
@@ -170,7 +148,7 @@ void PostProcessing::render(
continue;
}
auto& shader = effect->use();
configureEffect(context, shader, timer, camera, shadowMap);
configureEffect(context, *effect, shader, timer, camera, shadowMap);
if (currentPass > 1) {
fbo->getTexture()->bind();
+1 -2
View File
@@ -58,6 +58,7 @@ public:
private:
void configureEffect(
const DrawContext& context,
PostEffect& effect,
Shader& shader,
float timer,
const Camera& camera,
@@ -73,7 +74,5 @@ private:
std::unique_ptr<Mesh<PostProcessingVertex>> quadMesh;
std::vector<std::shared_ptr<PostEffect>> effectSlots;
std::unique_ptr<GBuffer> gbuffer;
std::vector<glm::vec3> ssaoKernel;
uint noiseTexture;
};
+19
View File
@@ -76,6 +76,25 @@ void Shader::uniform4f(const std::string& name, const glm::vec4& xyzw) {
glUniform4f(getUniformLocation(name), xyzw.x, xyzw.y, xyzw.z, xyzw.w);
}
void Shader::uniform1v(const std::string& name, int length, const int* v) {
glUniform1iv(getUniformLocation(name), length, v);
}
void Shader::uniform1v(const std::string& name, int length, const float* v) {
glUniform1fv(getUniformLocation(name), length, v);
}
void Shader::uniform2v(const std::string& name, int length, const float* v) {
glUniform2fv(getUniformLocation(name), length, v);
}
void Shader::uniform3v(const std::string& name, int length, const float* v) {
glUniform3fv(getUniformLocation(name), length, v);
}
void Shader::uniform4v(const std::string& name, int length, const float* v) {
glUniform4fv(getUniformLocation(name), length, v);
}
inline auto shader_deleter = [](GLuint* shader) {
glDeleteShader(*shader);
+6
View File
@@ -32,6 +32,12 @@ public:
void uniform3f(const std::string& name, const glm::vec3& xyz);
void uniform4f(const std::string& name, const glm::vec4& xyzw);
void uniform1v(const std::string& name, int length, const int* v);
void uniform1v(const std::string& name, int length, const float* v);
void uniform2v(const std::string& name, int length, const float* v);
void uniform3v(const std::string& name, int length, const float* v);
void uniform4v(const std::string& name, int length, const float* v);
/// @brief Create shader program using vertex and fragment shaders source.
/// @param vertexFile vertex shader file name
/// @param fragmentFile fragment shader file name