1
1

Compare commits

..

10 Commits

121 changed files with 1883 additions and 2711 deletions

View File

@@ -143,6 +143,7 @@ set(SRC
engines/overlay/overlay_outline.c
engines/overlay/overlay_paint.c
engines/overlay/overlay_particle.c
engines/overlay/overlay_pointcloud.c
engines/overlay/overlay_sculpt.c
engines/overlay/overlay_shader.c
engines/overlay/overlay_wireframe.c
@@ -185,11 +186,10 @@ set(LIB
)
data_to_c_simple(engines/eevee/shaders/ambient_occlusion_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/concentric_samples_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/closure_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/common_uniforms_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/common_utiltex_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lights_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)
@@ -204,8 +204,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_grid_display_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_grid_fill_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lookdev_world_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/closure_lit_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
@@ -229,7 +229,6 @@ data_to_c_simple(engines/eevee/shaders/object_motion_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
@@ -240,9 +239,13 @@ 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/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)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/surface_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/surface_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/surface_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_lib.glsl SRC)
@@ -270,7 +273,6 @@ data_to_c_simple(engines/workbench/shaders/workbench_material_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_merge_infront_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_hair_vert.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_vert.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_shader_interface_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.glsl SRC)
@@ -285,9 +287,10 @@ data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_colormanagement_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_globals_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_pointcloud_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_hair_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC)
data_to_c_simple(intern/shaders/common_math_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_math_geom_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_view_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_fxaa_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_smaa_lib.glsl SRC)

View File

@@ -54,24 +54,30 @@ extern char datatoc_common_view_lib_glsl[];
static void eevee_create_shader_depth_of_field(const bool use_alpha)
{
char *frag = BLI_string_joinN(datatoc_common_view_lib_glsl, datatoc_effect_dof_frag_glsl);
e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen(
frag,
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_dof_frag_glsl,
lib,
use_alpha ? "#define USE_ALPHA_DOF\n"
"#define STEP_DOWNSAMPLE\n" :
"#define STEP_DOWNSAMPLE\n");
e_data.dof_scatter_sh[use_alpha] = DRW_shader_create(datatoc_effect_dof_vert_glsl,
NULL,
frag,
use_alpha ? "#define USE_ALPHA_DOF\n"
"#define STEP_SCATTER\n" :
"#define STEP_SCATTER\n");
e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen(frag,
use_alpha ?
"#define USE_ALPHA_DOF\n"
"#define STEP_RESOLVE\n" :
"#define STEP_RESOLVE\n");
MEM_freeN(frag);
e_data.dof_scatter_sh[use_alpha] = DRW_shader_create_with_shaderlib(
datatoc_effect_dof_vert_glsl,
NULL,
datatoc_effect_dof_frag_glsl,
lib,
use_alpha ? "#define USE_ALPHA_DOF\n"
"#define STEP_SCATTER\n" :
"#define STEP_SCATTER\n");
e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_dof_frag_glsl,
lib,
use_alpha ? "#define USE_ALPHA_DOF\n"
"#define STEP_RESOLVE\n" :
"#define STEP_RESOLVE\n");
}
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata),

View File

@@ -53,9 +53,6 @@
#if defined(IRRADIANCE_SH_L2)
# define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
# define IRRADIANCE_SAMPLE_SIZE_Y 4 /* 3 in reality */
#elif defined(IRRADIANCE_CUBEMAP)
# define IRRADIANCE_SAMPLE_SIZE_X 8
# define IRRADIANCE_SAMPLE_SIZE_Y 8
#elif defined(IRRADIANCE_HL2)
# define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
# define IRRADIANCE_SAMPLE_SIZE_Y 2

View File

@@ -179,8 +179,6 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (!sldata->fallback_lightcache) {
#if defined(IRRADIANCE_SH_L2)
int grid_res = 4;
#elif defined(IRRADIANCE_CUBEMAP)
int grid_res = 8;
#elif defined(IRRADIANCE_HL2)
int grid_res = 4;
#endif
@@ -328,38 +326,28 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
{
DRW_PASS_CREATE(psl->probe_background, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = NULL;
EEVEE_lookdev_cache_init(vedata, sldata, psl->probe_background, pinfo, &grp);
Scene *scene = draw_ctx->scene;
World *wo = scene->world;
if (grp == NULL) {
Scene *scene = draw_ctx->scene;
World *world = (scene->world) ? scene->world : EEVEE_world_default_get();
/* LookDev */
EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->probe_background, wo, pinfo);
if (!grp && wo) {
struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_WORLD_PROBE);
int options = VAR_WORLD_BACKGROUND;
struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
/* TODO (fclem): remove those (need to clean the GLSL files). */
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call(grp, geom, NULL);
}
/* Fallback if shader fails or if not using nodetree. */
if (grp == NULL) {
grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background);
DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1);
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
DRW_shgroup_call(grp, geom, NULL);
}
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
if (DRW_state_draw_support()) {
@@ -1114,9 +1102,6 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata,
/* NOTE : Keep in sync with load_irradiance_cell() */
#if defined(IRRADIANCE_SH_L2)
int size[2] = {3, 3};
#elif defined(IRRADIANCE_CUBEMAP)
int size[2] = {8, 8};
pinfo->samples_len = 1024.0f;
#elif defined(IRRADIANCE_HL2)
int size[2] = {3, 2};
pinfo->samples_len = 1024.0f;

View File

@@ -97,10 +97,9 @@ static void eevee_lookdev_hdri_preview_init(EEVEE_Data *vedata, EEVEE_ViewLayerD
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
DRWShadingGroup **r_grp,
DRWPass *pass,
World *UNUSED(world),
EEVEE_LightProbesInfo *pinfo)
EEVEE_LightProbesInfo *pinfo,
DRWShadingGroup **r_shgrp)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
@@ -153,91 +152,88 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
const View3DShading *shading = &v3d->shading;
StudioLight *sl = BKE_studiolight_find(shading->lookdev_light,
STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE);
if (sl && (sl->flag & STUDIOLIGHT_TYPE_WORLD)) {
GPUShader *shader = probe_render ? EEVEE_shaders_default_studiolight_sh_get() :
EEVEE_shaders_background_studiolight_sh_get();
if (sl == NULL || (sl->flag & STUDIOLIGHT_TYPE_WORLD) == 0) {
return;
}
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
int cube_res = scene_eval->eevee.gi_cubemap_resolution;
GPUShader *shader = probe_render ? EEVEE_shaders_studiolight_probe_sh_get() :
EEVEE_shaders_studiolight_background_sh_get();
/* If one of the component is missing we start from scratch. */
if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
(txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
(g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
eevee_lookdev_lightcache_delete(vedata);
}
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
int cube_res = scene_eval->eevee.gi_cubemap_resolution;
if (stl->lookdev_lightcache == NULL) {
/* If one of the component is missing we start from scratch. */
if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
(txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
(g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
eevee_lookdev_lightcache_delete(vedata);
}
if (stl->lookdev_lightcache == NULL) {
#if defined(IRRADIANCE_SH_L2)
int grid_res = 4;
#elif defined(IRRADIANCE_CUBEMAP)
int grid_res = 8;
int grid_res = 4;
#elif defined(IRRADIANCE_HL2)
int grid_res = 4;
int grid_res = 4;
#endif
stl->lookdev_lightcache = EEVEE_lightcache_create(
1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
stl->lookdev_lightcache = EEVEE_lightcache_create(
1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
/* XXX: Fix memleak. TODO find out why. */
MEM_SAFE_FREE(stl->lookdev_cube_mips);
/* XXX: Fix memleak. TODO find out why. */
MEM_SAFE_FREE(stl->lookdev_cube_mips);
/* We do this to use a special light cache for lookdev.
* This light-cache needs to be per viewport. But we need to
* have correct freeing when the viewport is closed. So we
* need to reference all textures to the txl and the memblocks
* to the stl. */
stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
}
/* We do this to use a special light cache for lookdev.
* This light-cache needs to be per viewport. But we need to
* have correct freeing when the viewport is closed. So we
* need to reference all textures to the txl and the memblocks
* to the stl. */
stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
}
g_data->light_cache = stl->lookdev_lightcache;
g_data->light_cache = stl->lookdev_lightcache;
DRWShadingGroup *grp = *r_grp = DRW_shgroup_create(shader, pass);
axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
if (probe_render) {
DRW_shgroup_uniform_float_copy(
grp, "studioLightIntensity", shading->studiolight_intensity);
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(grp, "image", sl->equirect_radiance_gputexture);
/* Do not fadeout when doing probe rendering, only when drawing the background */
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
}
else {
float background_alpha = g_data->background_alpha * shading->studiolight_background;
float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
}
if (probe_render) {
/* Avoid artifact with equirectangular mapping. */
eGPUSamplerState state = (GPU_SAMPLER_FILTER | GPU_SAMPLER_REPEAT_S);
DRW_shgroup_uniform_float_copy(grp, "studioLightIntensity", shading->studiolight_intensity);
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture_ex(grp, "studioLight", sl->equirect_radiance_gputexture, state);
/* Do not fadeout when doing probe rendering, only when drawing the background */
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
}
else {
float background_alpha = g_data->background_alpha * shading->studiolight_background;
float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
}
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
/* Common UBOs are setup latter. */
*r_shgrp = grp;
/* Do we need to recalc the lightprobes? */
if (g_data->studiolight_index != sl->index ||
g_data->studiolight_rot_z != shading->studiolight_rot_z ||
g_data->studiolight_intensity != shading->studiolight_intensity ||
g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
g_data->studiolight_index = sl->index;
g_data->studiolight_rot_z = shading->studiolight_rot_z;
g_data->studiolight_intensity = shading->studiolight_intensity;
g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
}
/* Do we need to recalc the lightprobes? */
if (g_data->studiolight_index != sl->index ||
g_data->studiolight_rot_z != shading->studiolight_rot_z ||
g_data->studiolight_intensity != shading->studiolight_intensity ||
g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
g_data->studiolight_index = sl->index;
g_data->studiolight_rot_z = shading->studiolight_rot_z;
g_data->studiolight_intensity = shading->studiolight_intensity;
g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
}
}
}

View File

@@ -31,6 +31,8 @@
#include "BLI_rand.h"
#include "BLI_string_utils.h"
#include "eevee_private.h"
extern char datatoc_bsdf_lut_frag_glsl[];
extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
@@ -45,15 +47,13 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
static float samples_len = 8192.0f;
static float inv_samples_len = 1.0f / 8192.0f;
char *lib_str = BLI_string_joinN(datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
struct GPUShader *sh = DRW_shader_create_with_lib(datatoc_lightprobe_vert_glsl,
datatoc_lightprobe_geom_glsl,
datatoc_bsdf_lut_frag_glsl,
lib_str,
"#define HAMMERSLEY_SIZE 8192\n"
"#define BRDF_LUT_SIZE 64\n"
"#define NOISE_SIZE 64\n");
struct GPUShader *sh = DRW_shader_create_with_shaderlib(datatoc_lightprobe_vert_glsl,
datatoc_lightprobe_geom_glsl,
datatoc_bsdf_lut_frag_glsl,
lib,
"#define HAMMERSLEY_SIZE 8192\n");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
@@ -106,16 +106,10 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
static float a2 = 0.0f;
static float inv_samples_len = 1.0f / 8192.0f;
char *frag_str = BLI_string_joinN(
datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl, datatoc_btdf_lut_frag_glsl);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
struct GPUShader *sh = DRW_shader_create_fullscreen(frag_str,
"#define HAMMERSLEY_SIZE 8192\n"
"#define BRDF_LUT_SIZE 64\n"
"#define NOISE_SIZE 64\n"
"#define LUT_SIZE 64\n");
MEM_freeN(frag_str);
struct GPUShader *sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_btdf_lut_frag_glsl, lib, "#define HAMMERSLEY_SIZE 8192\n");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);

View File

@@ -56,37 +56,6 @@ static struct {
float noise_offsets[3];
} e_data = {NULL}; /* Engine data */
extern char datatoc_lights_lib_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_prepass_frag_glsl[];
extern char datatoc_prepass_vert_glsl[];
extern char datatoc_default_frag_glsl[];
extern char datatoc_default_world_frag_glsl[];
extern char datatoc_ltc_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_lit_surface_frag_glsl[];
extern char datatoc_lit_surface_vert_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_ssr_lib_glsl[];
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_lightprobe_vert_glsl[];
extern char datatoc_background_vert_glsl[];
extern char datatoc_update_noise_frag_glsl[];
extern char datatoc_volumetric_vert_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_lib_glsl[];
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
typedef struct EeveeMaterialCache {
struct DRWShadingGroup *depth_grp;
struct DRWShadingGroup *shading_grp;
@@ -238,46 +207,6 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const d
DRW_draw_pass(psl->update_noise_pass);
}
void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4])
{
/* view vectors for the corners of the view frustum.
* Can be used to recreate the world space position easily */
float view_vecs[4][4] = {
{-1.0f, -1.0f, -1.0f, 1.0f},
{1.0f, -1.0f, -1.0f, 1.0f},
{-1.0f, 1.0f, -1.0f, 1.0f},
{-1.0f, -1.0f, 1.0f, 1.0f},
};
/* convert the view vectors to view space */
const bool is_persp = (winmat[3][3] == 0.0f);
for (int i = 0; i < 4; i++) {
mul_project_m4_v3(invproj, view_vecs[i]);
/* normalized trick see:
* http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
if (is_persp) {
/* Divide XY by Z. */
mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
}
}
/**
* If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
* view_vecs[1] is the vector going from the near-bottom-left corner to
* the far-top-right corner.
* If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
* when Z = 1, and top-left corner if Z = 1.
* view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
* distance from the near plane to the far clip plane.
*/
copy_v4_v4(r_viewvecs[0], view_vecs[0]);
/* we need to store the differences */
r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
}
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
EEVEE_StorageList *stl,
@@ -304,15 +233,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
sldata->common_data.alpha_hash_scale = 0.01f;
}
{
/* Update view_vecs */
float invproj[4][4], winmat[4][4];
DRW_view_winmat_get(NULL, winmat, false);
DRW_view_winmat_get(NULL, invproj, true);
EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
}
{
/* Update noise Framebuffer. */
GPU_framebuffer_ensure_config(
@@ -391,39 +311,28 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
DRW_PASS_CREATE(psl->background_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = NULL;
EEVEE_lookdev_cache_init(vedata, sldata, psl->background_ps, NULL, &grp);
Scene *scene = draw_ctx->scene;
World *wo = scene->world;
if (grp == NULL) {
Scene *scene = draw_ctx->scene;
World *world = (scene->world) ? scene->world : EEVEE_world_default_get();
EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->background_ps, wo, NULL);
if (!grp && wo) {
struct GPUMaterial *gpumat = EEVEE_material_get(
vedata, scene, NULL, wo, VAR_WORLD_BACKGROUND);
int options = VAR_WORLD_BACKGROUND;
struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
grp = DRW_shgroup_material_create(gpumat, psl->background_ps);
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
/* TODO (fclem): remove those (need to clean the GLSL files). */
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
DRW_shgroup_call(grp, geom, NULL);
}
/* Fallback if shader fails or if not using nodetree. */
if (grp == NULL) {
GPUShader *sh = EEVEE_shaders_default_background_sh_get();
grp = DRW_shgroup_create(sh, psl->background_ps);
DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1);
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
DRW_shgroup_call(grp, geom, NULL);
}
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
#define EEVEE_PASS_CREATE(pass, state) \

View File

@@ -56,14 +56,10 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
if (e_data.mist_sh == NULL) {
char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_effect_mist_frag_glsl);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
e_data.mist_sh = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
MEM_freeN(frag_str);
e_data.mist_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_mist_frag_glsl, lib, "#define FIRST_PASS\n");
}
/* Create FrameBuffer. */
@@ -98,11 +94,11 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
}
else {
float near = -sldata->common_data.view_vecs[0][2];
float range = sldata->common_data.view_vecs[1][2];
float near = DRW_view_near_distance_get(NULL);
float far = DRW_view_far_distance_get(NULL);
/* Fallback */
g_data->mist_start = near;
g_data->mist_inv_dist = 1.0f / fabsf(range);
g_data->mist_inv_dist = 1.0f / fabsf(far - near);
g_data->mist_falloff = 1.0f;
}

View File

@@ -68,27 +68,23 @@ extern char datatoc_common_view_lib_glsl[];
static void eevee_create_shader_motion_blur(void)
{
e_data.motion_blur_sh = DRW_shader_create_fullscreen(
datatoc_effect_motion_blur_frag_glsl,
"#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
e_data.motion_blur_object_sh = DRW_shader_create_with_lib(datatoc_object_motion_vert_glsl,
NULL,
datatoc_object_motion_frag_glsl,
datatoc_common_view_lib_glsl,
NULL);
e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(
datatoc_effect_velocity_tile_frag_glsl,
"#define TILE_GATHER\n"
"#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
e_data.velocity_tiles_expand_sh = DRW_shader_create_fullscreen(
datatoc_effect_velocity_tile_frag_glsl,
"#define TILE_EXPANSION\n"
"#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
#define TILE_SIZE_STR "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n"
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
e_data.motion_blur_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_motion_blur_frag_glsl, lib, TILE_SIZE_STR);
e_data.motion_blur_object_sh = DRW_shader_create_with_shaderlib(
datatoc_object_motion_vert_glsl, NULL, datatoc_object_motion_frag_glsl, lib, NULL);
char *vert = BLI_string_joinN(datatoc_common_hair_lib_glsl, datatoc_object_motion_vert_glsl);
e_data.motion_blur_hair_sh = DRW_shader_create_with_lib(
vert, NULL, datatoc_object_motion_frag_glsl, datatoc_common_view_lib_glsl, "#define HAIR\n");
MEM_freeN(vert);
e_data.motion_blur_hair_sh = DRW_shader_create_with_shaderlib(datatoc_object_motion_vert_glsl,
NULL,
datatoc_object_motion_frag_glsl,
lib,
"#define HAIR\n");
e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(datatoc_effect_velocity_tile_frag_glsl,
"#define TILE_GATHER\n" TILE_SIZE_STR);
e_data.velocity_tiles_expand_sh = DRW_shader_create_fullscreen(
datatoc_effect_velocity_tile_frag_glsl, "#define TILE_EXPANSION\n" TILE_SIZE_STR);
}
int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)

View File

@@ -53,17 +53,14 @@ extern char datatoc_effect_gtao_frag_glsl[];
static void eevee_create_shader_occlusion(void)
{
char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_effect_gtao_frag_glsl);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
e_data.gtao_sh = DRW_shader_create_fullscreen(frag_str, NULL);
e_data.gtao_layer_sh = DRW_shader_create_fullscreen(frag_str, "#define LAYERED_DEPTH\n");
e_data.gtao_debug_sh = DRW_shader_create_fullscreen(frag_str, "#define DEBUG_AO\n");
MEM_freeN(frag_str);
e_data.gtao_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_gtao_frag_glsl, lib, NULL);
e_data.gtao_layer_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_gtao_frag_glsl, lib, "#define LAYERED_DEPTH\n");
e_data.gtao_debug_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_gtao_frag_glsl, lib, "#define DEBUG_AO\n");
}
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)

View File

