1
1

Compare commits

...

15 Commits

Author SHA1 Message Date
7499e7912e Fix subpass iteration 2020-05-26 13:04:23 +02:00
b2320263f2 EEVEE: Fix assert during default shader compilation
The default shader could have been requested as deferred and then as non
defered. This could make the shader compilation assert.
2020-05-14 16:55:25 +02:00
c11aea538f Cleanup: DRW: Remove unused DRW_shgroup_hair_create/DRW_shgroup_material_hair_create 2020-05-14 16:55:25 +02:00
3b86d5e95c Cleanup: EEVEE: Remove EEVEE_material_default_render_pass_ubo_get 2020-05-14 16:55:25 +02:00
ca22d1ec79 Cleanup: EEVEE: Move shader related function to eevee_shaders.c 2020-05-14 16:55:25 +02:00
9f8c22929b Cleanup: EEVEE: Split LUT generation code from eevee_material.c 2020-05-14 16:55:25 +02:00
5ead114e1c Cleanup: EEVEE: Remove Unused variable after refactor. 2020-05-14 16:55:25 +02:00
8197022d6c EEVEE: Rewrite Passes and Material handling
Passes of the same type are now chained together and reusing the same
shgroup when possible.

Materials are now always handled as a nodetree compiled shader (GPUMaterial)
even for default materials.

Render passes use a ubo reference to change output pass type instead of
creating a lot of DRWPasses.

# Conflicts:
#	source/blender/draw/engines/eevee/eevee_materials.c
2020-05-14 16:53:03 +02:00
6e18b02065 EEVEE: Rename / merge passes using new DRWPass chaining/instancing
Now calling DRW_pass_draw on material_ps will draw all opaque passes.
Same for depth_ps for opaque prepass.
2020-05-14 16:46:18 +02:00
cf6ee13fab EEVEE: Make lit_surface_vert.glsl usable for depth pass 2020-05-14 16:46:18 +02:00
4f89f4e1b0 EEVEE: Use alpha hash shader for alpha clip material
This reduces the number of shader combination. We use the nodetree material
output node shader code to do the alpha comparison.
2020-05-14 16:46:18 +02:00
2ef54d03b5 DRW: Expose DRW_shgroup_add_material_resources for better flexibility 2020-05-14 16:46:18 +02:00
4090f06b2d DRW: Add pass chaining and instances
Instancing will draw the same shgroups but with the instancer pass' state.

Chaining (linking) will render multiple passes by just calling DRW_draw_pass
on the first one.
2020-05-14 16:46:18 +02:00
4d05823055 DRW: Add texture ref persist, block ref and block ref persist uniforms 2020-05-14 16:46:18 +02:00
5ce4ce2e50 GPUMaterial: Expose shader getter 2020-05-14 16:46:17 +02:00
37 changed files with 1752 additions and 2365 deletions

View File

@@ -34,6 +34,7 @@ set(INC
../imbuf
../makesdna
../makesrna
../nodes
../render/extern/include
../render/intern/include
../windowmanager

View File

@@ -24,6 +24,8 @@
#include "DRW_render.h"
#include "BLI_memblock.h"
#include "eevee_lightcache.h"
#include "eevee_private.h"
@@ -54,8 +56,17 @@ void EEVEE_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->grid_ubo);
DRW_UBO_FREE_SAFE(sldata->planar_ubo);
DRW_UBO_FREE_SAFE(sldata->common_ubo);
for (int i = 0; i < MAX_MATERIAL_RENDER_PASSES_UBO; i++) {
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo[i]);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.combined);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.diff_color);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.diff_light);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.spec_color);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.spec_light);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.emit);
if (sldata->material_cache) {
BLI_memblock_destroy(sldata->material_cache, NULL);
sldata->material_cache = NULL;
}
}

View File

@@ -333,8 +333,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp = DRW_shgroup_create(EEVEE_shaders_velocity_resolve_sh_get(), psl->velocity_resolve);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_uniform_mat4(grp, "currPersinv", effects->velocity_curr_persinv);
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
DRW_shgroup_call(grp, quad, NULL);

View File

@@ -88,7 +88,7 @@ static void eevee_engine_init(void *ved)
* `EEVEE_effects_init` needs to go second for TAA. */
EEVEE_renderpasses_init(vedata);
EEVEE_effects_init(sldata, vedata, camera, false);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_materials_init(sldata, vedata, stl, fbl);
EEVEE_shadows_init(sldata);
EEVEE_lightprobes_init(sldata, vedata);
}
@@ -230,7 +230,7 @@ static void eevee_draw_scene(void *vedata)
BLI_halton_3d(primes, offset, samp, r);
EEVEE_update_noise(psl, fbl, r);
EEVEE_volumes_set_jitter(sldata, samp - 1);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_materials_init(sldata, vedata, stl, fbl);
}
/* Copy previous persmat to UBO data */
copy_m4_m4(sldata->common_data.prev_persmat, stl->effects->prev_persmat);
@@ -274,8 +274,7 @@ static void eevee_draw_scene(void *vedata)
/* Depth prepass */
DRW_stats_group_start("Prepass");
DRW_draw_pass(psl->depth_pass);
DRW_draw_pass(psl->depth_pass_cull);
DRW_draw_pass(psl->depth_ps);
DRW_stats_group_end();
/* Create minmax texture */
@@ -289,9 +288,9 @@ static void eevee_draw_scene(void *vedata)
/* Shading pass */
DRW_stats_group_start("Shading");
if (DRW_state_draw_background()) {
DRW_draw_pass(psl->background_pass);
DRW_draw_pass(psl->background_ps);
}
EEVEE_materials_draw_opaque(sldata, psl);
DRW_draw_pass(psl->material_ps);
EEVEE_subsurface_data_render(sldata, vedata);
DRW_stats_group_end();
@@ -306,9 +305,8 @@ static void eevee_draw_scene(void *vedata)
/* Opaque refraction */
DRW_stats_group_start("Opaque Refraction");
DRW_draw_pass(psl->refract_depth_pass);
DRW_draw_pass(psl->refract_depth_pass_cull);
DRW_draw_pass(psl->refract_pass);
DRW_draw_pass(psl->depth_refract_ps);
DRW_draw_pass(psl->material_refract_ps);
DRW_stats_group_end();
/* Volumetrics Resolve Opaque */

View File

@@ -822,7 +822,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
DRW_render_viewport_size_set(viewport_size);
EEVEE_effects_init(sldata, vedata, NULL, true);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_materials_init(sldata, vedata, stl, fbl);
EEVEE_shadows_init(sldata);
EEVEE_lightprobes_init(sldata, vedata);

View File

