From 6a7f6f2867dc8a7aba8e91bf0fdf299ef276a65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 12 Mar 2021 15:59:38 +0100 Subject: Cleanup: EEVEE: Remove hammersley texture and split hammersley code --- source/blender/draw/CMakeLists.txt | 1 + .../blender/draw/engines/eevee/eevee_lightprobes.c | 45 +---------- source/blender/draw/engines/eevee/eevee_private.h | 3 - source/blender/draw/engines/eevee/eevee_shaders.c | 66 ++++++++-------- .../engines/eevee/shaders/bsdf_sampling_lib.glsl | 92 ++++++++-------------- .../shaders/lightprobe_filter_diffuse_frag.glsl | 6 +- .../shaders/lightprobe_filter_glossy_frag.glsl | 6 +- .../shaders/lightprobe_filter_visibility_frag.glsl | 9 ++- .../draw/engines/eevee/shaders/random_lib.glsl | 38 +++++++++ .../draw/intern/shaders/common_math_geom_lib.glsl | 10 +++ source/blender/draw/tests/shaders_test.cc | 1 - 11 files changed, 133 insertions(+), 144 deletions(-) create mode 100644 source/blender/draw/engines/eevee/shaders/random_lib.glsl (limited to 'source/blender/draw') diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index dff9e302fdf..98f42858812 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -263,6 +263,7 @@ data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/cubemap_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/random_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/renderpass_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 3e1d4a8aaa6..d692a3e420e 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -50,12 +50,10 @@ #include "WM_types.h" static struct { - struct GPUTexture *hammersley; struct GPUTexture *planar_pool_placeholder; struct GPUTexture *depth_placeholder; struct GPUTexture *depth_array_placeholder; - struct GPUVertFormat *format_probe_display_cube; struct GPUVertFormat *format_probe_display_planar; } e_data = {NULL}; /* Engine data */ @@ -90,25 +88,6 @@ bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data) return vis_in && oed->ob_vis; } -static struct GPUTexture *create_hammersley_sample_texture(int samples) -{ - struct GPUTexture *tex; - float(*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex"); - int i; - - for (i = 0; i < samples; i++) { - double dphi; - BLI_hammersley_1d(i, &dphi); - float phi = (float)dphi * 2.0f * M_PI; - texels[i][0] = cosf(phi); - texels[i][1] = sinf(phi); - } - - tex = DRW_texture_create_1d(samples, GPU_RG16F, DRW_TEX_WRAP, (float *)texels); - MEM_freeN(texels); - return tex; -} - static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) { EEVEE_TextureList *txl = vedata->txl; @@ -166,10 +145,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); vedata->info[0] = '\0'; - if (!e_data.hammersley) { - EEVEE_shaders_lightprobe_shaders_init(); - e_data.hammersley = create_hammersley_sample_texture(HAMMERSLEY_SIZE); - } + EEVEE_shaders_material_shaders_init(); memset(stl->g_data->bake_views, 0, sizeof(stl->g_data->bake_views)); memset(stl->g_data->cube_views, 0, sizeof(stl->g_data->cube_views)); @@ -244,7 +220,6 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); DRW_shgroup_uniform_float(grp, "roughness", &pinfo->roughness, 1); DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); @@ -252,7 +227,6 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_float(grp, "paddingSize", &pinfo->padding_size, 1); DRW_shgroup_uniform_float(grp, "fireflyFactor", &pinfo->firefly_fac, 1); DRW_shgroup_uniform_int(grp, "Layer", &pinfo->layer, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter); DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); @@ -270,10 +244,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_int(grp, "probeSize", &pinfo->shres, 1); #else DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); #endif DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); @@ -292,11 +264,9 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_float(grp, "visibilityRange", &pinfo->visibility_range, 1); DRW_shgroup_uniform_float(grp, "visibilityBlur", &pinfo->visibility_blur, 1); DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); DRW_shgroup_uniform_float(grp, "storedTexelSize", &pinfo->texel_size, 1); DRW_shgroup_uniform_float(grp, "nearClip", &pinfo->near_clip, 1); DRW_shgroup_uniform_float(grp, "farClip", &pinfo->far_clip, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); @@ -1078,10 +1048,7 @@ void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata, CLAMP(filter_quality, 1.0f, 8.0f); pinfo->samples_len *= filter_quality; - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; - pinfo->lodfactor = bias + - 0.5f * log((float)(target_size * target_size) * pinfo->samples_len_inv) / - log(2); + pinfo->lodfactor = bias + 0.5f * log(square_f(target_size) / pinfo->samples_len) / log(2); pinfo->firefly_fac = (firefly_fac > 0.0) ? firefly_fac : 1e16; GPU_framebuffer_ensure_config(&fb, @@ -1129,10 +1096,7 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata, #ifndef IRRADIANCE_SH_L2 /* Tweaking parameters to balance perf. vs precision */ const float bias = 0.0f; - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; - pinfo->lodfactor = bias + 0.5f * - log((float)(target_size * target_size) * pinfo->samples_len_inv) / - log(2); + pinfo->lodfactor = bias + 0.5f * log(square_f(target_size) / pinfo->samples_len) / log(2); pinfo->lod_rt_max = log2_floor_u(target_size) - 2.0f; #else pinfo->shres = 32; /* Less texture fetches & reduce branches */ @@ -1170,7 +1134,6 @@ void EEVEE_lightbake_filter_visibility(EEVEE_ViewLayerData *sldata, LightCache *light_cache = vedata->stl->g_data->light_cache; pinfo->samples_len = 512.0f; /* TODO refine */ - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; pinfo->shres = vis_size; pinfo->visibility_range = vis_range; pinfo->visibility_blur = vis_blur; @@ -1293,9 +1256,7 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) void EEVEE_lightprobes_free(void) { - MEM_SAFE_FREE(e_data.format_probe_display_cube); MEM_SAFE_FREE(e_data.format_probe_display_planar); - DRW_TEXTURE_FREE_SAFE(e_data.hammersley); DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder); DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder); DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 1ffd4a071f1..d03f52fd3a2 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -63,7 +63,6 @@ extern struct DrawEngineType draw_engine_eevee_type; /* Only define one of these. */ // #define IRRADIANCE_SH_L2 #define IRRADIANCE_HL2 -#define HAMMERSLEY_SIZE 1024 #if defined(IRRADIANCE_SH_L2) # define SHADER_IRRADIANCE "#define IRRADIANCE_SH_L2\n" @@ -608,7 +607,6 @@ typedef struct EEVEE_LightProbesInfo { float texel_size; float padding_size; float samples_len; - float samples_len_inv; float near_clip; float far_clip; float roughness; @@ -1180,7 +1178,6 @@ void EEVEE_sample_ellipse(int sample_ofs, void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]); /* eevee_shaders.c */ -void EEVEE_shaders_lightprobe_shaders_init(void); void EEVEE_shaders_material_shaders_init(void); struct DRWShaderLibrary *EEVEE_shader_lib_get(void); struct GPUShader *EEVEE_shaders_bloom_blit_get(bool high_quality); diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index 74c4803928a..b704521ce39 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -41,11 +41,11 @@ #include "eevee_engine.h" #include "eevee_private.h" -static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n" +static const char *filter_defines = #if defined(IRRADIANCE_SH_L2) - "#define IRRADIANCE_SH_L2\n"; + "#define IRRADIANCE_SH_L2\n"; #elif defined(IRRADIANCE_HL2) - "#define IRRADIANCE_HL2\n"; + "#define IRRADIANCE_HL2\n"; #endif static struct { @@ -252,6 +252,7 @@ extern char datatoc_object_motion_vert_glsl[]; extern char datatoc_octahedron_lib_glsl[]; extern char datatoc_prepass_frag_glsl[]; extern char datatoc_prepass_vert_glsl[]; +extern char datatoc_random_lib_glsl[]; extern char datatoc_raytrace_lib_glsl[]; extern char datatoc_renderpass_lib_glsl[]; extern char datatoc_renderpass_postprocess_frag_glsl[]; @@ -286,6 +287,7 @@ static void eevee_shader_library_ensure(void) DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib); DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib); + DRW_SHADER_LIB_ADD(e_data.lib, random_lib); DRW_SHADER_LIB_ADD(e_data.lib, renderpass_lib); DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_utiltex_lib); @@ -320,35 +322,6 @@ static void eevee_shader_library_ensure(void) } } -void EEVEE_shaders_lightprobe_shaders_init(void) -{ - BLI_assert(e_data.probe_filter_glossy_sh == NULL); - - eevee_shader_library_ensure(); - - e_data.probe_filter_glossy_sh = DRW_shader_create_with_shaderlib( - datatoc_lightprobe_vert_glsl, - datatoc_lightprobe_geom_glsl, - datatoc_lightprobe_filter_glossy_frag_glsl, - e_data.lib, - filter_defines); - - e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines); - - e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines); - - e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_lightprobe_grid_fill_frag_glsl, e_data.lib, filter_defines); - - e_data.probe_planar_downsample_sh = DRW_shader_create( - datatoc_lightprobe_planar_downsample_vert_glsl, - datatoc_lightprobe_planar_downsample_geom_glsl, - datatoc_lightprobe_planar_downsample_frag_glsl, - NULL); -} - void EEVEE_shaders_material_shaders_init(void) { eevee_shader_library_ensure(); @@ -362,26 +335,53 @@ DRWShaderLibrary *EEVEE_shader_lib_get(void) GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void) { + if (e_data.probe_filter_glossy_sh == NULL) { + e_data.probe_filter_glossy_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_vert_glsl, + datatoc_lightprobe_geom_glsl, + datatoc_lightprobe_filter_glossy_frag_glsl, + e_data.lib, + filter_defines); + } return e_data.probe_filter_glossy_sh; } GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void) { + if (e_data.probe_filter_diffuse_sh == NULL) { + e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines); + } return e_data.probe_filter_diffuse_sh; } GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void) { + if (e_data.probe_filter_visibility_sh == NULL) { + e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines); + } return e_data.probe_filter_visibility_sh; } GPUShader *EEVEE_shaders_probe_grid_fill_sh_get(void) { + if (e_data.probe_grid_fill_sh == NULL) { + e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_grid_fill_frag_glsl, e_data.lib, filter_defines); + } return e_data.probe_grid_fill_sh; } GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void) { + if (e_data.probe_planar_downsample_sh == NULL) { + e_data.probe_planar_downsample_sh = DRW_shader_create( + datatoc_lightprobe_planar_downsample_vert_glsl, + datatoc_lightprobe_planar_downsample_geom_glsl, + datatoc_lightprobe_planar_downsample_frag_glsl, + NULL); + } return e_data.probe_planar_downsample_sh; } @@ -588,7 +588,7 @@ GPUShader *EEVEE_shaders_ggx_refraction_lut_sh_get(void) { if (e_data.ggx_refraction_lut_sh == NULL) { e_data.ggx_refraction_lut_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_btdf_lut_frag_glsl, e_data.lib, "#define HAMMERSLEY_SIZE 8192\n"); + datatoc_btdf_lut_frag_glsl, e_data.lib, NULL); } return e_data.ggx_refraction_lut_sh; } diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl index c190ca0e245..7ce95a4aff2 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl @@ -1,32 +1,14 @@ +/** + * Sampling distribution routines for Monte-carlo integration. + **/ + #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) -uniform sampler1D texHammersley; - -vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) -{ - return T * vector.x + B * vector.y + N * vector.z; -} - -vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) -{ - return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); -} - -#ifdef HAMMERSLEY_SIZE -vec3 hammersley_3d(float i, float invsamplenbr) -{ - vec3 Xi; /* Theta, cos(Phi), sin(Phi) */ - - Xi.x = i * invsamplenbr; - Xi.yz = texelFetch(texHammersley, int(i), 0).rg; - - return Xi; -} -#endif - -/* -------------- BSDFS -------------- */ +/* -------------------------------------------------------------------- */ +/** \name Microfacet GGX distribution + * \{ */ #define USE_VISIBLE_NORMAL 1 @@ -89,12 +71,18 @@ vec3 sample_ggx(vec3 rand, float alpha, vec3 V, vec3 N, vec3 T, vec3 B, out floa return tangent_to_world(Ht, N, T, B); } -float pdf_hemisphere() +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniform Hemisphere + * \{ */ + +float pdf_uniform_hemisphere() { return 0.5 * M_1_PI; } -vec3 sample_hemisphere(vec3 rand) +vec3 sample_uniform_hemisphere(vec3 rand) { float z = rand.x; /* cos theta */ float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */ @@ -103,45 +91,33 @@ vec3 sample_hemisphere(vec3 rand) return vec3(x, y, z); } -vec3 sample_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B, out float pdf) +vec3 sample_uniform_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B, out float pdf) { - vec3 Ht = sample_hemisphere(rand); - pdf = pdf_hemisphere(); + vec3 Ht = sample_uniform_hemisphere(rand); + pdf = pdf_uniform_hemisphere(); return tangent_to_world(Ht, N, T, B); } -#ifdef HAMMERSLEY_SIZE -vec3 sample_ggx(float nsample, - float inv_sample_count, - float alpha, - vec3 V, - vec3 N, - vec3 T, - vec3 B, - out float pdf) -{ - vec3 Xi = hammersley_3d(nsample, inv_sample_count); - return sample_ggx(Xi, alpha, V, N, T, B, pdf); -} +/** \} */ -vec3 sample_hemisphere( - float nsample, float inv_sample_count, vec3 N, vec3 T, vec3 B, out float pdf) -{ - vec3 Xi = hammersley_3d(nsample, inv_sample_count); - return sample_hemisphere(Xi, N, T, B, pdf); -} +/* -------------------------------------------------------------------- */ +/** \name Uniform Cone sampling + * \{ */ -vec3 sample_cone(float nsample, float inv_sample_count, float angle, vec3 N, vec3 T, vec3 B) +vec3 sample_uniform_cone(vec3 rand, float angle) { - vec3 Xi = hammersley_3d(nsample, inv_sample_count); - - float z = cos(angle * Xi.x); /* cos theta */ + float z = cos(angle * rand.x); /* cos theta */ float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */ - float x = r * Xi.y; - float y = r * Xi.z; - - vec3 Ht = vec3(x, y, z); + float x = r * rand.y; + float y = r * rand.z; + return vec3(x, y, z); +} +vec3 sample_uniform_cone(vec3 rand, float angle, vec3 N, vec3 T, vec3 B) +{ + vec3 Ht = sample_uniform_cone(rand, angle); + /* TODO pdf? */ return tangent_to_world(Ht, N, T, B); } -#endif + +/** \} */ diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl index 18fcfd4fd41..9ecc50d9df5 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl @@ -1,4 +1,5 @@ +#pragma BLENDER_REQUIRE(random_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(irradiance_lib.glsl) @@ -10,7 +11,6 @@ uniform float lodMax; uniform float intensityFac; uniform float sampleCount; -uniform float invSampleCount; in vec3 worldPosition; @@ -147,8 +147,10 @@ void main() float weight = 0.0; vec3 out_radiance = vec3(0.0); for (float i = 0; i < sampleCount; i++) { + vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount)); + float pdf; - vec3 L = sample_hemisphere(i, invSampleCount, N, T, B, pdf); + vec3 L = sample_uniform_hemisphere(Xi, N, T, B, pdf); float NL = dot(N, L); if (NL > 0.0) { diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl index 99cbf2839ad..11fc1fb4295 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl @@ -1,4 +1,5 @@ +#pragma BLENDER_REQUIRE(random_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) @@ -12,7 +13,6 @@ uniform float intensityFac; uniform float fireflyFactor; uniform float sampleCount; -uniform float invSampleCount; in vec3 worldPosition; @@ -52,9 +52,11 @@ void main() float weight = 0.0; vec3 out_radiance = vec3(0.0); for (float i = 0; i < sampleCount; i++) { + vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount)); + float pdf; /* Microfacet normal */ - vec3 H = sample_ggx(i, invSampleCount, roughness, V, N, T, B, pdf); + vec3 H = sample_ggx(Xi, roughness, V, N, T, B, pdf); vec3 L = -reflect(V, H); float NL = dot(N, L); diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl index b802b39c56e..d25ef23a706 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl @@ -1,4 +1,5 @@ +#pragma BLENDER_REQUIRE(random_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(irradiance_lib.glsl) @@ -14,7 +15,7 @@ uniform float visibilityRange; uniform float visibilityBlur; uniform float sampleCount; -uniform float invSampleCount; +uniform float; out vec4 FragColor; @@ -80,13 +81,15 @@ void main() vec2 accum = vec2(0.0); for (float i = 0; i < sampleCount; i++) { - vec3 samp = sample_cone(i, invSampleCount, M_PI_2 * visibilityBlur, cos, T, B); + vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount)); + + vec3 samp = sample_uniform_cone(Xi, M_PI_2 * visibilityBlur, cos, T, B); float depth = texture(probeDepth, samp).r; depth = get_world_distance(depth, samp); accum += vec2(depth, depth * depth); } - accum *= invSampleCount; + accum /= sampleCount; accum = abs(accum); /* Encode to normalized RGBA 8 */ diff --git a/source/blender/draw/engines/eevee/shaders/random_lib.glsl b/source/blender/draw/engines/eevee/shaders/random_lib.glsl new file mode 100644 index 00000000000..25a3e0f56b4 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/random_lib.glsl @@ -0,0 +1,38 @@ + +/** + * Random numbers and low discrepency sequences utilities. + **/ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + +/* From: http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */ +float van_der_corput_radical_inverse(uint bits) +{ + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + /* Same as dividing by 0x100000000. */ + return float(bits) * 2.3283064365386963e-10; +} + +vec2 hammersley_2d(float i, float sample_count) +{ + vec2 rand; + rand.x = i / sample_count; + rand.y = van_der_corput_radical_inverse(uint(i)); + return rand; +} + +/* This transform a 2d random sample (in [0..1] range) to a sample located on a cylinder of the + * same range. This is because the sampling functions expect such a random sample which is + * normally precomputed. */ +vec3 rand2d_to_cylinder(vec2 rand) +{ + float theta = rand.x; + float phi = (rand.y - 0.5) * M_2PI; + float cos_phi = cos(phi); + float sin_phi = sqrt(1.0 - sqr(cos_phi)) * sign(phi); + return vec3(theta, cos_phi, sin_phi); +} diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl index 643d7e7d942..6b0a7b028ee 100644 --- a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl @@ -116,4 +116,14 @@ vec3 normal_decode(vec2 enc, vec3 view) return n; } +vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) +{ + return T * vector.x + B * vector.y + N * vector.z; +} + +vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) +{ + return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); +} + /** \} */ diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index 8ab626ed7ba..126e7230843 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -288,7 +288,6 @@ TEST_F(DrawTest, overlay_glsl_shaders) TEST_F(DrawTest, eevee_glsl_shaders_static) { - EEVEE_shaders_lightprobe_shaders_init(); EEVEE_shaders_material_shaders_init(); EXPECT_NE(EEVEE_shaders_bloom_blit_get(false), nullptr); -- cgit v1.2.3