fix render advanced pipeline issues

This commit is contained in:
MihailRis
2025-07-12 17:31:55 +03:00
parent 0ab23a117d
commit ac9772cd67
12 changed files with 192 additions and 86 deletions
+8 -4
View File
@@ -24,15 +24,19 @@ uniform vec3 u_sunDir;
void main() { void main() {
float shadow = calc_shadow(a_modelpos, a_realnormal, a_distance); float shadow = calc_shadow(a_modelpos, a_realnormal, a_distance);
vec3 fogColor = texture(u_skybox, a_dir).rgb; vec4 texColor = texture(u_texture0, a_texCoord);
vec4 tex_color = texture(u_texture0, a_texCoord); float alpha = a_color.a * texColor.a;
float alpha = a_color.a * tex_color.a;
// anyway it's any alpha-test alternative required // anyway it's any alpha-test alternative required
if (alpha < (u_alphaClip ? 0.5f : 0.15f)) { if (alpha < (u_alphaClip ? 0.5f : 0.15f)) {
discard; discard;
} }
f_color = a_color * tex_color * shadow; f_color = a_color * texColor * shadow;
#ifndef ADVANCED_RENDER
vec3 fogColor = texture(u_skybox, a_dir).rgb;
f_color = mix(f_color, vec4(fogColor, 1.0), a_fog); f_color = mix(f_color, vec4(fogColor, 1.0), a_fog);
#endif
f_color.a = alpha; f_color.a = alpha;
f_position = vec4(a_position, 1.0); f_position = vec4(a_position, 1.0);
f_normal = vec4(a_normal, 1.0); f_normal = vec4(a_normal, 1.0);
+6 -2
View File
@@ -25,7 +25,6 @@ uniform bool u_debugNormals;
#include <shadows> #include <shadows>
void main() { void main() {
//vec3 fogColor = texture(u_skybox, a_dir).rgb;
vec4 texColor = texture(u_texture0, a_texCoord); vec4 texColor = texture(u_texture0, a_texCoord);
float alpha = texColor.a; float alpha = texColor.a;
if (u_alphaClip) { if (u_alphaClip) {
@@ -43,7 +42,12 @@ void main() {
} }
f_color = texColor; f_color = texColor;
f_color.rgb *= min(vec3(1.0), a_torchLight.rgb + a_skyLight); f_color.rgb *= min(vec3(1.0), a_torchLight.rgb + a_skyLight);
//f_color = mix(f_color, vec4(fogColor, 1.0), a_fog * 0.0);
#ifndef ADVANCED_RENDER
vec3 fogColor = texture(u_skybox, a_dir).rgb;
f_color = mix(f_color, vec4(fogColor, 1.0), a_fog);
#endif
f_color.a = alpha; f_color.a = alpha;
f_position = vec4(a_position, 1.0); f_position = vec4(a_position, 1.0);
f_normal = vec4(a_normal, 1.0); f_normal = vec4(a_normal, 1.0);
-1
View File
@@ -158,7 +158,6 @@ public:
} }
bool processVersionDirective() { bool processVersionDirective() {
parsing_warning(filename, line, "removed #version directive");
source_line(ss, line); source_line(ss, line);
skipLine(); skipLine();
return false; return false;
+4
View File
@@ -96,3 +96,7 @@ uint Framebuffer::getWidth() const {
uint Framebuffer::getHeight() const { uint Framebuffer::getHeight() const {
return height; return height;
} }
uint Framebuffer::getFBO() const {
return fbo;
}
+2
View File
@@ -37,4 +37,6 @@ public:
uint getWidth() const; uint getWidth() const;
/// @brief Get framebuffer height /// @brief Get framebuffer height
uint getHeight() const; uint getHeight() const;
uint getFBO() const;
}; };
+2 -2
View File
@@ -181,9 +181,9 @@ void GBuffer::bindSSAOBuffer() const {
glBindTexture(GL_TEXTURE_2D, ssaoBuffer); glBindTexture(GL_TEXTURE_2D, ssaoBuffer);
} }
void GBuffer::bindDepthBuffer() { void GBuffer::bindDepthBuffer(int drawFbo) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL_DEPTH_BUFFER_BIT, GL_NEAREST); GL_DEPTH_BUFFER_BIT, GL_NEAREST);
} }
+1 -1
View File
@@ -16,7 +16,7 @@ public:
void bindBuffers() const; void bindBuffers() const;
void bindSSAOBuffer() const; void bindSSAOBuffer() const;
void bindDepthBuffer(); void bindDepthBuffer(int drawFbo);
void resize(uint width, uint height); void resize(uint width, uint height);
+78 -46
View File
@@ -77,7 +77,9 @@ void PostProcessing::refreshFbos(uint width, uint height) {
} }
void PostProcessing::bindDepthBuffer() { void PostProcessing::bindDepthBuffer() {
gbuffer->bindDepthBuffer(); if (gbuffer) {
gbuffer->bindDepthBuffer(fbo->getFBO());
}
} }
void PostProcessing::configureEffect( void PostProcessing::configureEffect(
@@ -118,7 +120,7 @@ void PostProcessing::configureEffect(
shader.uniformMatrix("u_inverseView", glm::inverse(camera.getView())); shader.uniformMatrix("u_inverseView", glm::inverse(camera.getView()));
} }
void PostProcessing::render( void PostProcessing::renderDeferredShading(
const DrawContext& context, const DrawContext& context,
const Assets& assets, const Assets& assets,
float timer, float timer,
@@ -129,18 +131,9 @@ void PostProcessing::render(
const glm::mat4& shadowMatrix2, const glm::mat4& shadowMatrix2,
uint shadowMapResolution uint shadowMapResolution
) { ) {
if (fbo == nullptr && gbuffer == nullptr) { if (gbuffer == nullptr) {
throw std::runtime_error("'use(...)' was never called"); throw std::runtime_error("gbuffer is not initialized");
} }
int totalPasses = 0;
for (const auto& effect : effectSlots) {
totalPasses +=
(effect != nullptr && effect->isActive() &&
!(effect->isAdvanced() && gbuffer == nullptr));
}
const auto& vp = context.getViewport();
refreshFbos(vp.x, vp.y);
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0); glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0);
glBindTexture(GL_TEXTURE_2D, shadowMap); glBindTexture(GL_TEXTURE_2D, shadowMap);
@@ -149,43 +142,47 @@ void PostProcessing::render(
glBindTexture(GL_TEXTURE_2D, shadowMap2); glBindTexture(GL_TEXTURE_2D, shadowMap2);
// Generating ssao // Generating ssao
if (gbuffer) { gbuffer->bindBuffers();
gbuffer->bindBuffers();
glActiveTexture(GL_TEXTURE0 + TARGET_SSAO); glActiveTexture(GL_TEXTURE0 + TARGET_SSAO);
glBindTexture(GL_TEXTURE_2D, noiseTexture); glBindTexture(GL_TEXTURE_2D, noiseTexture);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
auto& ssaoEffect = assets.require<PostEffect>("ssao"); auto& ssaoEffect = assets.require<PostEffect>("ssao");
auto& shader = ssaoEffect.use(); auto& shader = ssaoEffect.use();
configureEffect( configureEffect(
context, context,
ssaoEffect, ssaoEffect,
shader, shader,
timer, timer,
camera, camera,
shadowMap, shadowMap,
shadowMap2, shadowMap2,
shadowMatrix, shadowMatrix,
shadowMatrix2, shadowMatrix2,
shadowMapResolution shadowMapResolution
); );
gbuffer->bindSSAO(); gbuffer->bindSSAO();
quadMesh->draw(); quadMesh->draw();
gbuffer->unbind(); gbuffer->unbind();
{
auto viewport = context.getViewport();
refreshFbos(viewport.x, viewport.y);
auto ctx = context.sub();
ctx.setFramebuffer(fbo.get());
glActiveTexture(GL_TEXTURE0 + TARGET_SSAO); glActiveTexture(GL_TEXTURE0 + TARGET_SSAO);
gbuffer->bindSSAOBuffer(); gbuffer->bindSSAOBuffer();
} else {
glActiveTexture(GL_TEXTURE0);
fbo->getTexture()->bind();
}
if (totalPasses == 0) { glActiveTexture(GL_TEXTURE0);
auto& effect = assets.require<PostEffect>(
gbuffer ? "deferred_lighting" : "default" gbuffer->bindBuffers();
);
// TODO: move upper & move skybox->draw(...) here
auto& effect = assets.require<PostEffect>("deferred_lighting");
auto& shader = effect.use(); auto& shader = effect.use();
configureEffect( configureEffect(
context, context,
@@ -200,6 +197,44 @@ void PostProcessing::render(
shadowMapResolution shadowMapResolution
); );
quadMesh->draw(); quadMesh->draw();
}
}
void PostProcessing::render(
const DrawContext& context,
const Assets& assets,
float timer,
const Camera& camera,
uint shadowMap,
uint shadowMap2,
const glm::mat4& shadowMatrix,
const glm::mat4& shadowMatrix2,
uint shadowMapResolution
) {
if (fbo == nullptr) {
throw std::runtime_error("'use(...)' was never called");
}
int totalPasses = 0;
for (const auto& effect : effectSlots) {
totalPasses +=
(effect != nullptr && effect->isActive() &&
!(effect->isAdvanced() && gbuffer == nullptr));
}
const auto& vp = context.getViewport();
refreshFbos(vp.x, vp.y);
glActiveTexture(GL_TEXTURE0);
fbo->getTexture()->bind();
if (totalPasses == 0) {
// TODO: move upper & move skybox->draw(...) here
auto& effect = assets.require<PostEffect>("default");
auto& shader = effect.use();
configureEffect(
context, effect, shader, timer, camera, 0, 0, {}, {}, 0
);
quadMesh->draw();
return; return;
} }
@@ -251,9 +286,6 @@ PostEffect* PostProcessing::getEffect(size_t slot) {
} }
std::unique_ptr<ImageData> PostProcessing::toImage() { std::unique_ptr<ImageData> PostProcessing::toImage() {
if (gbuffer) {
return gbuffer->toImage();
}
return fbo->getTexture()->readData(); return fbo->getTexture()->readData();
} }
+12
View File
@@ -35,6 +35,18 @@ public:
/// @param context graphics context will be modified /// @param context graphics context will be modified
void use(DrawContext& context, bool gbufferPipeline); void use(DrawContext& context, bool gbufferPipeline);
void renderDeferredShading(
const DrawContext& context,
const Assets& assets,
float timer,
const Camera& camera,
uint shadowMap,
uint shadowMap2,
const glm::mat4& shadowMatrix,
const glm::mat4& shadowMatrix2,
uint shadowMapResolution
);
/// @brief Render fullscreen quad using the passed shader /// @brief Render fullscreen quad using the passed shader
/// with framebuffer texture bound /// with framebuffer texture bound
/// @param context graphics context /// @param context graphics context
+71 -30
View File
@@ -38,6 +38,7 @@
#include "graphics/core/LineBatch.hpp" #include "graphics/core/LineBatch.hpp"
#include "graphics/core/Mesh.hpp" #include "graphics/core/Mesh.hpp"
#include "graphics/core/PostProcessing.hpp" #include "graphics/core/PostProcessing.hpp"
#include "graphics/core/Framebuffer.hpp"
#include "graphics/core/Shader.hpp" #include "graphics/core/Shader.hpp"
#include "graphics/core/Texture.hpp" #include "graphics/core/Texture.hpp"
#include "graphics/core/Font.hpp" #include "graphics/core/Font.hpp"
@@ -137,6 +138,7 @@ void WorldRenderer::setupWorldShader(
if (shadows) { if (shadows) {
const auto& worldInfo = level.getWorld()->getInfo(); const auto& worldInfo = level.getWorld()->getInfo();
float cloudsIntensity = glm::max(worldInfo.fog, weather.clouds()); float cloudsIntensity = glm::max(worldInfo.fog, weather.clouds());
shader.uniform1i("u_screen", 0);
shader.uniformMatrix("u_shadowsMatrix[0]", shadowCamera.getProjView()); shader.uniformMatrix("u_shadowsMatrix[0]", shadowCamera.getProjView());
shader.uniformMatrix("u_shadowsMatrix[1]", wideShadowCamera.getProjView()); shader.uniformMatrix("u_shadowsMatrix[1]", wideShadowCamera.getProjView());
shader.uniform3f("u_sunDir", shadowCamera.front); shader.uniform3f("u_sunDir", shadowCamera.front);
@@ -223,22 +225,6 @@ void WorldRenderer::renderLevel(
if (!pause) { if (!pause) {
scripting::on_frontend_render(); scripting::on_frontend_render();
} }
setupWorldShader(entityShader, camera, settings, fogFactor);
std::array<const WeatherPreset*, 2> weatherInstances {&weather.a, &weather.b};
for (const auto& weather : weatherInstances) {
float maxIntensity = weather->fall.maxIntensity;
float zero = weather->fall.minOpacity;
float one = weather->fall.maxOpacity;
float t = (weather->intensity * (one - zero)) * maxIntensity + zero;
entityShader.uniform1i("u_alphaClip", weather->fall.opaque);
entityShader.uniform1f("u_opacity", weather->fall.opaque ? t * t : t);
if (weather->intensity > 1.e-3f && !weather->fall.texture.empty()) {
precipitation->render(camera, pause ? 0.0f : delta, *weather);
}
}
skybox->unbind(); skybox->unbind();
} }
@@ -430,6 +416,7 @@ void WorldRenderer::draw(
float uiDelta, float uiDelta,
PostProcessing& postProcessing PostProcessing& postProcessing
) { ) {
// TODO: REFACTOR WHOLE RENDER ENGINE
float delta = uiDelta * !pause; float delta = uiDelta * !pause;
timer += delta; timer += delta;
weather.update(delta); weather.update(delta);
@@ -451,19 +438,37 @@ void WorldRenderer::draw(
shadowMap = std::make_unique<ShadowMap>(resolution); shadowMap = std::make_unique<ShadowMap>(resolution);
wideShadowMap = std::make_unique<ShadowMap>(resolution); wideShadowMap = std::make_unique<ShadowMap>(resolution);
shadows = true; shadows = true;
Shader::preprocessor->define("ENABLE_SHADOWS", "true");
mainShader.recompile();
entityShader.recompile();
deferredShader.recompile();
} else if (shadowsQuality == 0 && shadows) { } else if (shadowsQuality == 0 && shadows) {
shadowMap.reset(); shadowMap.reset();
wideShadowMap.reset(); wideShadowMap.reset();
shadows = false; shadows = false;
Shader::preprocessor->undefine("ENABLE_SHADOWS"); }
CompileTimeShaderSettings currentSettings {
gbufferPipeline, shadows
};
if (
prevCTShaderSettings.advancedRender != currentSettings.advancedRender ||
prevCTShaderSettings.shadows != currentSettings.shadows
) {
if (shadows) {
Shader::preprocessor->define("ENABLE_SHADOWS", "true");
} else {
Shader::preprocessor->undefine("ENABLE_SHADOWS");
}
if (gbufferPipeline) {
Shader::preprocessor->define("ADVANCED_RENDER", "true");
} else {
Shader::preprocessor->undefine("ADVANCED_RENDER");
}
mainShader.recompile(); mainShader.recompile();
entityShader.recompile(); entityShader.recompile();
deferredShader.recompile(); deferredShader.recompile();
prevCTShaderSettings = currentSettings;
} }
if (shadows && shadowMap->getResolution() != resolution) { if (shadows && shadowMap->getResolution() != resolution) {
shadowMap = std::make_unique<ShadowMap>(resolution); shadowMap = std::make_unique<ShadowMap>(resolution);
wideShadowMap = std::make_unique<ShadowMap>(resolution); wideShadowMap = std::make_unique<ShadowMap>(resolution);
@@ -513,10 +518,52 @@ void WorldRenderer::draw(
texts->render(pctx, camera, settings, hudVisible, true); texts->render(pctx, camera, settings, hudVisible, true);
} }
skybox->bind(); skybox->bind();
deferredShader.use();
float fogFactor = float fogFactor =
15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2); 15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2);
setupWorldShader(deferredShader, camera, settings, fogFactor); if (gbufferPipeline) {
deferredShader.use();
setupWorldShader(deferredShader, camera, settings, fogFactor);
postProcessing.renderDeferredShading(
pctx,
assets,
timer,
camera,
shadows ? shadowMap->getDepthMap() : 0,
shadows ? wideShadowMap->getDepthMap() : 0,
shadowCamera.getProjView(),
wideShadowCamera.getProjView(),
shadows ? shadowMap->getResolution() : 0
);
}
{
DrawContext ctx = pctx.sub();
ctx.setDepthTest(true);
if (gbufferPipeline) {
postProcessing.bindDepthBuffer();
} else {
postProcessing.getFramebuffer()->bind();
}
// Drawing background sky plane
skybox->draw(ctx, camera, assets, worldInfo.daytime, clouds);
entityShader.use();
setupWorldShader(entityShader, camera, settings, fogFactor);
std::array<const WeatherPreset*, 2> weatherInstances {&weather.a, &weather.b};
for (const auto& weather : weatherInstances) {
float maxIntensity = weather->fall.maxIntensity;
float zero = weather->fall.minOpacity;
float one = weather->fall.maxOpacity;
float t = (weather->intensity * (one - zero)) * maxIntensity + zero;
entityShader.uniform1i("u_alphaClip", weather->fall.opaque);
entityShader.uniform1f("u_opacity", weather->fall.opaque ? t * t : t);
if (weather->intensity > 1.e-3f && !weather->fall.texture.empty()) {
precipitation->render(camera, pause ? 0.0f : delta, *weather);
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
postProcessing.render( postProcessing.render(
pctx, pctx,
assets, assets,
@@ -528,13 +575,7 @@ void WorldRenderer::draw(
wideShadowCamera.getProjView(), wideShadowCamera.getProjView(),
shadows ? shadowMap->getResolution() : 0 shadows ? shadowMap->getResolution() : 0
); );
{
DrawContext ctx = pctx.sub();
ctx.setDepthTest(true);
postProcessing.bindDepthBuffer();
// Drawing background sky plane
skybox->draw(ctx, camera, assets, worldInfo.daytime, clouds);
}
skybox->unbind(); skybox->unbind();
if (player.currentCamera == player.fpCamera) { if (player.currentCamera == player.fpCamera) {
DrawContext ctx = pctx.sub(); DrawContext ctx = pctx.sub();
+7
View File
@@ -35,6 +35,11 @@ class ShadowMap;
class GBuffer; class GBuffer;
struct EngineSettings; struct EngineSettings;
struct CompileTimeShaderSettings {
bool advancedRender = false;
bool shadows = false;
};
class WorldRenderer { class WorldRenderer {
Engine& engine; Engine& engine;
const Level& level; const Level& level;
@@ -59,6 +64,8 @@ class WorldRenderer {
bool gbufferPipeline = false; bool gbufferPipeline = false;
bool shadows = false; bool shadows = false;
CompileTimeShaderSettings prevCTShaderSettings {};
/// @brief Render block selection lines /// @brief Render block selection lines
void renderBlockSelection(); void renderBlockSelection();
+1
View File
@@ -519,6 +519,7 @@ public:
} }
std::unique_ptr<ImageData> takeScreenshot() override { std::unique_ptr<ImageData> takeScreenshot() override {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
auto data = std::make_unique<ubyte[]>(size.x * size.y * 3); auto data = std::make_unique<ubyte[]>(size.x * size.y * 3);
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_BYTE, data.get()); glReadPixels(0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_BYTE, data.get());