@@ -248,8 +248,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
// DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call_instances(grp, NULL, geom, 6);
@@ -271,8 +270,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -293,8 +291,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -337,51 +334,29 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
Scene *scene = draw_ctx->scene;
World *wo = scene->world;
const float *col = G_draw.block.colorBackground;
/* LookDev */
EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->probe_background, wo, pinfo);
/* END */
if (!grp && wo) {
col = &wo->horr;
struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_WORLD_PROBE);
if (wo->use_nodes && wo->nodetree) {
static float error_col[3] = {1.0f, 0.0f, 1.0f};
static float queue_col[3] = {0.5f, 0.5f, 0.5f};
struct GPUMaterial *gpumat = EEVEE_material_world_lightprobe_get(scene, wo);
eGPUMaterialStatus status = GPU_material_status(gpumat);
switch (status) {
case GPU_MAT_SUCCESS:
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", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
stl->g_data->queued_shaders_count++;
col = queue_col;
break;
default:
col = error_col;
break;
}
}
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", col, 1);
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);
}
@@ -408,8 +383,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
/* TODO (fclem) get rid of those UBO. */
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call_procedural_triangles(grp, NULL, cube_len * 2);
}
@@ -436,8 +410,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(shgrp, "renderpass_block", sldata->renderpass_ubo.combined);
int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2;
DRW_shgroup_call_procedural_triangles(shgrp, NULL, tri_count);
}
@@ -455,8 +428,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_display_sh_get(),
psl->probe_display);
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
stl->g_data->planar_display_shgrp = DRW_shgroup_call_buffer_instance(
grp, e_data.format_probe_display_planar, DRW_cache_quad_get());
@@ -923,12 +895,10 @@ static void lightbake_render_scene_face(int face, EEVEE_BakeRenderData *user_dat
GPU_framebuffer_bind(face_fb[face]);
GPU_framebuffer_clear_depth(face_fb[face], 1.0f);
DRW_draw_pass(psl->depth_pass);
DRW_draw_pass(psl->depth_pass_cull);
DRW_draw_pass(psl->depth_ps);
DRW_draw_pass(psl->probe_background);
EEVEE_materials_draw_opaque(sldata, psl);
DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
DRW_draw_pass(psl->sss_pass_cull);
DRW_draw_pass(psl->material_ps);
DRW_draw_pass(psl->material_sss_ps); /* Only output standard pass */
DRW_draw_pass(psl->transparent_pass);
}
@@ -987,10 +957,8 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us
/* Slight modification: we handle refraction as normal
* shading and don't do SSRefraction. */
DRW_draw_pass(psl->depth_pass_clip);
DRW_draw_pass(psl->depth_pass_clip_cull);
DRW_draw_pass(psl->refract_depth_pass_clip);
DRW_draw_pass(psl->refract_depth_pass_clip_cull);
DRW_draw_pass(psl->depth_ps);
DRW_draw_pass(psl->depth_refract_ps);
DRW_draw_pass(psl->probe_background);
EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer);
@@ -999,10 +967,9 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us
GPU_framebuffer_bind(fbl->planarref_fb);
/* Shading pass */
EEVEE_materials_draw_opaque(sldata, psl);
DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
DRW_draw_pass(psl->sss_pass_cull);
DRW_draw_pass(psl->refract_pass);
DRW_draw_pass(psl->material_ps);
DRW_draw_pass(psl->material_sss_ps); /* Only output standard pass */
DRW_draw_pass(psl->material_refract_ps);
/* Transparent */
if (DRW_state_is_image_render()) {

View File

@@ -34,6 +34,8 @@
#include "ED_screen.h"
#include "GPU_material.h"
#include "UI_resources.h"
#include "eevee_lightcache.h"
@@ -56,6 +58,43 @@ static void eevee_lookdev_lightcache_delete(EEVEE_Data *vedata)
g_data->studiolight_rot_z = 0.0f;
}
static void eevee_lookdev_hdri_preview_init(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata)
{
EEVEE_PassList *psl = vedata->psl;
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
DRWShadingGroup *grp;
struct GPUBatch *sphere = DRW_cache_sphere_get();
int mat_options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS |
DRW_STATE_CULL_BACK;
{
Material *ma = EEVEE_material_default_diffuse_get();
GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
struct GPUShader *sh = GPU_material_get_shader(gpumat);
DRW_PASS_CREATE(psl->lookdev_diffuse_pass, state);
grp = DRW_shgroup_create(sh, psl->lookdev_diffuse_pass);
EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, false, false);
DRW_shgroup_add_material_resources(grp, gpumat);
DRW_shgroup_call(grp, sphere, NULL);
}
{
Material *ma = EEVEE_material_default_glossy_get();
GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
struct GPUShader *sh = GPU_material_get_shader(gpumat);
DRW_PASS_CREATE(psl->lookdev_glossy_pass, state);
grp = DRW_shgroup_create(sh, psl->lookdev_glossy_pass);
EEVEE_material_bind_resources(grp, gpumat, sldata, vedata, NULL, NULL, false, false);
DRW_shgroup_add_material_resources(grp, gpumat);
DRW_shgroup_call(grp, sphere, NULL);
}
}
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
DRWShadingGroup **r_grp,
@@ -106,6 +145,8 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
effects->anchor[1] = rect->ymin;
EEVEE_temporal_sampling_reset(vedata);
}
eevee_lookdev_hdri_preview_init(vedata, sldata);
}
if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
@@ -176,8 +217,7 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
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", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
}
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);

View File

@@ -0,0 +1,198 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright 2020, Blender Foundation.
*/
/** \file
* \ingroup draw_engine
*
* EEVEE LUT generation:
*
* Routine to generate the LUT used by eevee stored in eevee_lut.h
* Theses functions are not to be used in the final executable.
*/
#include "DRW_render.h"
#include "BLI_alloca.h"
#include "BLI_rand.h"
#include "BLI_string_utils.h"
extern char datatoc_bsdf_lut_frag_glsl[];
extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_lightprobe_vert_glsl[];
static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
{
struct GPUTexture *tex;
struct GPUFrameBuffer *fb = NULL;
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);
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");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_float(grp, "sampleCount", &samples_len, 1);
DRW_shgroup_uniform_float(grp, "invSampleCount", &inv_samples_len, 1);
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
tex = DRW_texture_create_2d(w, h, GPU_RG16F, DRW_TEX_FILTER, (float *)texels);
DRWFboTexture tex_filter = {&tex, GPU_RG16F, DRW_TEX_FILTER};
GPU_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 1);
GPU_framebuffer_bind(fb);
DRW_draw_pass(pass);
float *data = MEM_mallocN(sizeof(float[3]) * w * h, "lut");
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, w, h, GL_RGB, GL_FLOAT, data);
printf("{");
for (int i = 0; i < w * h * 3; i += 3) {
printf("%ff, %ff, ", data[i], data[i + 1]);
i += 3;
printf("%ff, %ff, ", data[i], data[i + 1]);
i += 3;
printf("%ff, %ff, ", data[i], data[i + 1]);
i += 3;
printf("%ff, %ff, \n", data[i], data[i + 1]);
}
printf("}");
MEM_freeN(texels);
MEM_freeN(data);
return tex;
}
static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
{
struct GPUTexture *tex;
struct GPUTexture *hammersley = create_hammersley_sample_texture(8192);
struct GPUFrameBuffer *fb = NULL;
static float samples_len = 8192.0f;
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);
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);
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_float(grp, "a2", &a2, 1);
DRW_shgroup_uniform_float(grp, "sampleCount", &samples_len, 1);
DRW_shgroup_uniform_float(grp, "invSampleCount", &inv_samples_len, 1);
DRW_shgroup_uniform_texture(grp, "texHammersley", hammersley);
DRW_shgroup_uniform_texture(grp, "utilTex", e_data.util_tex);
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
tex = DRW_texture_create_2d(w, h, GPU_R16F, DRW_TEX_FILTER, (float *)texels);
DRWFboTexture tex_filter = {&tex, GPU_R16F, DRW_TEX_FILTER};
GPU_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 1);
GPU_framebuffer_bind(fb);
float *data = MEM_mallocN(sizeof(float[3]) * w * h, "lut");
float inc = 1.0f / 31.0f;
float roughness = 1e-8f - inc;
FILE *f = BLI_fopen("btdf_split_sum_ggx.h", "w");
fprintf(f, "static float btdf_split_sum_ggx[32][64 * 64] = {\n");
do {
roughness += inc;
CLAMP(roughness, 1e-4f, 1.0f);
a2 = powf(roughness, 4.0f);
DRW_draw_pass(pass);
GPU_framebuffer_read_data(0, 0, w, h, 3, 0, data);
#if 1
fprintf(f, "\t{\n\t\t");
for (int i = 0; i < w * h * 3; i += 3) {
fprintf(f, "%ff,", data[i]);
if (((i / 3) + 1) % 12 == 0) {
fprintf(f, "\n\t\t");
}
else {
fprintf(f, " ");
}
}
fprintf(f, "\n\t},\n");
#else
for (int i = 0; i < w * h * 3; i += 3) {
if (data[i] < 0.01) {
printf(" ");
}
else if (data[i] < 0.3) {
printf(".");
}
else if (data[i] < 0.6) {
printf("+");
}
else if (data[i] < 0.9) {
printf("%%");
}
else {
printf("#");
}
if ((i / 3 + 1) % 64 == 0) {
printf("\n");
}
}
#endif
} while (roughness < 1.0f);
fprintf(f, "\n};\n");
fclose(f);
MEM_freeN(texels);
MEM_freeN(data);
return tex;
}

File diff suppressed because it is too large Load Diff

View File

@@ -114,8 +114,7 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(e_data.mist_sh, psl->mist_accum_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_uniform_vec3(grp, "mistSettings", &g_data->mist_start, 1);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}

View File

@@ -170,8 +170,7 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
@@ -209,8 +208,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call(grp, quad, NULL);
DRW_PASS_CREATE(psl->ao_horizon_search_layer, DRW_STATE_WRITE_COLOR);
@@ -219,8 +217,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBufferLayered", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_uniform_int(grp, "layer", &stl->effects->ao_depth_layer, 1);
DRW_shgroup_call(grp, quad, NULL);
@@ -233,8 +230,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call(grp, quad, NULL);
}
}

View File