@@ -53,14 +53,11 @@ extern struct DrawEngineType draw_engine_eevee_type;
/* Only define one of these. */
// #define IRRADIANCE_SH_L2
// #define IRRADIANCE_CUBEMAP
#define IRRADIANCE_HL2
#define HAMMERSLEY_SIZE 1024
#if defined(IRRADIANCE_SH_L2)
# define SHADER_IRRADIANCE "#define IRRADIANCE_SH_L2\n"
#elif defined(IRRADIANCE_CUBEMAP)
# define SHADER_IRRADIANCE "#define IRRADIANCE_CUBEMAP\n"
#elif defined(IRRADIANCE_HL2)
# define SHADER_IRRADIANCE "#define IRRADIANCE_HL2\n"
#endif
@@ -750,7 +747,6 @@ typedef struct EEVEE_EffectsInfo {
* - sizeof(bool) == sizeof(int) in GLSL so use int in C */
typedef struct EEVEE_CommonUniformBuffer {
float prev_persmat[4][4]; /* mat4 */
float view_vecs[2][4]; /* vec4[2] */
float mip_ratio[10][4]; /* vec2[10] */
/* Ambient Occlusion */
/* -- 16 byte aligned -- */
@@ -1004,7 +1000,6 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_materials_free(void);
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]);
void EEVEE_material_renderpasses_init(EEVEE_Data *vedata);
void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -1060,15 +1055,14 @@ 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_probe_filter_glossy_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_default_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_fill_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void);
struct GPUShader *EEVEE_shaders_default_studiolight_sh_get(void);
struct GPUShader *EEVEE_shaders_default_background_sh_get(void);
struct GPUShader *EEVEE_shaders_background_studiolight_sh_get(void);
struct GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void);
struct GPUShader *EEVEE_shaders_studiolight_background_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void);
@@ -1080,6 +1074,7 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo);
Material *EEVEE_material_default_diffuse_get(void);
Material *EEVEE_material_default_glossy_get(void);
Material *EEVEE_material_default_error_get(void);
World *EEVEE_world_default_get(void);
struct GPUMaterial *EEVEE_material_default_get(struct Scene *scene, Material *ma, int options);
struct GPUMaterial *EEVEE_material_get(
EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options);
@@ -1303,10 +1298,9 @@ void EEVEE_render_update_passes(struct RenderEngine *engine,
/** eevee_lookdev.c */
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
DRWShadingGroup **grp,
DRWPass *pass,
struct World *world,
EEVEE_LightProbesInfo *pinfo);
EEVEE_LightProbesInfo *pinfo,
DRWShadingGroup **r_shgrp);
void EEVEE_lookdev_draw(EEVEE_Data *vedata);
/** eevee_engine.c */

View File

@@ -199,12 +199,10 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
EEVEE_RENDERPASSES_WITH_POST_PROCESSING) > 0;
if (needs_post_processing) {
if (e_data.postprocess_sh == NULL) {
char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_renderpass_postprocess_frag_glsl);
e_data.postprocess_sh = DRW_shader_create_fullscreen(frag_str, NULL);
MEM_freeN(frag_str);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
e_data.postprocess_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_renderpass_postprocess_frag_glsl, lib, NULL);
}
DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);

View File

@@ -48,30 +48,12 @@ static struct {
struct GPUTexture *depth_src;
} e_data = {{NULL}}; /* Engine data */
extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_effect_ssr_frag_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
{
if (e_data.ssr_sh[options] == NULL) {
char *ssr_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_effect_ssr_frag_glsl);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
DynStr *ds_defines = BLI_dynstr_new();
BLI_dynstr_append(ds_defines, SHADER_DEFINES);
@@ -91,9 +73,9 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines);
BLI_dynstr_free(ds_defines);
e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str);
e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_ssr_frag_glsl, lib, ssr_define_str);
MEM_freeN(ssr_shader_str);
MEM_freeN(ssr_define_str);
}

View File

@@ -28,6 +28,8 @@
#include "BLI_dynstr.h"
#include "BLI_string_utils.h"
#include "DNA_world_types.h"
#include "MEM_guardedalloc.h"
#include "GPU_material.h"
@@ -40,19 +42,17 @@
static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
#if defined(IRRADIANCE_SH_L2)
"#define IRRADIANCE_SH_L2\n"
#elif defined(IRRADIANCE_CUBEMAP)
"#define IRRADIANCE_CUBEMAP\n"
"#define IRRADIANCE_SH_L2\n";
#elif defined(IRRADIANCE_HL2)
"#define IRRADIANCE_HL2\n"
"#define IRRADIANCE_HL2\n";
#endif
"#define NOISE_SIZE 64\n";
static struct {
/* Lookdev */
struct GPUShader *studiolight_probe_sh;
struct GPUShader *studiolight_background_sh;
/* Probes */
struct GPUShader *probe_default_sh;
struct GPUShader *probe_default_studiolight_sh;
struct GPUShader *probe_background_studiolight_sh;
struct GPUShader *probe_grid_display_sh;
struct GPUShader *probe_cube_display_sh;
struct GPUShader *probe_planar_display_sh;
@@ -70,17 +70,13 @@ static struct {
struct GPUShader *taa_resolve_reproject_sh;
/* General purpose Shaders. */
struct GPUShader *default_background;
struct GPUShader *lookdev_background;
struct GPUShader *update_noise_sh;
/* Shader strings */
char *frag_shader_lib;
char *vert_shader_str;
char *vert_shadow_shader_str;
char *vert_background_shader_str;
char *vert_volume_shader_str;
char *geom_volume_shader_str;
char *volume_shader_lib;
char *surface_lit_frag;
DRWShaderLibrary *lib;
/* LookDev Materials */
Material *glossy_mat;
@@ -88,6 +84,8 @@ static struct {
Material *error_mat;
World *default_world;
/* Default Material */
struct {
bNodeTree *ntree;
@@ -103,16 +101,39 @@ static struct {
} world;
} e_data = {NULL}; /* Engine data */
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_common_math_lib_glsl[];
extern char datatoc_common_math_geom_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_background_vert_glsl[];
extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_lut_frag_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_closure_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_utiltex_lib_glsl[];
extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_default_world_frag_glsl[];
extern char datatoc_default_frag_glsl[];
extern char datatoc_lookdev_world_frag_glsl[];
extern char datatoc_effect_bloom_frag_glsl[];
extern char datatoc_effect_dof_frag_glsl[];
extern char datatoc_effect_dof_vert_glsl[];
extern char datatoc_effect_downsample_cube_frag_glsl[];
extern char datatoc_effect_downsample_frag_glsl[];
extern char datatoc_effect_gtao_frag_glsl[];
extern char datatoc_effect_minmaxz_frag_glsl[];
extern char datatoc_effect_mist_frag_glsl[];
extern char datatoc_effect_motion_blur_frag_glsl[];
extern char datatoc_effect_ssr_frag_glsl[];
extern char datatoc_effect_subsurface_frag_glsl[];
extern char datatoc_effect_temporal_aa_glsl[];
extern char datatoc_effect_translucency_frag_glsl[];
extern char datatoc_effect_velocity_resolve_frag_glsl[];
extern char datatoc_effect_velocity_tile_frag_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_cube_display_frag_glsl[];
extern char datatoc_lightprobe_cube_display_vert_glsl[];
@@ -131,72 +152,105 @@ extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
extern char datatoc_lightprobe_vert_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_lit_surface_frag_glsl[];
extern char datatoc_lit_surface_vert_glsl[];
extern char datatoc_closure_lit_lib_glsl[];
extern char datatoc_ltc_lib_glsl[];
extern char datatoc_object_motion_frag_glsl[];
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_raytrace_lib_glsl[];
extern char datatoc_renderpass_lib_glsl[];
extern char datatoc_renderpass_postprocess_frag_glsl[];
extern char datatoc_shadow_accum_frag_glsl[];
extern char datatoc_shadow_frag_glsl[];
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_ssr_lib_glsl[];
extern char datatoc_surface_frag_glsl[];
extern char datatoc_surface_lib_glsl[];
extern char datatoc_surface_vert_glsl[];
extern char datatoc_update_noise_frag_glsl[];
extern char datatoc_volumetric_accum_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_integration_frag_glsl[];
extern char datatoc_volumetric_lib_glsl[];
extern char datatoc_volumetric_resolve_frag_glsl[];
extern char datatoc_volumetric_scatter_frag_glsl[];
extern char datatoc_volumetric_vert_glsl[];
/* Velocity Resolve */
extern char datatoc_effect_velocity_resolve_frag_glsl[];
/* Temporal Sampling */
extern char datatoc_effect_temporal_aa_glsl[];
/* *********** FUNCTIONS *********** */
static void eevee_shader_library_ensure(void)
{
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
/* NOTE: Theses needs to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
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, renderpass_lib);
DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_utiltex_lib);
DRW_SHADER_LIB_ADD(e_data.lib, bsdf_sampling_lib);
DRW_SHADER_LIB_ADD(e_data.lib, cubemap_lib);
DRW_SHADER_LIB_ADD(e_data.lib, raytrace_lib);
DRW_SHADER_LIB_ADD(e_data.lib, ambient_occlusion_lib);
DRW_SHADER_LIB_ADD(e_data.lib, octahedron_lib);
DRW_SHADER_LIB_ADD(e_data.lib, irradiance_lib);
DRW_SHADER_LIB_ADD(e_data.lib, lightprobe_lib);
DRW_SHADER_LIB_ADD(e_data.lib, ltc_lib);
DRW_SHADER_LIB_ADD(e_data.lib, lights_lib);
DRW_SHADER_LIB_ADD(e_data.lib, surface_lib);
DRW_SHADER_LIB_ADD(e_data.lib, volumetric_lib);
DRW_SHADER_LIB_ADD(e_data.lib, closure_lib);
DRW_SHADER_LIB_ADD(e_data.lib, ssr_lib);
/* Add one for each Closure */
char *lit_frag = BLI_string_joinN(datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
datatoc_closure_lit_lib_glsl,
"#define CLOSURE_FUNCTIONS\n",
datatoc_surface_frag_glsl);
e_data.surface_lit_frag = DRW_shader_library_create_shader_string(e_data.lib, lit_frag);
MEM_SAFE_FREE(lit_frag);
}
}
void EEVEE_shaders_lightprobe_shaders_init(void)
{
BLI_assert(e_data.probe_filter_glossy_sh == NULL);
char *shader_str = NULL;
shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_lightprobe_filter_glossy_frag_glsl);
eevee_shader_library_ensure();
e_data.probe_filter_glossy_sh = DRW_shader_create(
datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, shader_str, filter_defines);
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_default_sh = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
NULL,
datatoc_default_world_frag_glsl,
datatoc_common_view_lib_glsl,
NULL);
e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines);
MEM_freeN(shader_str);
e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines);
shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_lightprobe_filter_diffuse_frag_glsl);
e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
MEM_freeN(shader_str);
shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_lightprobe_filter_visibility_frag_glsl);
e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
MEM_freeN(shader_str);
e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen(datatoc_lightprobe_grid_fill_frag_glsl,
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,
@@ -207,60 +261,13 @@ void EEVEE_shaders_lightprobe_shaders_init(void)
void EEVEE_shaders_material_shaders_init(void)
{
e_data.frag_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_ssr_lib_glsl,
datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_ltc_lib_glsl,
datatoc_lights_lib_glsl,
/* Add one for each Closure */
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_volumetric_lib_glsl);
eevee_shader_library_ensure();
}
e_data.volume_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_ltc_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_volumetric_lib_glsl,
datatoc_volumetric_frag_glsl);
e_data.vert_shader_str = BLI_string_joinN(
datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_lit_surface_vert_glsl);
e_data.vert_shadow_shader_str = BLI_string_joinN(
datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_shadow_vert_glsl);
e_data.vert_background_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_background_vert_glsl);
e_data.vert_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_volumetric_vert_glsl);
e_data.geom_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_volumetric_geom_glsl);
DRWShaderLibrary *EEVEE_shader_lib_get(void)
{
eevee_shader_library_ensure();
return e_data.lib;
}
GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
@@ -268,11 +275,6 @@ GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
return e_data.probe_filter_glossy_sh;
}
GPUShader *EEVEE_shaders_probe_default_sh_get(void)
{
return e_data.probe_default_sh;
}
GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void)
{
return e_data.probe_filter_diffuse_sh;
@@ -293,59 +295,40 @@ GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void)
return e_data.probe_planar_downsample_sh;
}
GPUShader *EEVEE_shaders_default_studiolight_sh_get(void)
GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void)
{
if (e_data.probe_default_studiolight_sh == NULL) {
e_data.probe_default_studiolight_sh = DRW_shader_create_with_lib(
datatoc_background_vert_glsl,
NULL,
datatoc_default_world_frag_glsl,
datatoc_common_view_lib_glsl,
"#define LOOKDEV\n");
if (e_data.studiolight_probe_sh == NULL) {
e_data.studiolight_probe_sh = DRW_shader_create_with_shaderlib(datatoc_background_vert_glsl,
NULL,
datatoc_lookdev_world_frag_glsl,
e_data.lib,
SHADER_DEFINES);
}
return e_data.probe_default_studiolight_sh;
return e_data.studiolight_probe_sh;
}
GPUShader *EEVEE_shaders_background_studiolight_sh_get(void)
GPUShader *EEVEE_shaders_studiolight_background_sh_get(void)
{
if (e_data.probe_background_studiolight_sh == NULL) {
char *frag_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_default_world_frag_glsl);
e_data.probe_background_studiolight_sh = DRW_shader_create_with_lib(
if (e_data.studiolight_background_sh == NULL) {
e_data.studiolight_background_sh = DRW_shader_create_with_shaderlib(
datatoc_background_vert_glsl,
NULL,
frag_str,
datatoc_common_view_lib_glsl,
datatoc_lookdev_world_frag_glsl,
e_data.lib,
"#define LOOKDEV_BG\n" SHADER_DEFINES);
MEM_freeN(frag_str);
}
return e_data.probe_background_studiolight_sh;
return e_data.studiolight_background_sh;
}
GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
{
if (e_data.probe_cube_display_sh == NULL) {
char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_lightprobe_cube_display_frag_glsl);
char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_lightprobe_cube_display_vert_glsl);
e_data.probe_cube_display_sh = DRW_shader_create(vert_str, NULL, shader_str, SHADER_DEFINES);
MEM_freeN(vert_str);
MEM_freeN(shader_str);
e_data.probe_cube_display_sh = DRW_shader_create_with_shaderlib(
datatoc_lightprobe_cube_display_vert_glsl,
NULL,
datatoc_lightprobe_cube_display_frag_glsl,
e_data.lib,
SHADER_DEFINES);
}
return e_data.probe_cube_display_sh;
}
@@ -353,22 +336,12 @@ GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
{
if (e_data.probe_grid_display_sh == NULL) {
char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_lightprobe_grid_display_frag_glsl);
char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_lightprobe_grid_display_vert_glsl);
e_data.probe_grid_display_sh = DRW_shader_create(vert_str, NULL, shader_str, filter_defines);
MEM_freeN(vert_str);
MEM_freeN(shader_str);
e_data.probe_grid_display_sh = DRW_shader_create_with_shaderlib(
datatoc_lightprobe_grid_display_vert_glsl,
NULL,
datatoc_lightprobe_grid_display_frag_glsl,
e_data.lib,
filter_defines);
}
return e_data.probe_grid_display_sh;
}
@@ -376,16 +349,12 @@ GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void)
{
if (e_data.probe_planar_display_sh == NULL) {
char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_lightprobe_planar_display_vert_glsl);
char *shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_lightprobe_planar_display_frag_glsl);
e_data.probe_planar_display_sh = DRW_shader_create(vert_str, NULL, shader_str, NULL);
MEM_freeN(vert_str);
MEM_freeN(shader_str);
e_data.probe_planar_display_sh = DRW_shader_create_with_shaderlib(
datatoc_lightprobe_planar_display_vert_glsl,
NULL,
datatoc_lightprobe_planar_display_frag_glsl,
e_data.lib,
NULL);
}
return e_data.probe_planar_display_sh;
}
@@ -393,34 +362,17 @@ GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void)
GPUShader *EEVEE_shaders_velocity_resolve_sh_get(void)
{
if (e_data.velocity_resolve_sh == NULL) {
char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_effect_velocity_resolve_frag_glsl);
e_data.velocity_resolve_sh = DRW_shader_create_fullscreen(frag_str, NULL);
MEM_freeN(frag_str);
e_data.velocity_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_velocity_resolve_frag_glsl, e_data.lib, NULL);
}
return e_data.velocity_resolve_sh;
}
GPUShader *EEVEE_shaders_default_background_sh_get(void)
{
if (e_data.default_background == NULL) {
e_data.default_background = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
NULL,
datatoc_default_world_frag_glsl,
datatoc_common_view_lib_glsl,
NULL);
}
return e_data.default_background;
}
GPUShader *EEVEE_shaders_update_noise_sh_get(void)
{
if (e_data.update_noise_sh == NULL) {
e_data.update_noise_sh = DRW_shader_create_fullscreen(datatoc_update_noise_frag_glsl, NULL);
e_data.update_noise_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_update_noise_frag_glsl, e_data.lib, NULL);
}
return e_data.update_noise_sh;
}
@@ -437,13 +389,8 @@ GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects)
sh = &e_data.taa_resolve_sh;
}
if (*sh == NULL) {
char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_effect_temporal_aa_glsl);
*sh = DRW_shader_create_fullscreen(frag_str, define);
MEM_freeN(frag_str);
*sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_temporal_aa_glsl, e_data.lib, define);
}
return *sh;
@@ -583,6 +530,18 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo)
return e_data.world.ntree;
}
World *EEVEE_world_default_get(void)
{
if (e_data.default_world == NULL) {
e_data.default_world = BKE_id_new_nomain(ID_WO, "EEVEEE default world");
copy_v3_fl(&e_data.default_world->horr, 0.0f);
e_data.default_world->use_nodes = 0;
e_data.default_world->nodetree = NULL;
BLI_listbase_clear(&e_data.default_world->gpumaterial);
}
return e_data.default_world;
}
static char *eevee_get_defines(int options)
{
char *str = NULL;
@@ -635,13 +594,13 @@ static char *eevee_get_vert(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
str = BLI_strdup(e_data.vert_volume_shader_str);
str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_vert_glsl);
}
else if ((options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0) {
str = BLI_strdup(e_data.vert_background_shader_str);
str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_background_vert_glsl);
}
else {
str = BLI_strdup(e_data.vert_shader_str);
str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_surface_vert_glsl);
}
return str;
@@ -652,7 +611,7 @@ static char *eevee_get_geom(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
str = BLI_strdup(e_data.geom_volume_shader_str);
str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_geom_glsl);
}
return str;
@@ -663,13 +622,13 @@ static char *eevee_get_frag(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
str = BLI_strdup(e_data.volume_shader_lib);
str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_frag_glsl);
}
else if ((options & VAR_MAT_DEPTH) != 0) {
str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_prepass_frag_glsl);
str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_prepass_frag_glsl);
}
else {
str = BLI_strdup(e_data.frag_shader_lib);
str = BLI_strdup(e_data.surface_lit_frag);
}
return str;
@@ -764,30 +723,28 @@ struct GPUMaterial *EEVEE_material_get(
void EEVEE_shaders_free(void)
{
MEM_SAFE_FREE(e_data.frag_shader_lib);
MEM_SAFE_FREE(e_data.vert_shader_str);
MEM_SAFE_FREE(e_data.vert_shadow_shader_str);
MEM_SAFE_FREE(e_data.vert_background_shader_str);
MEM_SAFE_FREE(e_data.vert_volume_shader_str);
MEM_SAFE_FREE(e_data.geom_volume_shader_str);
MEM_SAFE_FREE(e_data.volume_shader_lib);
DRW_SHADER_FREE_SAFE(e_data.default_background);
MEM_SAFE_FREE(e_data.surface_lit_frag);
DRW_SHADER_FREE_SAFE(e_data.lookdev_background);
DRW_SHADER_FREE_SAFE(e_data.update_noise_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_visibility_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_fill_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_background_studiolight_sh);
DRW_SHADER_FREE_SAFE(e_data.studiolight_probe_sh);
DRW_SHADER_FREE_SAFE(e_data.studiolight_background_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh);
DRW_SHADER_FREE_SAFE(e_data.velocity_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_reproject_sh);
DRW_SHADER_LIB_FREE_SAFE(e_data.lib);
if (e_data.default_world) {
BKE_id_free(NULL, e_data.default_world);
e_data.default_world = NULL;
}
if (e_data.glossy_mat) {
BKE_id_free(NULL, e_data.glossy_mat);
e_data.glossy_mat = NULL;

View File

@@ -42,11 +42,6 @@ static struct {
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_shadow_frag_glsl[];
extern char datatoc_shadow_accum_frag_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh)
{
@@ -65,23 +60,13 @@ void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (!e_data.shadow_sh) {
e_data.shadow_sh = DRW_shader_create_with_lib(datatoc_shadow_vert_glsl,
NULL,
datatoc_shadow_frag_glsl,
datatoc_common_view_lib_glsl,
NULL);
}
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
if (!e_data.shadow_accum_sh) {
char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_shadow_accum_frag_glsl);
e_data.shadow_sh = DRW_shader_create_with_shaderlib(
datatoc_shadow_vert_glsl, NULL, datatoc_shadow_frag_glsl, lib, NULL);
e_data.shadow_accum_sh = DRW_shader_create_fullscreen(frag_str, SHADER_DEFINES);
MEM_freeN(frag_str);
e_data.shadow_accum_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_shadow_accum_frag_glsl, lib, SHADER_DEFINES);
}
if (!sldata->lights) {

View File

@@ -38,41 +38,19 @@ static struct {
struct GPUShader *sss_sh[3];
} e_data = {{NULL}}; /* Engine data */
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_effect_subsurface_frag_glsl[];
extern char datatoc_effect_translucency_frag_glsl[];
static void eevee_create_shader_subsurface(void)
{
char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_effect_subsurface_frag_glsl);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
/* TODO(fclem) remove some of these dependencies. */
char *frag_translucent_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_effect_translucency_frag_glsl);
e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_translucent_str,
"#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
MEM_freeN(frag_translucent_str);
MEM_freeN(frag_str);
e_data.sss_sh[0] = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_subsurface_frag_glsl, lib, "#define FIRST_PASS\n");
e_data.sss_sh[1] = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_subsurface_frag_glsl, lib, "#define SECOND_PASS\n");
e_data.sss_sh[2] = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_effect_translucency_frag_glsl, lib, "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
}
void EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *UNUSED(vedata))

