gfx: add fog

main
Dominik Madarász 2024-08-25 02:58:34 +02:00
parent 8183821f4c
commit 0753cfdd88
14 changed files with 142 additions and 8 deletions

View File

@ -1328,6 +1328,13 @@ enum SHADING_MODE {
SHADING_VERTEXLIT, SHADING_VERTEXLIT,
SHADING_PBR, SHADING_PBR,
}; };
enum FOG_MODE {
FOG_NONE,
FOG_LINEAR,
FOG_EXP,
FOG_EXP2,
FOG_DEPTH,
};
enum RENDER_PASS { enum RENDER_PASS {
RENDER_PASS_OPAQUE, RENDER_PASS_OPAQUE,
RENDER_PASS_TRANSPARENT, RENDER_PASS_TRANSPARENT,
@ -1422,6 +1429,7 @@ enum BILLBOARD_MODE {
void model_shading(model_t*, int shading); void model_shading(model_t*, int shading);
void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines); void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines);
void model_skybox(model_t*, skybox_t sky, bool load_sh); void model_skybox(model_t*, skybox_t sky, bool load_sh);
void model_fog(model_t*, unsigned mode, vec3 color, float start, float end, float density);
void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader); void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader);
void model_render_skeleton(model_t, mat44 model); void model_render_skeleton(model_t, mat44 model);
void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count); void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count);

View File

@ -0,0 +1,46 @@
#ifndef FOG_GLSL
#define FOG_GLSL
#include "utils.glsl"
// Fog uniforms
uniform vec3 u_fog_color;
uniform float u_fog_density;
uniform float u_fog_start;
uniform float u_fog_end;
uniform int u_fog_type;
uniform bool u_fog_dither;
vec3 do_fog(vec3 fragment_color) {
if (u_fog_type == 0) {
return fragment_color;
}
float distance = length(v_position_ws - u_cam_pos);
float fog_factor = 0.0;
if (u_fog_type == 1) {
// Linear fog
fog_factor = clamp((u_fog_end - distance) / (u_fog_end - u_fog_start), 0.0, 1.0);
} else if (u_fog_type == 2) {
// Exponential fog
fog_factor = exp(-u_fog_density * distance);
} else if (u_fog_type == 3) {
// Exponential squared fog
fog_factor = exp(-pow(u_fog_density * distance, 2.0));
} else if (u_fog_type == 4) {
// Distance fog
fog_factor = clamp((u_fog_start - v_depth) / (u_fog_end - u_fog_start), 0.0, 1.0);
}
// Dithering for PS1-style graininess
if (u_fog_dither) {
vec2 ditheredCoord = gl_FragCoord.xy / 12.0;
float dither = rand(ditheredCoord + frame_time * 0.1) * 0.1 - 0.05;
fog_factor += dither;
}
return mix(u_fog_color, fragment_color, fog_factor);
}
#endif

View File