@@ -158,35 +158,23 @@ BLI_INLINE bool eevee_hdri_preview_overlay_enabled(const View3D *v3d)
(EEVEE_RENDER_PASS_EMIT | EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_DIFFUSE_LIGHT | \
EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_SPECULAR_LIGHT | \
EEVEE_RENDER_PASS_ENVIRONMENT)
#define MAX_MATERIAL_RENDER_PASSES 6
#define MAX_MATERIAL_RENDER_PASSES_UBO 6
/* World shader variations */
enum {
VAR_WORLD_BACKGROUND = 0,
VAR_WORLD_PROBE = 1,
VAR_WORLD_VOLUME = 2,
};
/* Material shader variations */
enum {
VAR_MAT_MESH = (1 << 0),
VAR_MAT_PROBE = (1 << 1),
VAR_MAT_VOLUME = (1 << 1),
VAR_MAT_HAIR = (1 << 2),
VAR_MAT_BLEND = (1 << 3),
VAR_MAT_VOLUME = (1 << 4),
VAR_MAT_PROBE = (1 << 3),
VAR_MAT_BLEND = (1 << 4),
VAR_MAT_LOOKDEV = (1 << 5),
VAR_MAT_HOLDOUT = (1 << 6),
/* Max number of variation */
/* IMPORTANT : Leave it last and set
* it's value accordingly. */
VAR_MAT_MAX = (1 << 7),
/* These are options that are not counted in VAR_MAT_MAX
* because they are not cumulative with the others above. */
VAR_MAT_CLIP = (1 << 9),
VAR_MAT_HASH = (1 << 10),
VAR_MAT_MULT = (1 << 11),
VAR_MAT_SHADOW = (1 << 12),
VAR_MAT_REFRACT = (1 << 13),
VAR_MAT_HASH = (1 << 7),
VAR_MAT_DEPTH = (1 << 8),
VAR_MAT_REFRACT = (1 << 9),
VAR_WORLD_BACKGROUND = (1 << 10),
VAR_WORLD_PROBE = (1 << 11),
VAR_WORLD_VOLUME = (1 << 12),
VAR_DEFAULT = (1 << 13),
};
/* ************ PROBE UBO ************* */
@@ -272,23 +260,26 @@ typedef struct EEVEE_PassList {
struct DRWPass *maxz_copydepth_ps;
struct DRWPass *maxz_copydepth_layer_ps;
struct DRWPass *depth_pass;
struct DRWPass *depth_pass_cull;
struct DRWPass *depth_pass_clip;
struct DRWPass *depth_pass_clip_cull;
struct DRWPass *refract_depth_pass;
struct DRWPass *refract_depth_pass_cull;
struct DRWPass *refract_depth_pass_clip;
struct DRWPass *refract_depth_pass_clip_cull;
struct DRWPass *default_pass[VAR_MAT_MAX];
struct DRWPass *sss_pass;
struct DRWPass *sss_pass_cull;
struct DRWPass *material_pass;
struct DRWPass *material_pass_cull;
struct DRWPass *material_accum_pass[MAX_MATERIAL_RENDER_PASSES];
struct DRWPass *refract_pass;
/* Renderpass Accumulation. */
struct DRWPass *material_accum_ps;
struct DRWPass *background_accum_ps;
struct DRWPass *depth_ps;
struct DRWPass *depth_cull_ps;
struct DRWPass *depth_clip_ps;
struct DRWPass *depth_clip_cull_ps;
struct DRWPass *depth_refract_ps;
struct DRWPass *depth_refract_cull_ps;
struct DRWPass *depth_refract_clip_ps;
struct DRWPass *depth_refract_clip_cull_ps;
struct DRWPass *material_ps;
struct DRWPass *material_cull_ps;
struct DRWPass *material_refract_ps;
struct DRWPass *material_refract_cull_ps;
struct DRWPass *material_sss_ps;
struct DRWPass *material_sss_cull_ps;
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
struct DRWPass *background_ps;
struct DRWPass *update_noise_pass;
struct DRWPass *lookdev_glossy_pass;
struct DRWPass *lookdev_diffuse_pass;
@@ -348,7 +339,12 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *mist_accum;
struct GPUTexture *ao_accum;
struct GPUTexture *sss_accum;
struct GPUTexture *material_accum[MAX_MATERIAL_RENDER_PASSES];
struct GPUTexture *env_accum;
struct GPUTexture *diff_color_accum;
struct GPUTexture *diff_light_accum;
struct GPUTexture *spec_color_accum;
struct GPUTexture *spec_light_accum;
struct GPUTexture *emit_accum;
struct GPUTexture *bloom_accum;
struct GPUTexture *ssr_accum;
struct GPUTexture *shadow_accum;
@@ -574,6 +570,7 @@ typedef struct EEVEE_EffectsInfo {
bool swap_double_buffer;
/* SSSS */
int sss_sample_count;
int sss_surface_count;
struct GPUTexture *sss_irradiance; /* Textures from pool */
struct GPUTexture *sss_radius;
struct GPUTexture *sss_albedo;
@@ -754,14 +751,22 @@ typedef struct EEVEE_ViewLayerData {
struct GPUUniformBuffer *planar_ubo;
/* Material Render passes */
struct EEVEE_RenderPassData renderpass_data[MAX_MATERIAL_RENDER_PASSES_UBO];
struct GPUUniformBuffer *renderpass_ubo[MAX_MATERIAL_RENDER_PASSES_UBO];
struct {
struct GPUUniformBuffer *combined;
struct GPUUniformBuffer *diff_color;
struct GPUUniformBuffer *diff_light;
struct GPUUniformBuffer *spec_color;
struct GPUUniformBuffer *spec_light;
struct GPUUniformBuffer *emit;
} renderpass_ubo;
/* Common Uniform Buffer */
struct EEVEE_CommonUniformBuffer common_data;
struct GPUUniformBuffer *common_ubo;
struct LightCache *fallback_lightcache;
struct BLI_memblock *material_cache;
} EEVEE_ViewLayerData;
/* ************ OBJECT DATA ************ */
@@ -809,14 +814,6 @@ typedef struct EEVEE_Data {
typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *shadow_shgrp;
struct DRWShadingGroup *shadow_accum_shgrp;
struct DRWShadingGroup *depth_shgrp;
struct DRWShadingGroup *depth_shgrp_cull;
struct DRWShadingGroup *depth_shgrp_clip;
struct DRWShadingGroup *depth_shgrp_clip_cull;
struct DRWShadingGroup *refract_depth_shgrp;
struct DRWShadingGroup *refract_depth_shgrp_cull;
struct DRWShadingGroup *refract_depth_shgrp_clip;
struct DRWShadingGroup *refract_depth_shgrp_clip_cull;
struct DRWCallBuffer *planar_display_shgrp;
struct GHash *material_hash;
float background_alpha; /* TODO find a better place for this. */
@@ -862,9 +859,8 @@ typedef struct EEVEE_PrivateData {
GPUTexture *renderpass_input;
GPUTexture *renderpass_col_input;
GPUTexture *renderpass_light_input;
/* The number of active material based render passes */
uint render_passes_material_count;
/* Renderpass ubo reference used by material pass. */
struct GPUUniformBuffer *renderpass_ubo;
/** For rendering shadows. */
struct DRWView *cube_views[6];
/** For rendering probes. */
@@ -892,6 +888,7 @@ EEVEE_WorldEngineData *EEVEE_world_data_ensure(World *wo);
/* eevee_materials.c */
struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
EEVEE_StorageList *stl,
EEVEE_FramebufferList *fbl);
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -908,31 +905,20 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
Object *ob,
bool *cast_shadow);
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_mesh_get(
struct Scene *scene, Material *ma, EEVEE_Data *vedata, bool use_blend, bool use_refract);
struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material *ma);
struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene,
Material *ma,
bool use_hashed_alpha,
bool is_shadow);
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma);
struct GPUUniformBuffer *EEVEE_material_default_render_pass_ubo_get(EEVEE_ViewLayerData *sldata);
void EEVEE_materials_free(void);
void EEVEE_materials_draw_opaque(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
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);
int EEVEE_material_output_pass_index_get(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
eViewLayerEEVEEPassType renderpass_type);
int EEVEE_material_output_color_pass_index_get(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
eViewLayerEEVEEPassType renderpass_type);
void EEVEE_material_bind_resources(DRWShadingGroup *shgrp,
struct GPUMaterial *gpumat,
EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
int *ssr_id,
float *refract_depth,
bool use_ssrefraction,
bool use_alpha_blend);
/* eevee_lights.c */
void eevee_light_matrix_get(const EEVEE_Light *evli, float r_mat[4][4]);
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -943,16 +929,6 @@ void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh);
void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata);
void EEVEE_shadows_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_shadows_caster_add(EEVEE_ViewLayerData *sldata,
EEVEE_StorageList *stl,
struct GPUBatch *geom,
Object *ob);
void EEVEE_shadows_caster_material_add(EEVEE_ViewLayerData *sldata,
EEVEE_PassList *psl,
struct GPUMaterial *gpumat,
struct GPUBatch *geom,
struct Object *ob,
const float *alpha_threshold);
void EEVEE_shadows_caster_register(EEVEE_ViewLayerData *sldata, struct Object *ob);
void EEVEE_shadows_update(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_shadows_cube_add(EEVEE_LightsInfo *linfo, EEVEE_Light *evli, struct Object *ob);
@@ -986,6 +962,7 @@ 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 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);
@@ -993,12 +970,22 @@ 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_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);
struct GPUShader *EEVEE_shaders_update_noise_sh_get(void);
struct GPUShader *EEVEE_shaders_velocity_resolve_sh_get(void);
struct GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects);
struct bNodeTree *EEVEE_shader_default_surface_nodetree(Material *ma);
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);
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);
void EEVEE_shaders_free(void);
/* eevee_lightprobes.c */
@@ -1105,13 +1092,9 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata,
uint tot_samples);
void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint sss_id,
struct GPUUniformBuffer *sss_profile);
void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint sss_id,
struct GPUUniformBuffer *sss_profile,
struct GPUTexture *sss_tex_profile);
Material *ma,
DRWShadingGroup *shgrp,
struct GPUMaterial *gpumat);
void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);

View File