View File

@@ -51,9 +51,6 @@
#include "eevee_private.h"
static struct {
char *volumetric_common_lib;
char *volumetric_common_lights_lib;
struct GPUShader *volumetric_clear_sh;
struct GPUShader *scatter_sh;
struct GPUShader *scatter_with_lights_sh;
@@ -97,57 +94,48 @@ extern char datatoc_common_fullscreen_vert_glsl[];
static void eevee_create_shader_volumes(void)
{
e_data.volumetric_common_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_volumetric_lib_glsl);
DRWShaderLibrary *lib = EEVEE_shader_lib_get();
e_data.volumetric_common_lights_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_octahedron_lib_glsl,
datatoc_cubemap_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_volumetric_lib_glsl);
e_data.volumetric_clear_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_frag_glsl,
lib,
SHADER_DEFINES
"#define VOLUMETRICS\n"
"#define CLEAR\n");
e_data.volumetric_clear_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_frag_glsl,
e_data.volumetric_common_lib,
"#define VOLUMETRICS\n"
"#define CLEAR\n");
e_data.scatter_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_scatter_frag_glsl,
e_data.volumetric_common_lights_lib,
SHADER_DEFINES
"#define VOLUMETRICS\n"
"#define VOLUME_SHADOW\n");
e_data.scatter_with_lights_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_scatter_frag_glsl,
e_data.volumetric_common_lights_lib,
SHADER_DEFINES
"#define VOLUMETRICS\n"
"#define VOLUME_LIGHTING\n"
"#define VOLUME_SHADOW\n");
e_data.volumetric_integration_sh = DRW_shader_create_with_lib(
e_data.scatter_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_scatter_frag_glsl,
lib,
SHADER_DEFINES
"#define VOLUMETRICS\n"
"#define VOLUME_SHADOW\n");
e_data.scatter_with_lights_sh = DRW_shader_create_with_shaderlib(
datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_scatter_frag_glsl,
lib,
SHADER_DEFINES
"#define VOLUMETRICS\n"
"#define VOLUME_LIGHTING\n"
"#define VOLUME_SHADOW\n");
e_data.volumetric_integration_sh = DRW_shader_create_with_shaderlib(
datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_integration_frag_glsl,
e_data.volumetric_common_lib,
lib,
USE_VOLUME_OPTI ? "#extension GL_ARB_shader_image_load_store: enable\n"
"#extension GL_ARB_shading_language_420pack: enable\n"
"#define USE_VOLUME_OPTI\n" :
NULL);
e_data.volumetric_resolve_sh = DRW_shader_create_with_lib(datatoc_common_fullscreen_vert_glsl,
NULL,
datatoc_volumetric_resolve_frag_glsl,
e_data.volumetric_common_lib,
NULL);
e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl,
NULL);
"#define USE_VOLUME_OPTI\n" SHADER_DEFINES :
SHADER_DEFINES);
e_data.volumetric_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_volumetric_resolve_frag_glsl, lib, SHADER_DEFINES);
e_data.volumetric_accum_sh = DRW_shader_create_fullscreen_with_shaderlib(
datatoc_volumetric_accum_frag_glsl, lib, SHADER_DEFINES);
const float density[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, density);
@@ -259,17 +247,11 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->vol_shadow_steps = 0;
}
/* Update view_vecs */
float invproj[4][4], winmat[4][4];
DRW_view_winmat_get(NULL, winmat, false);
DRW_view_winmat_get(NULL, invproj, true);
EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
if (DRW_view_is_persp_get(NULL)) {
float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
sample_distribution = 4.0f * (max_ff(1.0f - sample_distribution, 1e-2f));
const float clip_start = common_data->view_vecs[0][2];
const float clip_start = DRW_view_near_distance_get(NULL);
/* Negate */
float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
float far = integration_end = min_ff(-integration_end, near - 1e-4f);
@@ -280,8 +262,8 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->vol_depth_param[2] = sample_distribution;
}
else {
const float clip_start = common_data->view_vecs[0][2];
const float clip_end = clip_start + common_data->view_vecs[1][2];
const float clip_start = DRW_view_near_distance_get(NULL);
const float clip_end = DRW_view_far_distance_get(NULL);
integration_start = min_ff(integration_end, clip_start);
integration_end = max_ff(-integration_end, clip_end);
@@ -848,9 +830,6 @@ void EEVEE_volumes_free_smoke_textures(void)
void EEVEE_volumes_free(void)
{
MEM_SAFE_FREE(e_data.volumetric_common_lib);
MEM_SAFE_FREE(e_data.volumetric_common_lights_lib);
DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter);
DRW_TEXTURE_FREE_SAFE(e_data.dummy_transmit);

View File

@@ -1,4 +1,7 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
/* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx
@@ -24,12 +27,6 @@
#define MAX_SEARCH_ITER 32
#define MAX_LOD 6.0
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
uniform sampler2D horizonBuffer;
/* aoSettings flags */
@@ -243,6 +240,11 @@ float gtao_multibounce(float visibility, vec3 albedo)
return max(x, ((x * a + b) * x + c) * x);
}
float specular_occlusion(float NV, float AO, float roughness)
{
return saturate(pow(NV + AO, roughness) - 1.0 + AO);
}
/* Use the right occlusion */
float occlusion_compute(vec3 N, vec3 vpos, float user_occlusion, vec4 rand, out vec3 bent_normal)
{

View File

@@ -1,17 +1,13 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
in vec2 pos;
out vec3 viewPosition;
#ifndef VOLUMETRICS
/* necessary for compilation*/
out vec3 worldPosition;
out vec3 worldNormal;
out vec3 viewNormal;
#endif
void main()
{
GPU_INTEL_VERTEX_SHADER_WORKAROUND
gl_Position = vec4(pos, 1.0, 1.0);
viewPosition = vec3(pos, -1.0);

View File

@@ -1,487 +1,7 @@
#define M_PI 3.14159265358979323846 /* pi */
#define M_2PI 6.28318530717958647692 /* 2*pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#define M_1_PI 0.318309886183790671538 /* 1/pi */
#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
#define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */
#define FLT_MAX 3.402823e+38
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#define LUT_SIZE 64
/* Buffers */
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
uniform sampler2D maxzBuffer;
uniform sampler2D minzBuffer;
uniform sampler2DArray planarDepth;
#define cameraForward ViewMatrixInverse[2].xyz
#define cameraPos ViewMatrixInverse[3].xyz
#define cameraVec \
((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
#define viewCameraVec \
((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0))
/* ------- Structures -------- */
/* ------ Lights ----- */
struct LightData {
vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */
vec4 color_spec; /* w : Spec Intensity */
vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */
};
/* convenience aliases */
#define l_color color_spec.rgb
#define l_spec color_spec.a
#define l_position position_influence.xyz
#define l_influence position_influence.w
#define l_sizex rightvec_sizex.w
#define l_sizey upvec_sizey.w
#define l_right rightvec_sizex.xyz
#define l_up upvec_sizey.xyz
#define l_forward forwardvec_type.xyz
#define l_type forwardvec_type.w
#define l_spot_size spotdata_radius_shadow.x
#define l_spot_blend spotdata_radius_shadow.y
#define l_radius spotdata_radius_shadow.z
#define l_shadowid spotdata_radius_shadow.w
/* ------ Shadows ----- */
#ifndef MAX_CASCADE_NUM
# define MAX_CASCADE_NUM 4
#endif
struct ShadowData {
vec4 near_far_bias_id;
vec4 contact_shadow_data;
};
struct ShadowCubeData {
mat4 shadowmat;
vec4 position;
};
struct ShadowCascadeData {
mat4 shadowmat[MAX_CASCADE_NUM];
vec4 split_start_distances;
vec4 split_end_distances;
vec4 shadow_vec_id;
};
/* convenience aliases */
#define sh_near near_far_bias_id.x
#define sh_far near_far_bias_id.y
#define sh_bias near_far_bias_id.z
#define sh_data_index near_far_bias_id.w
#define sh_contact_dist contact_shadow_data.x
#define sh_contact_offset contact_shadow_data.y
#define sh_contact_spread contact_shadow_data.z
#define sh_contact_thickness contact_shadow_data.w
#define sh_shadow_vec shadow_vec_id.xyz
#define sh_tex_index shadow_vec_id.w
/* ------ Render Passes ----- */
layout(std140) uniform renderpass_block
{
bool renderPassDiffuse;
bool renderPassDiffuseLight;
bool renderPassGlossy;
bool renderPassGlossyLight;
bool renderPassEmit;
bool renderPassSSSColor;
bool renderPassEnvironment;
};
vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
{
return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
}
vec3 render_pass_sss_mask(vec3 sss_color)
{
return renderPassSSSColor ? sss_color : vec3(0.0);
}
vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
{
return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
}
vec3 render_pass_emission_mask(vec3 emission_light)
{
return renderPassEmit ? emission_light : vec3(0.0);
}
/* ------- Convenience functions --------- */
vec3 mul(mat3 m, vec3 v)
{
return m * v;
}
mat3 mul(mat3 m1, mat3 m2)
{
return m1 * m2;
}
vec3 transform_direction(mat4 m, vec3 v)
{
return mat3(m) * v;
}
vec3 transform_point(mat4 m, vec3 v)
{
return (m * vec4(v, 1.0)).xyz;
}
vec3 project_point(mat4 m, vec3 v)
{
vec4 tmp = m * vec4(v, 1.0);
return tmp.xyz / tmp.w;
}
#define min3(a, b, c) min(a, min(b, c))
#define min4(a, b, c, d) min(a, min3(b, c, d))
#define min5(a, b, c, d, e) min(a, min4(b, c, d, e))
#define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f))
#define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g))
#define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h))
#define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i))
#define max3(a, b, c) max(a, max(b, c))
#define max4(a, b, c, d) max(a, max3(b, c, d))
#define max5(a, b, c, d, e) max(a, max4(b, c, d, e))
#define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f))
#define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g))
#define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h))
#define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i))
#define avg3(a, b, c) (a + b + c) * (1.0 / 3.0)
#define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0)
#define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0)
#define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0)
#define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0)
#define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0)
#define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0)
float min_v2(vec2 v)
{
return min(v.x, v.y);
}
float min_v3(vec3 v)
{
return min(v.x, min(v.y, v.z));
}
float min_v4(vec4 v)
{
return min(min(v.x, v.y), min(v.z, v.w));
}
float max_v2(vec2 v)
{
return max(v.x, v.y);
}
float max_v3(vec3 v)
{
return max(v.x, max(v.y, v.z));
}
float max_v4(vec4 v)
{
return max(max(v.x, v.y), max(v.z, v.w));
}
float sum(vec2 v)
{
return dot(vec2(1.0), v);
}
float sum(vec3 v)
{
return dot(vec3(1.0), v);
}
float sum(vec4 v)
{
return dot(vec4(1.0), v);
}
float avg(vec2 v)
{
return dot(vec2(1.0 / 2.0), v);
}
float avg(vec3 v)
{
return dot(vec3(1.0 / 3.0), v);
}
float avg(vec4 v)
{
return dot(vec4(1.0 / 4.0), v);
}
float saturate(float a)
{
return clamp(a, 0.0, 1.0);
}
vec2 saturate(vec2 a)
{
return clamp(a, 0.0, 1.0);
}
vec3 saturate(vec3 a)
{
return clamp(a, 0.0, 1.0);
}
vec4 saturate(vec4 a)
{
return clamp(a, 0.0, 1.0);
}
float distance_squared(vec2 a, vec2 b)
{
a -= b;
return dot(a, a);
}
float distance_squared(vec3 a, vec3 b)
{
a -= b;
return dot(a, a);
}
float len_squared(vec3 a)
{
return dot(a, a);
}
float inverse_distance(vec3 V)
{
return max(1 / length(V), 1e-8);
}
vec2 mip_ratio_interp(float mip)
{
float low_mip = floor(mip);
return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
}
/* ------- RNG ------- */
float wang_hash_noise(uint s)
{
s = (s ^ 61u) ^ (s >> 16u);
s *= 9u;
s = s ^ (s >> 4u);
s *= 0x27d4eb2du;
s = s ^ (s >> 15u);
return fract(float(s) / 4294967296.0);
}
/* ------- Fast Math ------- */
/* [Drobot2014a] Low Level Optimizations for GCN */
float fast_sqrt(float v)
{
return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
}
vec2 fast_sqrt(vec2 v)
{
return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
}
/* [Eberly2014] GPGPU Programming for Games and Science */
float fast_acos(float v)
{
float res = -0.156583 * abs(v) + M_PI_2;
res *= fast_sqrt(1.0 - abs(v));
return (v >= 0) ? res : M_PI - res;
}
vec2 fast_acos(vec2 v)
{
vec2 res = -0.156583 * abs(v) + M_PI_2;
res *= fast_sqrt(1.0 - abs(v));
v.x = (v.x >= 0) ? res.x : M_PI - res.x;
v.y = (v.y >= 0) ? res.y : M_PI - res.y;
return v;
}
float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal)
{
return dot(planenormal, planeorigin - lineorigin);
}
float line_plane_intersect_dist(vec3 lineorigin,
vec3 linedirection,
vec3 planeorigin,
vec3 planenormal)
{
return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
}
float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane)
{
vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz));
vec3 h = lineorigin - plane_co;
return -dot(plane.xyz, h) / dot(plane.xyz, linedirection);
}
vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
{
float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
return lineorigin + linedirection * dist;
}
vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane)
{
float dist = line_plane_intersect_dist(lineorigin, linedirection, plane);
return lineorigin + linedirection * dist;
}
float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
{
/* aligned plane normal */
vec3 L = planeorigin - lineorigin;
float diskdist = length(L);
vec3 planenormal = -normalize(L);
return -diskdist / dot(planenormal, linedirection);
}
vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
{
float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
if (dist < 0) {
/* if intersection is behind we fake the intersection to be
* really far and (hopefully) not inside the radius of interest */
dist = 1e16;
}
return lineorigin + linedirection * dist;
}
float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
{
float a = dot(linedirection, linedirection);
float b = dot(linedirection, lineorigin);
float c = dot(lineorigin, lineorigin) - 1;
float dist = 1e15;
float determinant = b * b - a * c;
if (determinant >= 0) {
dist = (sqrt(determinant) - b) / a;
}
return dist;
}
float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
{
/* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
*/
vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
vec3 furthestplane = max(firstplane, secondplane);
return min_v3(furthestplane);
}
/* Return texture coordinates to sample Surface LUT */
vec2 lut_coords(float cosTheta, float roughness)
{
float theta = acos(cosTheta);
vec2 coords = vec2(roughness, theta / M_PI_2);
/* scale and bias coordinates, for correct filtered lookup */
return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
}
vec2 lut_coords_ltc(float cosTheta, float roughness)
{
vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta));
/* scale and bias coordinates, for correct filtered lookup */
return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
}
/* -- Tangent Space conversion -- */
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));
}
void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
{
vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
T = normalize(cross(UpVector, N));
B = cross(N, T);
}
/* ---- Opengl Depth conversion ---- */
float linear_depth(bool is_persp, float z, float zf, float zn)
{
if (is_persp) {
return (zn * zf) / (z * (zn - zf) + zf);
}
else {
return (z * 2.0 - 1.0) * zf;
}
}
float buffer_depth(bool is_persp, float z, float zf, float zn)
{
if (is_persp) {
return (zf * (zn - z)) / (z * (zn - zf));
}
else {
return (z / (zf * 2.0)) + 0.5;
}
}
float get_view_z_from_depth(float depth)
{
if (ProjectionMatrix[3][3] == 0.0) {
float d = 2.0 * depth - 1.0;
return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
}
else {
return viewVecs[0].z + depth * viewVecs[1].z;
}
}
float get_depth_from_view_z(float z)
{
if (ProjectionMatrix[3][3] == 0.0) {
float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
return d * 0.5 + 0.5;
}
else {
return (z - viewVecs[0].z) / viewVecs[1].z;
}
}
vec2 get_uvs_from_view(vec3 view)
{
vec3 ndc = project_point(ProjectionMatrix, view);
return ndc.xy * 0.5 + 0.5;
}
vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
{
if (ProjectionMatrix[3][3] == 0.0) {
return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
}
else {
return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz;
}
}
vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
{
return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
}
vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
vec3 specular_dominant_dir(vec3 N, vec3 V, float roughness)
{
vec3 R = -reflect(V, N);
float smoothness = 1.0 - roughness;
@@ -489,13 +9,6 @@ vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
return normalize(mix(N, R, fac));
}
float specular_occlusion(float NV, float AO, float roughness)
{
return saturate(pow(NV + AO, roughness) - 1.0 + AO);
}
/* --- Refraction utils --- */
float ior_from_f0(float f0)
{
float f = sqrt(f0);
@@ -508,7 +21,7 @@ float f0_from_ior(float eta)
return A * A;
}
vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
vec3 refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
{
/* TODO: This a bad approximation. Better approximation should fit
* the refracted vector and roughness into the best prefiltered reflection
@@ -527,128 +40,6 @@ vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float
return R;
}
float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior)
{
const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
vec3 coords;
/* Try to compensate for the low resolution and interpolation error. */
coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) +
(0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) :
(0.9 + lut_scale_bias_texel_size.z) * ior * ior;
coords.y = 1.0 - saturate(NV);
coords.xy *= lut_scale_bias_texel_size.x;
coords.xy += lut_scale_bias_texel_size.y;
const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
float mip = roughness * lut_lvl_scale;
float mip_floor = floor(mip);
coords.z = lut_lvl_ofs + mip_floor + 1.0;
float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r;
coords.z -= 1.0;
float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r;
float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
return btdf;
}
/* ---- Encode / Decode Normal buffer data ---- */
/* From http://aras-p.info/texts/CompactNormalStorage.html
* Using Method #4: Spheremap Transform */
vec2 normal_encode(vec3 n, vec3 view)
{
float p = sqrt(n.z * 8.0 + 8.0);
return n.xy / p + 0.5;
}
vec3 normal_decode(vec2 enc, vec3 view)
{
vec2 fenc = enc * 4.0 - 2.0;
float f = dot(fenc, fenc);
float g = sqrt(1.0 - f / 4.0);
vec3 n;
n.xy = fenc * g;
n.z = 1 - f / 2;
return n;
}
/* ---- RGBM (shared multiplier) encoding ---- */
/* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */
/* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */
#define RGBM_MAX_RANGE 512.0
vec4 rgbm_encode(vec3 rgb)
{
float maxRGB = max_v3(rgb);
float M = maxRGB / RGBM_MAX_RANGE;
M = ceil(M * 255.0) / 255.0;
return vec4(rgb / (M * RGBM_MAX_RANGE), M);
}
vec3 rgbm_decode(vec4 data)
{
return data.rgb * (data.a * RGBM_MAX_RANGE);
}
/* ---- RGBE (shared exponent) encoding ---- */
vec4 rgbe_encode(vec3 rgb)
{
float maxRGB = max_v3(rgb);
float fexp = ceil(log2(maxRGB));
return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0);
}
vec3 rgbe_decode(vec4 data)
{
float fexp = data.a * 255.0 - 128.0;
return data.rgb * exp2(fexp);
}
#if 1
# define irradiance_encode rgbe_encode
# define irradiance_decode rgbe_decode
#else /* No ecoding (when using floating point format) */
# define irradiance_encode(X) (X).rgbb
# define irradiance_decode(X) (X).rgb
#endif
/* Irradiance Visibility Encoding */
#if 1
vec4 visibility_encode(vec2 accum, float range)
{
accum /= range;
vec4 data;
data.x = fract(accum.x);
data.y = floor(accum.x) / 255.0;
data.z = fract(accum.y);
data.w = floor(accum.y) / 255.0;
return data;
}
vec2 visibility_decode(vec4 data, float range)
{
return (data.xz + data.yw * 255.0) * range;
}
#else /* No ecoding (when using floating point format) */
vec4 visibility_encode(vec2 accum, float range)
{
return accum.xyxy;
}
vec2 visibility_decode(vec4 data, float range)
{
return data.xy;
}
#endif
/* Fresnel monochromatic, perfect mirror */
float F_eta(float eta, float cos_theta)
{
@@ -766,265 +157,3 @@ float cone_cosine(float r)
/* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/
return exp2(-3.32193 * r * r);
}
/* --------- Closure ---------- */
#ifdef VOLUMETRICS
struct Closure {
vec3 absorption;
vec3 scatter;
vec3 emission;
float anisotropy;
};
Closure nodetree_exec(void); /* Prototype */
# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0)
Closure closure_mix(Closure cl1, Closure cl2, float fac)
{
Closure cl;
cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
cl.emission = mix(cl1.emission, cl2.emission, fac);
cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
return cl;
}
Closure closure_add(Closure cl1, Closure cl2)
{
Closure cl;
cl.absorption = cl1.absorption + cl2.absorption;
cl.scatter = cl1.scatter + cl2.scatter;
cl.emission = cl1.emission + cl2.emission;
cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
return cl;
}
Closure closure_emission(vec3 rgb)
{
Closure cl = CLOSURE_DEFAULT;
cl.emission = rgb;
return cl;
}
#else /* VOLUMETRICS */
struct Closure {
vec3 radiance;
vec3 transmittance;
float holdout;
# ifdef USE_SSS
vec3 sss_irradiance;
vec3 sss_albedo;
float sss_radius;
# endif
vec4 ssr_data;
vec2 ssr_normal;
int flag;
};
Closure nodetree_exec(void); /* Prototype */
# define FLAG_TEST(flag, val) (((flag) & (val)) != 0)
# define CLOSURE_SSR_FLAG 1
# define CLOSURE_SSS_FLAG 2
# define CLOSURE_HOLDOUT_FLAG 4
# ifdef USE_SSS
# define CLOSURE_DEFAULT \
Closure(vec3(0.0), vec3(0.0), 0.0, vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
# else
# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
# endif
uniform int outputSsrId = 1;
uniform int outputSssId = 1;
void closure_load_ssr_data(
vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl)
{
/* Still encode to avoid artifacts in the SSR pass. */
vec3 vN = normalize(mat3(ViewMatrix) * N);
cl.ssr_normal = normal_encode(vN, viewVec);
if (ssr_id == outputSsrId) {
cl.ssr_data = vec4(ssr_spec, roughness);
cl.flag |= CLOSURE_SSR_FLAG;
}
}
void closure_load_sss_data(
float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
{
# ifdef USE_SSS
if (sss_id == outputSssId) {
cl.sss_irradiance = sss_irradiance;
cl.sss_radius = radius;
cl.sss_albedo = sss_albedo;
cl.flag |= CLOSURE_SSS_FLAG;
cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
}
else
# endif
{
cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
}
}
Closure closure_mix(Closure cl1, Closure cl2, float fac)
{
Closure cl;
cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) {
fac = 1.0;
}
else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) {
fac = 0.0;
}
cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
cl.flag = cl1.flag | cl2.flag;
cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac);
bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
/* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/
cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
# ifdef USE_SSS
cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
/* It also does not make sense to mix SSS radius or irradiance. */
cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
# endif
return cl;
}
Closure closure_add(Closure cl1, Closure cl2)
{
Closure cl;
cl.transmittance = cl1.transmittance + cl2.transmittance;
cl.radiance = cl1.radiance + cl2.radiance;
cl.holdout = cl1.holdout + cl2.holdout;
cl.flag = cl1.flag | cl2.flag;
cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
/* When mixing SSR don't blend roughness and normals.*/
cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
# ifdef USE_SSS
cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
/* It also does not make sense to mix SSS radius or irradiance. */
cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
# endif
return cl;
}
Closure closure_emission(vec3 rgb)
{
Closure cl = CLOSURE_DEFAULT;
cl.radiance = rgb;
return cl;
}
/* Breaking this across multiple lines causes issues for some older GLSL compilers. */
/* clang-format off */
# if defined(MESH_SHADER) && !defined(DEPTH_SHADER)
/* clang-format on */
# ifndef USE_ALPHA_BLEND
layout(location = 0) out vec4 outRadiance;
layout(location = 1) out vec2 ssrNormals;
layout(location = 2) out vec4 ssrData;
# ifdef USE_SSS
layout(location = 3) out vec3 sssIrradiance;
layout(location = 4) out float sssRadius;
layout(location = 5) out vec3 sssAlbedo;
# endif
# else /* USE_ALPHA_BLEND */
/* Use dual source blending to be able to make a whole range of effects. */
layout(location = 0, index = 0) out vec4 outRadiance;
layout(location = 0, index = 1) out vec4 outTransmittance;
# endif /* USE_ALPHA_BLEND */
# if defined(USE_ALPHA_BLEND)
/* Prototype because this file is included before volumetric_lib.glsl */
void volumetric_resolve(vec2 frag_uvs,
float frag_depth,
out vec3 transmittance,
out vec3 scattering);
# endif
# define NODETREE_EXEC
void main()
{
Closure cl = nodetree_exec();
float holdout = saturate(1.0 - cl.holdout);
float transmit = saturate(avg(cl.transmittance));
float alpha = 1.0 - transmit;
# ifdef USE_ALPHA_BLEND
vec2 uvs = gl_FragCoord.xy * volCoordScale.zw;
vec3 vol_transmit, vol_scatter;
volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter);
/* Removes part of the volume scattering that have
* already been added to the destination pixels.
* Since we do that using the blending pipeline we need to account for material transmittance. */
vol_scatter -= vol_scatter * cl.transmittance;
cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter;
outRadiance = vec4(cl.radiance, alpha * holdout);
outTransmittance = vec4(cl.transmittance, transmit) * holdout;
# else
outRadiance = vec4(cl.radiance, holdout);
ssrNormals = cl.ssr_normal;
ssrData = cl.ssr_data;
# ifdef USE_SSS
sssIrradiance = cl.sss_irradiance;
sssRadius = cl.sss_radius;
sssAlbedo = cl.sss_albedo;
# endif
# endif
/* For Probe capture */
# ifdef USE_SSS
float fac = float(!sssToggle);
/* TODO(fclem) we shouldn't need this.
* Just disable USE_SSS when USE_REFRACTION is enabled. */
# ifdef USE_REFRACTION
/* SSRefraction pass is done after the SSS pass.
* In order to not loose the diffuse light totally we
* need to merge the SSS radiance to the main radiance. */
fac = 1.0;
# endif
outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac;
# endif
# ifdef LOOKDEV
gl_FragDepth = 0.0;
# endif
# ifndef USE_ALPHA_BLEND
float alpha_div = 1.0 / max(1e-8, alpha);
outRadiance.rgb *= alpha_div;
ssrData.rgb *= alpha_div;
# ifdef USE_SSS
sssAlbedo.rgb *= alpha_div;
# endif
# endif
}
# endif /* MESH_SHADER */
#endif /* VOLUMETRICS */

