Compare commits
10 Commits
refactor-m
...
tmp-eevee-
Author | SHA1 | Date | |
---|---|---|---|
9034351b8d | |||
b5c67c2ec1 | |||
930c22e84a | |||
98f9a6667b | |||
92fbc81885 | |||
e148f6d697 | |||
c584dd2298 | |||
709c9f6bf0 | |||
83d902f33b | |||
5849f99009 |
@@ -186,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)
|
||||
@@ -205,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)
|
||||
@@ -230,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)
|
||||
@@ -241,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)
|
||||
@@ -287,6 +289,8 @@ 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_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)
|
||||
|
@@ -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),
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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) \
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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))
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
|
181
source/blender/draw/engines/eevee/shaders/closure_lib.glsl
Normal file
181
source/blender/draw/engines/eevee/shaders/closure_lib.glsl
Normal 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
|
@@ -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
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/** \} */
|
@@ -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));
|
@@ -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;
|
||||
}
|
@@ -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. */
|
||||
|
@@ -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()
|
||||
{
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -1,4 +1,8 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
|
||||
|
||||
uniform sampler2D depthBuffer;
|
||||
|
||||
uniform mat4 prevViewProjMatrix;
|
||||
uniform mat4 currViewProjMatrixInv;
|
||||
uniform mat4 nextViewProjMatrix;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -1,4 +1,7 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(cubemap_lib.glsl)
|
||||
|
||||
flat in int pid;
|
||||
in vec2 quadCoord;
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
/* XXX TODO fix code duplication */
|
||||
struct CubeData {
|
||||
vec4 position_type;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
uniform float sphere_size;
|
||||
uniform int offset;
|
||||
uniform ivec3 grid_resolution;
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
uniform sampler2DArray probePlanars;
|
||||
|
||||
in vec3 worldPosition;
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
in int probe_id;
|
||||
|
@@ -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
|
||||
|
||||
/** \} */
|
||||
|
@@ -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;
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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 */
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
||||
|
88
source/blender/draw/engines/eevee/shaders/surface_frag.glsl
Normal file
88
source/blender/draw/engines/eevee/shaders/surface_frag.glsl
Normal 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
|
||||
}
|
24
source/blender/draw/engines/eevee/shaders/surface_lib.glsl
Normal file
24
source/blender/draw/engines/eevee/shaders/surface_lib.glsl
Normal 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
|
||||
};
|
@@ -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();
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
#ifdef MESH_SHADER
|
||||
/* TODO tight slices */
|
||||
layout(triangles) in;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
||||
|
@@ -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 */
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
out vec4 vPos;
|
||||
|
||||
void main()
|
||||
|
@@ -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;
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
uniform sampler2D depthTex;
|
||||
uniform sampler2D lineTex;
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -5,7 +5,6 @@ struct LightData {
|
||||
};
|
||||
|
||||
struct WorldData {
|
||||
vec4 viewvecs[3];
|
||||
vec4 viewport_size;
|
||||
vec4 object_outline_color;
|
||||
vec4 shadow_direction_vs;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -1,10 +1,4 @@
|
||||
|
||||
#ifdef GPU_VERTEX_SHADER
|
||||
# define IN_OUT out
|
||||
#else
|
||||
# define IN_OUT in
|
||||
#endif
|
||||
|
||||
IN_OUT ShaderStageInterface
|
||||
{
|
||||
vec3 normal_interp;
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -168,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];
|
||||
|
@@ -28,6 +28,8 @@
|
||||
#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_view_lib_glsl[];
|
||||
extern char datatoc_common_smaa_lib_glsl[];
|
||||
@@ -117,6 +119,8 @@ 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, gpu_shader_common_obinfos_lib);
|
||||
|
@@ -204,6 +204,11 @@ struct GPUShader *DRW_shader_create(const char *vert,
|
||||
const char *defines);
|
||||
struct GPUShader *DRW_shader_create_with_lib(
|
||||
const char *vert, const char *geom, const char *frag, const char *lib, const char *defines);
|
||||
struct GPUShader *DRW_shader_create_with_shaderlib(const char *vert,
|
||||
const char *geom,
|
||||
const char *frag,
|
||||
const DRWShaderLibrary *lib,
|
||||
const char *defines);
|
||||
struct GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
|
||||
const char *geom,
|
||||
const char *defines,
|
||||
@@ -211,6 +216,9 @@ struct GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
|
||||
const char **varying_names,
|
||||
const int varying_count);
|
||||
struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
|
||||
struct GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag,
|
||||
const DRWShaderLibrary *lib,
|
||||
const char *defines);
|
||||
struct GPUMaterial *DRW_shader_find_from_world(struct World *wo,
|
||||
const void *engine_type,
|
||||
const int options,
|
||||
@@ -257,7 +265,8 @@ void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const ch
|
||||
#define DRW_SHADER_LIB_ADD(lib, lib_name) \
|
||||
DRW_shader_library_add_file(lib, datatoc_##lib_name##_glsl, STRINGIFY(lib_name) ".glsl")
|
||||
|
||||
char *DRW_shader_library_create_shader_string(DRWShaderLibrary *lib, char *shader_code);
|
||||
char *DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib,
|
||||
const char *shader_code);
|
||||
|
||||
void DRW_shader_library_free(DRWShaderLibrary *lib);
|
||||
#define DRW_SHADER_LIB_FREE_SAFE(lib) \
|
||||
|
@@ -380,6 +380,7 @@ typedef struct DRWViewUboStorage {
|
||||
float wininv[4][4];
|
||||
|
||||
float clipplanes[6][4];
|
||||
float viewvecs[2][4];
|
||||
/* Should not be here. Not view dependent (only main view). */
|
||||
float viewcamtexcofac[4];
|
||||
} DRWViewUboStorage;
|
||||
|
@@ -1656,6 +1656,52 @@ static void draw_view_matrix_state_update(DRWViewUboStorage *storage,
|
||||
|
||||
mul_m4_m4m4(storage->persmat, winmat, viewmat);
|
||||
invert_m4_m4(storage->persinv, storage->persmat);
|
||||
|
||||
const bool is_persp = (winmat[3][3] == 0.0f);
|
||||
|
||||
/* Near clip distance. */
|
||||
storage->viewvecs[0][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] - 1.0f) :
|
||||
-(winmat[3][2] + 1.0f) / winmat[2][2];
|
||||
|
||||
/* Far clip distance. */
|
||||
storage->viewvecs[1][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] + 1.0f) :
|
||||
-(winmat[3][2] - 1.0f) / winmat[2][2];
|
||||
|
||||
/* view vectors for the corners of the view frustum.
|
||||
* Can be used to recreate the world space position easily */
|
||||
float view_vecs[4][3] = {
|
||||
{-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 */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
mul_project_m4_v3(storage->wininv, 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_v3_v3(storage->viewvecs[0], view_vecs[0]);
|
||||
|
||||
/* we need to store the differences */
|
||||
storage->viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
|
||||
storage->viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
|
||||
storage->viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
|
||||
}
|
||||
|
||||
/* Create a view with culling. */
|
||||
|
@@ -328,6 +328,26 @@ GPUShader *DRW_shader_create_with_lib(
|
||||
return sh;
|
||||
}
|
||||
|
||||
GPUShader *DRW_shader_create_with_shaderlib(const char *vert,
|
||||
const char *geom,
|
||||
const char *frag,
|
||||
const DRWShaderLibrary *lib,
|
||||
const char *defines)
|
||||
{
|
||||
GPUShader *sh;
|
||||
char *vert_with_lib = DRW_shader_library_create_shader_string(lib, vert);
|
||||
char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
|
||||
char *geom_with_lib = (geom) ? DRW_shader_library_create_shader_string(lib, geom) : NULL;
|
||||
|
||||
sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, __func__);
|
||||
|
||||
MEM_SAFE_FREE(vert_with_lib);
|
||||
MEM_SAFE_FREE(frag_with_lib);
|
||||
MEM_SAFE_FREE(geom_with_lib);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
|
||||
const char *geom,
|
||||
const char *defines,
|
||||
@@ -352,6 +372,22 @@ GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines)
|
||||
datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, __func__);
|
||||
}
|
||||
|
||||
GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag,
|
||||
const DRWShaderLibrary *lib,
|
||||
const char *defines)
|
||||
{
|
||||
|
||||
GPUShader *sh;
|
||||
char *vert = datatoc_common_fullscreen_vert_glsl;
|
||||
char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
|
||||
|
||||
sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, __func__);
|
||||
|
||||
MEM_SAFE_FREE(frag_with_lib);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
GPUMaterial *DRW_shader_find_from_world(World *wo,
|
||||
const void *engine_type,
|
||||
const int options,
|
||||
@@ -505,7 +541,7 @@ void DRW_shader_library_free(DRWShaderLibrary *lib)
|
||||
MEM_SAFE_FREE(lib);
|
||||
}
|
||||
|
||||
static int drw_shader_library_search(DRWShaderLibrary *lib, const char *name)
|
||||
static int drw_shader_library_search(const DRWShaderLibrary *lib, const char *name)
|
||||
{
|
||||
for (int i = 0; i < MAX_LIB; i++) {
|
||||
if (lib->libs[i]) {
|
||||
@@ -521,18 +557,28 @@ static int drw_shader_library_search(DRWShaderLibrary *lib, const char *name)
|
||||
}
|
||||
|
||||
/* Return bitmap of dependencies. */
|
||||
static uint32_t drw_shader_dependencies_get(DRWShaderLibrary *lib, char *lib_code)
|
||||
static uint32_t drw_shader_dependencies_get(const DRWShaderLibrary *lib, const char *lib_code)
|
||||
{
|
||||
/* Search dependencies. */
|
||||
uint32_t deps = 0;
|
||||
char *haystack = lib_code;
|
||||
const char *haystack = lib_code;
|
||||
while ((haystack = strstr(haystack, "BLENDER_REQUIRE("))) {
|
||||
haystack += 16;
|
||||
int dep = drw_shader_library_search(lib, haystack);
|
||||
if (dep == -1) {
|
||||
char dbg_name[32];
|
||||
int i = 0;
|
||||
while ((haystack[0] != ')') && (i < 31)) {
|
||||
dbg_name[i] = haystack[0];
|
||||
haystack++;
|
||||
i++;
|
||||
}
|
||||
dbg_name[i + 1] = '\0';
|
||||
|
||||
printf(
|
||||
"Error: Dependency not found.\n"
|
||||
"This might be due to bad lib ordering.\n");
|
||||
"Error: Dependency not found: %s\n"
|
||||
"This might be due to bad lib ordering.\n",
|
||||
dbg_name);
|
||||
BLI_assert(0);
|
||||
}
|
||||
else {
|
||||
@@ -565,7 +611,7 @@ void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const ch
|
||||
|
||||
/* Return an allocN'ed string containing the shader code with its dependencies prepended.
|
||||
* Caller must free the string with MEM_freeN after use. */
|
||||
char *DRW_shader_library_create_shader_string(DRWShaderLibrary *lib, char *shader_code)
|
||||
char *DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib, const char *shader_code)
|
||||
{
|
||||
uint32_t deps = drw_shader_dependencies_get(lib, shader_code);
|
||||
|
||||
|
@@ -95,7 +95,7 @@ void hair_get_interp_attrs(
|
||||
* For final drawing, the vertex index and the number of vertex per segment
|
||||
*/
|
||||
|
||||
#ifndef HAIR_PHASE_SUBDIV
|
||||
#if !defined(HAIR_PHASE_SUBDIV) && defined(GPU_VERTEX_SHADER)
|
||||
int hair_get_strand_id(void)
|
||||
{
|
||||
return gl_VertexID / (hairStrandsRes * hairThicknessRes);
|
||||
|
119
source/blender/draw/intern/shaders/common_math_geom_lib.glsl
Normal file
119
source/blender/draw/intern/shaders/common_math_geom_lib.glsl
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Math intersection & projection functions.
|
||||
* \{ */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Other useful functions.
|
||||
* \{ */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* ---- 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;
|
||||
}
|
||||
|
||||
/** \} */
|
130
source/blender/draw/intern/shaders/common_math_lib.glsl
Normal file
130
source/blender/draw/intern/shaders/common_math_lib.glsl
Normal file
@@ -0,0 +1,130 @@
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Common Math Utilities
|
||||
* \{ */
|
||||
|
||||
#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
|
||||
|
||||
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)
|
||||
|
||||
/* clang-format off */
|
||||
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); }
|
||||
/* clang-format on */
|
||||
|
||||
#define saturate(a) 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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name 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;
|
||||
}
|
||||
|
||||
/** \} */
|
@@ -14,10 +14,24 @@ layout(std140) uniform viewBlock
|
||||
|
||||
vec4 clipPlanes[6];
|
||||
|
||||
/* View frustum corners [NDC(-1.0, -1.0, -1.0) & NDC(1.0, 1.0, 1.0)].
|
||||
* Fourth components are near and far values. */
|
||||
vec4 ViewVecs[2];
|
||||
|
||||
/* TODO move it elsewhere. */
|
||||
vec4 CameraTexCoFactors;
|
||||
};
|
||||
|
||||
#define ViewNear (ViewVecs[0].w)
|
||||
#define ViewFar (ViewVecs[1].w)
|
||||
|
||||
#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))
|
||||
|
||||
#ifdef world_clip_planes_calc_clip_distance
|
||||
# undef world_clip_planes_calc_clip_distance
|
||||
# define world_clip_planes_calc_clip_distance(p) \
|
||||
@@ -194,3 +208,78 @@ uniform mat4 ModelMatrixInverse;
|
||||
#define DRW_BASE_FROM_DUPLI (1 << 2)
|
||||
#define DRW_BASE_FROM_SET (1 << 3)
|
||||
#define DRW_BASE_ACTIVE (1 << 4)
|
||||
|
||||
/* ---- 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)
|
||||
{
|
||||
vec4 ndc = ProjectionMatrix * vec4(view, 1.0);
|
||||
return (ndc.xy / ndc.w) * 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_view_vector_from_screen_uv(vec2 uv)
|
||||
{
|
||||
if (ProjectionMatrix[3][3] == 0.0) {
|
||||
return normalize(vec3(ViewVecs[0].xy + uv * ViewVecs[1].xy, 1.0));
|
||||
}
|
||||
else {
|
||||
return vec3(0.0, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
@@ -610,21 +610,6 @@ static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
|
||||
|
||||
BLI_dynstr_append(ds, "}\n");
|
||||
|
||||
/* XXX This cannot go into gpu_shader_material.glsl because main()
|
||||
* would be parsed and generate error */
|
||||
/* Old glsl mode compat. */
|
||||
/* TODO(fclem) This is only used by world shader now. get rid of it? */
|
||||
BLI_dynstr_append(ds, "#ifndef NODETREE_EXEC\n");
|
||||
BLI_dynstr_append(ds, "out vec4 fragColor;\n");
|
||||
BLI_dynstr_append(ds, "void main()\n");
|
||||
BLI_dynstr_append(ds, "{\n");
|
||||
BLI_dynstr_append(ds, "\tClosure cl = nodetree_exec();\n");
|
||||
BLI_dynstr_append(ds,
|
||||
"\tfragColor = vec4(cl.radiance, "
|
||||
"saturate(1.0 - avg(cl.transmittance)));\n");
|
||||
BLI_dynstr_append(ds, "}\n");
|
||||
BLI_dynstr_append(ds, "#endif\n\n");
|
||||
|
||||
/* create shader */
|
||||
code = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
@@ -453,7 +453,9 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
|
||||
int num_source = 0;
|
||||
|
||||
source[num_source++] = gpu_shader_version();
|
||||
source[num_source++] = "#define GPU_VERTEX_SHADER\n";
|
||||
source[num_source++] =
|
||||
"#define GPU_VERTEX_SHADER\n"
|
||||
"#define IN_OUT out\n";
|
||||
source[num_source++] = standard_extensions;
|
||||
source[num_source++] = standard_defines;
|
||||
|
||||
@@ -484,7 +486,9 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
|
||||
int num_source = 0;
|
||||
|
||||
source[num_source++] = gpu_shader_version();
|
||||
source[num_source++] = "#define GPU_FRAGMENT_SHADER\n";
|
||||
source[num_source++] =
|
||||
"#define GPU_FRAGMENT_SHADER\n"
|
||||
"#define IN_OUT in\n";
|
||||
source[num_source++] = standard_extensions;
|
||||
source[num_source++] = standard_defines;
|
||||
|
||||
|
@@ -3,7 +3,7 @@ void node_ambient_occlusion(
|
||||
vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao)
|
||||
{
|
||||
vec3 bent_normal;
|
||||
vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
|
||||
vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
|
||||
result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal);
|
||||
result_color = result_ao * color;
|
||||
}
|
||||
|
@@ -1,3 +1,15 @@
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void node_hair_info(out float is_strand,
|
||||
out float intercept,
|
||||
out float thickness,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user