@ -58,8 +58,8 @@ vec3 shading_light(light_t l, material_t m) {
if (l.type == LIGHT_SPOT) { if (l.type == LIGHT_SPOT) {
float angle = dot(l.dir, -lightDir); float angle = dot(l.dir, -lightDir);
if (angle > l.outerCone) { if (angle > l.innerCone) {
float intensity = (angle-l.outerCone)/(l.innerCone-l.outerCone); float intensity = (angle-l.innerCone)/(l.outerCone-l.innerCone);
attenuation *= clamp(intensity, 0.0, 1.0); attenuation *= clamp(intensity, 0.0, 1.0);
} else { } else {
attenuation = 0.0; attenuation = 0.0;

View File

@ -31,6 +31,7 @@ in vec3 v_tangent;
in vec3 v_binormal; in vec3 v_binormal;
in vec3 v_to_camera; in vec3 v_to_camera;
in vec3 v_vertcolor; in vec3 v_vertcolor;
in float v_depth;
out vec4 fragcolor; out vec4 fragcolor;

View File

@ -10,6 +10,7 @@ uniform mat4 M; // RIM
uniform mat4 VP; uniform mat4 VP;
uniform mat4 P; uniform mat4 P;
uniform vec3 u_cam_dir; uniform vec3 u_cam_dir;
uniform float frame_time;
uniform int u_billboard; uniform int u_billboard;
#if 0 #if 0
@ -70,6 +71,7 @@ out vec3 v_binormal;
out vec3 v_viewpos; out vec3 v_viewpos;
out vec3 v_to_camera; out vec3 v_to_camera;
out vec3 v_vertcolor; out vec3 v_vertcolor;
out float v_depth;
// shadow // shadow
uniform mat4 model, view, inv_view; uniform mat4 model, view, inv_view;

View File

@ -26,6 +26,10 @@ float random( vec3 v )
return random(floatBitsToUint( v )); return random(floatBitsToUint( v ));
} }
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
// Classic Perlin 3D Noise // Classic Perlin 3D Noise
// by Stefan Gustavson // by Stefan Gustavson
// //

View File

@ -1,10 +1,13 @@
#include "model_fs.glsl" #include "model_fs.glsl"
#include "lightmap.glsl" #include "lightmap.glsl"
#include "surface.glsl" #include "surface.glsl"
#include "fog.glsl"
void main() { void main() {
if (do_lightmap()) if (do_lightmap())
return; return;
surface_t surf = surface(); surface_t surf = surface();
fragcolor = surf.fragcolor; fragcolor = surf.fragcolor;
fragcolor.rgb = do_fog(fragcolor.rgb);
} }

View File

@ -39,6 +39,7 @@ void main() {
v_to_camera = mat3( inv_view ) * to_camera; v_to_camera = mat3( inv_view ) * to_camera;
// Set final position // Set final position
v_depth = -finalPos.z;
gl_Position = P * finalPos; gl_Position = P * finalPos;
// Prepare shadow data for shadow mapping // Prepare shadow data for shadow mapping

View File

@ -17575,6 +17575,14 @@ enum SHADING_MODE {
SHADING_PBR, SHADING_PBR,
}; };
enum FOG_MODE {
FOG_NONE,
FOG_LINEAR,
FOG_EXP,
FOG_EXP2,
FOG_DEPTH,
};
enum RENDER_PASS { enum RENDER_PASS {
RENDER_PASS_OPAQUE, RENDER_PASS_OPAQUE,
RENDER_PASS_TRANSPARENT, RENDER_PASS_TRANSPARENT,
@ -17688,6 +17696,7 @@ API void model_lod(model_t*, float lo_detail, float hi_detail, float morph);
API void model_shading(model_t*, int shading); API void model_shading(model_t*, int shading);
API void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines); API void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines);
API void model_skybox(model_t*, skybox_t sky, bool load_sh); API void model_skybox(model_t*, skybox_t sky, bool load_sh);
API void model_fog(model_t*, unsigned mode, vec3 color, float start, float end, float density);
API void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader); API void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader);
API void model_render_skeleton(model_t, mat44 model); API void model_render_skeleton(model_t, mat44 model);
API void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count); API void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count);
@ -386366,13 +386375,27 @@ void model_shading(model_t *m, int shading) {
void model_skybox(model_t *mdl, skybox_t sky, bool load_sh) { void model_skybox(model_t *mdl, skybox_t sky, bool load_sh) {
if (load_sh) { if (load_sh) {
unsigned oldprog = last_shader;
shader_bind(mdl->program);
shader_vec3v("u_coefficients_sh", 9, sky.cubemap.sh); shader_vec3v("u_coefficients_sh", 9, sky.cubemap.sh);
shader_bind(oldprog);
} }
mdl->sky_refl = sky.refl; mdl->sky_refl = sky.refl;
mdl->sky_env = sky.env; mdl->sky_env = sky.env;
} }
void model_fog(model_t *mdl, unsigned mode, vec3 color, float start, float end, float density) {
unsigned oldprog = last_shader;
shader_bind(mdl->program);
shader_vec3("u_fog_color", color);
shader_float("u_fog_density", density);
shader_float("u_fog_start", start);
shader_float("u_fog_end", end);
shader_int("u_fog_type", mode);
shader_bind(oldprog);
}
// static // static
aabb aabb_transform( aabb A, mat44 M ) { aabb aabb_transform( aabb A, mat44 M ) {
// Based on "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 1990 // Based on "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 1990
@ -388026,8 +388049,8 @@ light_t light() {
l.falloff.linear = 0.09f; l.falloff.linear = 0.09f;
l.falloff.quadratic = 0.0032f; l.falloff.quadratic = 0.0032f;
l.specularPower = 32.f; l.specularPower = 32.f;
l.innerCone = 0.9f; // 25 deg l.innerCone = 0.85f;// 31 deg
l.outerCone = 0.85f; // 31 deg l.outerCone = 0.9f; // 25 deg
return l; return l;
} }

View File

@ -4709,13 +4709,27 @@ void model_shading(model_t *m, int shading) {
void model_skybox(model_t *mdl, skybox_t sky, bool load_sh) { void model_skybox(model_t *mdl, skybox_t sky, bool load_sh) {
if (load_sh) { if (load_sh) {
unsigned oldprog = last_shader;
shader_bind(mdl->program);
shader_vec3v("u_coefficients_sh", 9, sky.cubemap.sh); shader_vec3v("u_coefficients_sh", 9, sky.cubemap.sh);
shader_bind(oldprog);
} }
mdl->sky_refl = sky.refl; mdl->sky_refl = sky.refl;
mdl->sky_env = sky.env; mdl->sky_env = sky.env;
} }
void model_fog(model_t *mdl, unsigned mode, vec3 color, float start, float end, float density) {
unsigned oldprog = last_shader;
shader_bind(mdl->program);
shader_vec3("u_fog_color", color);
shader_float("u_fog_density", density);
shader_float("u_fog_start", start);
shader_float("u_fog_end", end);
shader_int("u_fog_type", mode);
shader_bind(oldprog);
}
// static // static
aabb aabb_transform( aabb A, mat44 M ) { aabb aabb_transform( aabb A, mat44 M ) {
// Based on "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 1990 // Based on "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 1990

View File

@ -607,6 +607,14 @@ enum SHADING_MODE {
SHADING_PBR, SHADING_PBR,
}; };
enum FOG_MODE {
FOG_NONE,
FOG_LINEAR,
FOG_EXP,
FOG_EXP2,
FOG_DEPTH,
};
enum RENDER_PASS { enum RENDER_PASS {
RENDER_PASS_OPAQUE, RENDER_PASS_OPAQUE,
RENDER_PASS_TRANSPARENT, RENDER_PASS_TRANSPARENT,
@ -720,6 +728,7 @@ API void model_lod(model_t*, float lo_detail, float hi_detail, float morph);
API void model_shading(model_t*, int shading); API void model_shading(model_t*, int shading);
API void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines); API void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines);
API void model_skybox(model_t*, skybox_t sky, bool load_sh); API void model_skybox(model_t*, skybox_t sky, bool load_sh);
API void model_fog(model_t*, unsigned mode, vec3 color, float start, float end, float density);
API void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader); API void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader);
API void model_render_skeleton(model_t, mat44 model); API void model_render_skeleton(model_t, mat44 model);
API void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count); API void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count);