View File

@@ -1,3 +1,4 @@
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
out vec4 FragColor;
@@ -5,8 +6,8 @@ void main()
{
vec3 N, T, B, V;
float NV = (1.0 - (clamp(gl_FragCoord.y / BRDF_LUT_SIZE, 1e-4, 0.9999)));
float sqrtRoughness = clamp(gl_FragCoord.x / BRDF_LUT_SIZE, 1e-4, 0.9999);
float NV = (1.0 - (clamp(gl_FragCoord.y / b, 1e-4, 0.9999)));
float sqrtRoughness = clamp(gl_FragCoord.x / LUT_SIZE, 1e-4, 0.9999);
float a = sqrtRoughness * sqrtRoughness;
float a2 = a * a;

View File

@@ -1,6 +1,7 @@
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
uniform sampler1D texHammersley;
uniform sampler2D texJitter;
uniform float sampleCount;
uniform float invSampleCount;
@@ -8,8 +9,7 @@ vec2 jitternoise = vec2(0.0);
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
void setup_noise(void)
@@ -17,6 +17,11 @@ void setup_noise(void)
jitternoise = texelfetch_noise_tex(gl_FragCoord.xy).rg; /* Global variable */
}
vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
{
return T * vector.x + B * vector.y + N * vector.z;
}
#ifdef HAMMERSLEY_SIZE
vec3 hammersley_3d(float i, float invsamplenbr)
{

View File

@@ -1,3 +1,4 @@
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
uniform float a2;
@@ -7,8 +8,8 @@ void main()
{
vec3 N, T, B, V;
float x = gl_FragCoord.x / BRDF_LUT_SIZE;
float y = gl_FragCoord.y / BRDF_LUT_SIZE;
float x = gl_FragCoord.x / LUT_SIZE;
float y = gl_FragCoord.y / LUT_SIZE;
/* There is little variation if ior > 1.0 so we
* maximize LUT precision for ior < 1.0 */
x = x * 1.1;

View File

@@ -0,0 +1,181 @@
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(renderpass_lib.glsl)
#ifndef VOLUMETRICS
uniform int outputSsrId = 1;
uniform int outputSssId = 1;
#endif
struct Closure {
#ifdef VOLUMETRICS
vec3 absorption;
vec3 scatter;
vec3 emission;
float anisotropy;
#else /* SURFACE */
vec3 radiance;
vec3 transmittance;
float holdout;
vec4 ssr_data;
vec2 ssr_normal;
int flag;
# ifdef USE_SSS
vec3 sss_irradiance;
vec3 sss_albedo;
float sss_radius;
# endif
#endif
};
/* Prototype */
Closure nodetree_exec(void);
/* clang-format off */
/* Avoid multiline defines. */
#ifdef VOLUMETRICS
# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), vec3(0), 0.0)
#elif !defined(USE_SSS)
# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0)
#else
# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0, vec3(0), vec3(0), 0.0)
#endif
/* clang-format on */
#define FLAG_TEST(flag, val) (((flag) & (val)) != 0)
#define CLOSURE_SSR_FLAG 1
#define CLOSURE_SSS_FLAG 2
#define CLOSURE_HOLDOUT_FLAG 4
#ifdef VOLUMETRICS
Closure closure_mix(Closure cl1, Closure cl2, float fac)
{
Closure cl;
cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
cl.emission = mix(cl1.emission, cl2.emission, fac);
cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
return cl;
}
Closure closure_add(Closure cl1, Closure cl2)
{
Closure cl;
cl.absorption = cl1.absorption + cl2.absorption;
cl.scatter = cl1.scatter + cl2.scatter;
cl.emission = cl1.emission + cl2.emission;
cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
return cl;
}
Closure closure_emission(vec3 rgb)
{
Closure cl = CLOSURE_DEFAULT;
cl.emission = rgb;
return cl;
}
#else /* SURFACE */
Closure closure_mix(Closure cl1, Closure cl2, float fac)
{
Closure cl;
cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) {
fac = 1.0;
}
else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) {
fac = 0.0;
}
cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
cl.flag = cl1.flag | cl2.flag;
cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac);
bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
/* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/
cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
# ifdef USE_SSS
cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
/* It also does not make sense to mix SSS radius or irradiance. */
cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
# endif
return cl;
}
Closure closure_add(Closure cl1, Closure cl2)
{
Closure cl;
cl.transmittance = cl1.transmittance + cl2.transmittance;
cl.radiance = cl1.radiance + cl2.radiance;
cl.holdout = cl1.holdout + cl2.holdout;
cl.flag = cl1.flag | cl2.flag;
cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
/* When mixing SSR don't blend roughness and normals.*/
cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
# ifdef USE_SSS
cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
/* It also does not make sense to mix SSS radius or irradiance. */
cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
# endif
return cl;
}
Closure closure_emission(vec3 rgb)
{
Closure cl = CLOSURE_DEFAULT;
cl.radiance = rgb;
return cl;
}
#endif
#ifndef VOLUMETRICS
void closure_load_ssr_data(
vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl)
{
/* Still encode to avoid artifacts in the SSR pass. */
vec3 vN = normalize(mat3(ViewMatrix) * N);
cl.ssr_normal = normal_encode(vN, viewVec);
if (ssr_id == outputSsrId) {
cl.ssr_data = vec4(ssr_spec, roughness);
cl.flag |= CLOSURE_SSR_FLAG;
}
}
void closure_load_sss_data(
float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
{
# ifdef USE_SSS
if (sss_id == outputSssId) {
cl.sss_irradiance = sss_irradiance;
cl.sss_radius = radius;
cl.sss_albedo = sss_albedo;
cl.flag |= CLOSURE_SSS_FLAG;
cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
}
else
# endif
{
cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
}
}
#endif

View File

@@ -1,32 +1,8 @@
#ifndef LIT_SURFACE_UNIFORM
# define LIT_SURFACE_UNIFORM
uniform float refractionDepth;
# ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
# endif /* UTIL_TEX */
in vec3 worldPosition;
in vec3 viewPosition;
in vec3 worldNormal;
in vec3 viewNormal;
# ifdef HAIR_SHADER
in vec3 hairTangent; /* world space */
in float hairThickTime;
in float hairThickness;
in float hairTime;
flat in int hairStrandID;
uniform int hairThicknessRes = 1;
# endif
#endif /* LIT_SURFACE_UNIFORM */
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
#pragma BLENDER_REQUIRE(ssr_lib.glsl)
/**
* AUTO CONFIG
@@ -209,7 +185,7 @@ void CLOSURE_NAME(vec3 N
vec3 V = cameraVec;
vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
/* ---------------------------------------------------------------- */
/* -------------------- SCENE LIGHTS LIGHTING --------------------- */
@@ -328,11 +304,11 @@ void CLOSURE_NAME(vec3 N
# endif
# ifdef CLOSURE_GLOSSY
vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared);
# endif
# ifdef CLOSURE_CLEARCOAT
vec3 C_spec_dir = get_specular_reflection_dominant_dir(C_N, V, C_roughnessSquared);
vec3 C_spec_dir = specular_dominant_dir(C_N, V, C_roughnessSquared);
# endif
# ifdef CLOSURE_REFRACTION
@@ -345,7 +321,7 @@ void CLOSURE_NAME(vec3 N
line_plane_intersect(
worldPosition, refr_V, worldPosition - N * refractionDepth, N) :
worldPosition;
vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, roughness, final_ior);
vec3 refr_dir = refraction_dominant_dir(N, refr_V, roughness, final_ior);
# endif
# ifdef CLOSURE_REFRACTION
@@ -485,7 +461,7 @@ void CLOSURE_NAME(vec3 N
# endif
# ifdef CLOSURE_REFRACTION
float btdf = get_btdf_lut(utilTex, NV, roughness, ior);
float btdf = get_btdf_lut(NV, roughness, ior);
out_refr += refr_accum.rgb * btdf;
# endif

View File

@@ -2,7 +2,6 @@
layout(std140) uniform common_block
{
mat4 pastViewProjectionMatrix;
vec4 viewVecs[2];
vec2 mipRatio[10]; /* To correct mip level texel misalignment */
/* Ambient Occlusion */
vec4 aoParameters[2];
@@ -70,3 +69,9 @@ layout(std140) uniform common_block
#define ssrQuality ssrParameters.x
#define ssrThickness ssrParameters.y
#define ssrPixelSize ssrParameters.zw
vec2 mip_ratio_interp(float mip)
{
float low_mip = floor(mip);
return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
}

View File

@@ -0,0 +1,65 @@
#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
/* ---------------------------------------------------------------------- */
/** \name Utiltex
*
* Utiltex is a sampler2DArray that stores a number of useful small utilitary textures and lookup
* tables.
* \{ */
uniform sampler2DArray utilTex;
#define LUT_SIZE 64
#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
/* Return texture coordinates to sample Surface LUT */
vec2 lut_coords(float cosTheta, float roughness)
{
float theta = acos(cosTheta);
vec2 coords = vec2(roughness, theta / M_PI_2);
/* scale and bias coordinates, for correct filtered lookup */
return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
}
vec2 lut_coords_ltc(float cosTheta, float roughness)
{
vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta));
/* scale and bias coordinates, for correct filtered lookup */
return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
}
float get_btdf_lut(float NV, float roughness, float ior)
{
const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
vec3 coords;
/* Try to compensate for the low resolution and interpolation error. */
coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) +
(0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) :
(0.9 + lut_scale_bias_texel_size.z) * ior * ior;
coords.y = 1.0 - saturate(NV);
coords.xy *= lut_scale_bias_texel_size.x;
coords.xy += lut_scale_bias_texel_size.y;
const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
float mip = roughness * lut_lvl_scale;
float mip_floor = floor(mip);
coords.z = lut_lvl_ofs + mip_floor + 1.0;
float btdf_high = textureLod(utilTex, coords, 0.0).r;
coords.z -= 1.0;
float btdf_low = textureLod(utilTex, coords, 0.0).r;
float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
return btdf;
}
/** \} */

