2017-06-04 12:12:58 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright 2016, Blender Foundation.
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): Blender Institute
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/** \file eevee_materials.c
|
|
|
|
|
* \ingroup draw_engine
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "DRW_render.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_dynstr.h"
|
2017-06-05 22:05:21 +02:00
|
|
|
#include "BLI_ghash.h"
|
2017-06-28 13:33:55 +10:00
|
|
|
#include "BLI_alloca.h"
|
2018-01-16 19:40:17 +01:00
|
|
|
#include "BLI_rand.h"
|
2018-01-17 21:40:43 +11:00
|
|
|
#include "BLI_string_utils.h"
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-14 12:39:57 +02:00
|
|
|
#include "BKE_particle.h"
|
2017-07-13 19:09:40 +10:00
|
|
|
#include "BKE_paint.h"
|
|
|
|
|
#include "BKE_pbvh.h"
|
2018-05-25 08:06:36 +02:00
|
|
|
#include "BKE_studiolight.h"
|
2017-06-14 12:39:57 +02:00
|
|
|
|
2017-11-20 14:11:45 +11:00
|
|
|
#include "DNA_world_types.h"
|
|
|
|
|
#include "DNA_modifier_types.h"
|
|
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
#include "GPU_material.h"
|
|
|
|
|
|
|
|
|
|
#include "eevee_engine.h"
|
|
|
|
|
#include "eevee_lut.h"
|
|
|
|
|
#include "eevee_private.h"
|
|
|
|
|
|
|
|
|
|
/* *********** STATIC *********** */
|
|
|
|
|
static struct {
|
|
|
|
|
char *frag_shader_lib;
|
2018-05-29 12:25:43 +02:00
|
|
|
char *vert_shader_str;
|
2017-07-03 22:08:07 +02:00
|
|
|
char *volume_shader_lib;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-16 23:50:40 +02:00
|
|
|
struct GPUShader *default_prepass_sh;
|
|
|
|
|
struct GPUShader *default_prepass_clip_sh;
|
2018-05-29 12:25:43 +02:00
|
|
|
struct GPUShader *default_hair_prepass_sh;
|
|
|
|
|
struct GPUShader *default_hair_prepass_clip_sh;
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUShader *default_lit[VAR_MAT_MAX];
|
2017-06-04 12:12:58 +02:00
|
|
|
struct GPUShader *default_background;
|
2018-05-25 08:06:36 +02:00
|
|
|
struct GPUShader *default_studiolight_background;
|
2018-01-17 14:02:48 +01:00
|
|
|
struct GPUShader *update_noise_sh;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
/* 64*64 array texture containing all LUTs and other utilitarian arrays.
|
|
|
|
|
* Packing enables us to same precious textures slots. */
|
|
|
|
|
struct GPUTexture *util_tex;
|
2018-01-17 14:02:48 +01:00
|
|
|
struct GPUTexture *noise_tex;
|
2017-06-22 02:41:17 +02:00
|
|
|
|
2018-05-11 07:48:52 +02:00
|
|
|
uint sss_count;
|
2017-11-14 00:49:54 +01:00
|
|
|
|
2018-01-16 19:40:17 +01:00
|
|
|
float alpha_hash_offset;
|
2018-01-17 14:02:48 +01:00
|
|
|
float noise_offsets[3];
|
2017-06-04 12:12:58 +02:00
|
|
|
} e_data = {NULL}; /* Engine data */
|
|
|
|
|
|
2017-06-28 16:31:25 +02:00
|
|
|
extern char datatoc_lamps_lib_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_lib_glsl[];
|
2017-06-22 03:10:39 +02:00
|
|
|
extern char datatoc_ambient_occlusion_lib_glsl[];
|
2017-06-16 23:50:40 +02:00
|
|
|
extern char datatoc_prepass_frag_glsl[];
|
|
|
|
|
extern char datatoc_prepass_vert_glsl[];
|
2017-06-04 12:12:58 +02:00
|
|
|
extern char datatoc_default_frag_glsl[];
|
|
|
|
|
extern char datatoc_default_world_frag_glsl[];
|
|
|
|
|
extern char datatoc_ltc_lib_glsl[];
|
|
|
|
|
extern char datatoc_bsdf_lut_frag_glsl[];
|
2017-08-04 18:43:02 +02:00
|
|
|
extern char datatoc_btdf_lut_frag_glsl[];
|
2017-06-04 12:12:58 +02:00
|
|
|
extern char datatoc_bsdf_common_lib_glsl[];
|
|
|
|
|
extern char datatoc_bsdf_direct_lib_glsl[];
|
|
|
|
|
extern char datatoc_bsdf_sampling_lib_glsl[];
|
2018-01-21 17:25:10 +01:00
|
|
|
extern char datatoc_common_uniforms_lib_glsl[];
|
2018-05-29 12:25:43 +02:00
|
|
|
extern char datatoc_common_hair_lib_glsl[];
|
2018-03-10 00:00:04 +01:00
|
|
|
extern char datatoc_common_view_lib_glsl[];
|
2017-06-14 11:09:13 +02:00
|
|
|
extern char datatoc_irradiance_lib_glsl[];
|
2017-06-15 00:09:49 +02:00
|
|
|
extern char datatoc_octahedron_lib_glsl[];
|
2017-06-04 12:12:58 +02:00
|
|
|
extern char datatoc_lit_surface_frag_glsl[];
|
|
|
|
|
extern char datatoc_lit_surface_vert_glsl[];
|
2017-08-09 16:54:18 +02:00
|
|
|
extern char datatoc_raytrace_lib_glsl[];
|
|
|
|
|
extern char datatoc_ssr_lib_glsl[];
|
2017-06-04 12:12:58 +02:00
|
|
|
extern char datatoc_shadow_vert_glsl[];
|
2017-06-12 20:59:54 +10:00
|
|
|
extern char datatoc_lightprobe_geom_glsl[];
|
|
|
|
|
extern char datatoc_lightprobe_vert_glsl[];
|
2017-06-04 12:12:58 +02:00
|
|
|
extern char datatoc_background_vert_glsl[];
|
2018-01-17 14:02:48 +01:00
|
|
|
extern char datatoc_update_noise_frag_glsl[];
|
2017-10-24 14:49:00 +02:00
|
|
|
extern char datatoc_volumetric_vert_glsl[];
|
|
|
|
|
extern char datatoc_volumetric_geom_glsl[];
|
2017-07-03 16:38:14 +02:00
|
|
|
extern char datatoc_volumetric_frag_glsl[];
|
2017-10-24 14:49:00 +02:00
|
|
|
extern char datatoc_volumetric_lib_glsl[];
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
extern Material defmaterial;
|
|
|
|
|
extern GlobalsUboStorage ts;
|
|
|
|
|
|
|
|
|
|
/* *********** FUNCTIONS *********** */
|
|
|
|
|
|
|
|
|
|
#if 0 /* Used only to generate the LUT values */
|
|
|
|
|
static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
|
|
|
|
|
{
|
|
|
|
|
struct GPUTexture *tex;
|
|
|
|
|
struct GPUFrameBuffer *fb = NULL;
|
|
|
|
|
static float samples_ct = 8192.0f;
|
|
|
|
|
static float inv_samples_ct = 1.0f / 8192.0f;
|
|
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
char *lib_str = BLI_string_joinN(
|
|
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_bsdf_sampling_lib_glsl);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
struct GPUShader *sh = DRW_shader_create_with_lib(
|
2018-01-17 20:35:06 +11:00
|
|
|
datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, datatoc_bsdf_lut_frag_glsl, lib_str,
|
2017-06-04 12:12:58 +02:00
|
|
|
"#define HAMMERSLEY_SIZE 8192\n"
|
|
|
|
|
"#define BRDF_LUT_SIZE 64\n"
|
2018-01-17 20:35:06 +11:00
|
|
|
"#define NOISE_SIZE 64\n");
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-12 20:59:54 +10:00
|
|
|
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
|
2017-06-04 12:12:58 +02:00
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "sampleCount", &samples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "invSampleCount", &inv_samples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
|
|
|
|
|
DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
|
|
|
|
|
|
2017-06-19 20:18:04 +10:00
|
|
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
2017-06-04 12:12:58 +02:00
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
|
|
|
|
|
float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
|
|
|
|
|
|
2018-04-30 16:02:24 +02:00
|
|
|
tex = DRW_texture_create_2D(w, h, GPU_RG16F, DRW_TEX_FILTER, (float *)texels);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-04-30 16:02:24 +02:00
|
|
|
DRWFboTexture tex_filter = {&tex, GPU_RG16F, DRW_TEX_FILTER};
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 1);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_bind(fb);
|
2017-06-04 12:12:58 +02:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-04 18:43:02 +02:00
|
|
|
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_ct = 8192.0f;
|
|
|
|
|
static float a2 = 0.0f;
|
|
|
|
|
static float inv_samples_ct = 1.0f / 8192.0f;
|
|
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
char *frag_str = BLI_string_joinN(
|
|
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_bsdf_sampling_lib_glsl,
|
|
|
|
|
datatoc_btdf_lut_frag_glsl);
|
2017-08-04 18:43:02 +02:00
|
|
|
|
|
|
|
|
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_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "invSampleCount", &inv_samples_ct, 1);
|
|
|
|
|
DRW_shgroup_uniform_texture(grp, "texHammersley", hammersley);
|
|
|
|
|
DRW_shgroup_uniform_texture(grp, "utilTex", e_data.util_tex);
|
|
|
|
|
|
|
|
|
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
|
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
|
|
|
|
|
float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
|
|
|
|
|
|
2018-04-30 16:02:24 +02:00
|
|
|
tex = DRW_texture_create_2D(w, h, GPU_R16F, DRW_TEX_FILTER, (float *)texels);
|
2017-08-04 18:43:02 +02:00
|
|
|
|
2018-04-30 16:02:24 +02:00
|
|
|
DRWFboTexture tex_filter = {&tex, GPU_R16F, DRW_TEX_FILTER};
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 1);
|
2017-08-04 18:43:02 +02:00
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_bind(fb);
|
2017-08-04 18:43:02 +02:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_read_data(0, 0, w, h, 3, 0, data);
|
2017-08-04 18:43:02 +02:00
|
|
|
|
2017-10-07 15:57:14 +11:00
|
|
|
#if 1
|
2017-08-04 18:43:02 +02:00
|
|
|
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");
|
2017-10-07 15:57:14 +11:00
|
|
|
#else
|
2017-08-04 18:43:02 +02:00
|
|
|
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");
|
|
|
|
|
}
|
2017-10-07 15:57:14 +11:00
|
|
|
#endif
|
2017-08-04 18:43:02 +02:00
|
|
|
|
|
|
|
|
} while (roughness < 1.0f);
|
|
|
|
|
fprintf(f, "\n};\n");
|
|
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(texels);
|
|
|
|
|
MEM_freeN(data);
|
|
|
|
|
|
|
|
|
|
return tex;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2017-07-03 16:38:14 +02:00
|
|
|
/* XXX TODO define all shared resources in a shared place without duplication */
|
|
|
|
|
struct GPUTexture *EEVEE_materials_get_util_tex(void)
|
|
|
|
|
{
|
|
|
|
|
return e_data.util_tex;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-01 18:39:39 +02:00
|
|
|
static int eevee_material_shadow_option(int shadow_method)
|
|
|
|
|
{
|
|
|
|
|
switch (shadow_method) {
|
|
|
|
|
case SHADOW_ESM: return VAR_MAT_ESM;
|
|
|
|
|
case SHADOW_VSM: return VAR_MAT_VSM;
|
|
|
|
|
default:
|
|
|
|
|
BLI_assert(!"Incorrect Shadow Method");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
static char *eevee_get_defines(int options)
|
|
|
|
|
{
|
|
|
|
|
char *str = NULL;
|
|
|
|
|
|
|
|
|
|
DynStr *ds = BLI_dynstr_new();
|
|
|
|
|
BLI_dynstr_appendf(ds, SHADER_DEFINES);
|
|
|
|
|
|
|
|
|
|
if ((options & VAR_MAT_MESH) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define MESH_SHADER\n");
|
|
|
|
|
}
|
|
|
|
|
if ((options & VAR_MAT_HAIR) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n");
|
|
|
|
|
}
|
|
|
|
|
if ((options & VAR_MAT_PROBE) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define PROBE_CAPTURE\n");
|
|
|
|
|
}
|
|
|
|
|
if ((options & VAR_MAT_FLAT) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_FLAT_NORMAL\n");
|
|
|
|
|
}
|
2017-07-09 12:01:29 +02:00
|
|
|
if ((options & VAR_MAT_CLIP) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_ALPHA_CLIP\n");
|
|
|
|
|
}
|
2017-07-11 01:10:57 +02:00
|
|
|
if ((options & VAR_MAT_SHADOW) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define SHADOW_SHADER\n");
|
|
|
|
|
}
|
2017-07-09 12:01:29 +02:00
|
|
|
if ((options & VAR_MAT_HASH) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_ALPHA_HASH\n");
|
|
|
|
|
}
|
2017-07-10 11:41:33 +02:00
|
|
|
if ((options & VAR_MAT_BLEND) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_ALPHA_BLEND\n");
|
|
|
|
|
}
|
|
|
|
|
if ((options & VAR_MAT_MULT) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_MULTIPLY\n");
|
|
|
|
|
}
|
2017-08-09 16:54:18 +02:00
|
|
|
if ((options & VAR_MAT_REFRACT) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_REFRACTION\n");
|
|
|
|
|
}
|
2017-11-14 00:49:54 +01:00
|
|
|
if ((options & VAR_MAT_SSS) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_SSS\n");
|
|
|
|
|
}
|
2017-11-24 22:29:18 +01:00
|
|
|
if ((options & VAR_MAT_SSSALBED) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_SSS_ALBEDO\n");
|
|
|
|
|
}
|
2017-11-22 04:51:21 +01:00
|
|
|
if ((options & VAR_MAT_TRANSLUC) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_TRANSLUCENCY\n");
|
|
|
|
|
}
|
2017-09-01 18:39:39 +02:00
|
|
|
if ((options & VAR_MAT_VSM) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define SHADOW_VSM\n");
|
|
|
|
|
}
|
|
|
|
|
if ((options & VAR_MAT_ESM) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define SHADOW_ESM\n");
|
|
|
|
|
}
|
2017-10-24 17:52:20 +02:00
|
|
|
if (((options & VAR_MAT_VOLUME) != 0) && ((options & VAR_MAT_BLEND) != 0)) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_ALPHA_BLEND_VOLUMETRICS\n");
|
|
|
|
|
}
|
2018-05-25 08:06:36 +02:00
|
|
|
if ((options & VAR_MAT_LOOKDEV) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define LOOKDEV\n");
|
|
|
|
|
}
|
2017-06-22 02:41:17 +02:00
|
|
|
|
|
|
|
|
str = BLI_dynstr_get_cstring(ds);
|
|
|
|
|
BLI_dynstr_free(ds);
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-27 16:20:33 +02:00
|
|
|
static char *eevee_get_volume_defines(int options)
|
2017-07-05 18:28:48 +02:00
|
|
|
{
|
|
|
|
|
char *str = NULL;
|
|
|
|
|
|
|
|
|
|
DynStr *ds = BLI_dynstr_new();
|
|
|
|
|
BLI_dynstr_appendf(ds, SHADER_DEFINES);
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define VOLUMETRICS\n");
|
|
|
|
|
|
2017-10-27 16:20:33 +02:00
|
|
|
if ((options & VAR_MAT_VOLUME) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define MESH_SHADER\n");
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-05 18:28:48 +02:00
|
|
|
str = BLI_dynstr_get_cstring(ds);
|
|
|
|
|
BLI_dynstr_free(ds);
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-16 23:49:25 +02:00
|
|
|
/**
|
|
|
|
|
* ssr_id can be null to disable ssr contribution.
|
|
|
|
|
**/
|
2017-08-09 16:54:18 +02:00
|
|
|
static void add_standard_uniforms(
|
2017-11-22 10:52:39 -02:00
|
|
|
DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
2018-01-21 17:25:10 +01:00
|
|
|
int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend)
|
2017-06-22 02:41:17 +02:00
|
|
|
{
|
2018-01-03 20:41:14 +01:00
|
|
|
if (ssr_id == NULL) {
|
2017-07-16 23:49:25 +02:00
|
|
|
static int no_ssr = -1.0f;
|
|
|
|
|
ssr_id = &no_ssr;
|
|
|
|
|
}
|
2018-01-21 17:25:10 +01:00
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
|
|
|
|
|
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
|
|
|
|
|
DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
|
|
|
|
|
DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
|
|
|
|
|
DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
|
2018-01-21 17:25:10 +01:00
|
|
|
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
|
2018-03-10 00:02:01 +01:00
|
|
|
DRW_shgroup_uniform_block(shgrp, "clip_block", sldata->clip_ubo);
|
2018-01-21 17:25:10 +01:00
|
|
|
|
|
|
|
|
/* TODO if glossy or diffuse bsdf */
|
|
|
|
|
if (true) {
|
|
|
|
|
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
|
2018-05-04 14:39:05 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "shadowCubeTexture", &sldata->shadow_cube_pool);
|
|
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
|
2018-01-21 17:25:10 +01:00
|
|
|
|
|
|
|
|
if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) != 0) {
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &vedata->stl->effects->gtao_horizons);
|
2018-01-21 17:25:10 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Use maxzbuffer as fallback to avoid sampling problem on certain platform, see: T52593 */
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &vedata->txl->maxzbuffer);
|
2018-01-21 17:25:10 +01:00
|
|
|
}
|
2017-08-10 15:43:15 +02:00
|
|
|
}
|
2017-10-24 17:52:20 +02:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
/* TODO if diffuse bsdf */
|
|
|
|
|
if (true) {
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &sldata->irradiance_pool);
|
2017-08-09 16:54:18 +02:00
|
|
|
}
|
2017-10-24 17:52:20 +02:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
/* TODO if glossy bsdf */
|
|
|
|
|
if (true) {
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &sldata->probe_pool);
|
|
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool);
|
2018-01-21 17:25:10 +01:00
|
|
|
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
|
2017-06-22 03:10:39 +02:00
|
|
|
}
|
2018-01-21 17:25:10 +01:00
|
|
|
|
|
|
|
|
if (use_ssrefraction) {
|
|
|
|
|
BLI_assert(refract_depth != NULL);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1);
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "colorBuffer", &vedata->txl->refract_color);
|
2017-09-11 23:17:33 +02:00
|
|
|
}
|
2017-10-24 17:52:20 +02:00
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
if ((vedata->stl->effects->enabled_effects & EFFECT_VOLUMETRIC) != 0 &&
|
|
|
|
|
use_alpha_blend)
|
|
|
|
|
{
|
2017-10-24 17:52:20 +02:00
|
|
|
/* Do not use history buffers as they already have been swapped */
|
2018-03-25 19:24:19 +02:00
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "inScattering", &vedata->txl->volume_scatter);
|
|
|
|
|
DRW_shgroup_uniform_texture_ref(shgrp, "inTransmittance", &vedata->txl->volume_transmittance);
|
2017-11-25 17:39:21 +01:00
|
|
|
}
|
2017-06-22 02:41:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void create_default_shader(int options)
|
|
|
|
|
{
|
2018-01-17 21:40:43 +11:00
|
|
|
char *frag_str = BLI_string_joinN(
|
|
|
|
|
e_data.frag_shader_lib,
|
|
|
|
|
datatoc_default_frag_glsl);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
char *defines = eevee_get_defines(options);
|
|
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
e_data.default_lit[options] = DRW_shader_create(e_data.vert_shader_str, NULL, frag_str, defines);
|
2017-06-22 02:41:17 +02:00
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
2018-01-17 20:35:06 +11:00
|
|
|
MEM_freeN(frag_str);
|
2017-06-22 02:41:17 +02:00
|
|
|
}
|
2017-06-22 03:10:39 +02:00
|
|
|
|
2018-01-17 14:02:48 +01:00
|
|
|
static void eevee_init_noise_texture(void)
|
2017-08-21 01:38:14 +02:00
|
|
|
{
|
2018-04-30 16:02:24 +02:00
|
|
|
e_data.noise_tex = DRW_texture_create_2D(64, 64, GPU_RGBA16F, 0, (float *)blue_noise);
|
2018-01-17 14:02:48 +01:00
|
|
|
}
|
2017-08-21 01:38:14 +02:00
|
|
|
|
2018-01-17 14:02:48 +01:00
|
|
|
static void eevee_init_util_texture(void)
|
|
|
|
|
{
|
2017-08-21 01:38:14 +02:00
|
|
|
const int layers = 3 + 16;
|
|
|
|
|
float (*texels)[4] = MEM_mallocN(sizeof(float[4]) * 64 * 64 * layers, "utils texels");
|
|
|
|
|
float (*texels_layer)[4] = texels;
|
|
|
|
|
|
|
|
|
|
/* Copy ltc_mat_ggx into 1st layer */
|
|
|
|
|
memcpy(texels_layer, ltc_mat_ggx, sizeof(float[4]) * 64 * 64);
|
|
|
|
|
texels_layer += 64 * 64;
|
|
|
|
|
|
|
|
|
|
/* Copy bsdf_split_sum_ggx into 2nd layer red and green channels.
|
|
|
|
|
Copy ltc_mag_ggx into 2nd layer blue channel. */
|
|
|
|
|
for (int i = 0; i < 64 * 64; i++) {
|
2017-10-07 15:57:14 +11:00
|
|
|
texels_layer[i][0] = bsdf_split_sum_ggx[i * 2 + 0];
|
|
|
|
|
texels_layer[i][1] = bsdf_split_sum_ggx[i * 2 + 1];
|
2017-08-21 01:38:14 +02:00
|
|
|
texels_layer[i][2] = ltc_mag_ggx[i];
|
2018-01-18 16:19:04 +01:00
|
|
|
texels_layer[i][3] = ltc_disk_integral[i];
|
2017-08-21 01:38:14 +02:00
|
|
|
}
|
|
|
|
|
texels_layer += 64 * 64;
|
|
|
|
|
|
|
|
|
|
/* Copy blue noise in 3rd layer */
|
|
|
|
|
for (int i = 0; i < 64 * 64; i++) {
|
2018-01-17 14:02:48 +01:00
|
|
|
texels_layer[i][0] = blue_noise[i][0];
|
2018-04-19 18:05:25 +02:00
|
|
|
texels_layer[i][1] = blue_noise[i][2];
|
2018-01-17 14:02:48 +01:00
|
|
|
texels_layer[i][2] = cosf(blue_noise[i][1] * 2.0f * M_PI);
|
|
|
|
|
texels_layer[i][3] = sinf(blue_noise[i][1] * 2.0f * M_PI);
|
2017-08-21 01:38:14 +02:00
|
|
|
}
|
|
|
|
|
texels_layer += 64 * 64;
|
|
|
|
|
|
|
|
|
|
/* Copy Refraction GGX LUT in layer 4 - 20 */
|
|
|
|
|
for (int j = 0; j < 16; ++j) {
|
|
|
|
|
for (int i = 0; i < 64 * 64; i++) {
|
2017-10-07 15:57:14 +11:00
|
|
|
texels_layer[i][0] = btdf_split_sum_ggx[j * 2][i];
|
|
|
|
|
texels_layer[i][1] = btdf_split_sum_ggx[j * 2][i];
|
|
|
|
|
texels_layer[i][2] = btdf_split_sum_ggx[j * 2][i];
|
|
|
|
|
texels_layer[i][3] = btdf_split_sum_ggx[j * 2][i];
|
2017-08-21 01:38:14 +02:00
|
|
|
}
|
|
|
|
|
texels_layer += 64 * 64;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-17 14:02:48 +01:00
|
|
|
e_data.util_tex = DRW_texture_create_2D_array(
|
2018-04-30 16:02:24 +02:00
|
|
|
64, 64, layers, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels);
|
2017-08-22 10:22:11 +02:00
|
|
|
|
2017-08-21 01:38:14 +02:00
|
|
|
MEM_freeN(texels);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-03 23:45:53 +01:00
|
|
|
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3])
|
2018-01-17 14:02:48 +01:00
|
|
|
{
|
|
|
|
|
e_data.noise_offsets[0] = offsets[0];
|
|
|
|
|
e_data.noise_offsets[1] = offsets[1];
|
|
|
|
|
e_data.noise_offsets[2] = offsets[2];
|
|
|
|
|
|
|
|
|
|
/* Attach & detach because we don't currently support multiple FB per texture,
|
|
|
|
|
* and this would be the case for multiple viewport. */
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_bind(fbl->update_noise_fb);
|
2018-01-17 14:02:48 +01:00
|
|
|
DRW_draw_pass(psl->update_noise_pass);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-01 18:07:09 +01:00
|
|
|
static void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4])
|
|
|
|
|
{
|
|
|
|
|
/* view vectors for the corners of the view frustum.
|
|
|
|
|
* Can be used to recreate the world space position easily */
|
|
|
|
|
float view_vecs[4][4] = {
|
|
|
|
|
{-1.0f, -1.0f, -1.0f, 1.0f},
|
|
|
|
|
{ 1.0f, -1.0f, -1.0f, 1.0f},
|
|
|
|
|
{-1.0f, 1.0f, -1.0f, 1.0f},
|
|
|
|
|
{-1.0f, -1.0f, 1.0f, 1.0f}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* convert the view vectors to view space */
|
|
|
|
|
const bool is_persp = (winmat[3][3] == 0.0f);
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
mul_project_m4_v3(invproj, view_vecs[i]);
|
|
|
|
|
/* normalized trick see:
|
|
|
|
|
* http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
|
|
|
|
|
if (is_persp) {
|
|
|
|
|
/* Divide XY by Z. */
|
|
|
|
|
mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
|
|
|
|
|
* view_vecs[1] is the vector going from the near-bottom-left corner to
|
|
|
|
|
* the far-top-right corner.
|
|
|
|
|
* If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
|
|
|
|
|
* when Z = 1, and top-left corner if Z = 1.
|
|
|
|
|
* view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
|
|
|
|
|
* distance from the near plane to the far clip plane.
|
|
|
|
|
**/
|
|
|
|
|
copy_v4_v4(r_viewvecs[0], view_vecs[0]);
|
|
|
|
|
|
|
|
|
|
/* we need to store the differences */
|
|
|
|
|
r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
|
|
|
|
|
r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
|
|
|
|
|
r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-21 17:25:10 +01:00
|
|
|
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
|
|
|
|
if (!e_data.frag_shader_lib) {
|
2018-01-17 20:35:06 +11:00
|
|
|
/* Shaders */
|
2018-04-15 22:22:50 +02:00
|
|
|
e_data.frag_shader_lib = BLI_string_joinN(
|
|
|
|
|
datatoc_common_view_lib_glsl,
|
2018-01-21 17:25:10 +01:00
|
|
|
datatoc_common_uniforms_lib_glsl,
|
2018-01-17 21:40:43 +11:00
|
|
|
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_irradiance_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_lib_glsl,
|
|
|
|
|
datatoc_ltc_lib_glsl,
|
|
|
|
|
datatoc_bsdf_direct_lib_glsl,
|
|
|
|
|
datatoc_lamps_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_volumetric_lib_glsl);
|
|
|
|
|
|
|
|
|
|
e_data.volume_shader_lib = BLI_string_joinN(
|
2018-03-10 00:00:04 +01:00
|
|
|
datatoc_common_view_lib_glsl,
|
2018-01-21 17:25:10 +01:00
|
|
|
datatoc_common_uniforms_lib_glsl,
|
2018-01-17 21:40:43 +11:00
|
|
|
datatoc_bsdf_common_lib_glsl,
|
|
|
|
|
datatoc_ambient_occlusion_lib_glsl,
|
|
|
|
|
datatoc_octahedron_lib_glsl,
|
|
|
|
|
datatoc_irradiance_lib_glsl,
|
|
|
|
|
datatoc_lightprobe_lib_glsl,
|
|
|
|
|
datatoc_ltc_lib_glsl,
|
|
|
|
|
datatoc_bsdf_direct_lib_glsl,
|
|
|
|
|
datatoc_lamps_lib_glsl,
|
|
|
|
|
datatoc_volumetric_lib_glsl,
|
|
|
|
|
datatoc_volumetric_frag_glsl);
|
|
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
e_data.vert_shader_str = BLI_string_joinN(
|
|
|
|
|
datatoc_common_view_lib_glsl,
|
|
|
|
|
datatoc_common_hair_lib_glsl,
|
|
|
|
|
datatoc_lit_surface_vert_glsl);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-07-31 15:15:42 +02:00
|
|
|
e_data.default_background = DRW_shader_create(
|
|
|
|
|
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl,
|
|
|
|
|
NULL);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-05-25 08:06:36 +02:00
|
|
|
e_data.default_studiolight_background = DRW_shader_create(
|
|
|
|
|
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl,
|
|
|
|
|
"#define LOOKDEV\n");
|
|
|
|
|
|
2017-06-16 23:50:40 +02:00
|
|
|
e_data.default_prepass_sh = DRW_shader_create(
|
|
|
|
|
datatoc_prepass_vert_glsl, NULL, datatoc_prepass_frag_glsl,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
e_data.default_prepass_clip_sh = DRW_shader_create(
|
|
|
|
|
datatoc_prepass_vert_glsl, NULL, datatoc_prepass_frag_glsl,
|
|
|
|
|
"#define CLIP_PLANES\n");
|
|
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
char *vert_str = BLI_string_joinN(
|
|
|
|
|
datatoc_common_view_lib_glsl,
|
|
|
|
|
datatoc_common_hair_lib_glsl,
|
|
|
|
|
datatoc_prepass_vert_glsl);
|
|
|
|
|
|
|
|
|
|
e_data.default_hair_prepass_sh = DRW_shader_create(
|
|
|
|
|
vert_str, NULL, datatoc_prepass_frag_glsl,
|
|
|
|
|
"#define HAIR_SHADER\n");
|
|
|
|
|
|
|
|
|
|
e_data.default_hair_prepass_clip_sh = DRW_shader_create(
|
|
|
|
|
vert_str, NULL, datatoc_prepass_frag_glsl,
|
|
|
|
|
"#define HAIR_SHADER\n"
|
|
|
|
|
"#define CLIP_PLANES\n");
|
|
|
|
|
|
|
|
|
|
MEM_freeN(vert_str);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
2018-01-17 14:02:48 +01:00
|
|
|
e_data.update_noise_sh = DRW_shader_create_fullscreen(
|
|
|
|
|
datatoc_update_noise_frag_glsl, NULL);
|
|
|
|
|
|
|
|
|
|
eevee_init_util_texture();
|
|
|
|
|
eevee_init_noise_texture();
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
2017-06-22 03:10:39 +02:00
|
|
|
|
2018-01-16 19:40:17 +01:00
|
|
|
if (!DRW_state_is_image_render() &&
|
2018-02-15 18:03:55 +11:00
|
|
|
((stl->effects->enabled_effects & EFFECT_TAA) == 0))
|
2018-01-16 19:40:17 +01:00
|
|
|
{
|
|
|
|
|
e_data.alpha_hash_offset = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
double r;
|
2018-02-03 02:14:36 +01:00
|
|
|
BLI_halton_1D(5, 0.0, stl->effects->taa_current_sample - 1, &r);
|
2018-01-16 19:40:17 +01:00
|
|
|
e_data.alpha_hash_offset = (float)r;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 03:10:39 +02:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
/* Update view_vecs */
|
2017-06-22 03:10:39 +02:00
|
|
|
float invproj[4][4], winmat[4][4];
|
|
|
|
|
DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
|
2018-02-01 18:07:09 +01:00
|
|
|
DRW_viewport_matrix_get(invproj, DRW_MAT_WININV);
|
2017-06-22 03:10:39 +02:00
|
|
|
|
2018-02-01 18:07:09 +01:00
|
|
|
EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
|
2017-06-22 03:10:39 +02:00
|
|
|
}
|
2018-01-17 14:02:48 +01:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
/* Update noise Framebuffer. */
|
2018-03-25 17:46:48 +02:00
|
|
|
GPU_framebuffer_ensure_config(&fbl->update_noise_fb, {
|
|
|
|
|
GPU_ATTACHMENT_NONE,
|
|
|
|
|
GPU_ATTACHMENT_TEXTURE_LAYER(e_data.util_tex, 2)
|
|
|
|
|
});
|
2018-01-17 14:02:48 +01:00
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-12 20:59:54 +10:00
|
|
|
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, World *wo)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2017-06-28 10:50:33 +10:00
|
|
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
|
|
|
|
const int options = VAR_WORLD_PROBE;
|
|
|
|
|
|
2018-03-13 03:58:00 +01:00
|
|
|
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
|
2017-06-28 10:50:33 +10:00
|
|
|
if (mat != NULL) {
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
2018-03-05 00:54:31 +01:00
|
|
|
return DRW_shader_create_from_world(
|
|
|
|
|
scene, wo, engine, options,
|
2017-06-29 17:07:41 +02:00
|
|
|
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
|
2017-06-28 10:50:33 +10:00
|
|
|
SHADER_DEFINES "#define PROBE_CAPTURE\n");
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo)
|
|
|
|
|
{
|
2017-06-28 10:50:33 +10:00
|
|
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
|
|
|
|
int options = VAR_WORLD_BACKGROUND;
|
|
|
|
|
|
2018-03-13 03:58:00 +01:00
|
|
|
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
|
2017-06-28 10:50:33 +10:00
|
|
|
if (mat != NULL) {
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
2018-03-05 00:54:31 +01:00
|
|
|
return DRW_shader_create_from_world(
|
|
|
|
|
scene, wo, engine, options,
|
2017-06-28 10:50:33 +10:00
|
|
|
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
|
|
|
|
|
SHADER_DEFINES "#define WORLD_BACKGROUND\n");
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-24 14:49:00 +02:00
|
|
|
struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, World *wo)
|
2017-07-03 16:38:14 +02:00
|
|
|
{
|
2017-07-03 22:08:07 +02:00
|
|
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
|
|
|
|
int options = VAR_WORLD_VOLUME;
|
|
|
|
|
|
2018-03-13 03:58:00 +01:00
|
|
|
GPUMaterial *mat = DRW_shader_find_from_world(wo, engine, options);
|
2017-07-03 22:08:07 +02:00
|
|
|
if (mat != NULL) {
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
2017-07-05 18:28:48 +02:00
|
|
|
|
|
|
|
|
char *defines = eevee_get_volume_defines(options);
|
|
|
|
|
|
2018-03-05 00:54:31 +01:00
|
|
|
mat = DRW_shader_create_from_world(
|
|
|
|
|
scene, wo, engine, options,
|
2017-10-24 14:49:00 +02:00
|
|
|
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
|
2017-07-05 18:28:48 +02:00
|
|
|
defines);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
|
|
|
|
|
|
|
|
|
return mat;
|
2017-07-03 16:38:14 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *EEVEE_material_mesh_get(
|
2017-10-24 17:52:20 +02:00
|
|
|
struct Scene *scene, Material *ma, EEVEE_Data *vedata,
|
2017-11-22 04:51:21 +01:00
|
|
|
bool use_blend, bool use_multiply, bool use_refract, bool use_sss, bool use_translucency, int shadow_method)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_EffectsInfo *effects = vedata->stl->effects;
|
2017-06-28 10:50:33 +10:00
|
|
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
2017-06-22 02:41:17 +02:00
|
|
|
int options = VAR_MAT_MESH;
|
|
|
|
|
|
2017-07-10 11:41:33 +02:00
|
|
|
if (use_blend) options |= VAR_MAT_BLEND;
|
|
|
|
|
if (use_multiply) options |= VAR_MAT_MULT;
|
2017-08-09 16:54:18 +02:00
|
|
|
if (use_refract) options |= VAR_MAT_REFRACT;
|
2017-11-14 00:49:54 +01:00
|
|
|
if (use_sss) options |= VAR_MAT_SSS;
|
2018-01-21 17:25:10 +01:00
|
|
|
if (use_sss && effects->sss_separate_albedo) options |= VAR_MAT_SSSALBED;
|
2017-11-22 04:51:21 +01:00
|
|
|
if (use_translucency) options |= VAR_MAT_TRANSLUC;
|
2018-01-21 17:25:10 +01:00
|
|
|
if (((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_blend) options |= VAR_MAT_VOLUME;
|
2017-06-22 02:41:17 +02:00
|
|
|
|
2017-09-01 18:39:39 +02:00
|
|
|
options |= eevee_material_shadow_option(shadow_method);
|
|
|
|
|
|
2018-03-13 03:58:00 +01:00
|
|
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
2017-06-28 10:50:33 +10:00
|
|
|
if (mat) {
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
char *defines = eevee_get_defines(options);
|
|
|
|
|
|
2018-03-05 00:54:31 +01:00
|
|
|
mat = DRW_shader_create_from_material(
|
|
|
|
|
scene, ma, engine, options,
|
2018-05-29 12:25:43 +02:00
|
|
|
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
|
2017-06-28 10:50:33 +10:00
|
|
|
defines);
|
2017-06-22 02:41:17 +02:00
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
|
|
|
|
|
|
|
|
|
return mat;
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-27 16:20:33 +02:00
|
|
|
struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material *ma)
|
|
|
|
|
{
|
|
|
|
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
|
|
|
|
int options = VAR_MAT_VOLUME;
|
|
|
|
|
|
2018-03-13 03:58:00 +01:00
|
|
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
2017-10-27 16:20:33 +02:00
|
|
|
if (mat != NULL) {
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *defines = eevee_get_volume_defines(options);
|
|
|
|
|
|
2018-03-05 00:54:31 +01:00
|
|
|
mat = DRW_shader_create_from_material(
|
|
|
|
|
scene, ma, engine, options,
|
2017-10-27 16:20:33 +02:00
|
|
|
datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
|
|
|
|
|
defines);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
|
|
|
|
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-11 01:10:57 +02:00
|
|
|
struct GPUMaterial *EEVEE_material_mesh_depth_get(
|
|
|
|
|
struct Scene *scene, Material *ma,
|
|
|
|
|
bool use_hashed_alpha, bool is_shadow)
|
2017-07-09 12:01:29 +02:00
|
|
|
{
|
|
|
|
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
|
|
|
|
int options = VAR_MAT_MESH;
|
|
|
|
|
|
|
|
|
|
if (use_hashed_alpha) {
|
|
|
|
|
options |= VAR_MAT_HASH;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
options |= VAR_MAT_CLIP;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-11 01:10:57 +02:00
|
|
|
if (is_shadow)
|
|
|
|
|
options |= VAR_MAT_SHADOW;
|
|
|
|
|
|
2018-03-13 03:58:00 +01:00
|
|
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
2017-07-09 12:01:29 +02:00
|
|
|
if (mat) {
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *defines = eevee_get_defines(options);
|
|
|
|
|
|
2018-01-17 21:40:43 +11:00
|
|
|
char *frag_str = BLI_string_joinN(
|
2018-04-15 22:22:50 +02:00
|
|
|
e_data.frag_shader_lib,
|
2018-01-17 21:40:43 +11:00
|
|
|
datatoc_prepass_frag_glsl);
|
2018-01-17 20:35:06 +11:00
|
|
|
|
2018-03-05 00:54:31 +01:00
|
|
|
mat = DRW_shader_create_from_material(
|
|
|
|
|
scene, ma, engine, options,
|
2018-05-29 12:25:43 +02:00
|
|
|
(is_shadow) ? datatoc_shadow_vert_glsl : e_data.vert_shader_str,
|
2018-04-15 22:22:50 +02:00
|
|
|
NULL,
|
2018-01-17 20:35:06 +11:00
|
|
|
frag_str,
|
2017-07-09 12:01:29 +02:00
|
|
|
defines);
|
|
|
|
|
|
2018-01-17 20:35:06 +11:00
|
|
|
MEM_freeN(frag_str);
|
2017-07-09 12:01:29 +02:00
|
|
|
MEM_freeN(defines);
|
|
|
|
|
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *EEVEE_material_hair_get(
|
2017-09-01 18:39:39 +02:00
|
|
|
struct Scene *scene, Material *ma, int shadow_method)
|
2017-06-14 12:39:57 +02:00
|
|
|
{
|
2017-06-28 10:50:33 +10:00
|
|
|
const void *engine = &DRW_engine_viewport_eevee_type;
|
2017-06-22 02:41:17 +02:00
|
|
|
int options = VAR_MAT_MESH | VAR_MAT_HAIR;
|
|
|
|
|
|
2017-09-01 18:39:39 +02:00
|
|
|
options |= eevee_material_shadow_option(shadow_method);
|
|
|
|
|
|
2018-03-13 03:58:00 +01:00
|
|
|
GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options);
|
2017-06-28 10:50:33 +10:00
|
|
|
if (mat) {
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
char *defines = eevee_get_defines(options);
|
|
|
|
|
|
2018-03-05 00:54:31 +01:00
|
|
|
mat = DRW_shader_create_from_material(
|
|
|
|
|
scene, ma, engine, options,
|
2018-05-29 12:25:43 +02:00
|
|
|
e_data.vert_shader_str, NULL, e_data.frag_shader_lib,
|
2017-06-28 10:50:33 +10:00
|
|
|
defines);
|
2017-06-22 02:41:17 +02:00
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
|
|
|
|
|
|
|
|
|
return mat;
|
2017-06-14 12:39:57 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-10 11:41:33 +02:00
|
|
|
/**
|
|
|
|
|
* Create a default shading group inside the given pass.
|
|
|
|
|
**/
|
|
|
|
|
static struct DRWShadingGroup *EEVEE_default_shading_group_create(
|
2017-11-22 10:52:39 -02:00
|
|
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWPass *pass,
|
2017-09-01 18:39:39 +02:00
|
|
|
bool is_hair, bool is_flat_normal, bool use_blend, bool use_ssr, int shadow_method)
|
2017-07-10 11:41:33 +02:00
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_EffectsInfo *effects = vedata->stl->effects;
|
2017-07-16 23:49:25 +02:00
|
|
|
static int ssr_id;
|
2017-11-18 22:14:53 +01:00
|
|
|
ssr_id = (use_ssr) ? 1 : -1;
|
2017-07-10 11:41:33 +02:00
|
|
|
int options = VAR_MAT_MESH;
|
|
|
|
|
|
|
|
|
|
if (is_hair) options |= VAR_MAT_HAIR;
|
|
|
|
|
if (is_flat_normal) options |= VAR_MAT_FLAT;
|
|
|
|
|
if (use_blend) options |= VAR_MAT_BLEND;
|
2018-01-21 17:25:10 +01:00
|
|
|
if (((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_blend) options |= VAR_MAT_VOLUME;
|
2017-07-10 11:41:33 +02:00
|
|
|
|
2017-09-01 18:39:39 +02:00
|
|
|
options |= eevee_material_shadow_option(shadow_method);
|
|
|
|
|
|
2017-07-10 11:41:33 +02:00
|
|
|
if (e_data.default_lit[options] == NULL) {
|
|
|
|
|
create_default_shader(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
|
2018-01-21 17:25:10 +01:00
|
|
|
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, use_blend);
|
2017-07-10 11:41:33 +02:00
|
|
|
|
|
|
|
|
return shgrp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a default shading group inside the default pass without standard uniforms.
|
|
|
|
|
**/
|
2017-06-22 02:41:17 +02:00
|
|
|
static struct DRWShadingGroup *EEVEE_default_shading_group_get(
|
2017-11-22 10:52:39 -02:00
|
|
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
2018-05-29 12:25:43 +02:00
|
|
|
Object *ob, ParticleSystem *psys, ModifierData *md,
|
2017-09-01 18:39:39 +02:00
|
|
|
bool is_hair, bool is_flat_normal, bool use_ssr, int shadow_method)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2017-07-16 23:49:25 +02:00
|
|
|
static int ssr_id;
|
2017-11-18 22:14:53 +01:00
|
|
|
ssr_id = (use_ssr) ? 1 : -1;
|
2017-06-22 02:41:17 +02:00
|
|
|
int options = VAR_MAT_MESH;
|
|
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
BLI_assert(!is_hair || (ob && psys && md));
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
if (is_hair) options |= VAR_MAT_HAIR;
|
|
|
|
|
if (is_flat_normal) options |= VAR_MAT_FLAT;
|
|
|
|
|
|
2017-09-01 18:39:39 +02:00
|
|
|
options |= eevee_material_shadow_option(shadow_method);
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
if (e_data.default_lit[options] == NULL) {
|
|
|
|
|
create_default_shader(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (vedata->psl->default_pass[options] == NULL) {
|
2017-06-23 19:19:19 +02:00
|
|
|
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
|
2017-06-22 02:41:17 +02:00
|
|
|
vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state);
|
|
|
|
|
|
2018-03-16 08:49:13 +01:00
|
|
|
/* XXX / WATCH: This creates non persistent binds for the ubos and textures.
|
2018-05-29 12:25:43 +02:00
|
|
|
* But it's currently OK because the following shgroups does not add any bind.
|
|
|
|
|
* EDIT: THIS IS NOT THE CASE FOR HAIRS !!! DUMMY!!! */
|
|
|
|
|
if (!is_hair) {
|
|
|
|
|
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
|
|
|
|
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false);
|
|
|
|
|
}
|
2017-06-22 02:41:17 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
if (is_hair) {
|
|
|
|
|
DRWShadingGroup *shgrp = DRW_shgroup_hair_create(ob, psys, md,
|
|
|
|
|
vedata->psl->default_pass[options], vedata->psl->hair_tf_pass,
|
|
|
|
|
e_data.default_lit[options]);
|
|
|
|
|
add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false, false);
|
|
|
|
|
return shgrp;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
|
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-25 08:06:36 +02:00
|
|
|
/**
|
|
|
|
|
* Create a default shading group inside the lookdev pass without standard uniforms.
|
|
|
|
|
**/
|
|
|
|
|
static struct DRWShadingGroup *EEVEE_lookdev_shading_group_get(
|
|
|
|
|
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
|
|
|
|
bool use_ssr, int shadow_method)
|
|
|
|
|
{
|
|
|
|
|
static int ssr_id;
|
|
|
|
|
ssr_id = (use_ssr) ? 1 : -1;
|
|
|
|
|
int options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
|
|
|
|
|
|
|
|
|
|
options |= eevee_material_shadow_option(shadow_method);
|
|
|
|
|
|
|
|
|
|
if (e_data.default_lit[options] == NULL) {
|
|
|
|
|
create_default_shader(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (vedata->psl->lookdev_pass == NULL) {
|
|
|
|
|
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_CULL_BACK;
|
|
|
|
|
vedata->psl->lookdev_pass = DRW_pass_create("LookDev Pass", state);
|
|
|
|
|
|
|
|
|
|
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass);
|
|
|
|
|
/* XXX / WATCH: This creates non persistent binds for the ubos and textures.
|
|
|
|
|
* But it's currently OK because the following shgroups does not add any bind. */
|
|
|
|
|
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass);
|
|
|
|
|
}
|
2018-03-06 02:19:28 +01:00
|
|
|
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
|
|
|
|
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
2017-06-22 02:41:17 +02:00
|
|
|
|
2017-06-05 22:05:21 +02:00
|
|
|
/* Create Material Ghash */
|
|
|
|
|
{
|
|
|
|
|
stl->g_data->material_hash = BLI_ghash_ptr_new("Eevee_material ghash");
|
2017-06-14 12:39:57 +02:00
|
|
|
stl->g_data->hair_material_hash = BLI_ghash_ptr_new("Eevee_hair_material ghash");
|
2017-06-05 22:05:21 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2017-07-31 15:15:42 +02:00
|
|
|
psl->background_pass = DRW_pass_create("Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-19 20:18:04 +10:00
|
|
|
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
2017-06-04 12:12:58 +02:00
|
|
|
DRWShadingGroup *grp = NULL;
|
|
|
|
|
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
|
World *wo = scene->world;
|
|
|
|
|
|
|
|
|
|
float *col = ts.colorBackground;
|
|
|
|
|
|
2018-05-25 08:06:36 +02:00
|
|
|
/* LookDev */
|
2018-05-29 12:38:19 +02:00
|
|
|
EEVEE_lookdev_cache_init(vedata, &grp, e_data.default_studiolight_background, psl->background_pass, wo, NULL);
|
2018-05-25 08:06:36 +02:00
|
|
|
/* END */
|
|
|
|
|
|
|
|
|
|
if (!grp && wo) {
|
2017-06-04 12:12:58 +02:00
|
|
|
col = &wo->horr;
|
|
|
|
|
|
|
|
|
|
if (wo->use_nodes && wo->nodetree) {
|
2018-03-05 00:54:31 +01:00
|
|
|
static float error_col[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
|
2017-06-04 12:12:58 +02:00
|
|
|
struct GPUMaterial *gpumat = EEVEE_material_world_background_get(scene, wo);
|
|
|
|
|
|
2018-03-05 00:54:31 +01:00
|
|
|
switch (GPU_material_status(gpumat)) {
|
|
|
|
|
case GPU_MAT_SUCCESS:
|
|
|
|
|
grp = DRW_shgroup_material_create(gpumat, psl->background_pass);
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
|
|
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
break;
|
|
|
|
|
case GPU_MAT_QUEUED:
|
2018-03-06 02:19:28 +01:00
|
|
|
sldata->probes->all_materials_updated = false;
|
2018-03-05 00:54:31 +01:00
|
|
|
/* TODO Bypass probe compilation. */
|
|
|
|
|
col = compile_col;
|
|
|
|
|
break;
|
|
|
|
|
case GPU_MAT_FAILED:
|
|
|
|
|
default:
|
|
|
|
|
col = error_col;
|
|
|
|
|
break;
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fallback if shader fails or if not using nodetree. */
|
|
|
|
|
if (grp == NULL) {
|
|
|
|
|
grp = DRW_shgroup_create(e_data.default_background, psl->background_pass);
|
|
|
|
|
DRW_shgroup_uniform_vec3(grp, "color", col, 1);
|
2017-06-24 05:24:59 +02:00
|
|
|
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
|
2017-06-04 12:12:58 +02:00
|
|
|
DRW_shgroup_call_add(grp, geom, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2018-05-20 19:05:13 +02:00
|
|
|
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE;
|
2017-06-04 12:12:58 +02:00
|
|
|
psl->depth_pass = DRW_pass_create("Depth Pass", state);
|
2017-06-16 23:50:40 +02:00
|
|
|
stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-05-20 19:05:13 +02:00
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
|
2017-06-04 12:12:58 +02:00
|
|
|
psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", state);
|
2017-06-16 23:50:40 +02:00
|
|
|
stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass_cull);
|
|
|
|
|
|
2018-05-20 19:05:13 +02:00
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
|
2017-06-16 23:50:40 +02:00
|
|
|
psl->depth_pass_clip = DRW_pass_create("Depth Pass Clip", state);
|
|
|
|
|
stl->g_data->depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->depth_pass_clip);
|
2018-03-10 00:02:01 +01:00
|
|
|
DRW_shgroup_uniform_block(stl->g_data->depth_shgrp_clip, "clip_block", sldata->clip_ubo);
|
2017-06-16 23:50:40 +02:00
|
|
|
|
2018-05-20 19:05:13 +02:00
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
|
2017-06-16 23:50:40 +02:00
|
|
|
psl->depth_pass_clip_cull = DRW_pass_create("Depth Pass Cull Clip", state);
|
2018-05-26 10:41:25 +02:00
|
|
|
stl->g_data->depth_shgrp_clip_cull = DRW_shgroup_create(
|
|
|
|
|
e_data.default_prepass_clip_sh, psl->depth_pass_clip_cull);
|
2018-03-10 00:02:01 +01:00
|
|
|
DRW_shgroup_uniform_block(stl->g_data->depth_shgrp_clip_cull, "clip_block", sldata->clip_ubo);
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2018-05-29 12:25:43 +02:00
|
|
|
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
|
2017-06-04 12:12:58 +02:00
|
|
|
psl->material_pass = DRW_pass_create("Material Shader Pass", state);
|
|
|
|
|
}
|
2017-07-10 11:41:33 +02:00
|
|
|
|
2017-08-09 23:48:42 +02:00
|
|
|
{
|
2018-05-20 19:05:13 +02:00
|
|
|
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE;
|
2017-08-09 23:48:42 +02:00
|
|
|
psl->refract_depth_pass = DRW_pass_create("Refract Depth Pass", state);
|
|
|
|
|
stl->g_data->refract_depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass);
|
|
|
|
|
|
2018-05-20 19:05:13 +02:00
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
|
2017-08-09 23:48:42 +02:00
|
|
|
psl->refract_depth_pass_cull = DRW_pass_create("Refract Depth Pass Cull", state);
|
2018-05-26 10:41:25 +02:00
|
|
|
stl->g_data->refract_depth_shgrp_cull = DRW_shgroup_create(
|
|
|
|
|
e_data.default_prepass_sh, psl->refract_depth_pass_cull);
|
2017-08-09 23:48:42 +02:00
|
|
|
|
2018-05-20 19:05:13 +02:00
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
|
2017-08-09 23:48:42 +02:00
|
|
|
psl->refract_depth_pass_clip = DRW_pass_create("Refract Depth Pass Clip", state);
|
2018-05-26 10:41:25 +02:00
|
|
|
stl->g_data->refract_depth_shgrp_clip = DRW_shgroup_create(
|
|
|
|
|
e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip);
|
2018-03-10 00:02:01 +01:00
|
|
|
DRW_shgroup_uniform_block(stl->g_data->refract_depth_shgrp_clip, "clip_block", sldata->clip_ubo);
|
2017-08-09 23:48:42 +02:00
|
|
|
|
2018-05-20 19:05:13 +02:00
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
|
2017-08-09 23:48:42 +02:00
|
|
|
psl->refract_depth_pass_clip_cull = DRW_pass_create("Refract Depth Pass Cull Clip", state);
|
2018-05-26 10:41:25 +02:00
|
|
|
stl->g_data->refract_depth_shgrp_clip_cull = DRW_shgroup_create(
|
|
|
|
|
e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip_cull);
|
2018-03-10 00:02:01 +01:00
|
|
|
DRW_shgroup_uniform_block(stl->g_data->refract_depth_shgrp_clip_cull, "clip_block", sldata->clip_ubo);
|
2017-08-09 23:48:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2018-05-26 10:41:25 +02:00
|
|
|
DRWState state = (
|
|
|
|
|
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
|
|
|
|
|
DRW_STATE_WIRE);
|
2017-08-09 23:48:42 +02:00
|
|
|
psl->refract_pass = DRW_pass_create("Opaque Refraction Pass", state);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-14 00:49:54 +01:00
|
|
|
{
|
2018-05-26 10:41:25 +02:00
|
|
|
DRWState state = (
|
|
|
|
|
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
|
|
|
|
|
DRW_STATE_WIRE | DRW_STATE_WRITE_STENCIL);
|
2017-11-14 00:49:54 +01:00
|
|
|
psl->sss_pass = DRW_pass_create("Subsurface Pass", state);
|
|
|
|
|
e_data.sss_count = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-10 11:41:33 +02:00
|
|
|
{
|
2018-05-20 19:05:13 +02:00
|
|
|
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
|
2017-07-10 11:41:33 +02:00
|
|
|
psl->transparent_pass = DRW_pass_create("Material Transparent Pass", state);
|
|
|
|
|
}
|
2018-01-17 14:02:48 +01:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
psl->update_noise_pass = DRW_pass_create("Update Noise Pass", DRW_STATE_WRITE_COLOR);
|
|
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(e_data.update_noise_sh, psl->update_noise_pass);
|
|
|
|
|
DRW_shgroup_uniform_texture(grp, "blueNoise", e_data.noise_tex);
|
|
|
|
|
DRW_shgroup_uniform_vec3(grp, "offsets", e_data.noise_offsets, 1);
|
|
|
|
|
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
{
|
|
|
|
|
psl->hair_tf_pass = DRW_pass_create("Update Hair Pass", DRW_STATE_TRANS_FEEDBACK);
|
|
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2018-04-24 12:45:59 +02:00
|
|
|
#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) do { \
|
2017-07-13 00:27:06 +10:00
|
|
|
if (is_sculpt_mode_draw) { \
|
2017-06-04 12:12:58 +02:00
|
|
|
DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat); \
|
|
|
|
|
} \
|
|
|
|
|
else { \
|
2018-05-01 17:59:33 +02:00
|
|
|
if (oedata) { \
|
|
|
|
|
DRW_shgroup_call_object_add_with_callback(shgrp, geom, ob, EEVEE_lightprobes_obj_visibility_cb, oedata); \
|
|
|
|
|
} \
|
|
|
|
|
else { \
|
|
|
|
|
DRW_shgroup_call_object_add(shgrp, geom, ob); \
|
|
|
|
|
} \
|
2017-06-04 12:12:58 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2018-04-24 12:45:59 +02:00
|
|
|
#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom, oedata) do { \
|
2017-07-10 11:41:33 +02:00
|
|
|
if (shgrp) { \
|
2018-04-24 12:45:59 +02:00
|
|
|
ADD_SHGROUP_CALL(shgrp, ob, geom, oedata); \
|
2017-07-10 11:41:33 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2017-10-07 15:57:14 +11:00
|
|
|
typedef struct EeveeMaterialShadingGroups {
|
2017-07-09 17:50:39 +02:00
|
|
|
struct DRWShadingGroup *shading_grp;
|
|
|
|
|
struct DRWShadingGroup *depth_grp;
|
|
|
|
|
struct DRWShadingGroup *depth_clip_grp;
|
|
|
|
|
} EeveeMaterialShadingGroups;
|
|
|
|
|
|
|
|
|
|
static void material_opaque(
|
2017-11-22 10:52:39 -02:00
|
|
|
Material *ma, GHash *material_hash, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
2017-07-09 17:50:39 +02:00
|
|
|
bool do_cull, bool use_flat_nor, struct GPUMaterial **gpumat, struct GPUMaterial **gpumat_depth,
|
|
|
|
|
struct DRWShadingGroup **shgrp, struct DRWShadingGroup **shgrp_depth, struct DRWShadingGroup **shgrp_depth_clip)
|
|
|
|
|
{
|
2018-01-21 17:25:10 +01:00
|
|
|
EEVEE_EffectsInfo *effects = vedata->stl->effects;
|
2017-07-09 17:50:39 +02:00
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
|
|
|
|
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
2017-09-01 18:39:39 +02:00
|
|
|
EEVEE_LampsInfo *linfo = sldata->lamps;
|
2017-07-09 17:50:39 +02:00
|
|
|
|
|
|
|
|
float *color_p = &ma->r;
|
2018-05-31 13:32:53 +02:00
|
|
|
float *metal_p = &ma->metallic;
|
2017-07-09 17:50:39 +02:00
|
|
|
float *spec_p = &ma->spec;
|
2018-05-31 13:32:53 +02:00
|
|
|
float *rough_p = &ma->roughness;
|
2017-07-09 17:50:39 +02:00
|
|
|
|
|
|
|
|
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
|
2018-01-17 00:01:17 +01:00
|
|
|
const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
|
2018-01-21 17:25:10 +01:00
|
|
|
((effects->enabled_effects & EFFECT_REFRACT) != 0);
|
2018-01-17 00:01:17 +01:00
|
|
|
const bool use_sss = ((ma->blend_flag & MA_BL_SS_SUBSURFACE) != 0) &&
|
2018-01-21 17:25:10 +01:00
|
|
|
((effects->enabled_effects & EFFECT_SSS) != 0);
|
2018-01-17 00:01:17 +01:00
|
|
|
const bool use_translucency = use_sss && ((ma->blend_flag & MA_BL_TRANSLUCENCY) != 0);
|
2017-07-09 17:50:39 +02:00
|
|
|
|
|
|
|
|
EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma);
|
|
|
|
|
|
|
|
|
|
if (emsg) {
|
|
|
|
|
*shgrp = emsg->shading_grp;
|
|
|
|
|
*shgrp_depth = emsg->depth_grp;
|
|
|
|
|
*shgrp_depth_clip = emsg->depth_clip_grp;
|
|
|
|
|
|
|
|
|
|
/* This will have been created already, just perform a lookup. */
|
|
|
|
|
*gpumat = (use_gpumat) ? EEVEE_material_mesh_get(
|
2017-11-22 04:51:21 +01:00
|
|
|
scene, ma, vedata, false, false, use_refract, use_sss, use_translucency, linfo->shadow_method) : NULL;
|
2017-07-09 17:50:39 +02:00
|
|
|
*gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get(
|
2017-07-11 01:10:57 +02:00
|
|
|
scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL;
|
2017-07-09 17:50:39 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (use_gpumat) {
|
2018-03-06 02:19:28 +01:00
|
|
|
static float error_col[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
|
|
|
|
|
static float half = 0.5f;
|
|
|
|
|
|
2017-07-09 17:50:39 +02:00
|
|
|
/* Shading */
|
2018-05-26 10:41:25 +02:00
|
|
|
*gpumat = EEVEE_material_mesh_get(
|
|
|
|
|
scene, ma, vedata, false, false, use_refract,
|
|
|
|
|
use_sss, use_translucency, linfo->shadow_method);
|
2017-07-09 17:50:39 +02:00
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
GPUMaterialStatus status_mat_surface = GPU_material_status(*gpumat);
|
2017-07-09 17:50:39 +02:00
|
|
|
|
|
|
|
|
/* Alpha CLipped : Discard pixel from depth pass, then
|
|
|
|
|
* fail the depth test for shading. */
|
|
|
|
|
if (ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED)) {
|
2018-05-26 10:41:25 +02:00
|
|
|
*gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma, (ma->blend_method == MA_BM_HASHED), false);
|
2017-07-09 17:50:39 +02:00
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
GPUMaterialStatus status_mat_depth = GPU_material_status(*gpumat_depth);
|
|
|
|
|
if (status_mat_depth != GPU_MAT_SUCCESS) {
|
|
|
|
|
/* Mixing both flags. If depth shader fails, show it to the user by not using
|
|
|
|
|
* the surface shader. */
|
|
|
|
|
status_mat_surface = status_mat_depth;
|
|
|
|
|
}
|
|
|
|
|
else if (use_refract) {
|
2018-05-26 10:41:25 +02:00
|
|
|
*shgrp_depth = DRW_shgroup_material_create(
|
|
|
|
|
*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
|
|
|
|
|
*shgrp_depth_clip = DRW_shgroup_material_create(
|
|
|
|
|
*gpumat_depth, (do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
|
2017-08-09 23:48:42 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-05-26 10:41:25 +02:00
|
|
|
*shgrp_depth = DRW_shgroup_material_create(
|
|
|
|
|
*gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass);
|
|
|
|
|
*shgrp_depth_clip = DRW_shgroup_material_create(
|
|
|
|
|
*gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
|
2017-08-09 23:48:42 +02:00
|
|
|
}
|
2017-07-09 17:50:39 +02:00
|
|
|
|
2017-10-10 16:41:13 +02:00
|
|
|
if (*shgrp_depth != NULL) {
|
2018-01-21 17:25:10 +01:00
|
|
|
add_standard_uniforms(*shgrp_depth, sldata, vedata, NULL, NULL, false, false);
|
2018-03-10 00:02:01 +01:00
|
|
|
add_standard_uniforms(*shgrp_depth_clip, sldata, vedata, NULL, NULL, false, false);
|
2017-10-10 16:41:13 +02:00
|
|
|
|
2017-07-09 17:50:39 +02:00
|
|
|
if (ma->blend_method == MA_BM_CLIP) {
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp_depth_clip, "alphaThreshold", &ma->alpha_threshold, 1);
|
|
|
|
|
}
|
2018-01-16 19:40:17 +01:00
|
|
|
else if (ma->blend_method == MA_BM_HASHED) {
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp_depth, "hashAlphaOffset", &e_data.alpha_hash_offset, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp_depth_clip, "hashAlphaOffset", &e_data.alpha_hash_offset, 1);
|
|
|
|
|
}
|
2017-07-09 17:50:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-03-06 02:19:28 +01:00
|
|
|
|
|
|
|
|
switch (status_mat_surface) {
|
|
|
|
|
case GPU_MAT_SUCCESS:
|
|
|
|
|
{
|
|
|
|
|
static int no_ssr = -1;
|
|
|
|
|
static int first_ssr = 1;
|
|
|
|
|
int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_refract) ? &first_ssr : &no_ssr;
|
|
|
|
|
|
2018-05-26 10:41:25 +02:00
|
|
|
*shgrp = DRW_shgroup_material_create(
|
|
|
|
|
*gpumat,
|
|
|
|
|
(use_refract) ? psl->refract_pass :
|
|
|
|
|
(use_sss) ? psl->sss_pass : psl->material_pass);
|
2018-03-06 02:19:28 +01:00
|
|
|
add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false);
|
|
|
|
|
|
|
|
|
|
if (use_sss) {
|
|
|
|
|
struct GPUTexture *sss_tex_profile = NULL;
|
2018-05-26 10:41:25 +02:00
|
|
|
struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(
|
|
|
|
|
*gpumat,
|
|
|
|
|
stl->effects->sss_sample_count,
|
|
|
|
|
&sss_tex_profile);
|
2018-03-06 02:19:28 +01:00
|
|
|
|
|
|
|
|
if (sss_profile) {
|
|
|
|
|
if (use_translucency) {
|
|
|
|
|
DRW_shgroup_uniform_block(*shgrp, "sssProfile", sss_profile);
|
|
|
|
|
DRW_shgroup_uniform_texture(*shgrp, "sssTexProfile", sss_tex_profile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Limit of 8 bit stencil buffer. ID 255 is refraction. */
|
|
|
|
|
if (e_data.sss_count < 254) {
|
|
|
|
|
DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
|
|
|
|
|
EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
|
|
|
|
|
e_data.sss_count++;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* TODO : display message. */
|
|
|
|
|
printf("Error: Too many different Subsurface shader in the scene.\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case GPU_MAT_QUEUED:
|
|
|
|
|
{
|
|
|
|
|
sldata->probes->all_materials_updated = false;
|
|
|
|
|
/* TODO Bypass probe compilation. */
|
|
|
|
|
color_p = compile_col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case GPU_MAT_FAILED:
|
|
|
|
|
default:
|
|
|
|
|
color_p = error_col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-07-09 17:50:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fallback to default shader */
|
|
|
|
|
if (*shgrp == NULL) {
|
2018-01-21 17:25:10 +01:00
|
|
|
bool use_ssr = ((effects->enabled_effects & EFFECT_SSR) != 0);
|
2018-05-29 12:25:43 +02:00
|
|
|
*shgrp = EEVEE_default_shading_group_get(sldata, vedata,
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
false, use_flat_nor, use_ssr, linfo->shadow_method);
|
2017-07-09 17:50:39 +02:00
|
|
|
DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fallback default depth prepass */
|
|
|
|
|
if (*shgrp_depth == NULL) {
|
2017-08-09 23:48:42 +02:00
|
|
|
if (use_refract) {
|
|
|
|
|
*shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull : stl->g_data->refract_depth_shgrp;
|
|
|
|
|
*shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull : stl->g_data->refract_depth_shgrp_clip;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
*shgrp_depth = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
|
|
|
|
|
*shgrp_depth_clip = (do_cull) ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
|
|
|
|
|
}
|
2017-07-09 17:50:39 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-05 01:26:12 +01:00
|
|
|
emsg = MEM_mallocN(sizeof(EeveeMaterialShadingGroups), "EeveeMaterialShadingGroups");
|
2017-07-09 17:50:39 +02:00
|
|
|
emsg->shading_grp = *shgrp;
|
|
|
|
|
emsg->depth_grp = *shgrp_depth;
|
|
|
|
|
emsg->depth_clip_grp = *shgrp_depth_clip;
|
|
|
|
|
BLI_ghash_insert(material_hash, ma, emsg);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-10 11:41:33 +02:00
|
|
|
static void material_transparent(
|
2017-11-22 10:52:39 -02:00
|
|
|
Material *ma, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
2018-05-26 10:41:25 +02:00
|
|
|
bool do_cull, bool use_flat_nor,
|
|
|
|
|
struct GPUMaterial **gpumat, struct DRWShadingGroup **shgrp, struct DRWShadingGroup **shgrp_depth)
|
2017-07-10 11:41:33 +02:00
|
|
|
{
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
|
|
|
|
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
2017-09-01 18:39:39 +02:00
|
|
|
EEVEE_LampsInfo *linfo = sldata->lamps;
|
2017-07-10 11:41:33 +02:00
|
|
|
|
2018-05-26 10:41:25 +02:00
|
|
|
const bool use_refract = (
|
|
|
|
|
((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
|
|
|
|
|
((stl->effects->enabled_effects & EFFECT_REFRACT) != 0)
|
|
|
|
|
);
|
2017-07-10 11:41:33 +02:00
|
|
|
float *color_p = &ma->r;
|
2018-05-31 13:32:53 +02:00
|
|
|
float *metal_p = &ma->metallic;
|
2017-07-10 11:41:33 +02:00
|
|
|
float *spec_p = &ma->spec;
|
2018-05-31 13:32:53 +02:00
|
|
|
float *rough_p = &ma->roughness;
|
2017-07-10 11:41:33 +02:00
|
|
|
|
|
|
|
|
if (ma->use_nodes && ma->nodetree) {
|
2018-03-06 02:19:28 +01:00
|
|
|
static float error_col[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
|
|
|
|
|
static float half = 0.5f;
|
|
|
|
|
|
2017-07-10 11:41:33 +02:00
|
|
|
/* Shading */
|
2018-05-26 10:41:25 +02:00
|
|
|
*gpumat = EEVEE_material_mesh_get(
|
|
|
|
|
scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract,
|
|
|
|
|
false, false, linfo->shadow_method);
|
2017-07-10 11:41:33 +02:00
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
switch (GPU_material_status(*gpumat)) {
|
|
|
|
|
case GPU_MAT_SUCCESS:
|
|
|
|
|
{
|
|
|
|
|
static int ssr_id = -1; /* TODO transparent SSR */
|
|
|
|
|
bool use_blend = (ma->blend_method & MA_BM_BLEND) != 0;
|
2017-07-10 11:41:33 +02:00
|
|
|
|
2018-03-06 02:19:28 +01:00
|
|
|
*shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
|
|
|
|
|
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract, use_blend);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case GPU_MAT_QUEUED:
|
|
|
|
|
{
|
|
|
|
|
sldata->probes->all_materials_updated = false;
|
|
|
|
|
/* TODO Bypass probe compilation. */
|
|
|
|
|
color_p = compile_col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case GPU_MAT_FAILED:
|
|
|
|
|
default:
|
|
|
|
|
color_p = error_col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
break;
|
2017-07-10 11:41:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fallback to default shader */
|
|
|
|
|
if (*shgrp == NULL) {
|
|
|
|
|
*shgrp = EEVEE_default_shading_group_create(
|
|
|
|
|
sldata, vedata, psl->transparent_pass,
|
2017-09-01 18:39:39 +02:00
|
|
|
false, use_flat_nor, true, false, linfo->shadow_method);
|
2017-07-10 11:41:33 +02:00
|
|
|
DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-10 18:34:33 +02:00
|
|
|
const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKSIDE) != 0);
|
|
|
|
|
|
2018-05-26 10:41:25 +02:00
|
|
|
DRWState all_state = (
|
|
|
|
|
DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_CULL_BACK |
|
|
|
|
|
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
|
|
|
|
|
DRW_STATE_BLEND | DRW_STATE_ADDITIVE | DRW_STATE_MULTIPLY
|
|
|
|
|
);
|
2017-07-10 18:34:33 +02:00
|
|
|
|
|
|
|
|
DRWState cur_state = DRW_STATE_WRITE_COLOR;
|
2018-05-20 19:05:13 +02:00
|
|
|
cur_state |= (use_prepass) ? DRW_STATE_DEPTH_EQUAL : DRW_STATE_DEPTH_LESS_EQUAL;
|
2017-07-10 18:34:33 +02:00
|
|
|
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
|
2017-07-10 11:41:33 +02:00
|
|
|
|
|
|
|
|
switch (ma->blend_method) {
|
|
|
|
|
case MA_BM_ADD:
|
|
|
|
|
cur_state |= DRW_STATE_ADDITIVE;
|
|
|
|
|
break;
|
|
|
|
|
case MA_BM_MULTIPLY:
|
|
|
|
|
cur_state |= DRW_STATE_MULTIPLY;
|
|
|
|
|
break;
|
2017-07-10 14:42:43 +02:00
|
|
|
case MA_BM_BLEND:
|
|
|
|
|
cur_state |= DRW_STATE_BLEND;
|
|
|
|
|
break;
|
2017-07-10 11:41:33 +02:00
|
|
|
default:
|
|
|
|
|
BLI_assert(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Disable other blend modes and use the one we want. */
|
|
|
|
|
DRW_shgroup_state_disable(*shgrp, all_state);
|
|
|
|
|
DRW_shgroup_state_enable(*shgrp, cur_state);
|
2017-07-10 18:34:33 +02:00
|
|
|
|
|
|
|
|
/* Depth prepass */
|
|
|
|
|
if (use_prepass) {
|
|
|
|
|
*shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
|
2018-03-10 00:02:01 +01:00
|
|
|
DRW_shgroup_uniform_block(*shgrp_depth, "clip_block", sldata->clip_ubo);
|
2017-07-10 18:34:33 +02:00
|
|
|
|
2018-05-20 19:05:13 +02:00
|
|
|
cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
2017-07-10 18:34:33 +02:00
|
|
|
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
|
|
|
|
|
|
|
|
|
|
DRW_shgroup_state_disable(*shgrp_depth, all_state);
|
|
|
|
|
DRW_shgroup_state_enable(*shgrp_depth, cur_state);
|
|
|
|
|
}
|
2017-07-10 11:41:33 +02:00
|
|
|
}
|
2017-07-09 17:50:39 +02:00
|
|
|
|
2018-05-01 19:32:24 +02:00
|
|
|
void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2018-03-01 19:27:38 +01:00
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
2017-06-04 12:12:58 +02:00
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
2017-07-11 01:10:57 +02:00
|
|
|
Scene *scene = draw_ctx->scene;
|
2017-06-05 22:05:21 +02:00
|
|
|
GHash *material_hash = stl->g_data->material_hash;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2018-05-03 15:09:09 +02:00
|
|
|
const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->flag2 & V3D_BACKFACE_CULLING));
|
2017-06-04 12:12:58 +02:00
|
|
|
const bool is_active = (ob == draw_ctx->obact);
|
2018-02-06 16:10:03 +11:00
|
|
|
const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
|
2017-07-13 19:09:40 +10:00
|
|
|
#if 0
|
2017-07-13 00:27:06 +10:00
|
|
|
const bool is_sculpt_mode_draw = is_sculpt_mode && (draw_ctx->v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0;
|
2017-07-13 19:09:40 +10:00
|
|
|
#else
|
|
|
|
|
/* For now just force fully shaded with eevee when supported. */
|
|
|
|
|
const bool is_sculpt_mode_draw =
|
|
|
|
|
is_sculpt_mode &&
|
|
|
|
|
((ob->sculpt && ob->sculpt->pbvh) && (BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES));
|
|
|
|
|
#endif
|
2017-06-04 12:12:58 +02:00
|
|
|
const bool is_default_mode_shader = is_sculpt_mode;
|
|
|
|
|
|
2017-06-28 13:33:55 +10:00
|
|
|
/* First get materials for this mesh. */
|
2017-12-14 12:22:55 -02:00
|
|
|
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
|
2017-07-13 00:27:06 +10:00
|
|
|
const int materials_len = MAX2(1, (is_sculpt_mode_draw ? 1 : ob->totcol));
|
2017-07-09 17:50:39 +02:00
|
|
|
|
2017-06-28 13:33:55 +10:00
|
|
|
struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len);
|
2017-07-09 17:50:39 +02:00
|
|
|
struct DRWShadingGroup **shgrp_depth_array = BLI_array_alloca(shgrp_depth_array, materials_len);
|
|
|
|
|
struct DRWShadingGroup **shgrp_depth_clip_array = BLI_array_alloca(shgrp_depth_clip_array, materials_len);
|
|
|
|
|
|
2017-06-28 13:38:24 +10:00
|
|
|
struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
|
2017-07-09 17:50:39 +02:00
|
|
|
struct GPUMaterial **gpumat_depth_array = BLI_array_alloca(gpumat_array, materials_len);
|
2017-06-28 13:33:55 +10:00
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
bool use_flat_nor = false;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
if (is_default_mode_shader) {
|
2017-07-13 00:27:06 +10:00
|
|
|
if (is_sculpt_mode_draw) {
|
2017-06-22 02:41:17 +02:00
|
|
|
use_flat_nor = DRW_object_is_flat_normal(ob);
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-28 13:33:55 +10:00
|
|
|
for (int i = 0; i < materials_len; ++i) {
|
2017-07-13 00:27:06 +10:00
|
|
|
Material *ma;
|
|
|
|
|
|
|
|
|
|
if (is_sculpt_mode_draw) {
|
|
|
|
|
ma = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ma = give_current_material(ob, i + 1);
|
|
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-28 13:38:24 +10:00
|
|
|
gpumat_array[i] = NULL;
|
2017-07-09 17:50:39 +02:00
|
|
|
gpumat_depth_array[i] = NULL;
|
|
|
|
|
shgrp_array[i] = NULL;
|
|
|
|
|
shgrp_depth_array[i] = NULL;
|
|
|
|
|
shgrp_depth_clip_array[i] = NULL;
|
2017-06-28 13:38:24 +10:00
|
|
|
|
2017-07-09 17:50:39 +02:00
|
|
|
if (ma == NULL)
|
|
|
|
|
ma = &defmaterial;
|
2017-06-05 22:05:21 +02:00
|
|
|
|
2017-07-09 17:50:39 +02:00
|
|
|
switch (ma->blend_method) {
|
|
|
|
|
case MA_BM_SOLID:
|
|
|
|
|
case MA_BM_CLIP:
|
|
|
|
|
case MA_BM_HASHED:
|
|
|
|
|
material_opaque(ma, material_hash, sldata, vedata, do_cull, use_flat_nor,
|
|
|
|
|
&gpumat_array[i], &gpumat_depth_array[i],
|
|
|
|
|
&shgrp_array[i], &shgrp_depth_array[i], &shgrp_depth_clip_array[i]);
|
|
|
|
|
break;
|
|
|
|
|
case MA_BM_ADD:
|
|
|
|
|
case MA_BM_MULTIPLY:
|
2017-07-10 14:42:43 +02:00
|
|
|
case MA_BM_BLEND:
|
2017-07-10 11:41:33 +02:00
|
|
|
material_transparent(ma, sldata, vedata, do_cull, use_flat_nor,
|
2017-07-10 18:34:33 +02:00
|
|
|
&gpumat_array[i], &shgrp_array[i], &shgrp_depth_array[i]);
|
2017-07-09 17:50:39 +02:00
|
|
|
break;
|
2017-07-10 14:42:43 +02:00
|
|
|
default:
|
|
|
|
|
BLI_assert(0);
|
|
|
|
|
break;
|
2017-06-28 13:33:55 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-13 00:27:06 +10:00
|
|
|
if (is_sculpt_mode && is_sculpt_mode_draw == false) {
|
|
|
|
|
DRW_cache_mesh_sculpt_coords_ensure(ob);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-27 16:20:33 +02:00
|
|
|
/* Only support single volume material for now. */
|
|
|
|
|
/* XXX We rely on the previously compiled surface shader
|
|
|
|
|
* to know if the material has a "volume nodetree".
|
|
|
|
|
*/
|
|
|
|
|
bool use_volume_material = (gpumat_array[0] && GPU_material_use_domain_volume(gpumat_array[0]));
|
|
|
|
|
|
2017-06-28 13:33:55 +10:00
|
|
|
/* Get per-material split surface */
|
2018-05-02 15:36:09 +02:00
|
|
|
char *auto_layer_names;
|
|
|
|
|
int *auto_layer_is_srgb;
|
|
|
|
|
int auto_layer_count;
|
2018-05-26 10:41:25 +02:00
|
|
|
struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(
|
|
|
|
|
ob, gpumat_array, materials_len,
|
|
|
|
|
&auto_layer_names,
|
|
|
|
|
&auto_layer_is_srgb,
|
|
|
|
|
&auto_layer_count);
|
2017-06-28 13:33:55 +10:00
|
|
|
if (mat_geom) {
|
|
|
|
|
for (int i = 0; i < materials_len; ++i) {
|
2018-05-01 17:59:33 +02:00
|
|
|
EEVEE_ObjectEngineData *oedata = NULL;
|
2017-07-11 01:10:57 +02:00
|
|
|
Material *ma = give_current_material(ob, i + 1);
|
|
|
|
|
|
|
|
|
|
if (ma == NULL)
|
|
|
|
|
ma = &defmaterial;
|
|
|
|
|
|
2017-10-27 16:20:33 +02:00
|
|
|
/* Do not render surface if we are rendering a volume object
|
|
|
|
|
* and do not have a surface closure. */
|
|
|
|
|
if (use_volume_material &&
|
2017-12-04 17:19:34 +11:00
|
|
|
(gpumat_array[i] && !GPU_material_use_domain_surface(gpumat_array[i])))
|
2017-10-27 16:20:33 +02:00
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-01 17:59:33 +02:00
|
|
|
/* XXX TODO rewrite this to include the dupli objects.
|
|
|
|
|
* This means we cannot exclude dupli objects from reflections!!! */
|
|
|
|
|
if ((ob->base_flag & BASE_FROMDUPLI) == 0) {
|
|
|
|
|
oedata = EEVEE_object_data_ensure(ob);
|
|
|
|
|
oedata->ob = ob;
|
|
|
|
|
oedata->test_data = &sldata->probes->vis_data;
|
|
|
|
|
}
|
2018-04-24 12:45:59 +02:00
|
|
|
|
2017-07-09 17:50:39 +02:00
|
|
|
/* Shading pass */
|
2018-04-24 12:45:59 +02:00
|
|
|
ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i], oedata);
|
2017-07-09 12:01:29 +02:00
|
|
|
|
|
|
|
|
/* Depth Prepass */
|
2018-04-24 12:45:59 +02:00
|
|
|
ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata);
|
|
|
|
|
ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata);
|
2017-07-09 12:01:29 +02:00
|
|
|
|
2018-05-02 15:36:09 +02:00
|
|
|
char *name = auto_layer_names;
|
|
|
|
|
for (int j = 0; j < auto_layer_count; ++j) {
|
|
|
|
|
/* TODO don't add these uniform when not needed (default pass shaders). */
|
|
|
|
|
if (shgrp_array[i]) {
|
|
|
|
|
DRW_shgroup_uniform_bool(shgrp_array[i], name, &auto_layer_is_srgb[j], 1);
|
|
|
|
|
}
|
|
|
|
|
if (shgrp_depth_array[i]) {
|
|
|
|
|
DRW_shgroup_uniform_bool(shgrp_depth_array[i], name, &auto_layer_is_srgb[j], 1);
|
|
|
|
|
}
|
|
|
|
|
if (shgrp_depth_clip_array[i]) {
|
|
|
|
|
DRW_shgroup_uniform_bool(shgrp_depth_clip_array[i], name, &auto_layer_is_srgb[j], 1);
|
|
|
|
|
}
|
|
|
|
|
/* Go to next layer name. */
|
|
|
|
|
while (*name != '\0') { name++; }
|
|
|
|
|
name += 1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-09 17:50:39 +02:00
|
|
|
/* Shadow Pass */
|
2017-07-11 21:52:02 +02:00
|
|
|
if (ma->use_nodes && ma->nodetree && (ma->blend_method != MA_BM_SOLID)) {
|
2017-07-11 12:39:20 +02:00
|
|
|
struct GPUMaterial *gpumat;
|
|
|
|
|
switch (ma->blend_shadow) {
|
|
|
|
|
case MA_BS_SOLID:
|
2018-05-26 10:41:25 +02:00
|
|
|
EEVEE_lights_cache_shcaster_add(
|
|
|
|
|
sldata, stl, mat_geom[i], ob);
|
2018-05-01 19:32:24 +02:00
|
|
|
*cast_shadow = true;
|
2017-07-11 12:39:20 +02:00
|
|
|
break;
|
|
|
|
|
case MA_BS_CLIP:
|
|
|
|
|
gpumat = EEVEE_material_mesh_depth_get(scene, ma, false, true);
|
2018-05-26 10:41:25 +02:00
|
|
|
EEVEE_lights_cache_shcaster_material_add(
|
|
|
|
|
sldata, psl, gpumat, mat_geom[i], ob, &ma->alpha_threshold);
|
2018-05-01 19:32:24 +02:00
|
|
|
*cast_shadow = true;
|
2017-07-11 12:39:20 +02:00
|
|
|
break;
|
|
|
|
|
case MA_BS_HASHED:
|
|
|
|
|
gpumat = EEVEE_material_mesh_depth_get(scene, ma, true, true);
|
2018-05-26 10:41:25 +02:00
|
|
|
EEVEE_lights_cache_shcaster_material_add(
|
|
|
|
|
sldata, psl, gpumat, mat_geom[i], ob, NULL);
|
2018-05-01 19:32:24 +02:00
|
|
|
*cast_shadow = true;
|
2017-07-11 12:39:20 +02:00
|
|
|
break;
|
|
|
|
|
case MA_BS_NONE:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-07-11 01:10:57 +02:00
|
|
|
}
|
2017-07-11 12:39:20 +02:00
|
|
|
else {
|
2018-03-01 19:27:38 +01:00
|
|
|
EEVEE_lights_cache_shcaster_add(sldata, stl, mat_geom[i], ob);
|
2018-05-01 19:32:24 +02:00
|
|
|
*cast_shadow = true;
|
2017-07-11 01:10:57 +02:00
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-10-27 16:20:33 +02:00
|
|
|
|
|
|
|
|
/* Volumetrics */
|
2018-01-21 17:25:10 +01:00
|
|
|
if (((stl->effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_volume_material) {
|
2017-11-01 01:03:36 +01:00
|
|
|
EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
|
2017-10-27 16:20:33 +02:00
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
2018-06-02 12:06:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
2017-06-14 12:39:57 +02:00
|
|
|
|
|
|
|
|
if (ob->type == OB_MESH) {
|
2018-05-15 11:35:39 +02:00
|
|
|
if (ob != draw_ctx->object_edit) {
|
2017-06-14 12:39:57 +02:00
|
|
|
material_hash = stl->g_data->hair_material_hash;
|
2017-06-22 19:19:55 +02:00
|
|
|
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
|
2018-05-09 16:36:09 +02:00
|
|
|
if (md->type != eModifierType_ParticleSystem) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
|
|
|
|
|
if (!psys_check_enabled(ob, psys, false)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-05-15 11:35:39 +02:00
|
|
|
if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-05-09 16:36:09 +02:00
|
|
|
ParticleSettings *part = psys->part;
|
2018-05-15 11:35:39 +02:00
|
|
|
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
|
|
|
|
|
if (draw_as != PART_DRAW_PATH) {
|
2018-05-09 16:36:09 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2018-05-29 12:25:43 +02:00
|
|
|
|
2018-05-09 16:36:09 +02:00
|
|
|
DRWShadingGroup *shgrp = NULL;
|
|
|
|
|
Material *ma = give_current_material(ob, part->omat);
|
2017-06-14 12:39:57 +02:00
|
|
|
|
2018-05-09 16:36:09 +02:00
|
|
|
if (ma == NULL) {
|
|
|
|
|
ma = &defmaterial;
|
|
|
|
|
}
|
2017-06-14 12:39:57 +02:00
|
|
|
|
2018-05-09 16:36:09 +02:00
|
|
|
float *color_p = &ma->r;
|
2018-05-31 13:32:53 +02:00
|
|
|
float *metal_p = &ma->metallic;
|
2018-05-09 16:36:09 +02:00
|
|
|
float *spec_p = &ma->spec;
|
2018-05-31 13:32:53 +02:00
|
|
|
float *rough_p = &ma->roughness;
|
2017-06-14 12:39:57 +02:00
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
shgrp = DRW_shgroup_hair_create(
|
|
|
|
|
ob, psys, md,
|
|
|
|
|
psl->depth_pass, psl->hair_tf_pass,
|
|
|
|
|
e_data.default_hair_prepass_sh);
|
|
|
|
|
|
|
|
|
|
shgrp = DRW_shgroup_hair_create(
|
|
|
|
|
ob, psys, md,
|
|
|
|
|
psl->depth_pass_clip, psl->hair_tf_pass,
|
|
|
|
|
e_data.default_hair_prepass_clip_sh);
|
|
|
|
|
DRW_shgroup_uniform_block(shgrp, "clip_block", sldata->clip_ubo);
|
|
|
|
|
|
|
|
|
|
shgrp = NULL;
|
|
|
|
|
if (ma->use_nodes && ma->nodetree) {
|
|
|
|
|
static float half = 0.5f;
|
|
|
|
|
static float error_col[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
|
|
|
|
|
struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma, sldata->lamps->shadow_method);
|
|
|
|
|
|
|
|
|
|
switch (GPU_material_status(gpumat)) {
|
|
|
|
|
case GPU_MAT_SUCCESS:
|
|
|
|
|
{
|
|
|
|
|
shgrp = DRW_shgroup_material_hair_create(
|
|
|
|
|
ob, psys, md,
|
|
|
|
|
psl->material_pass, psl->hair_tf_pass,
|
|
|
|
|
gpumat);
|
|
|
|
|
add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false, false);
|
|
|
|
|
break;
|
2017-06-14 12:39:57 +02:00
|
|
|
}
|
2018-05-29 12:25:43 +02:00
|
|
|
case GPU_MAT_QUEUED:
|
|
|
|
|
{
|
|
|
|
|
sldata->probes->all_materials_updated = false;
|
|
|
|
|
color_p = compile_col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case GPU_MAT_FAILED:
|
|
|
|
|
default:
|
|
|
|
|
color_p = error_col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
break;
|
2017-06-14 12:39:57 +02:00
|
|
|
}
|
2018-05-29 12:25:43 +02:00
|
|
|
}
|
2018-05-09 16:36:09 +02:00
|
|
|
|
2018-05-29 12:25:43 +02:00
|
|
|
/* Fallback to default shader */
|
|
|
|
|
if (shgrp == NULL) {
|
|
|
|
|
bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
|
|
|
|
|
shgrp = EEVEE_default_shading_group_get(sldata, vedata,
|
|
|
|
|
ob, psys, md,
|
|
|
|
|
true, false, use_ssr,
|
|
|
|
|
sldata->lamps->shadow_method);
|
|
|
|
|
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
|
2017-06-14 12:39:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-05 22:05:21 +02:00
|
|
|
void EEVEE_materials_cache_finish(EEVEE_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
|
|
|
|
|
2018-05-25 08:06:36 +02:00
|
|
|
/* Look-Dev */
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
const View3D *v3d = draw_ctx->v3d;
|
2018-05-29 10:59:37 +02:00
|
|
|
if (LOOK_DEV_OVERLAY_ENABLED(v3d)) {
|
2018-05-25 08:06:36 +02:00
|
|
|
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
|
|
|
|
EEVEE_LampsInfo *linfo = sldata->lamps;
|
|
|
|
|
struct Gwn_Batch *sphere = DRW_cache_sphere_get();
|
|
|
|
|
static float mat1[4][4];
|
2018-05-28 19:35:08 +02:00
|
|
|
static float color[3] = {0.8f, 0.8f, 0.8f};
|
2018-05-25 08:06:36 +02:00
|
|
|
static float metallic_on = 1.0f;
|
|
|
|
|
static float metallic_off = 0.00f;
|
2018-05-28 19:35:08 +02:00
|
|
|
static float specular_off = 0.5f;
|
|
|
|
|
static float specular_on = 1.0f;
|
|
|
|
|
static float roughness_off = 0.05f;
|
|
|
|
|
static float roughness_on = 1.00f;
|
2018-05-25 08:06:36 +02:00
|
|
|
|
|
|
|
|
float view_mat[4][4];
|
|
|
|
|
DRW_viewport_matrix_get(view_mat, DRW_MAT_VIEWINV);
|
|
|
|
|
|
|
|
|
|
DRWShadingGroup *shgrp = EEVEE_lookdev_shading_group_get(sldata, vedata, false, linfo->shadow_method);
|
|
|
|
|
DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_on, 1);
|
2018-05-28 19:35:08 +02:00
|
|
|
DRW_shgroup_uniform_float(shgrp, "specular", &specular_on, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "roughness", &roughness_off, 1);
|
2018-05-25 08:06:36 +02:00
|
|
|
unit_m4(mat1);
|
|
|
|
|
mul_m4_m4m4(mat1, mat1, view_mat);
|
|
|
|
|
translate_m4(mat1, -1.5f, 0.0f, -5.0f);
|
|
|
|
|
DRW_shgroup_call_add(shgrp, sphere, mat1);
|
|
|
|
|
|
|
|
|
|
shgrp = EEVEE_lookdev_shading_group_get(sldata, vedata, false, linfo->shadow_method);
|
|
|
|
|
DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_off, 1);
|
2018-05-28 19:35:08 +02:00
|
|
|
DRW_shgroup_uniform_float(shgrp, "specular", &specular_off, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "roughness", &roughness_on, 1);
|
2018-05-25 08:06:36 +02:00
|
|
|
translate_m4(mat1, 3.0f, 0.0f, 0.0f);
|
|
|
|
|
DRW_shgroup_call_add(shgrp, sphere, mat1);
|
|
|
|
|
}
|
|
|
|
|
/* END */
|
|
|
|
|
|
2017-07-09 17:50:39 +02:00
|
|
|
BLI_ghash_free(stl->g_data->material_hash, NULL, MEM_freeN);
|
2017-06-14 12:39:57 +02:00
|
|
|
BLI_ghash_free(stl->g_data->hair_material_hash, NULL, NULL);
|
2017-06-05 22:05:21 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
void EEVEE_materials_free(void)
|
|
|
|
|
{
|
2017-06-22 02:41:17 +02:00
|
|
|
for (int i = 0; i < VAR_MAT_MAX; ++i) {
|
|
|
|
|
DRW_SHADER_FREE_SAFE(e_data.default_lit[i]);
|
|
|
|
|
}
|
2018-04-15 22:22:50 +02:00
|
|
|
MEM_SAFE_FREE(e_data.frag_shader_lib);
|
2018-05-29 12:25:43 +02:00
|
|
|
MEM_SAFE_FREE(e_data.vert_shader_str);
|
2017-07-03 22:08:07 +02:00
|
|
|
MEM_SAFE_FREE(e_data.volume_shader_lib);
|
2018-05-29 12:25:43 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_sh);
|
|
|
|
|
DRW_SHADER_FREE_SAFE(e_data.default_hair_prepass_clip_sh);
|
2017-06-16 23:50:40 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.default_prepass_sh);
|
|
|
|
|
DRW_SHADER_FREE_SAFE(e_data.default_prepass_clip_sh);
|
2017-06-04 12:12:58 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.default_background);
|
2018-05-25 08:06:36 +02:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.default_studiolight_background);
|
2018-01-17 14:02:48 +01:00
|
|
|
DRW_SHADER_FREE_SAFE(e_data.update_noise_sh);
|
2017-06-04 12:12:58 +02:00
|
|
|
DRW_TEXTURE_FREE_SAFE(e_data.util_tex);
|
2018-01-17 14:02:48 +01:00
|
|
|
DRW_TEXTURE_FREE_SAFE(e_data.noise_tex);
|
2017-06-14 12:39:57 +02:00
|
|
|
}
|
2017-06-22 02:41:17 +02:00
|
|
|
|
|
|
|
|
void EEVEE_draw_default_passes(EEVEE_PassList *psl)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < VAR_MAT_MAX; ++i) {
|
|
|
|
|
if (psl->default_pass[i]) {
|
|
|
|
|
DRW_draw_pass(psl->default_pass[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|