feat: deferred shading (day 2)
This commit is contained in:
parent
a585b52aa2
commit
0bd901d1a6
@ -3,11 +3,12 @@ layout (location = 0) out vec4 f_color;
|
||||
layout (location = 1) out vec4 f_position;
|
||||
layout (location = 2) out vec4 f_normal;
|
||||
|
||||
uniform mat4 u_view;
|
||||
uniform samplerCube u_skybox;
|
||||
|
||||
void main(){
|
||||
vec3 dir = normalize(v_coord);
|
||||
f_position = vec4(0.0, 0.0, -1e9, 1.0);
|
||||
f_normal = vec4(0.0);
|
||||
vec3 dir = normalize(v_coord) * 1e6;
|
||||
f_position = u_view * vec4(dir, 1.0);
|
||||
f_normal = vec4(0.0, 0.0, 1.0, 1.0);
|
||||
f_color = texture(u_skybox, dir);
|
||||
}
|
||||
|
||||
@ -7,6 +7,6 @@ uniform float u_ar;
|
||||
uniform float u_zoom;
|
||||
|
||||
void main(){
|
||||
v_coord = (vec4(v_position*vec2(u_ar, 1.0f)*u_zoom, -1.0, 1.0) * u_view).xyz;
|
||||
gl_Position = vec4(v_position, 0.0, 1.0);
|
||||
v_coord = (vec4(v_position * vec2(u_ar, 1.0f) * u_zoom, -1.0, 1.0) * u_view).xyz;
|
||||
gl_Position = vec4(v_position, 1.0 - 1e-6, 1.0);
|
||||
}
|
||||
|
||||
@ -6,13 +6,17 @@ uniform sampler2D u_position;
|
||||
uniform sampler2D u_normal;
|
||||
uniform sampler2D u_noise;
|
||||
uniform sampler2D u_ssao;
|
||||
uniform sampler2D u_shadows;
|
||||
uniform samplerCube u_skybox;
|
||||
|
||||
uniform ivec2 u_screenSize;
|
||||
uniform float u_intensity;
|
||||
uniform float u_timer;
|
||||
uniform bool u_enableShadows;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_view;
|
||||
uniform mat4 u_inverseView;
|
||||
uniform vec3 u_sunDir;
|
||||
uniform vec3 u_cameraPos;
|
||||
|
||||
#include <__effect__>
|
||||
|
||||
|
||||
@ -1,15 +1,24 @@
|
||||
#include <shadows>
|
||||
#include <fog>
|
||||
|
||||
vec4 effect() {
|
||||
float ssao = 0.0;
|
||||
float z = texture(u_position, v_uv).z;
|
||||
vec4 pos = texture(u_position, v_uv);
|
||||
float z = pos.z;
|
||||
for (int y = -2; y <= 2; y++) {
|
||||
for (int x = -2; x <= 2; x++) {
|
||||
vec2 offset = vec2(x, y) / u_screenSize;
|
||||
if (abs(z - texture(u_position, v_uv + offset * 2.0).z) > 0.05)
|
||||
ssao += 1.0;
|
||||
else
|
||||
ssao += texture(u_ssao, v_uv + offset * 2.0).r;
|
||||
ssao += texture(u_ssao, v_uv + offset * 2.0).r;
|
||||
}
|
||||
}
|
||||
ssao /= 24.0;
|
||||
return vec4(texture(u_screen, v_uv).rgb * mix(1.0, ssao, 1.0), 1.0);
|
||||
vec4 modelpos = u_inverseView * pos;
|
||||
vec3 normal = transpose(mat3(u_view)) * texture(u_normal, v_uv).xyz;
|
||||
vec3 dir = modelpos.xyz - u_cameraPos;
|
||||
#ifdef ENABLE_SHADOWS
|
||||
ssao *= calc_shadow(modelpos, normal, length(pos));
|
||||
#endif
|
||||
vec3 fogColor = texture(u_skybox, dir).rgb;
|
||||
float fog = calc_fog(length(u_view * vec4((modelpos.xyz - u_cameraPos) * FOG_POS_SCALE, 0.0)) / 256.0);
|
||||
return vec4(mix(texture(u_screen, v_uv).rgb * mix(1.0, ssao, 1.0), fogColor, fog), 1.0);
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ uniform vec3 u_sunDir;
|
||||
#include <shadows>
|
||||
|
||||
void main() {
|
||||
float shadow = calc_shadow();
|
||||
float shadow = calc_shadow(a_modelpos, a_realnormal, a_distance);
|
||||
vec3 fogColor = texture(u_skybox, a_dir).rgb;
|
||||
vec4 tex_color = texture(u_texture0, a_texCoord);
|
||||
float alpha = a_color.a * tex_color.a;
|
||||
|
||||
@ -29,6 +29,7 @@ uniform vec3 u_torchlightColor;
|
||||
uniform float u_torchlightDistance;
|
||||
|
||||
#include <lighting>
|
||||
#include <fog>
|
||||
|
||||
void main() {
|
||||
a_modelpos = u_model * vec4(v_position, 1.0);
|
||||
|
||||
19
res/shaders/lib/fog.glsl
Normal file
19
res/shaders/lib/fog.glsl
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef FOG_GLSL_
|
||||
#define FOG_GLSL_
|
||||
|
||||
uniform float u_fogFactor;
|
||||
uniform float u_fogCurve;
|
||||
uniform float u_weatherFogOpacity;
|
||||
uniform float u_weatherFogDencity;
|
||||
uniform float u_weatherFogCurve;
|
||||
|
||||
float calc_fog(float depth) {
|
||||
return min(
|
||||
1.0,
|
||||
max(pow(depth * u_fogFactor, u_fogCurve),
|
||||
min(pow(depth * u_weatherFogDencity, u_weatherFogCurve),
|
||||
u_weatherFogOpacity))
|
||||
);
|
||||
}
|
||||
|
||||
#endif // FOG_GLSL_
|
||||
@ -1,12 +1,6 @@
|
||||
#ifndef LIGHTING_GLSL_
|
||||
#define LIGHTING_GLSL_
|
||||
|
||||
uniform float u_fogFactor;
|
||||
uniform float u_fogCurve;
|
||||
uniform float u_weatherFogOpacity;
|
||||
uniform float u_weatherFogDencity;
|
||||
uniform float u_weatherFogCurve;
|
||||
|
||||
float calc_torch_light(vec3 normal, vec3 modelpos) {
|
||||
return max(0.0, 1.0 - distance(u_cameraPos, modelpos) / u_torchlightDistance)
|
||||
* max(0.0, -dot(normal, normalize(modelpos - u_cameraPos)));
|
||||
@ -16,13 +10,4 @@ vec3 calc_screen_normal(vec3 normal) {
|
||||
return transpose(inverse(mat3(u_view * u_model))) * normal;
|
||||
}
|
||||
|
||||
float calc_fog(float depth) {
|
||||
return min(
|
||||
1.0,
|
||||
max(pow(depth * u_fogFactor, u_fogCurve),
|
||||
min(pow(depth * u_weatherFogDencity, u_weatherFogCurve),
|
||||
u_weatherFogOpacity))
|
||||
);
|
||||
}
|
||||
|
||||
#endif // LIGHTING_GLSL_
|
||||
|
||||
@ -10,14 +10,14 @@ uniform int u_shadowsRes;
|
||||
uniform float u_shadowsOpacity;
|
||||
uniform float u_shadowsSoftness;
|
||||
|
||||
float calc_shadow() {
|
||||
float calc_shadow(vec4 modelPos, vec3 realnormal, float distance) {
|
||||
#ifdef ENABLE_SHADOWS
|
||||
float step = 1.0 / float(u_shadowsRes);
|
||||
float s = pow(abs(cos(u_dayTime * PI2)), 0.25) * u_shadowsOpacity;
|
||||
vec3 normalOffset = a_realnormal * (a_distance > 64.0 ? 0.2 : 0.04);
|
||||
int shadowIdx = a_distance > 80.0 ? 1 : 0;
|
||||
vec3 normalOffset = realnormal * (distance > 64.0 ? 0.2 : 0.04);
|
||||
int shadowIdx = distance > 80.0 ? 1 : 0;
|
||||
|
||||
vec4 mpos = u_shadowsMatrix[shadowIdx] * vec4(a_modelpos.xyz + normalOffset, 1.0);
|
||||
vec4 mpos = u_shadowsMatrix[shadowIdx] * vec4(modelPos.xyz + normalOffset, 1.0);
|
||||
vec3 projCoords = mpos.xyz / mpos.w;
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
projCoords.z -= 0.00001 / u_shadowsRes;
|
||||
@ -26,7 +26,7 @@ float calc_shadow() {
|
||||
}
|
||||
|
||||
float shadow = 0.0;
|
||||
if (dot(a_realnormal, u_sunDir) < 0.0) {
|
||||
if (dot(realnormal, u_sunDir) < 0.0) {
|
||||
// 3x3 kernel
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
|
||||
@ -25,8 +25,7 @@ uniform bool u_debugNormals;
|
||||
#include <shadows>
|
||||
|
||||
void main() {
|
||||
float shadow = calc_shadow();
|
||||
vec3 fogColor = texture(u_skybox, a_dir).rgb;
|
||||
//vec3 fogColor = texture(u_skybox, a_dir).rgb;
|
||||
vec4 texColor = texture(u_texture0, a_texCoord);
|
||||
float alpha = texColor.a;
|
||||
if (u_alphaClip) {
|
||||
@ -43,8 +42,8 @@ void main() {
|
||||
texColor.rgb *= a_normal * 0.5 + 0.5;
|
||||
}
|
||||
f_color = texColor;
|
||||
f_color.rgb *= min(vec3(1.0), a_torchLight.rgb + a_skyLight * shadow);
|
||||
f_color = mix(f_color, vec4(fogColor, 1.0), a_fog);
|
||||
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);
|
||||
f_color.a = alpha;
|
||||
f_position = vec4(a_position, 1.0);
|
||||
f_normal = vec4(a_normal, 1.0);
|
||||
|
||||
@ -28,6 +28,7 @@ uniform vec3 u_torchlightColor;
|
||||
uniform float u_torchlightDistance;
|
||||
|
||||
#include <lighting>
|
||||
#include <fog>
|
||||
|
||||
void main() {
|
||||
a_modelpos = u_model * vec4(v_position, 1.0f);
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
#include "debug/Logger.hpp"
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
static debug::Logger logger("gl-gbuffer");
|
||||
|
||||
void GBuffer::createColorBuffer() {
|
||||
@ -162,20 +164,30 @@ void GBuffer::unbind() {
|
||||
}
|
||||
|
||||
void GBuffer::bindBuffers() const {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_NORMALS);
|
||||
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_POSITIONS);
|
||||
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_COLOR);
|
||||
glBindTexture(GL_TEXTURE_2D, colorBuffer);
|
||||
|
||||
if (TARGET_COLOR != 0)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void GBuffer::bindSSAOBuffer() const {
|
||||
glBindTexture(GL_TEXTURE_2D, ssaoBuffer);
|
||||
}
|
||||
|
||||
void GBuffer::bindDepthBuffer() {
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||
GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
void GBuffer::resize(uint width, uint height) {
|
||||
if (this->width == width && this->height == height) {
|
||||
return;
|
||||
|
||||
@ -16,6 +16,8 @@ public:
|
||||
void bindBuffers() const;
|
||||
void bindSSAOBuffer() const;
|
||||
|
||||
void bindDepthBuffer();
|
||||
|
||||
void resize(uint width, uint height);
|
||||
|
||||
uint getWidth() const;
|
||||
|
||||
@ -100,6 +100,10 @@ Shader& PostEffect::use() {
|
||||
return *shader;
|
||||
}
|
||||
|
||||
Shader& PostEffect::getShader() {
|
||||
return *shader;
|
||||
}
|
||||
|
||||
float PostEffect::getIntensity() const {
|
||||
return intensity;
|
||||
}
|
||||
|
||||
@ -48,6 +48,8 @@ public:
|
||||
|
||||
Shader& use();
|
||||
|
||||
Shader& getShader();
|
||||
|
||||
float getIntensity() const;
|
||||
void setIntensity(float value);
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
#include <stdexcept>
|
||||
#include <random>
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
PostProcessing::PostProcessing(size_t effectSlotsCount)
|
||||
: effectSlots(effectSlotsCount) {
|
||||
// Fullscreen quad mesh bulding
|
||||
@ -74,28 +76,46 @@ void PostProcessing::refreshFbos(uint width, uint height) {
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessing::bindDepthBuffer() {
|
||||
gbuffer->bindDepthBuffer();
|
||||
}
|
||||
|
||||
void PostProcessing::configureEffect(
|
||||
const DrawContext& context,
|
||||
PostEffect& effect,
|
||||
Shader& shader,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
) {
|
||||
const auto& viewport = context.getViewport();
|
||||
shader.uniform1i("u_screen", 0);
|
||||
shader.uniform1i("u_screen", TARGET_COLOR);
|
||||
shader.uniform1i("u_skybox", TARGET_SKYBOX);
|
||||
if (gbuffer) {
|
||||
shader.uniform1i("u_position", 1);
|
||||
shader.uniform1i("u_normal", 2);
|
||||
shader.uniform1i("u_position", TARGET_POSITIONS);
|
||||
shader.uniform1i("u_normal", TARGET_NORMALS);
|
||||
}
|
||||
shader.uniform1i("u_noise", 3); // used in SSAO pass
|
||||
shader.uniform1i("u_ssao", 3);
|
||||
shader.uniform1i("u_noise", TARGET_SSAO); // used in SSAO pass
|
||||
shader.uniform1i("u_ssao", TARGET_SSAO);
|
||||
|
||||
shader.uniform1i("u_shadows", 4);
|
||||
shader.uniform1i("u_shadows[0]", TARGET_SHADOWS0);
|
||||
shader.uniform1i("u_shadows[1]", TARGET_SHADOWS1);
|
||||
shader.uniformMatrix("u_shadowsMatrix[0]", shadowMatrix);
|
||||
shader.uniformMatrix("u_shadowsMatrix[1]", shadowMatrix2);
|
||||
shader.uniform1f("u_shadowsOpacity", 1.0f);
|
||||
shader.uniform1f("u_shadowsSoftness", 1.0f);
|
||||
shader.uniform1i("u_shadowsRes", shadowMapResolution);
|
||||
shader.uniform2i("u_screenSize", viewport);
|
||||
shader.uniform3f("u_cameraPos", camera.position);
|
||||
shader.uniform1f("u_timer", timer);
|
||||
shader.uniform1i("u_enableShadows", shadowMap != 0);
|
||||
shader.uniformMatrix("u_projection", camera.getProjection());
|
||||
shader.uniformMatrix("u_view", camera.getView());
|
||||
shader.uniformMatrix("u_inverseView", glm::inverse(camera.getView()));
|
||||
}
|
||||
|
||||
void PostProcessing::render(
|
||||
@ -103,7 +123,11 @@ void PostProcessing::render(
|
||||
const Assets& assets,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
) {
|
||||
if (fbo == nullptr && gbuffer == nullptr) {
|
||||
throw std::runtime_error("'use(...)' was never called");
|
||||
@ -118,25 +142,40 @@ void PostProcessing::render(
|
||||
const auto& vp = context.getViewport();
|
||||
refreshFbos(vp.x, vp.y);
|
||||
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMap);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS1);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMap2);
|
||||
|
||||
// Generating ssao
|
||||
if (gbuffer) {
|
||||
gbuffer->bindBuffers();
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SSAO);
|
||||
glBindTexture(GL_TEXTURE_2D, noiseTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
auto& ssaoEffect = assets.require<PostEffect>("ssao");
|
||||
auto& shader = ssaoEffect.use();
|
||||
configureEffect(context, ssaoEffect, shader, timer, camera, shadowMap);
|
||||
configureEffect(
|
||||
context,
|
||||
ssaoEffect,
|
||||
shader,
|
||||
timer,
|
||||
camera,
|
||||
shadowMap,
|
||||
shadowMap2,
|
||||
shadowMatrix,
|
||||
shadowMatrix2,
|
||||
shadowMapResolution
|
||||
);
|
||||
gbuffer->bindSSAO();
|
||||
quadMesh->draw();
|
||||
gbuffer->unbind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SSAO);
|
||||
gbuffer->bindSSAOBuffer();
|
||||
} else {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@ -148,7 +187,18 @@ void PostProcessing::render(
|
||||
gbuffer ? "deferred_lighting" : "default"
|
||||
);
|
||||
auto& shader = effect.use();
|
||||
configureEffect(context, effect, shader, timer, camera, shadowMap);
|
||||
configureEffect(
|
||||
context,
|
||||
effect,
|
||||
shader,
|
||||
timer,
|
||||
camera,
|
||||
shadowMap,
|
||||
shadowMap2,
|
||||
shadowMatrix,
|
||||
shadowMatrix2,
|
||||
shadowMapResolution
|
||||
);
|
||||
quadMesh->draw();
|
||||
return;
|
||||
}
|
||||
@ -162,7 +212,18 @@ void PostProcessing::render(
|
||||
continue;
|
||||
}
|
||||
auto& shader = effect->use();
|
||||
configureEffect(context, *effect, shader, timer, camera, shadowMap);
|
||||
configureEffect(
|
||||
context,
|
||||
*effect,
|
||||
shader,
|
||||
timer,
|
||||
camera,
|
||||
shadowMap,
|
||||
shadowMap2,
|
||||
shadowMatrix,
|
||||
shadowMatrix2,
|
||||
shadowMapResolution
|
||||
);
|
||||
|
||||
if (currentPass > 1) {
|
||||
fbo->getTexture()->bind();
|
||||
|
||||
@ -44,7 +44,11 @@ public:
|
||||
const Assets& assets,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
);
|
||||
|
||||
void setEffect(size_t slot, std::shared_ptr<PostEffect> effect);
|
||||
@ -55,6 +59,7 @@ public:
|
||||
std::unique_ptr<ImageData> toImage();
|
||||
|
||||
Framebuffer* getFramebuffer() const;
|
||||
void bindDepthBuffer();
|
||||
private:
|
||||
void configureEffect(
|
||||
const DrawContext& context,
|
||||
@ -62,7 +67,11 @@ private:
|
||||
Shader& shader,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
);
|
||||
|
||||
void refreshFbos(uint width, uint height);
|
||||
|
||||
@ -51,6 +51,12 @@ void Shader::uniformMatrix(const std::string& name, const glm::mat4& matrix) {
|
||||
);
|
||||
}
|
||||
|
||||
void Shader::uniformMatrix(const std::string& name, const glm::mat3& matrix) {
|
||||
glUniformMatrix3fv(
|
||||
getUniformLocation(name), 1, GL_FALSE, glm::value_ptr(matrix)
|
||||
);
|
||||
}
|
||||
|
||||
void Shader::uniform1i(const std::string& name, int x){
|
||||
glUniform1i(getUniformLocation(name), x);
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ public:
|
||||
|
||||
void use();
|
||||
void uniformMatrix(const std::string&, const glm::mat4& matrix);
|
||||
void uniformMatrix(const std::string&, const glm::mat3& matrix);
|
||||
void uniform1i(const std::string& name, int x);
|
||||
void uniform1f(const std::string& name, float x);
|
||||
void uniform2f(const std::string& name, float x, float y);
|
||||
|
||||
@ -50,6 +50,16 @@ enum class CursorShape {
|
||||
LAST=NOT_ALLOWED
|
||||
};
|
||||
|
||||
namespace advanced_pipeline {
|
||||
inline constexpr int TARGET_COLOR = 0;
|
||||
inline constexpr int TARGET_SKYBOX = 1;
|
||||
inline constexpr int TARGET_POSITIONS = 2;
|
||||
inline constexpr int TARGET_NORMALS = 3;
|
||||
inline constexpr int TARGET_SSAO = 4;
|
||||
inline constexpr int TARGET_SHADOWS0 = 5;
|
||||
inline constexpr int TARGET_SHADOWS1 = 6;
|
||||
}
|
||||
|
||||
VC_ENUM_METADATA(CursorShape)
|
||||
{"arrow", CursorShape::ARROW},
|
||||
{"text", CursorShape::TEXT},
|
||||
|
||||
@ -18,9 +18,7 @@
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/constants.hpp>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141592
|
||||
#endif // M_PI
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
const int STARS_COUNT = 3000;
|
||||
const int STARS_SEED = 632;
|
||||
@ -47,14 +45,6 @@ Skybox::Skybox(uint size, Shader& shader)
|
||||
|
||||
mesh = std::make_unique<Mesh<SkyboxVertex>>(vertices, 6);
|
||||
|
||||
sprites.push_back(SkySprite {
|
||||
"misc/moon_flare",
|
||||
glm::pi<float>() * 0.5f,
|
||||
0.5f,
|
||||
false,
|
||||
glm::pi<float>() * 0.25f,
|
||||
});
|
||||
|
||||
sprites.push_back(SkySprite {
|
||||
"misc/moon",
|
||||
glm::pi<float>() * 0.5f,
|
||||
@ -62,6 +52,14 @@ Skybox::Skybox(uint size, Shader& shader)
|
||||
false,
|
||||
glm::pi<float>() * 0.25f,
|
||||
});
|
||||
|
||||
sprites.push_back(SkySprite {
|
||||
"misc/moon_flare",
|
||||
glm::pi<float>() * 0.5f,
|
||||
0.5f,
|
||||
false,
|
||||
glm::pi<float>() * 0.25f,
|
||||
});
|
||||
|
||||
sprites.push_back(SkySprite {
|
||||
"misc/sun",
|
||||
@ -118,6 +116,8 @@ void Skybox::draw(
|
||||
{
|
||||
const glm::uvec2& viewport = pctx.getViewport();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
drawBackground(camera, assets, viewport.x, viewport.y);
|
||||
|
||||
DrawContext ctx = pctx.sub();
|
||||
@ -130,22 +130,23 @@ void Skybox::draw(
|
||||
batch3d->begin();
|
||||
|
||||
float angle = daytime * glm::pi<float>() * 2.0f;
|
||||
float opacity = glm::pow(1.0f-fog, 7.0f);
|
||||
float opacity = glm::pow(1.0f - fog, 7.0f);
|
||||
|
||||
float depthScale = 1e3;
|
||||
for (auto& sprite : sprites) {
|
||||
batch3d->texture(assets.get<Texture>(sprite.texture));
|
||||
|
||||
float sangle = daytime * glm::pi<float>() * 2.0 + sprite.phase;
|
||||
float distance = sprite.distance;
|
||||
float distance = sprite.distance * depthScale;
|
||||
|
||||
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), -sangle + glm::pi<float>() * 0.5f, glm::vec3(0, 0, -1));
|
||||
rotation = glm::rotate(rotation, sprite.altitude, glm::vec3(1, 0, 0));
|
||||
glm::vec3 pos = glm::vec4(0, distance, 0, 1) * rotation;
|
||||
glm::vec3 up = glm::vec4(1, 0, 0, 1) * rotation;
|
||||
glm::vec3 right = glm::vec4(0, 0, 1, 1) * rotation;
|
||||
glm::vec3 up = glm::vec4(depthScale, 0, 0, 1) * rotation;
|
||||
glm::vec3 right = glm::vec4(0, 0, depthScale, 1) * rotation;
|
||||
glm::vec4 tint (1,1,1, opacity);
|
||||
if (!sprite.emissive) {
|
||||
tint *= 0.6f+std::cos(angle)*0.4;
|
||||
tint *= 0.6f + std::cos(angle)*0.4;
|
||||
}
|
||||
batch3d->sprite(pos, right,
|
||||
up, 1, 1, UVRegion(), tint);
|
||||
@ -167,10 +168,10 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality)
|
||||
assert(cubemap != nullptr);
|
||||
|
||||
ready = true;
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||
cubemap->bind();
|
||||
shader.use();
|
||||
t *= glm::pi<float>()*2.0f;
|
||||
t *= glm::two_pi<float>();
|
||||
|
||||
lightDir = glm::normalize(glm::vec3(sin(t), -cos(t), 0.0f));
|
||||
shader.uniform1i("u_quality", quality);
|
||||
@ -237,13 +238,13 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) {
|
||||
}
|
||||
|
||||
void Skybox::bind() const {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||
fbo->getTexture()->bind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void Skybox::unbind() const {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
|
||||
fbo->getTexture()->unbind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
@ -54,8 +54,11 @@
|
||||
#include "Emitter.hpp"
|
||||
#include "TextNote.hpp"
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
inline constexpr size_t BATCH3D_CAPACITY = 4096;
|
||||
inline constexpr size_t MODEL_BATCH_CAPACITY = 20'000;
|
||||
inline constexpr GLenum TEXTURE_MAIN = GL_TEXTURE0;
|
||||
|
||||
bool WorldRenderer::showChunkBorders = false;
|
||||
bool WorldRenderer::showEntitiesDebug = false;
|
||||
@ -141,15 +144,15 @@ void WorldRenderer::setupWorldShader(
|
||||
shader.uniform1f("u_shadowsOpacity", 1.0f - cloudsIntensity); // TODO: make it configurable
|
||||
shader.uniform1f("u_shadowsSoftness", 1.0f + cloudsIntensity * 4); // TODO: make it configurable
|
||||
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
shader.uniform1i("u_shadows[0]", 4);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0);
|
||||
shader.uniform1i("u_shadows[0]", TARGET_SHADOWS0);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMap->getDepthMap());
|
||||
|
||||
glActiveTexture(GL_TEXTURE5);
|
||||
shader.uniform1i("u_shadows[1]", 5);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS1);
|
||||
shader.uniform1i("u_shadows[1]", TARGET_SHADOWS1);
|
||||
glBindTexture(GL_TEXTURE_2D, wideShadowMap->getDepthMap());
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(TEXTURE_MAIN);
|
||||
}
|
||||
|
||||
auto indices = level.content.getIndices();
|
||||
@ -438,9 +441,11 @@ void WorldRenderer::draw(
|
||||
|
||||
auto& mainShader = assets.require<Shader>("main");
|
||||
auto& entityShader = assets.require<Shader>("entity");
|
||||
auto& deferredShader = assets.require<PostEffect>("deferred_lighting").getShader();
|
||||
const auto& settings = engine.getSettings();
|
||||
|
||||
gbufferPipeline = settings.graphics.advancedRender.get();
|
||||
int shadowsQuality = settings.graphics.shadowsQuality.get();
|
||||
int shadowsQuality = settings.graphics.shadowsQuality.get() * gbufferPipeline;
|
||||
int resolution = 512 << shadowsQuality;
|
||||
if (shadowsQuality > 0 && !shadows) {
|
||||
shadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
@ -449,6 +454,7 @@ void WorldRenderer::draw(
|
||||
Shader::preprocessor->define("ENABLE_SHADOWS", "true");
|
||||
mainShader.recompile();
|
||||
entityShader.recompile();
|
||||
deferredShader.recompile();
|
||||
} else if (shadowsQuality == 0 && shadows) {
|
||||
shadowMap.reset();
|
||||
wideShadowMap.reset();
|
||||
@ -456,6 +462,7 @@ void WorldRenderer::draw(
|
||||
Shader::preprocessor->undefine("ENABLE_SHADOWS");
|
||||
mainShader.recompile();
|
||||
entityShader.recompile();
|
||||
deferredShader.recompile();
|
||||
}
|
||||
if (shadows && shadowMap->getResolution() != resolution) {
|
||||
shadowMap = std::make_unique<ShadowMap>(resolution);
|
||||
@ -489,9 +496,6 @@ void WorldRenderer::draw(
|
||||
|
||||
display::clearDepth();
|
||||
|
||||
// Drawing background sky plane
|
||||
skybox->draw(pctx, camera, assets, worldInfo.daytime, clouds);
|
||||
|
||||
/* Actually world render with depth buffer on */ {
|
||||
DrawContext ctx = wctx.sub();
|
||||
ctx.setDepthTest(true);
|
||||
@ -506,19 +510,32 @@ void WorldRenderer::draw(
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
DrawContext ctx = wctx.sub();
|
||||
texts->render(ctx, camera, settings, hudVisible, true);
|
||||
}
|
||||
texts->render(pctx, camera, settings, hudVisible, true);
|
||||
}
|
||||
|
||||
skybox->bind();
|
||||
deferredShader.use();
|
||||
float fogFactor =
|
||||
15.0f / static_cast<float>(settings.chunks.loadDistance.get() - 2);
|
||||
setupWorldShader(deferredShader, camera, settings, fogFactor);
|
||||
postProcessing.render(
|
||||
pctx,
|
||||
assets,
|
||||
timer,
|
||||
camera,
|
||||
shadows ? shadowMap->getDepthMap() : 0
|
||||
shadows ? shadowMap->getDepthMap() : 0,
|
||||
shadows ? wideShadowMap->getDepthMap() : 0,
|
||||
shadowCamera.getProjView(),
|
||||
wideShadowCamera.getProjView(),
|
||||
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();
|
||||
if (player.currentCamera == player.fpCamera) {
|
||||
DrawContext ctx = pctx.sub();
|
||||
ctx.setDepthTest(true);
|
||||
|
||||
@ -19,7 +19,7 @@ public:
|
||||
bool perspective = true;
|
||||
bool flipped = false;
|
||||
float near = 0.05f;
|
||||
float far = 1500.0f;
|
||||
float far = 1e4f;
|
||||
|
||||
bool projset = false;
|
||||
glm::mat4 projection;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user