View File

@@ -1,265 +0,0 @@
/* Precomputed table of concentric samples.
* Generated using this algorithm http://l2program.co.uk/900/concentric-disk-sampling
* Sorted by radius then by rotation angle.
* This way it's better for cache usage and for
* easily restricting to a certain number of
* sample while still having a circular kernel. */
#define CONCENTRIC_SAMPLE_NUM 256
const vec2 concentric[CONCENTRIC_SAMPLE_NUM] = vec2[CONCENTRIC_SAMPLE_NUM](
vec2(0.0441941738242, 0.0441941738242),
vec2(-0.0441941738242, -0.0441941738242),
vec2(-0.0441941738242, 0.0441941738242),
vec2(0.0441941738242, -0.0441941738242),
vec2(0.181111092429, 0.0485285709567),
vec2(0.132582521472, 0.132582521472),
vec2(-0.181111092429, 0.0485285709567),
vec2(0.0485285709567, 0.181111092429),
vec2(-0.181111092429, -0.0485285709567),
vec2(-0.0485285709567, 0.181111092429),
vec2(-0.132582521472, -0.132582521472),
vec2(-0.132582521472, 0.132582521472),
vec2(-0.0485285709567, -0.181111092429),
vec2(0.0485285709567, -0.181111092429),
vec2(0.132582521472, -0.132582521472),
vec2(0.181111092429, -0.0485285709567),
vec2(0.308652606436, 0.0488857703251),
vec2(0.278439538809, 0.141872031169),
vec2(0.220970869121, 0.220970869121),
vec2(-0.278439538809, 0.141872031169),
vec2(0.141872031169, 0.278439538809),
vec2(-0.308652606436, 0.0488857703251),
vec2(0.0488857703251, 0.308652606436),
vec2(-0.308652606436, -0.0488857703251),
vec2(-0.0488857703251, 0.308652606436),
vec2(-0.278439538809, -0.141872031169),
vec2(-0.141872031169, 0.278439538809),
vec2(-0.220970869121, -0.220970869121),
vec2(-0.220970869121, 0.220970869121),
vec2(-0.141872031169, -0.278439538809),
vec2(-0.0488857703251, -0.308652606436),
vec2(0.0488857703251, -0.308652606436),
vec2(0.141872031169, -0.278439538809),
vec2(0.220970869121, -0.220970869121),
vec2(0.278439538809, -0.141872031169),
vec2(0.308652606436, -0.0488857703251),
vec2(0.434749091828, 0.0489844582952),
vec2(0.41294895701, 0.144497089605),
vec2(0.370441837162, 0.232764033475),
vec2(0.309359216769, 0.309359216769),
vec2(-0.370441837162, 0.232764033475),
vec2(0.232764033475, 0.370441837162),
vec2(-0.41294895701, 0.144497089605),
vec2(0.144497089605, 0.41294895701),
vec2(-0.434749091828, 0.0489844582952),
vec2(0.0489844582952, 0.434749091828),
vec2(-0.434749091828, -0.0489844582952),
vec2(-0.0489844582952, 0.434749091828),
vec2(-0.41294895701, -0.144497089605),
vec2(-0.144497089605, 0.41294895701),
vec2(-0.370441837162, -0.232764033475),
vec2(-0.232764033475, 0.370441837162),
vec2(-0.309359216769, -0.309359216769),
vec2(-0.309359216769, 0.309359216769),
vec2(-0.232764033475, -0.370441837162),
vec2(-0.144497089605, -0.41294895701),
vec2(-0.0489844582952, -0.434749091828),
vec2(0.0489844582952, -0.434749091828),
vec2(0.144497089605, -0.41294895701),
vec2(0.232764033475, -0.370441837162),
vec2(0.309359216769, -0.309359216769),
vec2(0.370441837162, -0.232764033475),
vec2(0.41294895701, -0.144497089605),
vec2(0.434749091828, -0.0489844582952),
vec2(0.560359517677, 0.0490251052956),
vec2(0.543333277288, 0.14558571287),
vec2(0.509798130208, 0.237722772229),
vec2(0.460773024913, 0.322636745447),
vec2(0.397747564417, 0.397747564417),
vec2(-0.460773024913, 0.322636745447),
vec2(0.322636745447, 0.460773024913),
vec2(-0.509798130208, 0.237722772229),
vec2(0.237722772229, 0.509798130208),
vec2(-0.543333277288, 0.14558571287),
vec2(0.14558571287, 0.543333277288),
vec2(-0.560359517677, 0.0490251052956),
vec2(0.0490251052956, 0.560359517677),
vec2(-0.560359517677, -0.0490251052956),
vec2(-0.0490251052956, 0.560359517677),
vec2(-0.543333277288, -0.14558571287),
vec2(-0.14558571287, 0.543333277288),
vec2(-0.509798130208, -0.237722772229),
vec2(-0.237722772229, 0.509798130208),
vec2(-0.460773024913, -0.322636745447),
vec2(-0.322636745447, 0.460773024913),
vec2(-0.397747564417, -0.397747564417),
vec2(-0.397747564417, 0.397747564417),
vec2(-0.322636745447, -0.460773024913),
vec2(-0.237722772229, -0.509798130208),
vec2(-0.14558571287, -0.543333277288),
vec2(-0.0490251052956, -0.560359517677),
vec2(0.0490251052956, -0.560359517677),
vec2(0.14558571287, -0.543333277288),
vec2(0.237722772229, -0.509798130208),
vec2(0.322636745447, -0.460773024913),
vec2(0.397747564417, -0.397747564417),
vec2(0.460773024913, -0.322636745447),
vec2(0.509798130208, -0.237722772229),
vec2(0.543333277288, -0.14558571287),
vec2(0.560359517677, -0.0490251052956),
vec2(0.685748328795, 0.0490456884495),
vec2(0.671788470355, 0.146138636568),
vec2(0.644152935937, 0.240256623474),
vec2(0.603404305327, 0.32948367837),
vec2(0.550372103135, 0.412003395727),
vec2(0.486135912066, 0.486135912066),
vec2(-0.550372103135, 0.412003395727),
vec2(0.412003395727, 0.550372103135),
vec2(-0.603404305327, 0.32948367837),
vec2(0.32948367837, 0.603404305327),
vec2(-0.644152935937, 0.240256623474),
vec2(0.240256623474, 0.644152935937),
vec2(-0.671788470355, 0.146138636568),
vec2(0.146138636568, 0.671788470355),
vec2(-0.685748328795, 0.0490456884495),
vec2(0.0490456884495, 0.685748328795),
vec2(-0.685748328795, -0.0490456884495),
vec2(-0.0490456884495, 0.685748328795),
vec2(-0.671788470355, -0.146138636568),
vec2(-0.146138636568, 0.671788470355),
vec2(-0.644152935937, -0.240256623474),
vec2(-0.240256623474, 0.644152935937),
vec2(-0.603404305327, -0.32948367837),
vec2(-0.32948367837, 0.603404305327),
vec2(-0.550372103135, -0.412003395727),
vec2(-0.412003395727, 0.550372103135),
vec2(-0.486135912066, -0.486135912066),
vec2(-0.486135912066, 0.486135912066),
vec2(-0.412003395727, -0.550372103135),
vec2(-0.32948367837, -0.603404305327),
vec2(-0.240256623474, -0.644152935937),
vec2(-0.146138636568, -0.671788470355),
vec2(-0.0490456884495, -0.685748328795),
vec2(0.0490456884495, -0.685748328795),
vec2(0.146138636568, -0.671788470355),
vec2(0.240256623474, -0.644152935937),
vec2(0.32948367837, -0.603404305327),
vec2(0.412003395727, -0.550372103135),
vec2(0.486135912066, -0.486135912066),
vec2(0.550372103135, -0.412003395727),
vec2(0.603404305327, -0.32948367837),
vec2(0.644152935937, -0.240256623474),
vec2(0.671788470355, -0.146138636568),
vec2(0.685748328795, -0.0490456884495),
vec2(0.811017637806, 0.0490575291556),
vec2(0.799191174395, 0.146457218224),
vec2(0.775710704038, 0.241721231257),
vec2(0.740918624869, 0.33346040443),
vec2(0.695322283745, 0.420336974019),
vec2(0.639586577995, 0.501084084011),
vec2(0.574524259714, 0.574524259714),
vec2(-0.639586577995, 0.501084084011),
vec2(0.501084084011, 0.639586577995),
vec2(-0.695322283745, 0.420336974019),
vec2(0.420336974019, 0.695322283745),
vec2(-0.740918624869, 0.33346040443),
vec2(0.33346040443, 0.740918624869),
vec2(-0.775710704038, 0.241721231257),
vec2(0.241721231257, 0.775710704038),
vec2(-0.799191174395, 0.146457218224),
vec2(0.146457218224, 0.799191174395),
vec2(-0.811017637806, 0.0490575291556),
vec2(0.0490575291556, 0.811017637806),
vec2(-0.811017637806, -0.0490575291556),
vec2(-0.0490575291556, 0.811017637806),
vec2(-0.799191174395, -0.146457218224),
vec2(-0.146457218224, 0.799191174395),
vec2(-0.775710704038, -0.241721231257),
vec2(-0.241721231257, 0.775710704038),
vec2(-0.740918624869, -0.33346040443),
vec2(-0.33346040443, 0.740918624869),
vec2(-0.695322283745, -0.420336974019),
vec2(-0.420336974019, 0.695322283745),
vec2(-0.639586577995, -0.501084084011),
vec2(-0.501084084011, 0.639586577995),
vec2(-0.574524259714, -0.574524259714),
vec2(-0.574524259714, 0.574524259714),
vec2(-0.501084084011, -0.639586577995),
vec2(-0.420336974019, -0.695322283745),
vec2(-0.33346040443, -0.740918624869),
vec2(-0.241721231257, -0.775710704038),
vec2(-0.146457218224, -0.799191174395),
vec2(-0.0490575291556, -0.811017637806),
vec2(0.0490575291556, -0.811017637806),
vec2(0.146457218224, -0.799191174395),
vec2(0.241721231257, -0.775710704038),
vec2(0.33346040443, -0.740918624869),
vec2(0.420336974019, -0.695322283745),
vec2(0.501084084011, -0.639586577995),
vec2(0.574524259714, -0.574524259714),
vec2(0.639586577995, -0.501084084011),
vec2(0.695322283745, -0.420336974019),
vec2(0.740918624869, -0.33346040443),
vec2(0.775710704038, -0.241721231257),
vec2(0.799191174395, -0.146457218224),
vec2(0.811017637806, -0.0490575291556),
vec2(0.936215188832, 0.0490649589778),
vec2(0.925957819308, 0.146657310975),
vec2(0.905555462146, 0.242642854784),
vec2(0.875231649841, 0.335969952699),
vec2(0.835318616427, 0.425616093506),
vec2(0.786253657449, 0.510599095327),
vec2(0.728574338866, 0.589987866609),
vec2(0.662912607362, 0.662912607362),
vec2(-0.728574338866, 0.589987866609),
vec2(0.589987866609, 0.728574338866),
vec2(-0.786253657449, 0.510599095327),
vec2(0.510599095327, 0.786253657449),
vec2(-0.835318616427, 0.425616093506),
vec2(0.425616093506, 0.835318616427),
vec2(-0.875231649841, 0.335969952699),
vec2(0.335969952699, 0.875231649841),
vec2(-0.905555462146, 0.242642854784),
vec2(0.242642854784, 0.905555462146),
vec2(-0.925957819308, 0.146657310975),
vec2(0.146657310975, 0.925957819308),
vec2(-0.936215188832, 0.0490649589778),
vec2(0.0490649589778, 0.936215188832),
vec2(-0.936215188832, -0.0490649589778),
vec2(-0.0490649589778, 0.936215188832),
vec2(-0.925957819308, -0.146657310975),
vec2(-0.146657310975, 0.925957819308),
vec2(-0.905555462146, -0.242642854784),
vec2(-0.242642854784, 0.905555462146),
vec2(-0.875231649841, -0.335969952699),
vec2(-0.335969952699, 0.875231649841),
vec2(-0.835318616427, -0.425616093506),
vec2(-0.425616093506, 0.835318616427),
vec2(-0.786253657449, -0.510599095327),
vec2(-0.510599095327, 0.786253657449),
vec2(-0.728574338866, -0.589987866609),
vec2(-0.589987866609, 0.728574338866),
vec2(-0.662912607362, -0.662912607362),
vec2(-0.662912607362, 0.662912607362),
vec2(-0.589987866609, -0.728574338866),
vec2(-0.510599095327, -0.786253657449),
vec2(-0.425616093506, -0.835318616427),
vec2(-0.335969952699, -0.875231649841),
vec2(-0.242642854784, -0.905555462146),
vec2(-0.146657310975, -0.925957819308),
vec2(-0.0490649589778, -0.936215188832),
vec2(0.0490649589778, -0.936215188832),
vec2(0.146657310975, -0.925957819308),
vec2(0.242642854784, -0.905555462146),
vec2(0.335969952699, -0.875231649841),
vec2(0.425616093506, -0.835318616427),
vec2(0.510599095327, -0.786253657449),
vec2(0.589987866609, -0.728574338866),
vec2(0.662912607362, -0.662912607362),
vec2(0.728574338866, -0.589987866609),
vec2(0.786253657449, -0.510599095327),
vec2(0.835318616427, -0.425616093506),
vec2(0.875231649841, -0.335969952699),
vec2(0.905555462146, -0.242642854784),
vec2(0.925957819308, -0.146657310975),
vec2(0.936215188832, -0.0490649589778));

View File

@@ -1,51 +0,0 @@
uniform vec3 basecol;
uniform float metallic;
uniform float specular;
uniform float roughness;
Closure nodetree_exec(void)
{
#ifdef HAIR_SHADER
vec3 B = normalize(cross(worldNormal, hairTangent));
float cos_theta;
if (hairThicknessRes == 1) {
vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
/* Random cosine normal distribution on the hair surface. */
cos_theta = rand.x * 2.0 - 1.0;
}
else {
/* Shade as a cylinder. */
cos_theta = hairThickTime / hairThickness;
}
float sin_theta = sqrt(max(0.0, 1.0f - cos_theta * cos_theta));
vec3 N = normalize(worldNormal * sin_theta + B * cos_theta);
vec3 vN = mat3(ViewMatrix) * N;
#else
vec3 N = normalize(gl_FrontFacing ? worldNormal : -worldNormal);
vec3 vN = normalize(gl_FrontFacing ? viewNormal : -viewNormal);
#endif
vec3 dielectric = vec3(0.034) * specular * 2.0;
vec3 albedo = mix(basecol, vec3(0.0), metallic);
vec3 f0 = mix(dielectric, basecol, metallic);
vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
vec3 out_diff, out_spec, ssr_spec;
eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec);
Closure cl = CLOSURE_DEFAULT;
cl.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) +
render_pass_diffuse_mask(albedo, out_diff * albedo);
closure_load_ssr_data(ssr_spec, roughness, N, viewCameraVec, 1, cl);
#ifdef LOOKDEV
gl_FragDepth = 0.0;
#endif
#ifdef HOLDOUT
cl = CLOSURE_DEFAULT;
cl.holdout = 1.0;
#endif
return cl;
}

View File