@@ -151,7 +151,7 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
* `EEVEE_effects_init` needs to go second for TAA. */
EEVEE_renderpasses_init(vedata);
EEVEE_effects_init(sldata, vedata, ob_camera_eval, false);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_materials_init(sldata, vedata, stl, fbl);
EEVEE_shadows_init(sldata);
EEVEE_lightprobes_init(sldata, vedata);
@@ -463,7 +463,7 @@ static void eevee_render_draw_background(EEVEE_Data *vedata)
GPU_ATTACHMENT_NONE});
GPU_framebuffer_bind(fbl->main_fb);
DRW_draw_pass(psl->background_pass);
DRW_draw_pass(psl->background_ps);
GPU_framebuffer_ensure_config(&fbl->main_fb,
{GPU_ATTACHMENT_LEAVE,
@@ -556,7 +556,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
EEVEE_update_noise(psl, fbl, r);
EEVEE_temporal_sampling_matrices_calc(stl->effects, r);
EEVEE_volumes_set_jitter(sldata, stl->effects->taa_current_sample - 1);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_materials_init(sldata, vedata, stl, fbl);
/* Refresh Probes
* Shadows needs to be updated for correct probes */
@@ -578,8 +578,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
GPU_framebuffer_bind(fbl->main_fb);
GPU_framebuffer_clear_color_depth_stencil(fbl->main_fb, clear_col, clear_depth, clear_stencil);
/* Depth prepass */
DRW_draw_pass(psl->depth_pass);
DRW_draw_pass(psl->depth_pass_cull);
DRW_draw_pass(psl->depth_ps);
/* Create minmax texture */
EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1);
@@ -587,16 +586,15 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
/* Shading pass */
eevee_render_draw_background(vedata);
GPU_framebuffer_bind(fbl->main_fb);
EEVEE_materials_draw_opaque(sldata, psl);
DRW_draw_pass(psl->material_ps);
EEVEE_subsurface_data_render(sldata, vedata);
/* Effects pre-transparency */
EEVEE_subsurface_compute(sldata, vedata);
EEVEE_reflection_compute(sldata, vedata);
EEVEE_refraction_compute(sldata, vedata);
/* Opaque refraction */
DRW_draw_pass(psl->refract_depth_pass);
DRW_draw_pass(psl->refract_depth_pass_cull);
DRW_draw_pass(psl->refract_pass);
DRW_draw_pass(psl->depth_refract_ps);
DRW_draw_pass(psl->material_refract_ps);
/* Result NORMAL */
eevee_render_result_normal(rl, viewname, rect, vedata, sldata);
/* Volumetrics Resolve Opaque */

View File

@@ -201,8 +201,7 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
grp, "inputSecondLightBuffer", &g_data->renderpass_light_input);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_uniform_int(grp, "currentSample", &g_data->renderpass_current_sample, 1);
DRW_shgroup_uniform_int(grp, "renderpassType", &g_data->renderpass_type, 1);
DRW_shgroup_uniform_int(grp, "postProcessType", &g_data->renderpass_postprocess, 1);
@@ -225,7 +224,7 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
* Only invoke this function for passes that need post-processing.
*
* After invoking this function the active framebuffer is set to `vedata->fbl->renderpass_fb`. */
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
eViewLayerEEVEEPassType renderpass_type)
{
@@ -276,22 +275,30 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
g_data->renderpass_input = txl->shadow_accum;
break;
}
case EEVEE_RENDER_PASS_DIFFUSE_COLOR:
case EEVEE_RENDER_PASS_SPECULAR_COLOR:
case EEVEE_RENDER_PASS_ENVIRONMENT:
case EEVEE_RENDER_PASS_DIFFUSE_COLOR: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->diff_color_accum;
break;
}
case EEVEE_RENDER_PASS_SPECULAR_COLOR: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->spec_color_accum;
break;
}
case EEVEE_RENDER_PASS_ENVIRONMENT: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->env_accum;
break;
}
case EEVEE_RENDER_PASS_EMIT: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
g_data->renderpass_input = txl->material_accum[renderpass_index];
g_data->renderpass_input = txl->emit_accum;
break;
}
case EEVEE_RENDER_PASS_SPECULAR_LIGHT: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
sldata, vedata, renderpass_type);
g_data->renderpass_input = txl->material_accum[renderpass_index];
g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
g_data->renderpass_input = txl->spec_light_accum;
g_data->renderpass_col_input = txl->spec_color_accum;
if ((stl->effects->enabled_effects & EFFECT_SSR) != 0) {
g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
g_data->renderpass_light_input = txl->ssr_accum;
@@ -303,11 +310,8 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
}
case EEVEE_RENDER_PASS_DIFFUSE_LIGHT: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
sldata, vedata, renderpass_type);
g_data->renderpass_input = txl->material_accum[renderpass_index];
g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
g_data->renderpass_input = txl->diff_light_accum;
g_data->renderpass_col_input = txl->diff_color_accum;
if ((stl->effects->enabled_effects & EFFECT_SSS) != 0) {
g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
g_data->renderpass_light_input = txl->sss_accum;
@@ -343,10 +347,6 @@ void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
if ((render_pass & EEVEE_RENDER_PASS_MIST) != 0) {
EEVEE_mist_output_accumulate(sldata, vedata);
}
if ((render_pass & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0 &&
(effects->enabled_effects & EFFECT_SSS) != 0) {
EEVEE_subsurface_output_accumulate(sldata, vedata);
}
if ((render_pass & EEVEE_RENDER_PASS_AO) != 0) {
EEVEE_occlusion_output_accumulate(sldata, vedata);
}

View File

@@ -237,8 +237,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
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, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
if (!effects->reflection_trace_full) {
DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1);
}
@@ -259,8 +258,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
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, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1);
if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());

View File