View File

@ -305,8 +305,8 @@ light_t light() {
l.falloff.linear = 0.09f; l.falloff.linear = 0.09f;
l.falloff.quadratic = 0.0032f; l.falloff.quadratic = 0.0032f;
l.specularPower = 32.f; l.specularPower = 32.f;
l.innerCone = 0.9f; // 25 deg l.innerCone = 0.85f;// 31 deg
l.outerCone = 0.85f; // 31 deg l.outerCone = 0.9f; // 25 deg
return l; return l;
} }

View File

@ -21508,13 +21508,27 @@ void model_shading(model_t *m, int shading) {
void model_skybox(model_t *mdl, skybox_t sky, bool load_sh) { void model_skybox(model_t *mdl, skybox_t sky, bool load_sh) {
if (load_sh) { if (load_sh) {
unsigned oldprog = last_shader;
shader_bind(mdl->program);
shader_vec3v("u_coefficients_sh", 9, sky.cubemap.sh); shader_vec3v("u_coefficients_sh", 9, sky.cubemap.sh);
shader_bind(oldprog);
} }
mdl->sky_refl = sky.refl; mdl->sky_refl = sky.refl;
mdl->sky_env = sky.env; mdl->sky_env = sky.env;
} }
void model_fog(model_t *mdl, unsigned mode, vec3 color, float start, float end, float density) {
unsigned oldprog = last_shader;
shader_bind(mdl->program);
shader_vec3("u_fog_color", color);
shader_float("u_fog_density", density);
shader_float("u_fog_start", start);
shader_float("u_fog_end", end);
shader_int("u_fog_type", mode);
shader_bind(oldprog);
}
// static // static
aabb aabb_transform( aabb A, mat44 M ) { aabb aabb_transform( aabb A, mat44 M ) {
// Based on "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 1990 // Based on "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 1990
@ -23168,8 +23182,8 @@ light_t light() {
l.falloff.linear = 0.09f; l.falloff.linear = 0.09f;
l.falloff.quadratic = 0.0032f; l.falloff.quadratic = 0.0032f;
l.specularPower = 32.f; l.specularPower = 32.f;
l.innerCone = 0.9f; // 25 deg l.innerCone = 0.85f;// 31 deg
l.outerCone = 0.85f; // 31 deg l.outerCone = 0.9f; // 25 deg
return l; return l;
} }

View File

@ -3642,6 +3642,14 @@ enum SHADING_MODE {
SHADING_PBR, SHADING_PBR,
}; };
enum FOG_MODE {
FOG_NONE,
FOG_LINEAR,
FOG_EXP,
FOG_EXP2,
FOG_DEPTH,
};
enum RENDER_PASS { enum RENDER_PASS {
RENDER_PASS_OPAQUE, RENDER_PASS_OPAQUE,
RENDER_PASS_TRANSPARENT, RENDER_PASS_TRANSPARENT,
@ -3755,6 +3763,7 @@ API void model_lod(model_t*, float lo_detail, float hi_detail, float morph);
API void model_shading(model_t*, int shading); API void model_shading(model_t*, int shading);
API void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines); API void model_shading_custom(model_t*, int shading, const char *vs, const char *fs, const char *defines);
API void model_skybox(model_t*, skybox_t sky, bool load_sh); API void model_skybox(model_t*, skybox_t sky, bool load_sh);
API void model_fog(model_t*, unsigned mode, vec3 color, float start, float end, float density);
API void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader); API void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader);
API void model_render_skeleton(model_t, mat44 model); API void model_render_skeleton(model_t, mat44 model);
API void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count); API void model_render_instanced(model_t, mat44 proj, mat44 view, mat44 *models, int shader, unsigned count);