@@ -1,4 +1,8 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
@@ -18,9 +22,6 @@ uniform vec4 bokehParams[2];
uniform vec2 nearFar; /* Near & far view depths values */
#define M_PI 3.1415926535897932384626433832795
#define M_2PI 6.2831853071795864769252868
/* -------------- Utils ------------- */
/* divide by sensor size to get the normalized size */
@@ -34,11 +35,6 @@ uniform vec2 nearFar; /* Near & far view depths values */
#define weighted_sum(a, b, c, d, e) \
(a * e.x + b * e.y + c * e.z + d * e.w) / max(1e-6, dot(e, vec4(1.0)));
float max_v4(vec4 v)
{
return max(max(v.x, v.y), max(v.z, v.w));
}
vec4 safe_color(vec4 c)
{
/* Clamp to avoid black square artifacts if a pixel goes NaN. */

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
uniform vec4 bokehParams[2];
#define bokeh_rotation bokehParams[0].x
@@ -15,8 +17,6 @@ flat out float smoothFac;
flat out ivec2 edge;
out vec2 particlecoord;
#define M_PI 3.1415926535897932384626433832795
/* Scatter pass, calculate a triangle covering the CoC. */
void main()
{

View File

@@ -1,14 +1,34 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
/**
* This shader only compute maximum horizon angles for each directions.
* The final integration is done at the resolve stage with the shading normal.
*/
uniform float rotationOffset;
out vec4 FragColor;
#ifdef DEBUG_AO
uniform sampler2D normalBuffer;
#ifdef LAYERED_DEPTH
uniform sampler2DArray depthBufferLayered;
uniform int layer;
# define gtao_depthBuffer depthBufferLayered
# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c)
#else
uniform sampler2D depthBuffer;
# define gtao_depthBuffer depthBuffer
# define gtao_textureLod(a, b, c) textureLod(a, b, c)
#endif
uniform float rotationOffset;
#ifdef DEBUG_AO
void main()
{
@@ -34,18 +54,6 @@ void main()
#else
# ifdef LAYERED_DEPTH
uniform sampler2DArray depthBufferLayered;
uniform int layer;
# define gtao_depthBuffer depthBufferLayered
# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c)
# else
# define gtao_depthBuffer depthBuffer
# define gtao_textureLod(a, b, c) textureLod(a, b, c)
# endif
void main()
{
vec2 uvs = saturate(gl_FragCoord.xy / vec2(textureSize(gtao_depthBuffer, 0).xy));

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
/*
* Based on:
* A Fast and Stable Feature-Aware Motion Blur Filter
@@ -15,11 +17,6 @@ uniform sampler2D tileMaxBuffer;
#define KERNEL 8
/* TODO(fclem) deduplicate this code. */
uniform sampler2DArray utilTex;
#define LUT_SIZE 64
#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
uniform float depthScale;
uniform ivec2 tileBufferSize;
uniform vec2 viewportSize;

View File

@@ -1,4 +1,11 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(ssr_lib.glsl)
/* Based on Stochastic Screen Space Reflections
* https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */
@@ -131,7 +138,7 @@ void main()
return;
}
vec4 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0);
vec4 rand = texelfetch_noise_tex(halfres_texel);
/* Gives *perfect* reflection for very small roughness */
if (roughness < 0.04) {

View File

@@ -1,4 +1,9 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
#define MAX_SSS_SAMPLES 65
@@ -14,36 +19,16 @@ uniform sampler2D sssIrradiance;
uniform sampler2D sssRadius;
uniform sampler2D sssAlbedo;
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
layout(location = 0) out vec4 sssRadiance;
float get_view_z_from_depth(float depth)
{
if (ProjectionMatrix[3][3] == 0.0) {
float d = 2.0 * depth - 1.0;
return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
}
else {
return viewVecs[0].z + depth * viewVecs[1].z;
}
}
#define LUT_SIZE 64
#define M_PI_2 1.5707963267948966 /* pi/2 */
#define M_2PI 6.2831853071795865 /* 2*pi */
void main(void)
{
vec2 pixel_size = 1.0 / vec2(textureSize(depthBuffer, 0).xy); /* TODO precompute */
vec2 uvs = gl_FragCoord.xy * pixel_size;
vec3 sss_irradiance = texture(sssIrradiance, uvs).rgb;
float sss_radius = texture(sssRadius, uvs).r;
float depth_view = get_view_z_from_depth(texture(depthBuffer, uvs).r);
float depth = texture(depthBuffer, uvs).r;
float depth_view = get_view_z_from_depth(depth);
float rand = texelfetch_noise_tex(gl_FragCoord.xy).r;
#ifdef FIRST_PASS

View File

@@ -1,5 +1,11 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
uniform sampler2D colorHistoryBuffer;
uniform mat4 prevViewProjectionMatrix;
out vec4 FragColor;

View File

@@ -1,11 +1,16 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(lights_lib.glsl)
in vec4 uvcoordsvar;
out vec4 FragColor;
uniform sampler2D depthBuffer;
uniform sampler1D sssTexProfile;
uniform sampler2D sssRadius;
uniform sampler2DArray sssShadowCubes;
uniform sampler2DArray sssShadowCascades;
@@ -27,12 +32,6 @@ vec3 sss_profile(float s)
return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb;
}
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
float light_translucent_power_with_falloff(LightData ld, vec3 N, vec4 l_vector)
{
float power, falloff;

View File

@@ -1,4 +1,8 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
uniform sampler2D depthBuffer;
uniform mat4 prevViewProjMatrix;
uniform mat4 currViewProjMatrixInv;
uniform mat4 nextViewProjMatrix;

View File

@@ -1,44 +1,76 @@
uniform sampler2DArray irradianceGrid;
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
#pragma BLENDER_REQUIRE(octahedron_lib.glsl)
#define IRRADIANCE_LIB
#ifdef IRRADIANCE_CUBEMAP
struct IrradianceData {
vec3 color;
};
#elif defined(IRRADIANCE_SH_L2)
/* ---------------------------------------------------------------------- */
/** \name Structure
* \{ */
#if defined(IRRADIANCE_SH_L2)
struct IrradianceData {
vec3 shcoefs[9];
};
#else /* defined(IRRADIANCE_HL2) */
struct IrradianceData {
vec3 cubesides[3];
};
#endif
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Resources
* \{ */
uniform sampler2DArray irradianceGrid;
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Functions
* \{ */
vec4 irradiance_encode(vec3 rgb)
{
float maxRGB = max_v3(rgb);
float fexp = ceil(log2(maxRGB));
return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0);
}
vec3 irradiance_decode(vec4 data)
{
float fexp = data.a * 255.0 - 128.0;
return data.rgb * exp2(fexp);
}
vec4 visibility_encode(vec2 accum, float range)
{
accum /= range;
vec4 data;
data.x = fract(accum.x);
data.y = floor(accum.x) / 255.0;
data.z = fract(accum.y);
data.w = floor(accum.y) / 255.0;
return data;
}
vec2 visibility_decode(vec4 data, float range)
{
return (data.xz + data.yw * 255.0) * range;
}
IrradianceData load_irradiance_cell(int cell, vec3 N)
{
/* Keep in sync with diffuse_filter_probe() */
#if defined(IRRADIANCE_CUBEMAP)
# define AMBIANT_CUBESIZE 8
ivec2 cell_co = ivec2(AMBIANT_CUBESIZE);
int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x;
cell_co.x *= cell % cell_per_row;
cell_co.y *= cell / cell_per_row;
vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE);
vec2 uvs = mapping_octahedron(N, texelSize);
uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0));
uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0));
IrradianceData ir;
ir.color = texture(irradianceGrid, vec3(uvs, 0.0)).rgb;
#elif defined(IRRADIANCE_SH_L2)
#if defined(IRRADIANCE_SH_L2)
ivec2 cell_co = ivec2(3, 3);
int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x;
@@ -164,9 +196,7 @@ vec3 hl2_basis(vec3 N, vec3 cubesides[3])
vec3 compute_irradiance(vec3 N, IrradianceData ird)
{
#if defined(IRRADIANCE_CUBEMAP)
return ird.color;
#elif defined(IRRADIANCE_SH_L2)
#if defined(IRRADIANCE_SH_L2)
return spherical_harmonics_L2(N, ird.shcoefs);
#else /* defined(IRRADIANCE_HL2) */
return hl2_basis(N, ird.cubesides);
@@ -178,3 +208,5 @@ vec3 irradiance_from_cell_get(int cell, vec3 ir_dir)
IrradianceData ir_data = load_irradiance_cell(cell, ir_dir);
return compute_irradiance(ir_dir, ir_data);
}
/** \} */

View File

@@ -1,4 +1,7 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(cubemap_lib.glsl)
flat in int pid;
in vec2 quadCoord;

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
/* XXX TODO fix code duplication */
struct CubeData {
vec4 position_type;

View File

@@ -1,4 +1,8 @@
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
uniform samplerCube probeHdr;
uniform int probeSize;
uniform float lodFactor;
@@ -111,32 +115,7 @@ void main()
FragColor = vec4(sh, 1.0);
#else
# if defined(IRRADIANCE_CUBEMAP)
/* Downside: Need lots of memory for storage, distortion due to octahedral mapping */
const vec2 map_size = vec2(16.0);
const vec2 texelSize = 1.0 / map_size;
vec2 uvs = mod(gl_FragCoord.xy, map_size) * texelSize;
const float paddingSize = 1.0;
/* Add a N pixel border to ensure filtering is correct
* for N mipmap levels. */
uvs = (uvs - texelSize * paddingSize) / (1.0 - 2.0 * texelSize * paddingSize);
/* edge mirroring : only mirror if directly adjacent
* (not diagonally adjacent) */
vec2 m = abs(uvs - 0.5) + 0.5;
vec2 f = floor(m);
if (f.x - f.y != 0.0) {
uvs = 1.0 - uvs;
}
/* clamp to [0-1] */
uvs = fract(uvs);
/* get cubemap vector */
vec3 cubevec = octahedral_to_cubemap_proj(uvs);
# elif defined(IRRADIANCE_HL2)
# if defined(IRRADIANCE_HL2)
/* Downside: very very low resolution (6 texels), bleed lighting because of interpolation */
int x = int(gl_FragCoord.x) % 3;
int y = int(gl_FragCoord.y) % 2;

View File

@@ -1,4 +1,7 @@
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
uniform samplerCube probeHdr;
uniform float roughnessSquared;
uniform float texelSize;

View File

@@ -1,4 +1,8 @@
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
uniform samplerCube probeDepth;
uniform int outputSize;
uniform float lodFactor;

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
uniform float sphere_size;
uniform int offset;
uniform ivec3 grid_resolution;

View File

@@ -6,8 +6,6 @@ void main()
{
#if defined(IRRADIANCE_SH_L2)
const ivec2 data_size = ivec2(3, 3);
#elif defined(IRRADIANCE_CUBEMAP)
const ivec2 data_size = ivec2(8, 8);
#elif defined(IRRADIANCE_HL2)
const ivec2 data_size = ivec2(3, 2);
#endif

View File

@@ -1,3 +1,12 @@
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
#pragma BLENDER_REQUIRE(cubemap_lib.glsl)
#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
/* ----------- Uniforms --------- */
uniform sampler2DArray probePlanars;
@@ -73,12 +82,6 @@ struct GridData {
# define MAX_PLANAR 1
#endif
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
layout(std140) uniform probe_block
{
CubeData probes_data[MAX_PROBE];
@@ -218,7 +221,7 @@ void fallback_cubemap(vec3 N,
inout vec4 spec_accum)
{
/* Specular probes */
vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared);
#ifdef SSR_AO
vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
@@ -246,7 +249,6 @@ void fallback_cubemap(vec3 N,
}
}
#ifdef IRRADIANCE_LIB
vec3 probe_evaluate_grid(GridData gd, vec3 W, vec3 N, vec3 localpos)
{
localpos = localpos * 0.5 + 0.5;
@@ -308,5 +310,3 @@ vec3 probe_evaluate_world_diff(vec3 N)
{
return irradiance_from_cell_get(0, N);
}
#endif /* IRRADIANCE_LIB */

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
uniform sampler2DArray probePlanars;
in vec3 worldPosition;

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
in vec3 pos;
in int probe_id;

View File

@@ -1,8 +1,76 @@
uniform sampler2DArrayShadow shadowCubeTexture;
uniform sampler2DArrayShadow shadowCascadeTexture;
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
#pragma BLENDER_REQUIRE(ltc_lib.glsl)
#define LAMPS_LIB
#ifndef MAX_CASCADE_NUM
# define MAX_CASCADE_NUM 4
#endif
/* ---------------------------------------------------------------------- */
/** \name Structure
* \{ */
struct LightData {
vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */
vec4 color_spec; /* w : Spec Intensity */
vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */
};
/* convenience aliases */
#define l_color color_spec.rgb
#define l_spec color_spec.a
#define l_position position_influence.xyz
#define l_influence position_influence.w
#define l_sizex rightvec_sizex.w
#define l_sizey upvec_sizey.w
#define l_right rightvec_sizex.xyz
#define l_up upvec_sizey.xyz
#define l_forward forwardvec_type.xyz
#define l_type forwardvec_type.w
#define l_spot_size spotdata_radius_shadow.x
#define l_spot_blend spotdata_radius_shadow.y
#define l_radius spotdata_radius_shadow.z
#define l_shadowid spotdata_radius_shadow.w
struct ShadowData {
vec4 near_far_bias_id;
vec4 contact_shadow_data;
};
struct ShadowCubeData {
mat4 shadowmat;
vec4 position;
};
struct ShadowCascadeData {
mat4 shadowmat[MAX_CASCADE_NUM];
vec4 split_start_distances;
vec4 split_end_distances;
vec4 shadow_vec_id;
};
/* convenience aliases */
#define sh_near near_far_bias_id.x
#define sh_far near_far_bias_id.y
#define sh_bias near_far_bias_id.z
#define sh_data_index near_far_bias_id.w
#define sh_contact_dist contact_shadow_data.x
#define sh_contact_offset contact_shadow_data.y
#define sh_contact_spread contact_shadow_data.z
#define sh_contact_thickness contact_shadow_data.w
#define sh_shadow_vec shadow_vec_id.xyz
#define sh_tex_index shadow_vec_id.w
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Resources
* \{ */
layout(std140) uniform shadow_block
{
@@ -16,6 +84,15 @@ layout(std140) uniform light_block
LightData lights_data[MAX_LIGHT];
};
uniform sampler2DArrayShadow shadowCubeTexture;
uniform sampler2DArrayShadow shadowCascadeTexture;
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Shadow Functions
* \{ */
/* type */
#define POINT 0.0
#define SUN 1.0
@@ -133,9 +210,11 @@ float sample_cascade_shadow(int shadow_id, vec3 W)
#undef scube
#undef scsmd
/* ----------------------------------------------------------- */
/* --------------------- Light Functions --------------------- */
/* ----------------------------------------------------------- */
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Light Functions
* \{ */
/* From Frostbite PBR Course
* Distance based attenuation
@@ -258,7 +337,6 @@ float light_visibility(LightData ld,
l_atten);
}
#ifdef USE_LTC
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{
if (ld.l_type == AREA_RECT) {
@@ -321,4 +399,5 @@ float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector)
return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points);
}
}
#endif
/** \} */

View File

@@ -1,20 +1,17 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
uniform sampler2D studioLight;
uniform float backgroundAlpha;
uniform vec3 color;
out vec4 FragColor;
#if defined(LOOKDEV_BG) || defined(LOOKDEV)
uniform mat3 StudioLightMatrix;
uniform sampler2D image;
uniform float studioLightIntensity = 1.0;
uniform float studioLightBlur = 0.0;
in vec3 viewPosition;
# ifndef M_PI
# define M_PI 3.14159265358979323846
# endif
out vec4 FragColor;
vec3 background_transform_to_world(vec3 viewvec)
{
@@ -35,36 +32,20 @@ vec4 node_tex_environment_equirectangular(vec3 co, sampler2D ima)
vec3 nco = normalize(co);
float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
/* Fix pole bleeding */
float width = float(textureSize(ima, 0).x);
float texel_width = 1.0 / width;
v = clamp(v, texel_width, 1.0 - texel_width);
/* Fix u = 0 seam */
/* This is caused by texture filtering, since uv don't have smooth derivatives
* at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
* texels. So we force the highest mipmap and don't do anisotropic filtering. */
return textureLod(ima, vec2(u, v), 0.0);
}
#endif
void main()
{
vec3 worldvec = background_transform_to_world(viewPosition);
vec3 background_color;
#if defined(LOOKDEV_BG)
vec3 worldvec = background_transform_to_world(viewPosition);
background_color = probe_evaluate_world_spec(worldvec, studioLightBlur).rgb;
background_color *= studioLightIntensity;
#elif defined(LOOKDEV)
vec3 worldvec = background_transform_to_world(viewPosition);
background_color = node_tex_environment_equirectangular(StudioLightMatrix * worldvec, image).rgb;
background_color *= studioLightIntensity;
#else
background_color = color;
worldvec = StudioLightMatrix * worldvec;
background_color = node_tex_environment_equirectangular(worldvec, studioLight).rgb;
background_color *= studioLightIntensity;
#endif
FragColor = vec4(clamp(background_color, vec3(0.0), vec3(1e10)), 1.0) * backgroundAlpha;

View File

@@ -8,12 +8,6 @@
#define USE_LTC
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
/* Diffuse *clipped* sphere integral. */
float diffuse_sphere_integral(float avg_dir_z, float form_factor)
{

View File

@@ -1,4 +1,7 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
uniform mat4 currModelMatrix;
uniform mat4 prevModelMatrix;
uniform mat4 nextModelMatrix;
@@ -19,6 +22,8 @@ out vec3 nextWorldPos;
void main()
{
GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
float time, thick_time, thickness;

View File

@@ -1,4 +1,13 @@
/* Required by some nodes. */
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
#pragma BLENDER_REQUIRE(closure_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
#ifdef USE_ALPHA_HASH
/* From the paper "Hashed Alpha Testing" by Chris Wyman and Morgan McGuire */
@@ -56,8 +65,6 @@ float hashed_alpha_threshold(vec3 co)
#endif
#define NODETREE_EXEC
void main()
{
#if defined(USE_ALPHA_HASH)

View File

@@ -1,16 +1,14 @@
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#ifndef HAIR_SHADER
in vec3 pos;
#endif
void main()
{
#ifdef GPU_INTEL
/* Due to some shader compiler bug, we somewhat
* need to access gl_VertexID to make it work. even
* if it's actually dead code. */
gl_Position.x = float(gl_VertexID);
#endif
GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR_SHADER
float time, thick_time, thickness;
@@ -34,5 +32,4 @@ void main()
#ifdef CLIP_PLANES
gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), clipPlanes[0]);
#endif
/* TODO motion vectors */
}

View File

@@ -1,3 +1,11 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
uniform sampler2D maxzBuffer;
uniform sampler2DArray planarDepth;
#define MAX_STEP 256
float sample_depth(vec2 uv, int index, float lod)

View File

@@ -0,0 +1,43 @@
/* ---------------------------------------------------------------------- */
/** \name Resources
* \{ */
layout(std140) uniform renderpass_block
{
bool renderPassDiffuse;
bool renderPassDiffuseLight;
bool renderPassGlossy;
bool renderPassGlossyLight;
bool renderPassEmit;
bool renderPassSSSColor;
bool renderPassEnvironment;
};
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Functions
* \{ */
vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
{
return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
}
vec3 render_pass_sss_mask(vec3 sss_color)
{
return renderPassSSSColor ? sss_color : vec3(0.0);
}
vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
{
return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
}
vec3 render_pass_emission_mask(vec3 emission_light)
{
return renderPassEmit ? emission_light : vec3(0.0);
}
/** \} */

View File

@@ -1,3 +1,7 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#define PASS_POST_UNDEFINED 0
#define PASS_POST_ACCUMULATED_COLOR 1
#define PASS_POST_ACCUMULATED_LIGHT 2
@@ -9,6 +13,8 @@
uniform int postProcessType;
uniform int currentSample;
uniform sampler2D depthBuffer;
uniform sampler2D inputBuffer;
uniform sampler2D inputSecondLightBuffer;
uniform sampler2D inputColorBuffer;

View File

@@ -1,12 +1,12 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(lights_lib.glsl)
uniform sampler2D depthBuffer;
out vec4 fragColor;
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
void main()
{
if (laNumLight == 0) {

View File

@@ -1,30 +1,14 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
in vec3 pos;
in vec3 nor;
#ifdef MESH_SHADER
out vec3 worldPosition;
out vec3 viewPosition;
out vec3 worldNormal;
out vec3 viewNormal;
#endif
#ifdef HAIR_SHADER
out vec3 hairTangent;
out float hairThickTime;
out float hairThickness;
out float hairTime;
flat out int hairStrandID;
#endif
void main()
{
#ifdef GPU_INTEL
/* Due to some shader compiler bug, we somewhat
* need to access gl_VertexID to make it work. even
* if it's actually dead code. */
gl_Position.x = float(gl_VertexID);
#endif
GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR_SHADER
hairStrandID = hair_get_strand_id();

View File

@@ -1,3 +1,10 @@
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
/* ------------ Refraction ------------ */
#define BTDF_BIAS 0.85

View File

@@ -0,0 +1,88 @@
/* Required by some nodes. */
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
#pragma BLENDER_REQUIRE(closure_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
#ifdef USE_ALPHA_BLEND
/* Use dual source blending to be able to make a whole range of effects. */
layout(location = 0, index = 0) out vec4 outRadiance;
layout(location = 0, index = 1) out vec4 outTransmittance;
#else /* OPAQUE */
layout(location = 0) out vec4 outRadiance;
layout(location = 1) out vec2 ssrNormals;
layout(location = 2) out vec4 ssrData;
# ifdef USE_SSS
layout(location = 3) out vec3 sssIrradiance;
layout(location = 4) out float sssRadius;
layout(location = 5) out vec3 sssAlbedo;
# endif
#endif
void main()
{
Closure cl = nodetree_exec();
float holdout = saturate(1.0 - cl.holdout);
float transmit = saturate(avg(cl.transmittance));
float alpha = 1.0 - transmit;
#ifdef USE_ALPHA_BLEND
vec2 uvs = gl_FragCoord.xy * volCoordScale.zw;
vec3 vol_transmit, vol_scatter;
volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter);
/* Removes part of the volume scattering that have
* already been added to the destination pixels.
* Since we do that using the blending pipeline we need to account for material transmittance. */
vol_scatter -= vol_scatter * cl.transmittance;
cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter;
outRadiance = vec4(cl.radiance, alpha * holdout);
outTransmittance = vec4(cl.transmittance, transmit) * holdout;
#else
outRadiance = vec4(cl.radiance, holdout);
ssrNormals = cl.ssr_normal;
ssrData = cl.ssr_data;
# ifdef USE_SSS
sssIrradiance = cl.sss_irradiance;
sssRadius = cl.sss_radius;
sssAlbedo = cl.sss_albedo;
# endif
#endif
/* For Probe capture */
#ifdef USE_SSS
float fac = float(!sssToggle);
/* TODO(fclem) we shouldn't need this.
* Just disable USE_SSS when USE_REFRACTION is enabled. */
# ifdef USE_REFRACTION
/* SSRefraction pass is done after the SSS pass.
* In order to not loose the diffuse light totally we
* need to merge the SSS radiance to the main radiance. */
fac = 1.0;
# endif
outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac;
#endif
#ifndef USE_ALPHA_BLEND
float alpha_div = 1.0 / max(1e-8, alpha);
outRadiance.rgb *= alpha_div;
ssrData.rgb *= alpha_div;
# ifdef USE_SSS
sssAlbedo.rgb *= alpha_div;
# endif
#endif
#ifdef LOOKDEV
/* Lookdev spheres are rendered in front. */
gl_FragDepth = 0.0;
#endif
}

View File

@@ -0,0 +1,24 @@
/** This describe the entire interface of the shader. */
/* Samplers */
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
/* Uniforms */
uniform float refractionDepth;
IN_OUT ShaderStageInterface
{
vec3 worldPosition;
vec3 viewPosition;
vec3 worldNormal;
vec3 viewNormal;
#ifdef HAIR_SHADER
vec3 hairTangent; /* world space */
float hairThickTime;
float hairThickness;
float hairTime;
flat int hairStrandID;
#endif
};

View File

@@ -1,32 +1,16 @@
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
#ifndef HAIR_SHADER
in vec3 pos;
in vec3 nor;
#endif
#ifdef MESH_SHADER
out vec3 worldPosition;
out vec3 viewPosition;
out vec3 worldNormal;
out vec3 viewNormal;
#endif
#ifdef HAIR_SHADER
out vec3 hairTangent;
out float hairThickTime;
out float hairThickness;
out float hairTime;
flat out int hairStrandID;
#endif
void main()
{
#ifdef GPU_INTEL
/* Due to some shader compiler bug, we somewhat
* need to access gl_VertexID to make it work. even
* if it's actually dead code. */
gl_Position.x = float(gl_VertexID);
#endif
GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR_SHADER
hairStrandID = hair_get_strand_id();

View File

@@ -1,11 +1,11 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
uniform sampler2D blueNoise;
uniform vec3 offsets;
out vec4 FragColor;
#define M_2PI 6.28318530717958647692
void main(void)
{
vec3 blue_noise = texelFetch(blueNoise, ivec2(gl_FragCoord.xy), 0).xyz;

View File

@@ -1,9 +1,10 @@
#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
#pragma BLENDER_REQUIRE(closure_lib.glsl)
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
#define NODETREE_EXEC
#ifdef MESH_SHADER
uniform vec3 volumeOrcoLoc;
uniform vec3 volumeOrcoSize;

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#ifdef MESH_SHADER
/* TODO tight slices */
layout(triangles) in;

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
@@ -11,9 +13,11 @@ uniform sampler3D volumeExtinction;
#ifdef USE_VOLUME_OPTI
uniform layout(binding = 0, r11f_g11f_b10f) writeonly restrict image3D finalScattering_img;
uniform layout(binding = 1, r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img;
vec3 finalScattering;
vec3 finalTransmittance;
#else
flat in int slice;
layout(location = 0) out vec3 finalScattering;

View File

@@ -1,4 +1,8 @@
#pragma BLENDER_REQUIRE(lights_lib.glsl)
#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
@@ -58,7 +62,6 @@ float phase_function(vec3 v, vec3 l, float g)
return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0));
}
#ifdef LAMPS_LIB
vec3 light_volume(LightData ld, vec4 l_vector)
{
float power;
@@ -95,7 +98,7 @@ vec3 light_volume(LightData ld, vec4 l_vector)
return tint * lum;
}
# define VOLUMETRIC_SHADOW_MAX_STEP 32.0
#define VOLUMETRIC_SHADOW_MAX_STEP 32.0
vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
{
@@ -109,7 +112,7 @@ vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction)
{
# if defined(VOLUME_SHADOW)
#if defined(VOLUME_SHADOW)
/* Heterogeneous volume shadows */
float dd = l_vector.w / volShadowSteps;
vec3 L = l_vector.xyz * l_vector.w;
@@ -120,27 +123,24 @@ vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D v
shadow *= exp(-s_extinction * dd);
}
return shadow;
# else
#else
return vec3(1.0);
# endif /* VOLUME_SHADOW */
#endif /* VOLUME_SHADOW */
}
#endif
#ifdef IRRADIANCE_LIB
vec3 irradiance_volumetric(vec3 wpos)
{
# ifdef IRRADIANCE_HL2
#ifdef IRRADIANCE_HL2
IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0));
vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2];
ir_data = load_irradiance_cell(0, vec3(-1.0));
irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2];
irradiance *= 0.16666666; /* 1/6 */
return irradiance;
# else
#else
return vec3(0.0);
# endif
}
#endif
}
uniform sampler3D inScattering;
uniform sampler3D inTransmittance;

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
out vec4 vPos;
void main()

View File

@@ -137,12 +137,6 @@ void blend_mode_output(
}
}
#ifdef GPU_VERTEX_SHADER
# define IN_OUT out
#else
# define IN_OUT in
#endif
/* Shader interface. */
IN_OUT vec4 finalColorMul;
IN_OUT vec4 finalColorAdd;

View File

@@ -182,6 +182,7 @@ static void OVERLAY_cache_init(void *vedata)
OVERLAY_motion_path_cache_init(vedata);
OVERLAY_outline_cache_init(vedata);
OVERLAY_particle_cache_init(vedata);
OVERLAY_pointcloud_cache_init(vedata);
OVERLAY_wireframe_cache_init(vedata);
}
@@ -402,6 +403,12 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
OVERLAY_particle_cache_populate(vedata, ob);
}
/* TODO: these should not be overlays, just here for testing since it's
* easier to implement than integrating it into eevee/workbench. */
if (ob->type == OB_POINTCLOUD) {
OVERLAY_pointcloud_cache_populate(vedata, ob);
}
/* Relationship, object center, bounbox ... */
if (!pd->hide_overlays) {
OVERLAY_extra_cache_populate(vedata, ob);
@@ -475,6 +482,7 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_armature_draw(vedata);
OVERLAY_particle_draw(vedata);
OVERLAY_metaball_draw(vedata);
OVERLAY_pointcloud_draw(vedata);
OVERLAY_gpencil_draw(vedata);
OVERLAY_extra_draw(vedata);

View File

@@ -138,11 +138,6 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
pd->outlines_grp = grp = DRW_shgroup_create(sh_geom, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
GPUShader *sh_geom_ptcloud = OVERLAY_shader_outline_prepass_pointcloud();
pd->outlines_ptcloud_grp = grp = DRW_shgroup_create(sh_geom_ptcloud, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
GPUShader *sh_gpencil = OVERLAY_shader_outline_prepass_gpencil();
pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
@@ -293,12 +288,6 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
return;
}
if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) {
/* Looks bad in this case. Could be relaxed if we draw a
* wireframe of some sort in the future. */
return;
}
if (dupli && !init_dupli) {
geom = dupli->outline_geom;
shgroup = dupli->outline_shgrp;
@@ -318,18 +307,12 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
}
if (geom) {
shgroup = (ob->type == OB_POINTCLOUD) ? pd->outlines_ptcloud_grp : pd->outlines_grp;
shgroup = pd->outlines_grp;
}
}
if (shgroup && geom) {
if (ob->type == OB_POINTCLOUD) {
/* Draw range to avoid drawcall batching messing up the instance attrib. */
DRW_shgroup_call_instance_range(shgroup, ob, geom, 0, 0);
}
else {
DRW_shgroup_call(shgroup, geom, ob);
}
DRW_shgroup_call(shgroup, geom, ob);
}
if (init_dupli) {

View File

@@ -0,0 +1,72 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright 2020, Blender Foundation.
*/
/** \file
* \ingroup draw_engine
*/
#include "DRW_render.h"
#include "DEG_depsgraph_query.h"
#include "DNA_pointcloud_types.h"
#include "BKE_pointcache.h"
#include "overlay_private.h"
/* -------------------------------------------------------------------- */
/** \name PointCloud
* \{ */
void OVERLAY_pointcloud_cache_init(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
GPUShader *sh;
DRWShadingGroup *grp;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRW_PASS_CREATE(psl->pointcloud_ps, state | pd->clipping_state);
sh = OVERLAY_shader_pointcloud_dot();
pd->pointcloud_dots_grp = grp = DRW_shgroup_create(sh, psl->pointcloud_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
}
void OVERLAY_pointcloud_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
struct GPUBatch *geom = DRW_cache_pointcloud_get_dots(ob);
const float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->pointcloud_dots_grp);
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
DRW_shgroup_call(grp, geom, ob);
}
void OVERLAY_pointcloud_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
DRW_draw_pass(psl->pointcloud_ps);
}
/** \} */

View File

@@ -243,7 +243,6 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *motion_path_lines_grp;
DRWShadingGroup *motion_path_points_grp;
DRWShadingGroup *outlines_grp;
DRWShadingGroup *outlines_ptcloud_grp;
DRWShadingGroup *outlines_gpencil_grp;
DRWShadingGroup *paint_depth_grp;
DRWShadingGroup *paint_surf_grp;
@@ -551,6 +550,10 @@ void OVERLAY_particle_cache_init(OVERLAY_Data *vedata);
void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_particle_draw(OVERLAY_Data *vedata);
void OVERLAY_pointcloud_cache_init(OVERLAY_Data *vedata);
void OVERLAY_pointcloud_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_pointcloud_draw(OVERLAY_Data *vedata);
void OVERLAY_sculpt_cache_init(OVERLAY_Data *vedata);
void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_sculpt_draw(OVERLAY_Data *vedata);
@@ -607,7 +610,6 @@ GPUShader *OVERLAY_shader_motion_path_vert(void);
GPUShader *OVERLAY_shader_uniform_color(void);
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void);
GPUShader *OVERLAY_shader_extra_grid(void);
GPUShader *OVERLAY_shader_outline_detect(void);
GPUShader *OVERLAY_shader_paint_face(void);

View File

@@ -127,7 +127,6 @@ extern char datatoc_common_fullscreen_vert_glsl[];
extern char datatoc_common_fxaa_lib_glsl[];
extern char datatoc_common_smaa_lib_glsl[];
extern char datatoc_common_globals_lib_glsl[];
extern char datatoc_common_pointcloud_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
typedef struct OVERLAY_Shaders {
@@ -182,7 +181,6 @@ typedef struct OVERLAY_Shaders {
GPUShader *motion_path_vert;
GPUShader *outline_prepass;
GPUShader *outline_prepass_gpencil;
GPUShader *outline_prepass_pointcloud;
GPUShader *outline_prepass_wire;
GPUShader *outline_detect;
GPUShader *paint_face;
@@ -1137,33 +1135,6 @@ GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
return sh_data->outline_prepass_gpencil;
}
GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
if (!sh_data->outline_prepass_pointcloud) {
sh_data->outline_prepass_pointcloud = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg->lib,
datatoc_common_view_lib_glsl,
datatoc_common_pointcloud_lib_glsl,
datatoc_gpu_shader_common_obinfos_lib_glsl,
datatoc_outline_prepass_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_common_view_lib_glsl,
datatoc_gpencil_common_lib_glsl,
datatoc_outline_prepass_frag_glsl,
NULL},
.defs = (const char *[]){sh_cfg->def,
"#define POINTCLOUD\n",
"#define INSTANCED_ATTR\n",
"#define UNIFORM_RESOURCE_ID\n",
NULL},
});
}
return sh_data->outline_prepass_pointcloud;
}
GPUShader *OVERLAY_shader_outline_detect(void)
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];