@@ -22,12 +22,20 @@
#include "DRW_render.h"
#include "BKE_lib_id.h"
#include "BKE_node.h"
#include "BLI_dynstr.h"
#include "BLI_string_utils.h"
#include "MEM_guardedalloc.h"
#include "GPU_material.h"
#include "GPU_shader.h"
#include "NOD_shader.h"
#include "eevee_engine.h"
#include "eevee_private.h"
static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
@@ -61,6 +69,38 @@ static struct {
struct GPUShader *taa_resolve_sh;
struct GPUShader *taa_resolve_reproject_sh;
/* General purpose Shaders. */
struct GPUShader *default_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;
/* LookDev Materials */
Material *glossy_mat;
Material *diffuse_mat;
Material *error_mat;
/* Default Material */
struct {
bNodeTree *ntree;
bNodeSocketValueRGBA *color_socket;
bNodeSocketValueFloat *metallic_socket;
bNodeSocketValueFloat *roughness_socket;
bNodeSocketValueFloat *specular_socket;
} surface;
struct {
bNodeTree *ntree;
bNodeSocketValueRGBA *color_socket;
} world;
} e_data = {NULL}; /* Engine data */
extern char datatoc_bsdf_common_lib_glsl[];
@@ -68,27 +108,42 @@ extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_view_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_cubemap_lib_glsl[];
extern char datatoc_default_world_frag_glsl[];
extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_lightprobe_vert_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_cube_display_frag_glsl[];
extern char datatoc_lightprobe_cube_display_vert_glsl[];
extern char datatoc_lightprobe_filter_diffuse_frag_glsl[];
extern char datatoc_lightprobe_filter_glossy_frag_glsl[];
extern char datatoc_lightprobe_filter_visibility_frag_glsl[];
extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_lightprobe_grid_display_frag_glsl[];
extern char datatoc_lightprobe_grid_display_vert_glsl[];
extern char datatoc_lightprobe_grid_fill_frag_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_lightprobe_planar_display_frag_glsl[];
extern char datatoc_lightprobe_planar_display_vert_glsl[];
extern char datatoc_lightprobe_planar_downsample_frag_glsl[];
extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_lib_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_ltc_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_prepass_frag_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_ssr_lib_glsl[];
extern char datatoc_update_noise_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_lib_glsl[];
extern char datatoc_volumetric_vert_glsl[];
/* Velocity Resolve */
extern char datatoc_effect_velocity_resolve_frag_glsl[];
@@ -150,6 +205,64 @@ void EEVEE_shaders_lightprobe_shaders_init(void)
NULL);
}
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);
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);
}
GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
{
return e_data.probe_filter_glossy_sh;
@@ -292,6 +405,26 @@ GPUShader *EEVEE_shaders_velocity_resolve_sh_get(void)
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);
}
return e_data.update_noise_sh;
}
GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects)
{
GPUShader **sh;
@@ -316,8 +449,330 @@ GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects)
return *sh;
}
Material *EEVEE_material_default_diffuse_get(void)
{
if (!e_data.diffuse_mat) {
Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default diffuse");
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
ma->nodetree = ntree;
ma->use_nodes = true;
bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_DIFFUSE);
bNodeSocket *base_color = nodeFindSocket(bsdf, SOCK_IN, "Color");
copy_v3_fl(((bNodeSocketValueRGBA *)base_color->default_value)->value, 0.8f);
bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
nodeAddLink(ntree,
bsdf,
nodeFindSocket(bsdf, SOCK_OUT, "BSDF"),
output,
nodeFindSocket(output, SOCK_IN, "Surface"));
nodeSetActive(ntree, output);
e_data.diffuse_mat = ma;
}
return e_data.diffuse_mat;
}
Material *EEVEE_material_default_glossy_get(void)
{
if (!e_data.glossy_mat) {
Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default metal");
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
ma->nodetree = ntree;
ma->use_nodes = true;
bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_GLOSSY);
bNodeSocket *base_color = nodeFindSocket(bsdf, SOCK_IN, "Color");
copy_v3_fl(((bNodeSocketValueRGBA *)base_color->default_value)->value, 1.0f);
bNodeSocket *roughness = nodeFindSocket(bsdf, SOCK_IN, "Roughness");
((bNodeSocketValueFloat *)roughness->default_value)->value = 0.0f;
bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
nodeAddLink(ntree,
bsdf,
nodeFindSocket(bsdf, SOCK_OUT, "BSDF"),
output,
nodeFindSocket(output, SOCK_IN, "Surface"));
nodeSetActive(ntree, output);
e_data.glossy_mat = ma;
}
return e_data.glossy_mat;
}
Material *EEVEE_material_default_error_get(void)
{
if (!e_data.error_mat) {
Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default metal");
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
ma->nodetree = ntree;
ma->use_nodes = true;
/* Use emission and output material to be compatible with both World and Material. */
bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_EMISSION);
bNodeSocket *color = nodeFindSocket(bsdf, SOCK_IN, "Color");
copy_v3_fl3(((bNodeSocketValueRGBA *)color->default_value)->value, 1.0f, 0.0f, 1.0f);
bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
nodeAddLink(ntree,
bsdf,
nodeFindSocket(bsdf, SOCK_OUT, "Emission"),
output,
nodeFindSocket(output, SOCK_IN, "Surface"));
nodeSetActive(ntree, output);
e_data.error_mat = ma;
}
return e_data.error_mat;
}
/* Configure a default nodetree with the given material. */
struct bNodeTree *EEVEE_shader_default_surface_nodetree(Material *ma)
{
/* WARNING: This function is not threadsafe. Which is not a problem for the moment. */
if (!e_data.surface.ntree) {
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_PRINCIPLED);
bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
bNodeSocket *bsdf_out = nodeFindSocket(bsdf, SOCK_OUT, "BSDF");
bNodeSocket *output_in = nodeFindSocket(output, SOCK_IN, "Surface");
nodeAddLink(ntree, bsdf, bsdf_out, output, output_in);
nodeSetActive(ntree, output);
e_data.surface.color_socket = nodeFindSocket(bsdf, SOCK_IN, "Base Color")->default_value;
e_data.surface.metallic_socket = nodeFindSocket(bsdf, SOCK_IN, "Metallic")->default_value;
e_data.surface.roughness_socket = nodeFindSocket(bsdf, SOCK_IN, "Roughness")->default_value;
e_data.surface.specular_socket = nodeFindSocket(bsdf, SOCK_IN, "Specular")->default_value;
e_data.surface.ntree = ntree;
}
/* Update */
copy_v3_fl3(e_data.surface.color_socket->value, ma->r, ma->g, ma->b);
e_data.surface.metallic_socket->value = ma->metallic;
e_data.surface.roughness_socket->value = ma->roughness;
e_data.surface.specular_socket->value = ma->spec;
return e_data.surface.ntree;
}
/* Configure a default nodetree with the given world. */
struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo)
{
/* WARNING: This function is not threadsafe. Which is not a problem for the moment. */
if (!e_data.world.ntree) {
bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
bNode *bg = nodeAddStaticNode(NULL, ntree, SH_NODE_BACKGROUND);
bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_WORLD);
bNodeSocket *bg_out = nodeFindSocket(bg, SOCK_OUT, "Background");
bNodeSocket *output_in = nodeFindSocket(output, SOCK_IN, "Surface");
nodeAddLink(ntree, bg, bg_out, output, output_in);
nodeSetActive(ntree, output);
e_data.world.color_socket = nodeFindSocket(bg, SOCK_IN, "Color")->default_value;
e_data.world.ntree = ntree;
}
copy_v3_fl3(e_data.world.color_socket->value, wo->horr, wo->horg, wo->horb);
return e_data.world.ntree;
}
static char *eevee_get_defines(int options)
{
char *str = NULL;
DynStr *ds = BLI_dynstr_new();
BLI_dynstr_append(ds, SHADER_DEFINES);
if ((options & VAR_WORLD_BACKGROUND) != 0) {
BLI_dynstr_append(ds, "#define WORLD_BACKGROUND\n");
}
if ((options & VAR_MAT_VOLUME) != 0) {
BLI_dynstr_append(ds, "#define VOLUMETRICS\n");
}
if ((options & VAR_MAT_MESH) != 0) {
BLI_dynstr_append(ds, "#define MESH_SHADER\n");
}
if ((options & VAR_MAT_DEPTH) != 0) {
BLI_dynstr_append(ds, "#define DEPTH_SHADER\n");
}
if ((options & VAR_MAT_HAIR) != 0) {
BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
}
if ((options & (VAR_MAT_PROBE | VAR_WORLD_PROBE)) != 0) {
BLI_dynstr_append(ds, "#define PROBE_CAPTURE\n");
}
if ((options & VAR_MAT_HASH) != 0) {
BLI_dynstr_append(ds, "#define USE_ALPHA_HASH\n");
}
if ((options & VAR_MAT_BLEND) != 0) {
BLI_dynstr_append(ds, "#define USE_ALPHA_BLEND\n");
}
if ((options & VAR_MAT_REFRACT) != 0) {
BLI_dynstr_append(ds, "#define USE_REFRACTION\n");
}
if ((options & VAR_MAT_LOOKDEV) != 0) {
BLI_dynstr_append(ds, "#define LOOKDEV\n");
}
if ((options & VAR_MAT_HOLDOUT) != 0) {
BLI_dynstr_append(ds, "#define HOLDOUT\n");
}
str = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
return str;
}
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);
}
else if ((options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0) {
str = BLI_strdup(e_data.vert_background_shader_str);
}
else {
str = BLI_strdup(e_data.vert_shader_str);
}
return str;
}
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);
}
return str;
}
static char *eevee_get_frag(int options)
{
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
str = BLI_strdup(e_data.volume_shader_lib);
}
else if ((options & VAR_MAT_DEPTH) != 0) {
str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_prepass_frag_glsl);
}
else {
str = BLI_strdup(e_data.frag_shader_lib);
}
return str;
}
static struct GPUMaterial *eevee_material_get_ex(
struct Scene *scene, Material *ma, World *wo, int options, bool deferred)
{
BLI_assert(ma || wo);
const bool is_volume = (options & VAR_MAT_VOLUME) != 0;
const bool is_default = (options & VAR_DEFAULT) != 0;
const void *engine = &DRW_engine_viewport_eevee_type;
GPUMaterial *mat = NULL;
if (ma) {
mat = DRW_shader_find_from_material(ma, engine, options, deferred);
}
else {
mat = DRW_shader_find_from_world(wo, engine, options, deferred);
}
if (mat) {
return mat;
}
char *defines = eevee_get_defines(options);
char *vert = eevee_get_vert(options);
char *geom = eevee_get_geom(options);
char *frag = eevee_get_frag(options);
if (ma) {
bNodeTree *ntree = !is_default ? ma->nodetree : EEVEE_shader_default_surface_nodetree(ma);
mat = DRW_shader_create_from_material(
scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
}
else {
bNodeTree *ntree = !is_default ? wo->nodetree : EEVEE_shader_default_world_nodetree(wo);
mat = DRW_shader_create_from_world(
scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
}
MEM_SAFE_FREE(defines);
MEM_SAFE_FREE(vert);
MEM_SAFE_FREE(geom);
MEM_SAFE_FREE(frag);
return mat;
}
/* Note: Compilation is not deferred. */
struct GPUMaterial *EEVEE_material_default_get(struct Scene *scene, Material *ma, int options)
{
Material *def_ma = (ma && (options & VAR_MAT_VOLUME)) ? BKE_material_default_volume() :
BKE_material_default_surface();
BLI_assert(def_ma->use_nodes && def_ma->nodetree);
return eevee_material_get_ex(scene, def_ma, NULL, options, false);
}
struct GPUMaterial *EEVEE_material_get(
EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options)
{
if ((ma && (!ma->use_nodes || !ma->nodetree)) || (wo && (!wo->use_nodes || !wo->nodetree))) {
options |= VAR_DEFAULT;
}
/* Meh, implicit option. World probe cannot be deferred because they need
* to be rendered immediatly. */
const bool deferred = (options & VAR_WORLD_PROBE) == 0;
GPUMaterial *mat = eevee_material_get_ex(scene, ma, wo, options, deferred);
int status = GPU_material_status(mat);
switch (status) {
case GPU_MAT_SUCCESS:
break;
case GPU_MAT_QUEUED:
vedata->stl->g_data->queued_shaders_count++;
mat = EEVEE_material_default_get(scene, ma, options);
break;
case GPU_MAT_FAILED:
default:
ma = EEVEE_material_default_error_get();
mat = eevee_material_get_ex(scene, ma, NULL, options, false);
break;
}
/* Returned material should be ready to be drawn. */
BLI_assert(GPU_material_status(mat) == GPU_MAT_SUCCESS);
return mat;
}
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);
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);
@@ -332,4 +787,27 @@ void EEVEE_shaders_free(void)
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);
if (e_data.glossy_mat) {
BKE_id_free(NULL, e_data.glossy_mat);
e_data.glossy_mat = NULL;
}
if (e_data.diffuse_mat) {
BKE_id_free(NULL, e_data.diffuse_mat);
e_data.diffuse_mat = NULL;
}
if (e_data.error_mat) {
BKE_id_free(NULL, e_data.error_mat);
e_data.error_mat = NULL;
}
if (e_data.surface.ntree) {
ntreeFreeEmbeddedTree(e_data.surface.ntree);
MEM_freeN(e_data.surface.ntree);
e_data.surface.ntree = NULL;
}
if (e_data.world.ntree) {
ntreeFreeEmbeddedTree(e_data.world.ntree);
MEM_freeN(e_data.world.ntree);
e_data.world.ntree = NULL;
}
}

