From 30a0b816806f88384ae66603deb8aca87fac56c3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 9 May 2025 23:51:34 +0300 Subject: [PATCH] refactor shaders --- res/shaders/background.glslf | 4 +-- res/shaders/entity.glslf | 23 ++++++++++--- res/shaders/entity.glslv | 46 ++++++++++++------------- res/shaders/lib/lighting.glsl | 27 +++++++++++++++ res/shaders/lib/shadows.glsl | 32 ++++++++++++++++++ res/shaders/main.glslf | 32 +++--------------- res/shaders/main.glslv | 48 +++++++++++---------------- src/graphics/render/Skybox.cpp | 2 +- src/graphics/render/WorldRenderer.cpp | 2 +- 9 files changed, 128 insertions(+), 88 deletions(-) create mode 100644 res/shaders/lib/lighting.glsl create mode 100644 res/shaders/lib/shadows.glsl diff --git a/res/shaders/background.glslf b/res/shaders/background.glslf index 9f588ba5..c442bb06 100644 --- a/res/shaders/background.glslf +++ b/res/shaders/background.glslf @@ -3,11 +3,11 @@ layout (location = 0) out vec4 f_color; layout (location = 1) out vec4 f_position; layout (location = 2) out vec4 f_normal; -uniform samplerCube u_cubemap; +uniform samplerCube u_skybox; void main(){ vec3 dir = normalize(v_coord); f_position = vec4(0.0, 0.0, 0.0, 0.0); f_normal = vec4(0.0); - f_color = texture(u_cubemap, dir); + f_color = texture(u_skybox, dir); } diff --git a/res/shaders/entity.glslf b/res/shaders/entity.glslf index 3d2a251a..b9369874 100644 --- a/res/shaders/entity.glslf +++ b/res/shaders/entity.glslf @@ -3,6 +3,8 @@ in vec2 a_texCoord; in vec3 a_position; in vec3 a_dir; in vec3 a_normal; +in vec3 a_realnormal; +in vec4 a_modelpos; in float a_fog; layout (location = 0) out vec4 f_color; @@ -10,20 +12,33 @@ layout (location = 1) out vec4 f_position; layout (location = 2) out vec4 f_normal; uniform sampler2D u_texture0; -uniform samplerCube u_cubemap; +uniform samplerCube u_skybox; uniform vec3 u_fogColor; uniform float u_fogFactor; uniform float u_fogCurve; uniform bool u_alphaClip; +uniform sampler2DShadow u_shadows; +uniform vec3 u_sunDir; +uniform int u_shadowsRes; + +uniform bool u_enableShadows; +uniform mat4 u_shadowsMatrix; + +#include + void main() { - vec3 fogColor = texture(u_cubemap, a_dir).rgb; + float shadow = calc_shadow(); + vec3 fogColor = texture(u_skybox, a_dir).rgb; vec4 tex_color = texture(u_texture0, a_texCoord); float alpha = a_color.a * tex_color.a; // 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; - f_color = mix(a_color * tex_color, vec4(fogColor,1.0), a_fog); + } + f_color = a_color * tex_color; + f_color.rgb *= shadow; + f_color = mix(f_color, vec4(fogColor, 1.0), a_fog); f_color.a = alpha; f_position = vec4(a_position, 1.0); f_normal = vec4(a_normal, 1.0); diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index 57ed9866..607c4721 100644 --- a/res/shaders/entity.glslv +++ b/res/shaders/entity.glslv @@ -5,12 +5,15 @@ layout (location = 1) in vec2 v_texCoord; layout (location = 2) in vec3 v_color; layout (location = 3) in vec4 v_light; -out vec4 a_color; -out vec2 a_texCoord; -out vec3 a_normal; +out float a_distance; out float a_fog; -out vec3 a_position; +out vec2 a_texCoord; out vec3 a_dir; +out vec3 a_normal; +out vec3 a_position; +out vec3 a_realnormal; +out vec4 a_color; +out vec4 a_modelpos; uniform mat4 u_model; uniform mat4 u_proj; @@ -18,40 +21,37 @@ uniform mat4 u_view; uniform vec3 u_cameraPos; uniform float u_gamma; uniform float u_opacity; -uniform float u_fogFactor; -uniform float u_fogCurve; -uniform float u_weatherFogOpacity; -uniform float u_weatherFogDencity; -uniform float u_weatherFogCurve; -uniform samplerCube u_cubemap; +uniform float u_timer; +uniform samplerCube u_skybox; uniform vec3 u_torchlightColor; uniform float u_torchlightDistance; +#include + void main() { - vec4 modelpos = u_model * vec4(v_position, 1.0); - vec3 pos3d = modelpos.xyz - u_cameraPos; - modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d); + a_modelpos = u_model * vec4(v_position, 1.0); + vec3 pos3d = a_modelpos.xyz - u_cameraPos; + a_modelpos.xyz = apply_planet_curvature(a_modelpos.xyz, pos3d); a_normal = vec3(0.0, 1.0, 0.0);//v_normal.xyz * 2.0 - 1.0; + a_realnormal = a_normal; vec3 light = v_light.rgb; - float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / - u_torchlightDistance); + float torchlight = calc_torch_light(a_modelpos.xyz); light += torchlight * u_torchlightColor; a_color = vec4(pow(light, vec3(u_gamma)),1.0f); a_texCoord = v_texCoord; - a_dir = modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_cubemap); + a_dir = a_modelpos.xyz - u_cameraPos; + vec3 skyLightColor = pick_sky_color(u_skybox); a_color.rgb = max(a_color.rgb, skyLightColor.rgb*v_light.a) * v_color; a_color.a = u_opacity; - float dist = length(u_view * u_model * vec4(pos3d * FOG_POS_SCALE, 0.0)); - float depth = (dist / 256.0); - a_fog = min(1.0, max(pow(depth * u_fogFactor, u_fogCurve), - min(pow(depth * u_weatherFogDencity, u_weatherFogCurve), u_weatherFogOpacity))); - gl_Position = u_proj * u_view * modelpos; + a_distance = length(u_view * u_model * vec4(pos3d * FOG_POS_SCALE, 0.0)); + a_fog = calc_fog(a_distance / 256.0); - a_position = (u_view * modelpos).xyz; + vec4 viewmodelpos = u_view * a_modelpos; + a_position = viewmodelpos.xyz; + gl_Position = u_proj * viewmodelpos; } diff --git a/res/shaders/lib/lighting.glsl b/res/shaders/lib/lighting.glsl new file mode 100644 index 00000000..d2c4f896 --- /dev/null +++ b/res/shaders/lib/lighting.glsl @@ -0,0 +1,27 @@ +#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 modelpos) { + return max(0.0, 1.0 - distance(u_cameraPos, modelpos.xyz) / u_torchlightDistance); +} + +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_ diff --git a/res/shaders/lib/shadows.glsl b/res/shaders/lib/shadows.glsl new file mode 100644 index 00000000..db94e9dc --- /dev/null +++ b/res/shaders/lib/shadows.glsl @@ -0,0 +1,32 @@ +#ifndef SHADOWS_GLSL_ +#define SHADOWS_GLSL_ + +float calc_shadow() { + float shadow = 1.0; + if (u_enableShadows) { + vec4 mpos = u_shadowsMatrix * vec4(a_modelpos.xyz + a_realnormal * 0.08, 1.0); + vec3 projCoords = mpos.xyz / mpos.w; + projCoords = projCoords * 0.5 + 0.5; + projCoords.z -= 0.0001; + + shadow = 0.0; + + if (dot(a_realnormal, u_sunDir) < 0.0) { + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + shadow += texture(u_shadows, projCoords.xyz + vec3( + x * (1.0 / u_shadowsRes), + y * (1.0 / u_shadowsRes), 0.0 + )); + } + } + shadow /= 9; + shadow = shadow * 0.5 + 0.5; + } else { + shadow = 0.5; + } + } + return shadow; +} + +#endif // SHADOWS_GLSL_ diff --git a/res/shaders/main.glslf b/res/shaders/main.glslf index 55ecfe2f..89e83bbf 100644 --- a/res/shaders/main.glslf +++ b/res/shaders/main.glslf @@ -12,7 +12,7 @@ in vec3 a_realnormal; in vec4 a_modelpos; uniform sampler2D u_texture0; -uniform samplerCube u_cubemap; +uniform samplerCube u_skybox; uniform sampler2DShadow u_shadows; uniform vec3 u_sunDir; uniform int u_shadowsRes; @@ -25,35 +25,11 @@ uniform bool u_enableShadows; uniform mat4 u_shadowsMatrix; -const int BLUR_SAMPLES = 6; +#include void main() { - float shadow = 1.0; - if (u_enableShadows) { - vec4 mpos = u_shadowsMatrix * vec4(a_modelpos.xyz + a_realnormal * 0.08, 1.0); - vec3 projCoords = mpos.xyz / mpos.w; - projCoords = projCoords * 0.5 + 0.5; - projCoords.z -= 0.0001; - - shadow = 0.0; - - if (dot(a_realnormal, u_sunDir) < 0.0) { - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - shadow += texture(u_shadows, projCoords.xyz + vec3( - x * (1.0 / u_shadowsRes), - y * (1.0 / u_shadowsRes), 0.0 - )); - } - } - shadow /= 9; - shadow = shadow * 0.5 + 0.5; - } else { - shadow = 0.5; - } - } - - vec3 fogColor = texture(u_cubemap, a_dir).rgb; + float shadow = calc_shadow(); + vec3 fogColor = texture(u_skybox, a_dir).rgb; vec4 texColor = texture(u_texture0, a_texCoord); float alpha = a_color.a * texColor.a; if (u_alphaClip) { diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index 8df0b81e..032a6d8e 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -5,61 +5,51 @@ layout (location = 1) in vec2 v_texCoord; layout (location = 2) in vec4 v_light; layout (location = 3) in vec4 v_normal; -out vec4 a_color; -out vec2 a_texCoord; -out vec3 a_normal; out float a_distance; out float a_fog; -out vec3 a_position; -out vec4 a_modelpos; +out vec2 a_texCoord; out vec3 a_dir; +out vec3 a_normal; +out vec3 a_position; out vec3 a_realnormal; +out vec4 a_color; +out vec4 a_modelpos; uniform mat4 u_model; uniform mat4 u_proj; uniform mat4 u_view; uniform vec3 u_cameraPos; uniform float u_gamma; -uniform float u_fogFactor; -uniform float u_fogCurve; -uniform float u_weatherFogOpacity; -uniform float u_weatherFogDencity; -uniform float u_weatherFogCurve; uniform float u_timer; -uniform samplerCube u_cubemap; +uniform samplerCube u_skybox; uniform vec3 u_torchlightColor; uniform float u_torchlightDistance; -uniform bool u_enableShadows; + +#include void main() { - vec4 modelpos = u_model * vec4(v_position, 1.0f); - vec3 pos3d = modelpos.xyz-u_cameraPos; - modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d); + a_modelpos = u_model * vec4(v_position, 1.0f); + vec3 pos3d = a_modelpos.xyz - u_cameraPos; + a_modelpos.xyz = apply_planet_curvature(a_modelpos.xyz, pos3d); a_realnormal = v_normal.xyz * 2.0 - 1.0; - mat3 normalMatrix = transpose(inverse(mat3(u_view * u_model))); - a_normal = a_realnormal; - a_normal = normalMatrix * (false ? -a_normal : a_normal); - //a_normal = a_realnormal; + a_normal = calc_screen_normal(a_realnormal); vec3 light = v_light.rgb; - float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / - u_torchlightDistance); + float torchlight = calc_torch_light(a_modelpos.xyz); light += torchlight * u_torchlightColor; a_color = vec4(pow(light, vec3(u_gamma)),1.0f); a_texCoord = v_texCoord; - a_dir = modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_cubemap); + a_dir = a_modelpos.xyz - u_cameraPos; + vec3 skyLightColor = pick_sky_color(u_skybox); a_color.rgb = max(a_color.rgb, skyLightColor.rgb*v_light.a); a_distance = length(u_view * u_model * vec4(pos3d * FOG_POS_SCALE, 0.0)); - float depth = (a_distance / 256.0); - a_fog = min(1.0, max(pow(depth * u_fogFactor, u_fogCurve), - min(pow(depth * u_weatherFogDencity, u_weatherFogCurve), u_weatherFogOpacity))); - gl_Position = u_proj * u_view * modelpos; + a_fog = calc_fog(a_distance / 256.0); - a_position = (u_view * modelpos).xyz; - a_modelpos = modelpos; + vec4 viewmodelpos = u_view * a_modelpos; + a_position = viewmodelpos.xyz; + gl_Position = u_proj * viewmodelpos; } diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index 67b4efec..bf6eedc1 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -71,7 +71,7 @@ void Skybox::drawBackground( backShader->uniformMatrix("u_view", camera.getView(false)); backShader->uniform1f("u_zoom", camera.zoom*camera.getFov()/(M_PI*0.5f)); backShader->uniform1f("u_ar", float(width)/float(height)); - backShader->uniform1i("u_cubemap", 1); + backShader->uniform1i("u_skybox", 1); bind(); mesh->draw(); unbind(); diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 1a740fa5..b886c300 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -132,7 +132,7 @@ void WorldRenderer::setupWorldShader( shader.uniform1f("u_dayTime", level.getWorld()->getInfo().daytime); shader.uniform2f("u_lightDir", skybox->getLightDir()); shader.uniform3f("u_cameraPos", camera.position); - shader.uniform1i("u_cubemap", 1); + shader.uniform1i("u_skybox", 1); shader.uniform1i("u_enableShadows", gbufferPipeline); if (gbufferPipeline) {