View File

@@ -235,15 +235,10 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
}
}
if (use_wire && ELEM(ob->type, OB_VOLUME, OB_POINTCLOUD)) {
bool draw_as_points = true;
if (ob->type == OB_VOLUME) {
/* Volume object as points exception. */
Volume *volume = ob->data;
draw_as_points = volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS;
}
if (draw_as_points) {
if (use_wire && ob->type == OB_VOLUME) {
/* Volume object as points exception. */
Volume *volume = ob->data;
if (volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS) {
float *color;
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);

View File

@@ -1,4 +1,6 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
uniform sampler2D colorTex;
uniform sampler2D depthTex;
uniform sampler2D lineTex;

View File

@@ -14,19 +14,6 @@ layout(depth_greater) out float gl_FragDepth;
layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 lineOutput;
#define cameraPos ViewMatrixInverse[3].xyz
float get_depth_from_view_z(float z)
{
if (ProjectionMatrix[3][3] == 0.0) {
z = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
}
else {
z = z * ProjectionMatrix[2][2] / (1.0 - ProjectionMatrix[3][2]);
}
return z * 0.5 + 0.5;
}
void main()
{
const float sphere_radius = 0.05;

View File

@@ -14,8 +14,6 @@ uniform float meshSize;
uniform float lineKernel = 0.0;
uniform sampler2D depthBuffer;
#define cameraPos (ViewMatrixInverse[3].xyz)
uniform int gridFlag;
#define STEPS_LEN 8

View File

@@ -7,8 +7,6 @@ uniform float meshSize;
uniform int gridFlag;
#define cameraPos (ViewMatrixInverse[3].xyz)
#define PLANE_XY (1 << 4)
#define PLANE_XZ (1 << 5)
#define PLANE_YZ (1 << 6)

View File

@@ -1,7 +1,7 @@
uniform bool isTransform;
#if !defined(USE_GPENCIL) && !defined(POINTCLOUD)
#ifndef USE_GPENCIL
in vec3 pos;
#endif
@@ -56,11 +56,7 @@ void main()
# endif
#else
# ifdef POINTCLOUD
vec3 world_pos = pointcloud_get_pos();
# else
vec3 world_pos = point_object_to_world(pos);
# endif
gl_Position = point_world_to_ndc(world_pos);
# ifdef USE_GEOM
vPos = point_world_to_view(world_pos);

View File

@@ -2,15 +2,16 @@
uniform vec4 color;
/* ---- Per instance Attrs ---- */
in vec4 ptcloud; /* Position and radius. */
in vec3 pointcloud_pos;
in vec3 pointcloud_radius;
out vec4 finalColor;
void main()
{
vec3 world_pos = point_object_to_world(ptcloud.xyz);
vec3 world_pos = point_object_to_world(pointcloud_pos);
vec3 world_size = abs(mat3(ModelMatrix) * vec3(ptcloud.w));
vec3 world_size = abs(mat3(ModelMatrix) * vec3(pointcloud_radius));
float world_radius = (world_size.x + world_size.y + world_size.z) / 3.0;
gl_Position = point_world_to_ndc(world_pos);

View File

@@ -28,7 +28,7 @@ void cavity_compute(vec2 screenco,
return;
}
vec3 position = view_position_from_depth(screenco, depth, world_data.viewvecs, ProjectionMatrix);
vec3 position = get_view_space_from_depth(screenco, depth);
vec3 normal = workbench_normal_decode(texture(normalBuffer, screenco));
vec2 jitter_co = (screenco * world_data.viewport_size.xy) * world_data.cavity_jitter_scale;
@@ -68,8 +68,7 @@ void cavity_compute(vec2 screenco,
bool is_background = (s_depth == 1.0);
/* This trick provide good edge effect even if no neighbor is found. */
s_depth = (is_background) ? depth : s_depth;
vec3 s_pos = view_position_from_depth(
uvcoords, s_depth, world_data.viewvecs, ProjectionMatrix);
vec3 s_pos = get_view_space_from_depth(uvcoords, s_depth);
if (is_background) {
s_pos.z -= world_data.cavity_distance;

View File

@@ -67,31 +67,3 @@ void workbench_float_pair_decode(float data, out float v1, out float v2)
v1 = float(idata & v1_mask) * (1.0 / float(v1_mask));
v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0 / float(v2_mask));
}
vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat)
{
if (proj_mat[3][3] == 0.0) {
return normalize(viewvecs[0].xyz + vec3(uv, 0.0) * viewvecs[1].xyz);
}
else {
return vec3(0.0, 0.0, 1.0);
}
}
vec3 view_position_from_depth(vec2 uvcoords, float depth, vec4 viewvecs[3], mat4 proj_mat)
{
if (proj_mat[3][3] == 0.0) {
/* Perspective */
float d = 2.0 * depth - 1.0;
float zview = -proj_mat[3][2] / (d + proj_mat[2][2]);
return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz);
}
else {
/* Orthographic */
vec3 offset = vec3(uvcoords, depth);
return viewvecs[0].xyz + offset * viewvecs[1].xyz;
}
}

View File

@@ -14,7 +14,7 @@ out vec4 fragColor;
void main()
{
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
vec3 I = view_vector_from_screen_uv(uvcoordsvar.st, world_data.viewvecs, ProjectionMatrix);
vec3 I = get_view_vector_from_screen_uv(uvcoordsvar.st);
vec3 N = workbench_normal_decode(texture(normalBuffer, uvcoordsvar.st));
vec4 mat_data = texture(materialBuffer, uvcoordsvar.st);

View File

@@ -5,7 +5,6 @@ struct LightData {
};
struct WorldData {
vec4 viewvecs[3];
vec4 viewport_size;
vec4 object_outline_color;
vec4 shadow_direction_vs;

View File

@@ -1,3 +1,6 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
/**
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
@@ -21,13 +24,6 @@ uniform sampler2D noiseTex;
#define dof_distance dofParams.y
#define dof_invsensorsize dofParams.z
#define M_PI 3.1415926535897932 /* pi */
float max_v4(vec4 v)
{
return max(max(v.x, v.y), max(v.z, v.w));
}
#define weighted_sum(a, b, c, d, e, e_sum) \
((a)*e.x + (b)*e.y + (c)*e.z + (d)*e.w) / max(1e-6, e_sum);

View File

@@ -1,38 +0,0 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
#pragma BLENDER_REQUIRE(workbench_shader_interface_lib.glsl)
#pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
#pragma BLENDER_REQUIRE(workbench_material_lib.glsl)
#pragma BLENDER_REQUIRE(workbench_image_lib.glsl)
void main()
{
vec3 world_pos;
pointcloud_get_pos_and_nor(world_pos, normal_interp);
normal_interp = normalize(normal_world_to_view(normal_interp));
gl_Position = point_world_to_ndc(world_pos);
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(world_pos);
#endif
uv_interp = vec2(0.0);
#ifdef OPAQUE_MATERIAL
float metallic, roughness;
#endif
workbench_material_data_get(resource_handle, color_interp, alpha_interp, roughness, metallic);
if (materialIndex == 0) {
color_interp = vec3(1.0);
}
#ifdef OPAQUE_MATERIAL
packed_rough_metal = workbench_float_pair_encode(roughness, metallic);
#endif
object_id = int((uint(resource_id) + 1u) & 0xFFu);
}

View File

@@ -1,10 +1,4 @@
#ifdef GPU_VERTEX_SHADER
# define IN_OUT out
#else
# define IN_OUT in
#endif
IN_OUT ShaderStageInterface
{
vec3 normal_interp;

View File

@@ -15,7 +15,7 @@ layout(location = 1) out vec4 revealageAccum;
layout(location = 2) out uint objectId;
/* Special function only to be used with calculate_transparent_weight(). */
float linear_zdepth(float depth, vec4 viewvecs[3], mat4 proj_mat)
float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
{
if (proj_mat[3][3] == 0.0) {
float d = 2.0 * depth - 1.0;
@@ -33,7 +33,7 @@ float linear_zdepth(float depth, vec4 viewvecs[3], mat4 proj_mat)
*/
float calculate_transparent_weight(void)
{
float z = linear_zdepth(gl_FragCoord.z, world_data.viewvecs, ProjectionMatrix);
float z = linear_zdepth(gl_FragCoord.z, ViewVecs, ProjectionMatrix);
#if 0
/* Eq 10 : Good for surfaces with varying opacity (like particles) */
float a = min(1.0, alpha * 10.0) + 0.01;
@@ -57,7 +57,7 @@ void main()
{
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
vec2 uv_viewport = gl_FragCoord.xy * world_data.viewport_size_inv;
vec3 I = view_vector_from_screen_uv(uv_viewport, world_data.viewvecs, ProjectionMatrix);
vec3 I = get_view_vector_from_screen_uv(uv_viewport);
vec3 N = normalize(normal_interp);
vec3 color = color_interp;

View File

@@ -1,4 +1,5 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_common_obinfos_lib.glsl)
#pragma BLENDER_REQUIRE(workbench_data_lib.glsl)
@@ -33,11 +34,6 @@ float phase_function_isotropic()
return 1.0 / (4.0 * M_PI);
}
float max_v3(vec3 v)
{
return max(v.x, max(v.y, v.z));
}
float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
{
/* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
@@ -194,10 +190,8 @@ void main()
float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r;
float depth_end = min(depth, gl_FragCoord.z);
vec3 vs_ray_end = view_position_from_depth(
screen_uv, depth_end, world_data.viewvecs, ProjectionMatrix);
vec3 vs_ray_ori = view_position_from_depth(
screen_uv, 0.0, world_data.viewvecs, ProjectionMatrix);
vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end);
vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0);
vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0);
vs_ray_dir /= abs(vs_ray_dir.z);

View File

@@ -86,43 +86,6 @@ static WORKBENCH_ViewLayerData *workbench_view_layer_data_ensure_ex(struct ViewL
/* \} */
static void workbench_viewvecs_update(float r_viewvecs[3][4])
{
float invproj[4][4];
const bool is_persp = DRW_view_is_persp_get(NULL);
DRW_view_winmat_get(NULL, invproj, true);
/* view vectors for the corners of the view frustum.
* Can be used to recreate the world space position easily */
copy_v4_fl4(r_viewvecs[0], -1.0f, -1.0f, -1.0f, 1.0f);
copy_v4_fl4(r_viewvecs[1], 1.0f, -1.0f, -1.0f, 1.0f);
copy_v4_fl4(r_viewvecs[2], -1.0f, 1.0f, -1.0f, 1.0f);
/* convert the view vectors to view space */
for (int i = 0; i < 3; i++) {
mul_m4_v4(invproj, r_viewvecs[i]);
/* normalized trick see:
* http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
mul_v3_fl(r_viewvecs[i], 1.0f / r_viewvecs[i][3]);
if (is_persp) {
mul_v3_fl(r_viewvecs[i], 1.0f / r_viewvecs[i][2]);
}
r_viewvecs[i][3] = 1.0;
}
/* we need to store the differences */
r_viewvecs[1][0] -= r_viewvecs[0][0];
r_viewvecs[1][1] = r_viewvecs[2][1] - r_viewvecs[0][1];
/* calculate a depth offset as well */
if (!is_persp) {
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
mul_m4_v4(invproj, vec_far);
mul_v3_fl(vec_far, 1.0f / vec_far[3]);
r_viewvecs[1][2] = vec_far[2] - r_viewvecs[0][2];
}
}
static void workbench_studiolight_data_update(WORKBENCH_PrivateData *wpd, WORKBENCH_UBO_World *wd)
{
StudioLight *studiolight = wpd->studio_light;
@@ -311,7 +274,6 @@ void workbench_update_world_ubo(WORKBENCH_PrivateData *wpd)
workbench_studiolight_data_update(wpd, &wd);
workbench_shadow_data_update(wpd, &wd);
workbench_cavity_data_update(wpd, &wd);
workbench_viewvecs_update(wd.viewvecs);
DRW_uniformbuffer_update(wpd->world_ubo, &wd);
}

View File

@@ -130,17 +130,6 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
}
}
BLI_INLINE void workbench_object_drawcall(DRWShadingGroup *grp, struct GPUBatch *geom, Object *ob)
{
if (ob->type == OB_POINTCLOUD) {
/* Draw range to avoid drawcall batching messing up the instance attrib. */
DRW_shgroup_call_instance_range(grp, ob, geom, 0, 0);
}
else {
DRW_shgroup_call(grp, geom, ob);
}
}
static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object *ob)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -156,7 +145,7 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
SET_FLAG_FROM_TEST(state, imapaint->interp == IMAGEPAINT_INTERP_LINEAR, GPU_SAMPLER_FILTER);
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, state);
workbench_object_drawcall(grp, geom, ob);
DRW_shgroup_call(grp, geom, ob);
}
}
else {
@@ -168,7 +157,7 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
continue;
}
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, i + 1, NULL, NULL, 0);
workbench_object_drawcall(grp, geoms[i], ob);
DRW_shgroup_call(grp, geoms[i], ob);
}
}
}
@@ -205,7 +194,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
if (geom) {
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, r_transp);
workbench_object_drawcall(grp, geom, ob);
DRW_shgroup_call(grp, geom, ob);
}
}
else {
@@ -218,7 +207,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
continue;
}
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, i + 1, color_type, r_transp);
workbench_object_drawcall(grp, geoms[i], ob);
DRW_shgroup_call(grp, geoms[i], ob);
}
}
}
@@ -461,7 +450,7 @@ void workbench_cache_finish(void *ved)
/* TODO don't free reuse next redraw. */
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < WORKBENCH_DATATYPE_MAX; k++) {
for (int k = 0; k < 2; k++) {
if (wpd->prepass[i][j][k].material_hash) {
BLI_ghash_free(wpd->prepass[i][j][k].material_hash, NULL, NULL);
wpd->prepass[i][j][k].material_hash = NULL;

View File

@@ -162,7 +162,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
Object *ob,
int mat_nr,
eV3DShadingColorType color_type,
eWORKBENCH_DataType datatype,
bool hair,
bool *r_transp)
{
Image *ima = NULL;
@@ -180,7 +180,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
switch (color_type) {
case V3D_SHADING_TEXTURE_COLOR: {
return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, datatype);
return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, hair);
}
case V3D_SHADING_MATERIAL_COLOR: {
/* For now, we use the same ubo for material and object coloring but with different indices.
@@ -191,7 +191,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
Material *ma = workbench_object_material_get(ob, mat_nr);
const bool transp = wpd->shading.xray_alpha < 1.0f || ma->a < 1.0f;
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][datatype];
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][hair];
if (r_transp && transp) {
*r_transp = true;
@@ -216,7 +216,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
}
case V3D_SHADING_VERTEX_COLOR: {
const bool transp = wpd->shading.xray_alpha < 1.0f;
DRWShadingGroup *grp = wpd->prepass[transp][infront][datatype].vcol_shgrp;
DRWShadingGroup *grp = wpd->prepass[transp][infront][hair].vcol_shgrp;
return grp;
}
default: {
@@ -231,7 +231,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
workbench_material_ubo_data(wpd, ob, NULL, &wpd->material_ubo_data_curr[mat_id], color_type);
const bool transp = wpd->shading.xray_alpha < 1.0f || ob->color[3] < 1.0f;
DRWShadingGroup *grp = wpd->prepass[transp][infront][datatype].common_shgrp;
DRWShadingGroup *grp = wpd->prepass[transp][infront][hair].common_shgrp;
if (resource_changed) {
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
@@ -251,7 +251,7 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
Image *ima,
ImageUser *iuser,
eGPUSamplerState sampler,
eWORKBENCH_DataType datatype)
bool hair)
{
GPUTexture *tex = NULL, *tex_tile_data = NULL;
@@ -275,7 +275,7 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
const bool infront = (ob->dtx & OB_DRAWXRAY) != 0;
const bool transp = wpd->shading.xray_alpha < 1.0f;
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][datatype];
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][hair];
DRWShadingGroup **grp_tex = NULL;
/* A hashmap stores image shgroups to pack all similar drawcalls together. */

View File

@@ -59,10 +59,10 @@ void workbench_opaque_engine_init(WORKBENCH_Data *data)
});
}
void workbench_opaque_cache_init(WORKBENCH_Data *vedata)
void workbench_opaque_cache_init(WORKBENCH_Data *data)
{
WORKBENCH_PassList *psl = vedata->psl;
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
WORKBENCH_PassList *psl = data->psl;
WORKBENCH_PrivateData *wpd = data->stl->wpd;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
struct GPUShader *sh;
DRWShadingGroup *grp;
@@ -84,31 +84,31 @@ void workbench_opaque_cache_init(WORKBENCH_Data *vedata)
pass = psl->opaque_ps;
}
for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) {
wpd->prepass[opaque][infront][data].material_hash = BLI_ghash_ptr_new(__func__);
for (int hair = 0; hair < 2; hair++) {
wpd->prepass[opaque][infront][hair].material_hash = BLI_ghash_ptr_new(__func__);
sh = workbench_shader_opaque_get(wpd, data);
sh = workbench_shader_opaque_get(wpd, hair);
wpd->prepass[opaque][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass);
wpd->prepass[opaque][infront][hair].common_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
wpd->prepass[opaque][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
wpd->prepass[opaque][infront][hair].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
sh = workbench_shader_opaque_image_get(wpd, data, false);
sh = workbench_shader_opaque_image_get(wpd, hair, false);
wpd->prepass[opaque][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass);
wpd->prepass[opaque][infront][hair].image_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
sh = workbench_shader_opaque_image_get(wpd, data, true);
sh = workbench_shader_opaque_image_get(wpd, hair, true);
wpd->prepass[opaque][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
wpd->prepass[opaque][infront][hair].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);

View File

@@ -71,14 +71,6 @@ struct RenderEngine;
struct RenderLayer;
struct rcti;
typedef enum eWORKBENCH_DataType {
WORKBENCH_DATATYPE_MESH = 0,
WORKBENCH_DATATYPE_HAIR,
WORKBENCH_DATATYPE_POINTCLOUD,
WORKBENCH_DATATYPE_MAX,
} eWORKBENCH_DataType;
typedef struct WORKBENCH_FramebufferList {
struct GPUFrameBuffer *opaque_fb;
struct GPUFrameBuffer *opaque_infront_fb;
@@ -176,7 +168,6 @@ typedef struct WORKBENCH_UBO_Material {
} WORKBENCH_UBO_Material;
typedef struct WORKBENCH_UBO_World {
float viewvecs[3][4];
float viewport_size[2], viewport_size_inv[2];
float object_outline_color[4];
float shadow_direction_vs[4];
@@ -301,8 +292,8 @@ typedef struct WORKBENCH_PrivateData {
/** Object IDs buffer for curvature & outline. */
struct GPUTexture *object_id_tx;
/** Pre-pass information for each draw types [transparent][infront][datatype]. */
WORKBENCH_Prepass prepass[2][2][WORKBENCH_DATATYPE_MAX];
/** Pre-pass information for each draw types [transparent][infront][hair]. */
WORKBENCH_Prepass prepass[2][2][2];
/* Materials */
/** Copy of vldata->material_ubo for faster access. */
@@ -401,16 +392,14 @@ void workbench_shadow_cache_init(WORKBENCH_Data *data);
void workbench_shadow_cache_populate(WORKBENCH_Data *data, Object *ob, const bool has_transp_mat);
/* workbench_shader.c */
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data);
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd,
eWORKBENCH_DataType data,
bool tiled);
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, bool hair);
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, bool hair, bool tiled);
GPUShader *workbench_shader_composite_get(WORKBENCH_PrivateData *wpd);
GPUShader *workbench_shader_merge_infront_get(WORKBENCH_PrivateData *wpd);
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data);
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, bool hair);
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
eWORKBENCH_DataType data,
bool hair,
bool tiled);
GPUShader *workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData *wpd);
@@ -465,7 +454,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
Object *ob,
int mat_nr,
eV3DShadingColorType color_type,
eWORKBENCH_DataType datatype,
bool hair,
bool *r_transp);
DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
Object *ob,
@@ -473,20 +462,17 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
Image *ima,
ImageUser *iuser,
eGPUSamplerState sampler,
eWORKBENCH_DataType datatype);
#define WORKBENCH_OBJECT_DATATYPE(ob) \
((ob->type == OB_POINTCLOUD) ? WORKBENCH_DATATYPE_POINTCLOUD : WORKBENCH_DATATYPE_MESH)
bool hair);
#define workbench_material_setup(wpd, ob, mat_nr, color_type, r_transp) \
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, WORKBENCH_OBJECT_DATATYPE(ob), r_transp)
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, false, r_transp)
#define workbench_image_setup(wpd, ob, mat_nr, ima, iuser, interp) \
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_OBJECT_DATATYPE(ob))
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, false)
#define workbench_material_hair_setup(wpd, ob, mat_nr, color_type) \
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, WORKBENCH_DATATYPE_HAIR, 0)
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, true, 0)
#define workbench_image_hair_setup(wpd, ob, mat_nr, ima, iuser, interp) \
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_DATATYPE_HAIR)
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, true)
/* workbench_data.c */
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);