View File

@@ -159,47 +159,6 @@ void EEVEE_shadows_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
}
/* Add a shadow caster to the shadowpasses */
void EEVEE_shadows_caster_add(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_StorageList *stl,
struct GPUBatch *geom,
Object *ob)
{
DRW_shgroup_call(stl->g_data->shadow_shgrp, geom, ob);
}
void EEVEE_shadows_caster_material_add(EEVEE_ViewLayerData *sldata,
EEVEE_PassList *psl,
struct GPUMaterial *gpumat,
struct GPUBatch *geom,
struct Object *ob,
const float *alpha_threshold)
{
/* TODO / PERF : reuse the same shading group for objects with the same material */
DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, psl->shadow_pass);
if (grp == NULL) {
return;
}
/* Unfortunately needed for correctness but not 99% of the time not needed.
* TODO detect when needed? */
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, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
if (alpha_threshold != NULL) {
DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
}
DRW_shgroup_call(grp, geom, ob);
}
/* Make that object update shadow casting lights inside its influence bounding box. */
void EEVEE_shadows_caster_register(EEVEE_ViewLayerData *sldata, Object *ob)
{
@@ -470,8 +429,7 @@ void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata,
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, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);

View File

@@ -29,7 +29,9 @@
#include "DEG_depsgraph_query.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
#include "GPU_texture.h"
#include "eevee_private.h"
static struct {
@@ -83,6 +85,7 @@ void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
effects->sss_sample_count = 1 + scene_eval->eevee.sss_samples * 2;
effects->sss_surface_count = 0;
common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold;
}
@@ -221,70 +224,77 @@ void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint sss_id,
struct GPUUniformBuffer *sss_profile)
Material *ma,
DRWShadingGroup *shgrp,
struct GPUMaterial *gpumat)
{
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth;
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[0], psl->sss_blur_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_irradiance);
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
grp = DRW_shgroup_create(e_data.sss_sh[1], psl->sss_resolve_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_blur);
DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
}
void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint sss_id,
struct GPUUniformBuffer *sss_profile,
GPUTexture *sss_tex_profile)
{
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth;
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_translucency_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture(grp, "sssTexProfile", sss_tex_profile);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_texture_ref(grp, "sssShadowCubes", &sldata->shadow_cube_pool);
DRW_shgroup_uniform_texture_ref(grp, "sssShadowCascades", &sldata->shadow_cascade_pool);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
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, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
struct GPUTexture *sss_tex_profile = NULL;
struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(
gpumat, stl->effects->sss_sample_count, &sss_tex_profile);
if (!sss_profile) {
BLI_assert(0 && "SSS pass requested but no SSS data was found");
return;
}
/* Limit of 8 bit stencil buffer. ID 255 is refraction. */
if (effects->sss_surface_count >= 254) {
/* TODO : display message. */
printf("Error: Too many different Subsurface shader in the scene.\n");
return;
}
int sss_id = ++(effects->sss_surface_count);
/* Make main pass output stencil mask. */
DRW_shgroup_stencil_mask(shgrp, sss_id);
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[0], psl->sss_blur_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_irradiance);
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
grp = DRW_shgroup_create(e_data.sss_sh[1], psl->sss_resolve_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_blur);
DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
if (ma->blend_flag & MA_BL_TRANSLUCENCY) {
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_translucency_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture(grp, "sssTexProfile", sss_tex_profile);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_texture_ref(grp, "sssShadowCubes", &sldata->shadow_cube_pool);
DRW_shgroup_uniform_texture_ref(grp, "sssShadowCascades", &sldata->shadow_cascade_pool);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
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, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
}
void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -310,8 +320,7 @@ void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
GPU_ATTACHMENT_TEXTURE(effects->sss_albedo)});
GPU_framebuffer_bind(fbl->main_fb);
DRW_draw_pass(psl->sss_pass);
DRW_draw_pass(psl->sss_pass_cull);
DRW_draw_pass(psl->material_sss_ps);
/* Restore */
GPU_framebuffer_ensure_config(&fbl->main_fb,

View File

@@ -292,8 +292,7 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->taa_history);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
if (effects->enabled_effects & EFFECT_TAA_REPROJECT) {
// DefaultTextureList *dtxl = DRW_viewport_texture_list_get();

View File

@@ -355,7 +355,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
struct World *wo = scene->world;
if (wo != NULL && wo->use_nodes && wo->nodetree &&
!LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) {
struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
struct GPUMaterial *mat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_MAT_VOLUME);
if (GPU_material_has_volume_output(mat)) {
grp = DRW_shgroup_material_create(mat, psl->volumetric_world_ps);
@@ -369,8 +369,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
/* Fix principle volumetric not working with world materials. */
ListBase gpu_grids = GPU_material_volume_grids(mat);
@@ -388,8 +387,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* If no world or volume material is present just clear the buffer with this drawcall */
grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
}
@@ -591,12 +589,10 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
return;
}
struct GPUMaterial *mat = EEVEE_material_mesh_volume_get(scene, ma);
int mat_options = VAR_MAT_VOLUME | VAR_MAT_MESH;
struct GPUMaterial *mat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
eGPUMaterialStatus status = GPU_material_status(mat);
if (status == GPU_MAT_QUEUED) {
vedata->stl->g_data->queued_shaders_count++;
}
/* If shader failed to compile or is currently compiling. */
if (status != GPU_MAT_SUCCESS) {
return;
@@ -610,8 +606,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
@@ -662,8 +657,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
@@ -672,8 +666,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmit);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call_procedural_triangles(
grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
@@ -684,8 +677,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
@@ -921,8 +913,7 @@ void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
}
else {
/* There is no volumetrics in the scene. Use a shader to fill the accum textures with a default

View File

@@ -6,13 +6,9 @@
#if defined(MESH_SHADER)
# if !defined(USE_ALPHA_HASH)
# if !defined(USE_ALPHA_CLIP)
# if !defined(SHADOW_SHADER)
# if !defined(USE_MULTIPLY)
# if !defined(USE_ALPHA_BLEND)
# define ENABLE_DEFERED_AO
# endif
# endif
# if !defined(DEPTH_SHADER)
# if !defined(USE_ALPHA_BLEND)
# define ENABLE_DEFERED_AO
# endif
# endif
# endif

View File

@@ -928,7 +928,7 @@ Closure closure_emission(vec3 rgb)
/* Breaking this across multiple lines causes issues for some older GLSL compilers. */
/* clang-format off */
# if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER)
# if defined(MESH_SHADER) && !defined(DEPTH_SHADER)
/* clang-format on */
# ifndef USE_ALPHA_BLEND
layout(location = 0) out vec4 outRadiance;
@@ -1001,6 +1001,10 @@ void main()
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;
@@ -1011,6 +1015,6 @@ void main()
# endif
}
# endif /* MESH_SHADER && !SHADOW_SHADER */
# endif /* MESH_SHADER */
#endif /* VOLUMETRICS */

View File

@@ -177,7 +177,7 @@ void CLOSURE_NAME(vec3 N
out_refr = vec3(0.0);
#endif
#if defined(SHADOW_SHADER) || defined(WORLD_BACKGROUND)
#if defined(DEPTH_SHADER) || defined(WORLD_BACKGROUND)
/* This makes shader resources become unused and avoid issues with samplers. (see T59747) */
return;
#else

View File

@@ -4,11 +4,12 @@ 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;
@@ -41,22 +42,28 @@ void main()
hairThickness,
hairThickTime);
worldNormal = cross(hairTangent, binor);
worldPosition = pos;
vec3 world_pos = pos;
#else
worldPosition = point_object_to_world(pos);
worldNormal = normalize(normal_object_to_world(nor));
vec3 world_pos = point_object_to_world(pos);
#endif
gl_Position = point_world_to_ndc(world_pos);
/* Used for planar reflections */
gl_ClipDistance[0] = dot(vec4(world_pos, 1.0), clipPlanes[0]);
#ifdef MESH_SHADER
worldPosition = world_pos;
viewPosition = point_world_to_view(worldPosition);
# ifndef HAIR_SHADER
worldNormal = normalize(normal_object_to_world(nor));
# endif
/* No need to normalize since this is just a rotation. */
viewNormal = normal_world_to_view(worldNormal);
viewPosition = point_world_to_view(worldPosition);
gl_Position = point_world_to_ndc(worldPosition);
/* Used for planar reflections */
gl_ClipDistance[0] = dot(vec4(worldPosition, 1.0), clipPlanes[0]);
#ifdef USE_ATTR
# ifdef USE_ATTR
pass_attr(pos);
# endif
#endif
}

