feat: post-effects array parameters & add gfx.posteffects.set_array & make shadows opacity depending on clouds opacity
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user