View File

@@ -28,14 +28,14 @@
#include "workbench_engine.h"
#include "workbench_private.h"
extern char datatoc_common_math_lib_glsl[];
extern char datatoc_common_math_geom_lib_glsl[];
extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_common_pointcloud_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_common_smaa_lib_glsl[];
extern char datatoc_workbench_prepass_vert_glsl[];
extern char datatoc_workbench_prepass_hair_vert_glsl[];
extern char datatoc_workbench_prepass_pointcloud_vert_glsl[];
extern char datatoc_workbench_prepass_frag_glsl[];
extern char datatoc_workbench_effect_cavity_frag_glsl[];
@@ -76,6 +76,7 @@ extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
/* Maximum number of variations. */
#define MAX_LIGHTING 3
#define MAX_COLOR 3
#define MAX_GEOM 2
enum {
VOLUME_SH_SLICE = 0,
@@ -86,9 +87,8 @@ enum {
#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
static struct {
struct GPUShader *opaque_prepass_sh_cache[GPU_SHADER_CFG_LEN][WORKBENCH_DATATYPE_MAX][MAX_COLOR];
struct GPUShader *transp_prepass_sh_cache[GPU_SHADER_CFG_LEN][WORKBENCH_DATATYPE_MAX]
[MAX_LIGHTING][MAX_COLOR];
struct GPUShader *opaque_prepass_sh_cache[GPU_SHADER_CFG_LEN][MAX_GEOM][MAX_COLOR];
struct GPUShader *transp_prepass_sh_cache[GPU_SHADER_CFG_LEN][MAX_GEOM][MAX_LIGHTING][MAX_COLOR];
struct GPUShader *opaque_composite_sh[MAX_LIGHTING];
struct GPUShader *oit_resolve_sh;
@@ -119,9 +119,10 @@ void workbench_shader_library_ensure(void)
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
/* NOTE: Theses needs to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_pointcloud_lib);
DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib);
DRW_SHADER_LIB_ADD(e_data.lib, workbench_shader_interface_lib);
DRW_SHADER_LIB_ADD(e_data.lib, workbench_common_lib);
@@ -180,18 +181,15 @@ static int workbench_color_index(WORKBENCH_PrivateData *UNUSED(wpd), bool textur
return (textured) ? (tiled ? 2 : 1) : 0;
}
static GPUShader *workbench_shader_get_ex(WORKBENCH_PrivateData *wpd,
bool transp,
eWORKBENCH_DataType datatype,
bool textured,
bool tiled)
static GPUShader *workbench_shader_get_ex(
WORKBENCH_PrivateData *wpd, bool transp, bool hair, bool textured, bool tiled)
{
int color = workbench_color_index(wpd, textured, tiled);
int light = wpd->shading.light;
BLI_assert(light < MAX_LIGHTING);
struct GPUShader **shader =
(transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][datatype][light][color] :
&e_data.opaque_prepass_sh_cache[wpd->sh_cfg][datatype][color];
(transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][hair][light][color] :
&e_data.opaque_prepass_sh_cache[wpd->sh_cfg][hair][color];
if (*shader == NULL) {
char *defines = workbench_build_defines(wpd, textured, tiled, false, false);
@@ -200,11 +198,8 @@ static GPUShader *workbench_shader_get_ex(WORKBENCH_PrivateData *wpd,
datatoc_workbench_prepass_frag_glsl;
char *frag_src = DRW_shader_library_create_shader_string(e_data.lib, frag_file);
char *vert_file = (datatype == WORKBENCH_DATATYPE_HAIR) ?
datatoc_workbench_prepass_hair_vert_glsl :
((datatype == WORKBENCH_DATATYPE_POINTCLOUD) ?
datatoc_workbench_prepass_pointcloud_vert_glsl :
datatoc_workbench_prepass_vert_glsl);
char *vert_file = hair ? datatoc_workbench_prepass_hair_vert_glsl :
datatoc_workbench_prepass_vert_glsl;
char *vert_src = DRW_shader_library_create_shader_string(e_data.lib, vert_file);
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[wpd->sh_cfg];
@@ -216,10 +211,6 @@ static GPUShader *workbench_shader_get_ex(WORKBENCH_PrivateData *wpd,
defines,
transp ? "#define TRANSPARENT_MATERIAL\n" :
"#define OPAQUE_MATERIAL\n",
(datatype == WORKBENCH_DATATYPE_POINTCLOUD) ?
"#define UNIFORM_RESOURCE_ID\n"
"#define INSTANCED_ATTR\n" :
NULL,
NULL},
});
@@ -230,29 +221,26 @@ static GPUShader *workbench_shader_get_ex(WORKBENCH_PrivateData *wpd,
return *shader;
}
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType datatype)
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, bool hair)
{
return workbench_shader_get_ex(wpd, false, datatype, false, false);
return workbench_shader_get_ex(wpd, false, hair, false, false);
}
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd,
eWORKBENCH_DataType datatype,
bool tiled)
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, bool hair, bool tiled)
{
return workbench_shader_get_ex(wpd, false, datatype, true, tiled);
return workbench_shader_get_ex(wpd, false, hair, true, tiled);
}
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd,
eWORKBENCH_DataType datatype)
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, bool hair)
{
return workbench_shader_get_ex(wpd, true, datatype, false, false);
return workbench_shader_get_ex(wpd, true, hair, false, false);
}
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
eWORKBENCH_DataType datatype,
bool hair,
bool tiled)
{
return workbench_shader_get_ex(wpd, true, datatype, true, tiled);
return workbench_shader_get_ex(wpd, true, hair, true, tiled);
}
GPUShader *workbench_shader_composite_get(WORKBENCH_PrivateData *wpd)

Some files were not shown because too many files have changed in this diff Show More