View File

@@ -45,26 +45,22 @@ float hashed_alpha_threshold(vec3 co)
/* Find our final, uniformly distributed alpha threshold. */
float threshold = (x < one_a) ? ((x < a) ? cases.x : cases.y) : cases.z;
/* Jitter the threshold for TAA accumulation. */
threshold = fract(threshold + alphaHashOffset);
/* Avoids threshold == 0. */
threshold = clamp(threshold, 1.0e-6, 1.0);
/* Jitter the threshold for TAA accumulation. */
return fract(threshold + alphaHashOffset);
return threshold;
}
#endif
#ifdef USE_ALPHA_CLIP
uniform float alphaThreshold;
#endif
#define NODETREE_EXEC
void main()
{
/* For now do nothing.
* In the future, output object motion blur. */
#if defined(USE_ALPHA_HASH) || defined(USE_ALPHA_CLIP)
# define NODETREE_EXEC
#if defined(USE_ALPHA_HASH)
Closure cl = nodetree_exec();
@@ -75,11 +71,6 @@ void main()
if (opacity < hashed_alpha_threshold(worldPosition)) {
discard;
}
# elif defined(USE_ALPHA_CLIP)
/* Alpha clip */
if (opacity <= alphaThreshold) {
discard;
}
# endif
#endif
}

View File

@@ -224,6 +224,7 @@ struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma,
bool deferred);
struct GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
struct World *wo,
struct bNodeTree *ntree,
const void *engine_type,
const int options,
const bool is_volume_shader,
@@ -234,6 +235,7 @@ struct GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
bool deferred);
struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
struct Material *ma,
struct bNodeTree *ntree,
const void *engine_type,
const int options,
const bool is_volume_shader,
@@ -365,6 +367,8 @@ DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader,
DRWPass *pass,
struct GPUVertBuf *tf_target);
void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial *material);
/* return final visibility */
typedef bool(DRWCallVisibilityFn)(bool vis_in, void *user_data);
@@ -463,15 +467,24 @@ void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup,
void DRW_shgroup_uniform_texture_persistent(DRWShadingGroup *shgroup,
const char *name,
const struct GPUTexture *tex);
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup,
const char *name,
struct GPUTexture **tex);
void DRW_shgroup_uniform_texture_ref_persistent(DRWShadingGroup *shgroup,
const char *name,
struct GPUTexture **tex);
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
const char *name,
const struct GPUUniformBuffer *ubo);
void DRW_shgroup_uniform_block_persistent(DRWShadingGroup *shgroup,
const char *name,
const struct GPUUniformBuffer *ubo);
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup,
const char *name,
struct GPUTexture **tex);
void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup,
const char *name,
struct GPUUniformBuffer **ubo);
void DRW_shgroup_uniform_block_ref_persistent(DRWShadingGroup *shgroup,
const char *name,
struct GPUUniformBuffer **ubo);
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup,
const char *name,
const float *value,
@@ -526,6 +539,8 @@ bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup);
/* Passes */
DRWPass *DRW_pass_create(const char *name, DRWState state);
DRWPass *DRW_pass_create_instance(const char *name, DRWPass *original, DRWState state);
void DRW_pass_link(DRWPass *first, DRWPass *second);
/* TODO Replace with passes inheritance. */
void DRW_pass_state_set(DRWPass *pass, DRWState state);
void DRW_pass_state_add(DRWPass *pass, DRWState state);
@@ -539,6 +554,8 @@ void DRW_pass_sort_shgroup_reverse(DRWPass *pass);
bool DRW_pass_is_empty(DRWPass *pass);
#define DRW_PASS_CREATE(pass, state) (pass = DRW_pass_create(#pass, state))
#define DRW_PASS_INSTANCE_CREATE(pass, original, state) \
(pass = DRW_pass_create_instance(#pass, (original), state))
/* Views */
DRWView *DRW_view_create(const float viewmat[4][4],

View File

@@ -172,23 +172,11 @@ bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis);
/* This creates a shading group with display hairs.
* The draw call is already added by this function, just add additional uniforms. */
struct DRWShadingGroup *DRW_shgroup_hair_create(struct Object *object,
struct ParticleSystem *psys,
struct ModifierData *md,
struct DRWPass *hair_pass,
struct GPUShader *shader);
struct DRWShadingGroup *DRW_shgroup_hair_create_sub(struct Object *object,
struct ParticleSystem *psys,
struct ModifierData *md,
struct DRWShadingGroup *shgrp);
struct DRWShadingGroup *DRW_shgroup_material_hair_create(struct Object *object,
struct ParticleSystem *psys,
struct ModifierData *md,
struct DRWPass *hair_pass,
struct GPUMaterial *material);
void DRW_hair_init(void);
void DRW_hair_update(void);
void DRW_hair_free(void);

View File

@@ -124,13 +124,10 @@ void DRW_hair_init(void)
}
}
static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
ParticleSystem *psys,
ModifierData *md,
DRWPass *hair_pass,
DRWShadingGroup *shgrp_parent,
struct GPUMaterial *gpu_mat,
GPUShader *gpu_shader)
DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
ParticleSystem *psys,
ModifierData *md,
DRWShadingGroup *shgrp_parent)
{
/* TODO(fclem): Pass the scene as parameter */
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -154,24 +151,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
need_ft_update = hair_ensure_procedural_data(object, &hair_cache, subdiv, thickness_res);
}
DRWShadingGroup *shgrp;
if (shgrp_parent) {
shgrp = DRW_shgroup_create_sub(shgrp_parent);
}
else if (gpu_mat) {
shgrp = DRW_shgroup_material_create(gpu_mat, hair_pass);
}
else if (gpu_shader) {
shgrp = DRW_shgroup_create(gpu_shader, hair_pass);
}
else {
shgrp = NULL;
BLI_assert(0);
}
if (shgrp == NULL) {
return NULL;
}
DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent);
/* TODO optimize this. Only bind the ones GPUMaterial needs. */
for (int i = 0; i < hair_cache->num_uv_layers; i++) {
@@ -287,29 +267,6 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
return shgrp;
}
DRWShadingGroup *DRW_shgroup_hair_create(
Object *object, ParticleSystem *psys, ModifierData *md, DRWPass *hair_pass, GPUShader *shader)
{
return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, NULL, NULL, shader);
}
DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
ParticleSystem *psys,
ModifierData *md,
DRWShadingGroup *shgrp)
{
return drw_shgroup_create_hair_procedural_ex(object, psys, md, NULL, shgrp, NULL, NULL);
}
DRWShadingGroup *DRW_shgroup_material_hair_create(Object *object,
ParticleSystem *psys,
ModifierData *md,
DRWPass *hair_pass,
struct GPUMaterial *material)
{
return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, NULL, material, NULL);
}
void DRW_hair_update(void)
{
#ifndef USE_TRANSFORM_FEEDBACK

View File

@@ -278,8 +278,11 @@ typedef enum {
DRW_UNIFORM_TEXTURE,
DRW_UNIFORM_TEXTURE_PERSIST,
DRW_UNIFORM_TEXTURE_REF,
DRW_UNIFORM_TEXTURE_REF_PERSIST,
DRW_UNIFORM_BLOCK,
DRW_UNIFORM_BLOCK_PERSIST,
DRW_UNIFORM_BLOCK_REF,
DRW_UNIFORM_BLOCK_REF_PERSIST,
DRW_UNIFORM_TFEEDBACK_TARGET,
/** Per drawcall uniforms/UBO */
DRW_UNIFORM_BLOCK_OBMATS,
@@ -342,6 +345,13 @@ struct DRWPass {
DRWShadingGroup *last;
} shgroups;
/* Draw the shgroups of this pass instead.
* This avoid duplicating drawcalls/shgroups
* for similar passes. */
DRWPass *original;
/* Link list of additional passes to render. */
DRWPass *next;
DRWResourceHandle handle;
DRWState state;
char name[MAX_PASS_NAME];

View File

@@ -228,7 +228,11 @@ static void drw_shgroup_uniform(DRWShadingGroup *shgroup,
int arraysize)
{
int location;
if (ELEM(type, DRW_UNIFORM_BLOCK, DRW_UNIFORM_BLOCK_PERSIST)) {
if (ELEM(type,
DRW_UNIFORM_BLOCK,
DRW_UNIFORM_BLOCK_PERSIST,
DRW_UNIFORM_BLOCK_REF,
DRW_UNIFORM_BLOCK_REF_PERSIST)) {
location = GPU_shader_get_uniform_block(shgroup->shader, name);
}
else {
@@ -284,6 +288,22 @@ void DRW_shgroup_uniform_texture_persistent(DRWShadingGroup *shgroup,
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_PERSIST, tex, 0, 1);
}
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
{
BLI_assert(tex != NULL);
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_REF, tex, 0, 1);
}
/* Same as DRW_shgroup_uniform_texture_ref but is guaranteed to be bound if shader does not change
* between shgrp. */
void DRW_shgroup_uniform_texture_ref_persistent(DRWShadingGroup *shgroup,
const char *name,
GPUTexture **tex)
{
BLI_assert(tex != NULL);
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_REF_PERSIST, tex, 0, 1);
}
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
const char *name,
const GPUUniformBuffer *ubo)
@@ -302,9 +322,22 @@ void DRW_shgroup_uniform_block_persistent(DRWShadingGroup *shgroup,
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_PERSIST, ubo, 0, 1);
}
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup,
const char *name,
GPUUniformBuffer **ubo)
{
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_REF, tex, 0, 1);
BLI_assert(ubo != NULL);
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_REF, ubo, 0, 1);
}
/* Same as DRW_shgroup_uniform_block_ref but is guaranteed to be bound if shader does not change
* between shgrp. */
void DRW_shgroup_uniform_block_ref_persistent(DRWShadingGroup *shgroup,
const char *name,
GPUUniformBuffer **ubo)
{
BLI_assert(ubo != NULL);
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_REF_PERSIST, ubo, 0, 1);
}
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup,
@@ -1293,15 +1326,14 @@ static void drw_shgroup_material_texture(DRWShadingGroup *grp,
int textarget)
{
GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
DRW_shgroup_uniform_texture(grp, name, gputex);
DRW_shgroup_uniform_texture_persistent(grp, name, gputex);
GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
*gputex_ref = gputex;
GPU_texture_ref(gputex);
}
static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
struct GPUMaterial *material)
void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial *material)
{
ListBase textures = GPU_material_textures(material);
@@ -1319,7 +1351,7 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
}
else if (tex->colorband) {
/* Color Ramp */
DRW_shgroup_uniform_texture(grp, tex->sampler_name, *tex->colorband);
DRW_shgroup_uniform_texture_persistent(grp, tex->sampler_name, *tex->colorband);
}
}
@@ -1327,8 +1359,6 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
if (ubo != NULL) {
DRW_shgroup_uniform_block(grp, GPU_UBO_BLOCK_NAME, ubo);
}
return grp;
}
GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrFormat attrs[],
@@ -1353,7 +1383,7 @@ DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPa
if (shgroup) {
drw_shgroup_init(shgroup, GPU_pass_shader_get(gpupass));
drw_shgroup_material_inputs(shgroup, material);
DRW_shgroup_add_material_resources(shgroup, material);
}
return shgroup;
}
@@ -1904,9 +1934,28 @@ DRWPass *DRW_pass_create(const char *name, DRWState state)
pass->handle = DST.pass_handle;
DRW_handle_increment(&DST.pass_handle);
pass->original = NULL;
pass->next = NULL;
return pass;
}
DRWPass *DRW_pass_create_instance(const char *name, DRWPass *original, DRWState state)
{
DRWPass *pass = DRW_pass_create(name, state);
pass->original = original;
return pass;
}
/* Link two passes so that they are both rendered if the first one is being drawn. */
void DRW_pass_link(DRWPass *first, DRWPass *second)
{
BLI_assert(first != second);
BLI_assert(first->next == NULL);
first->next = second;
}
bool DRW_pass_is_empty(DRWPass *pass)
{
LISTBASE_FOREACH (DRWShadingGroup *, shgroup, &pass->shgroups) {

View File

@@ -971,6 +971,12 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
bind_texture(tex, BIND_TEMP);
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
break;
case DRW_UNIFORM_TEXTURE_REF_PERSIST:
tex = *((GPUTexture **)uni->pvalue);
BLI_assert(tex);
bind_texture(tex, BIND_PERSIST);
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
break;
case DRW_UNIFORM_BLOCK:
ubo = (GPUUniformBuffer *)uni->pvalue;
bind_ubo(ubo, BIND_TEMP);
@@ -981,6 +987,16 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
bind_ubo(ubo, BIND_PERSIST);
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
break;
case DRW_UNIFORM_BLOCK_REF:
ubo = *((GPUUniformBuffer **)uni->pvalue);
bind_ubo(ubo, BIND_TEMP);
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
break;
case DRW_UNIFORM_BLOCK_REF_PERSIST:
ubo = *((GPUUniformBuffer **)uni->pvalue);
bind_ubo(ubo, BIND_PERSIST);
GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
break;
case DRW_UNIFORM_BLOCK_OBMATS:
state->obmats_loc = uni->location;
ubo = DST.vmempool->matrices_ubo[0];
@@ -1426,6 +1442,11 @@ static void drw_draw_pass_ex(DRWPass *pass,
DRWShadingGroup *start_group,
DRWShadingGroup *end_group)
{
if (pass->original) {
start_group = pass->original->shgroups.first;
end_group = pass->original->shgroups.last;
}
if (start_group == NULL) {
return;
}
@@ -1511,7 +1532,9 @@ static void drw_draw_pass_ex(DRWPass *pass,
void DRW_draw_pass(DRWPass *pass)
{
drw_draw_pass_ex(pass, pass->shgroups.first, pass->shgroups.last);
for (; pass; pass = pass->next) {
drw_draw_pass_ex(pass, pass->shgroups.first, pass->shgroups.last);
}
}
/* Draw only a subset of shgroups. Used in special situations as grease pencil strokes */

View File

@@ -395,6 +395,7 @@ GPUMaterial *DRW_shader_find_from_material(Material *ma,
GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
World *wo,
struct bNodeTree *ntree,
const void *engine_type,
const int options,
const bool is_volume_shader,
@@ -405,7 +406,7 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
bool deferred)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render()) {
if (DRW_state_is_image_render() || !deferred) {
mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options);
}
@@ -413,7 +414,7 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id);
mat = GPU_material_from_nodetree(scene,
NULL,
wo->nodetree,
ntree,
&wo->gpumaterial,
engine_type,
options,
@@ -434,6 +435,7 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
Material *ma,
struct bNodeTree *ntree,
const void *engine_type,
const int options,
const bool is_volume_shader,
@@ -444,7 +446,7 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
bool deferred)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render()) {
if (DRW_state_is_image_render() || !deferred) {
mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options);
}
@@ -452,7 +454,7 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id);
mat = GPU_material_from_nodetree(scene,
ma,
ma->nodetree,
ntree,
&ma->gpumaterial,
engine_type,
options,

View File

@@ -190,6 +190,7 @@ void GPU_materials_free(struct Main *bmain);
struct Scene *GPU_material_scene(GPUMaterial *material);
struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
struct GPUShader *GPU_material_get_shader(GPUMaterial *material);
struct Material *GPU_material_get_material(GPUMaterial *material);
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat);

View File

@@ -209,6 +209,11 @@ GPUPass *GPU_material_get_pass(GPUMaterial *material)
return material->pass;
}
GPUShader *GPU_material_get_shader(GPUMaterial *material)
{
return material->pass ? GPU_pass_shader_get(material->pass) : NULL;
}
/* Return can be NULL if it's a world material. */
Material *GPU_material_get_material(GPUMaterial *material)
{
@@ -662,6 +667,9 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
/* Caller must re-use materials. */
BLI_assert(GPU_material_from_nodetree_find(gpumaterials, engine_type, options) == NULL);
/* HACK: Eevee assume this to create Ghash keys. */
BLI_assert(sizeof(GPUPass) > 16);
/* allocate material */
GPUMaterial *mat = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
mat->ma = ma;

View File

@@ -1576,6 +1576,7 @@ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat gpu_data_format, const vo
glClearTexImage(tex->bindcode, 0, data_format, data_type, color);
}
else {
/* TODO(fclem) speedup using the copy framebuffer. */
size_t buffer_len = gpu_texture_memory_footprint_compute(tex);
unsigned char *pixels = MEM_mallocN(buffer_len, __func__);
if (color) {

View File

@@ -1,8 +1,16 @@
void node_output_material(Closure surface, Closure volume, vec3 displacement, out Closure result)
void node_output_material(
Closure surface, Closure volume, vec3 displacement, float alpha_threshold, out Closure result)
{
#ifdef VOLUMETRICS
result = volume;
#else
result = surface;
# if defined(USE_ALPHA_HASH)
/* Alpha clip emulation. */
if (alpha_threshold >= 0.0) {
float alpha = saturate(1.0 - avg(result.transmittance));
result.transmittance = vec3(step(alpha, alpha_threshold));
}
# endif
#endif
}

View File

@@ -45,9 +45,18 @@ static int node_shader_gpu_output_material(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
GPUNodeLink *outlink;
GPUNodeLink *outlink, *alpha_threshold_link;
GPU_stack_link(mat, node, "node_output_material", in, out, &outlink);
Material *ma = GPU_material_get_material(mat);
if (ma && ma->blend_method == MA_BM_CLIP) {
alpha_threshold_link = GPU_uniform(&ma->alpha_threshold);
}
else {
static float no_alpha_threshold = -1.0f;
alpha_threshold_link = GPU_uniform(&no_alpha_threshold);
}
GPU_stack_link(mat, node, "node_output_material", in, out, alpha_threshold_link, &outlink);
GPU_material_output_link(mat, outlink);
return true;