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 "DNA_world_types.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_dynstr.h"
|
2017-06-05 22:05:21 +02:00
|
|
|
#include "BLI_ghash.h"
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-14 12:39:57 +02:00
|
|
|
#include "BKE_particle.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"
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
#if defined(IRRADIANCE_SH_L2)
|
|
|
|
|
#define SHADER_IRRADIANCE "#define IRRADIANCE_SH_L2\n"
|
|
|
|
|
#elif defined(IRRADIANCE_CUBEMAP)
|
|
|
|
|
#define SHADER_IRRADIANCE "#define IRRADIANCE_CUBEMAP\n"
|
|
|
|
|
#elif defined(IRRADIANCE_HL2)
|
|
|
|
|
#define SHADER_IRRADIANCE "#define IRRADIANCE_HL2\n"
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
#define SHADER_DEFINES \
|
|
|
|
|
"#define EEVEE_ENGINE\n" \
|
2017-06-04 16:50:22 +02:00
|
|
|
"#define MAX_PROBE " STRINGIFY(MAX_PROBE) "\n" \
|
2017-06-13 17:39:39 +02:00
|
|
|
"#define MAX_GRID " STRINGIFY(MAX_GRID) "\n" \
|
2017-06-17 00:08:03 +02:00
|
|
|
"#define MAX_PLANAR " STRINGIFY(MAX_PLANAR) "\n" \
|
2017-06-04 12:12:58 +02:00
|
|
|
"#define MAX_LIGHT " STRINGIFY(MAX_LIGHT) "\n" \
|
|
|
|
|
"#define MAX_SHADOW_CUBE " STRINGIFY(MAX_SHADOW_CUBE) "\n" \
|
|
|
|
|
"#define MAX_SHADOW_MAP " STRINGIFY(MAX_SHADOW_MAP) "\n" \
|
|
|
|
|
"#define MAX_SHADOW_CASCADE " STRINGIFY(MAX_SHADOW_CASCADE) "\n" \
|
2017-06-22 02:41:17 +02:00
|
|
|
"#define MAX_CASCADE_NUM " STRINGIFY(MAX_CASCADE_NUM) "\n" \
|
|
|
|
|
SHADER_IRRADIANCE
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
/* *********** STATIC *********** */
|
|
|
|
|
static struct {
|
|
|
|
|
char *frag_shader_lib;
|
|
|
|
|
|
2017-06-16 23:50:40 +02:00
|
|
|
struct GPUShader *default_prepass_sh;
|
|
|
|
|
struct GPUShader *default_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;
|
|
|
|
|
|
|
|
|
|
/* 64*64 array texture containing all LUTs and other utilitarian arrays.
|
|
|
|
|
* Packing enables us to same precious textures slots. */
|
|
|
|
|
struct GPUTexture *util_tex;
|
2017-06-22 02:41:17 +02:00
|
|
|
|
|
|
|
|
float viewvecs[2][4];
|
2017-06-04 12:12:58 +02:00
|
|
|
} e_data = {NULL}; /* Engine data */
|
|
|
|
|
|
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[];
|
|
|
|
|
extern char datatoc_bsdf_common_lib_glsl[];
|
|
|
|
|
extern char datatoc_bsdf_direct_lib_glsl[];
|
|
|
|
|
extern char datatoc_bsdf_sampling_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[];
|
|
|
|
|
extern char datatoc_shadow_frag_glsl[];
|
|
|
|
|
extern char datatoc_shadow_geom_glsl[];
|
|
|
|
|
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[];
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
char *lib_str = NULL;
|
|
|
|
|
|
|
|
|
|
DynStr *ds_vert = BLI_dynstr_new();
|
|
|
|
|
BLI_dynstr_append(ds_vert, datatoc_bsdf_common_lib_glsl);
|
|
|
|
|
BLI_dynstr_append(ds_vert, datatoc_bsdf_sampling_lib_glsl);
|
|
|
|
|
lib_str = BLI_dynstr_get_cstring(ds_vert);
|
|
|
|
|
BLI_dynstr_free(ds_vert);
|
|
|
|
|
|
|
|
|
|
struct GPUShader *sh = DRW_shader_create_with_lib(
|
2017-06-12 20:59:54 +10: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"
|
|
|
|
|
"#define NOISE_SIZE 64\n");
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
tex = DRW_texture_create_2D(w, h, DRW_TEX_RG_16, DRW_TEX_FILTER, (float *)texels);
|
|
|
|
|
|
|
|
|
|
DRWFboTexture tex_filter = {&tex, DRW_TEX_RG_16, DRW_TEX_FILTER};
|
|
|
|
|
DRW_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 1);
|
|
|
|
|
|
|
|
|
|
DRW_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;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
static char *eevee_get_defines(int options)
|
|
|
|
|
{
|
|
|
|
|
char *str = NULL;
|
|
|
|
|
|
|
|
|
|
BLI_assert(options < VAR_MAT_MAX);
|
|
|
|
|
|
|
|
|
|
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_AO) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_AO\n");
|
|
|
|
|
}
|
|
|
|
|
if ((options & VAR_MAT_FLAT) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_FLAT_NORMAL\n");
|
|
|
|
|
}
|
|
|
|
|
if ((options & VAR_MAT_BENT) != 0) {
|
|
|
|
|
BLI_dynstr_appendf(ds, "#define USE_BENT_NORMAL\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
str = BLI_dynstr_get_cstring(ds);
|
|
|
|
|
BLI_dynstr_free(ds);
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
DRW_shgroup_uniform_int(shgrp, "light_count", &sldata->lamps->num_light, 1);
|
|
|
|
|
DRW_shgroup_uniform_int(shgrp, "probe_count", &sldata->probes->num_render_cube, 1);
|
|
|
|
|
DRW_shgroup_uniform_int(shgrp, "grid_count", &sldata->probes->num_render_grid, 1);
|
|
|
|
|
DRW_shgroup_uniform_int(shgrp, "planar_count", &sldata->probes->num_planar, 1);
|
|
|
|
|
DRW_shgroup_uniform_bool(shgrp, "specToggle", &sldata->probes->specular_toggle, 1);
|
|
|
|
|
DRW_shgroup_uniform_float(shgrp, "lodMax", &sldata->probes->lodmax, 1);
|
|
|
|
|
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
|
|
|
|
|
DRW_shgroup_uniform_buffer(shgrp, "probeCubes", &sldata->probe_pool);
|
|
|
|
|
DRW_shgroup_uniform_buffer(shgrp, "probePlanars", &vedata->txl->planar_pool);
|
|
|
|
|
DRW_shgroup_uniform_buffer(shgrp, "irradianceGrid", &sldata->irradiance_pool);
|
|
|
|
|
DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool);
|
|
|
|
|
DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool);
|
2017-06-22 03:10:39 +02:00
|
|
|
if (vedata->stl->effects->use_ao) {
|
2017-06-23 01:33:28 +02:00
|
|
|
DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)e_data.viewvecs, 2);
|
2017-06-22 03:10:39 +02:00
|
|
|
DRW_shgroup_uniform_buffer(shgrp, "minMaxDepthTex", &vedata->stl->g_data->minmaxz);
|
2017-06-23 04:12:46 +02:00
|
|
|
DRW_shgroup_uniform_vec3(shgrp, "aoParameters", &vedata->stl->effects->ao_dist, 1);
|
2017-06-22 03:10:39 +02:00
|
|
|
}
|
2017-06-22 02:41:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void create_default_shader(int options)
|
|
|
|
|
{
|
|
|
|
|
DynStr *ds_frag = BLI_dynstr_new();
|
|
|
|
|
BLI_dynstr_append(ds_frag, e_data.frag_shader_lib);
|
|
|
|
|
BLI_dynstr_append(ds_frag, datatoc_default_frag_glsl);
|
|
|
|
|
char *frag_str = BLI_dynstr_get_cstring(ds_frag);
|
|
|
|
|
BLI_dynstr_free(ds_frag);
|
|
|
|
|
|
|
|
|
|
char *defines = eevee_get_defines(options);
|
|
|
|
|
|
|
|
|
|
e_data.default_lit[options] = DRW_shader_create(datatoc_lit_surface_vert_glsl, NULL, frag_str, defines);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
|
|
|
|
MEM_freeN(frag_str);
|
|
|
|
|
}
|
2017-06-22 03:10:39 +02:00
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
void EEVEE_materials_init(void)
|
|
|
|
|
{
|
|
|
|
|
if (!e_data.frag_shader_lib) {
|
|
|
|
|
char *frag_str = NULL;
|
|
|
|
|
|
|
|
|
|
/* Shaders */
|
|
|
|
|
DynStr *ds_frag = BLI_dynstr_new();
|
|
|
|
|
BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
|
2017-06-22 03:10:39 +02:00
|
|
|
BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl);
|
2017-06-15 00:09:49 +02:00
|
|
|
BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
|
2017-06-14 11:09:13 +02:00
|
|
|
BLI_dynstr_append(ds_frag, datatoc_irradiance_lib_glsl);
|
2017-06-04 12:12:58 +02:00
|
|
|
BLI_dynstr_append(ds_frag, datatoc_ltc_lib_glsl);
|
|
|
|
|
BLI_dynstr_append(ds_frag, datatoc_bsdf_direct_lib_glsl);
|
|
|
|
|
BLI_dynstr_append(ds_frag, datatoc_lit_surface_frag_glsl);
|
|
|
|
|
e_data.frag_shader_lib = BLI_dynstr_get_cstring(ds_frag);
|
|
|
|
|
BLI_dynstr_free(ds_frag);
|
|
|
|
|
|
|
|
|
|
ds_frag = BLI_dynstr_new();
|
|
|
|
|
BLI_dynstr_append(ds_frag, e_data.frag_shader_lib);
|
|
|
|
|
BLI_dynstr_append(ds_frag, datatoc_default_frag_glsl);
|
|
|
|
|
frag_str = BLI_dynstr_get_cstring(ds_frag);
|
|
|
|
|
BLI_dynstr_free(ds_frag);
|
|
|
|
|
|
|
|
|
|
e_data.default_background = DRW_shader_create_fullscreen(
|
|
|
|
|
datatoc_default_world_frag_glsl, NULL);
|
|
|
|
|
|
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");
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
MEM_freeN(frag_str);
|
|
|
|
|
|
|
|
|
|
/* Textures */
|
|
|
|
|
const int layers = 3;
|
|
|
|
|
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++) {
|
|
|
|
|
texels_layer[i][0] = bsdf_split_sum_ggx[i*2 + 0];
|
|
|
|
|
texels_layer[i][1] = bsdf_split_sum_ggx[i*2 + 1];
|
|
|
|
|
texels_layer[i][2] = ltc_mag_ggx[i];
|
|
|
|
|
}
|
|
|
|
|
texels_layer += 64 * 64;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 64 * 64; i++) {
|
2017-06-04 21:45:41 +02:00
|
|
|
texels_layer[i][0] = blue_noise[i][0];
|
2017-06-22 03:10:39 +02:00
|
|
|
texels_layer[i][1] = blue_noise[i][1] * 0.5 + 0.5;
|
2017-06-04 21:45:41 +02:00
|
|
|
texels_layer[i][2] = blue_noise[i][2];
|
|
|
|
|
texels_layer[i][3] = blue_noise[i][3];
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-22 03:10:39 +02:00
|
|
|
e_data.util_tex = DRW_texture_create_2D_array(64, 64, layers, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels);
|
2017-06-04 12:12:58 +02:00
|
|
|
MEM_freeN(texels);
|
|
|
|
|
}
|
2017-06-22 03:10:39 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
/* Update viewvecs */
|
|
|
|
|
const bool is_persp = DRW_viewport_is_persp_get();
|
|
|
|
|
float invproj[4][4], winmat[4][4];
|
|
|
|
|
/* view vectors for the corners of the view frustum.
|
|
|
|
|
* Can be used to recreate the world space position easily */
|
|
|
|
|
float viewvecs[3][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}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* invert the view matrix */
|
|
|
|
|
DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
|
|
|
|
|
invert_m4_m4(invproj, winmat);
|
|
|
|
|
|
|
|
|
|
/* convert the view vectors to view space */
|
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
|
mul_m4_v4(invproj, viewvecs[i]);
|
|
|
|
|
/* normalized trick see:
|
|
|
|
|
* http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
|
|
|
|
|
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
|
|
|
|
|
if (is_persp)
|
|
|
|
|
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
|
|
|
|
|
viewvecs[i][3] = 1.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copy_v4_v4(e_data.viewvecs[0], viewvecs[0]);
|
|
|
|
|
copy_v4_v4(e_data.viewvecs[1], viewvecs[1]);
|
|
|
|
|
|
|
|
|
|
/* we need to store the differences */
|
|
|
|
|
e_data.viewvecs[1][0] -= viewvecs[0][0];
|
|
|
|
|
e_data.viewvecs[1][1] = viewvecs[2][1] - viewvecs[0][1];
|
|
|
|
|
|
|
|
|
|
/* calculate a depth offset as well */
|
|
|
|
|
if (!is_persp) {
|
|
|
|
|
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
|
|
|
|
|
mul_m4_v4(invproj, vec_far);
|
|
|
|
|
mul_v3_fl(vec_far, 1.0f / vec_far[3]);
|
|
|
|
|
e_data.viewvecs[1][2] = vec_far[2] - viewvecs[0][2];
|
|
|
|
|
}
|
|
|
|
|
}
|
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
|
|
|
{
|
|
|
|
|
return GPU_material_from_nodetree(
|
|
|
|
|
scene, wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type,
|
|
|
|
|
VAR_WORLD_PROBE,
|
2017-06-12 20:59:54 +10:00
|
|
|
datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, e_data.frag_shader_lib,
|
2017-06-04 12:12:58 +02:00
|
|
|
SHADER_DEFINES "#define PROBE_CAPTURE\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo)
|
|
|
|
|
{
|
|
|
|
|
return GPU_material_from_nodetree(
|
|
|
|
|
scene, wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type,
|
|
|
|
|
VAR_WORLD_BACKGROUND,
|
|
|
|
|
datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib,
|
|
|
|
|
SHADER_DEFINES "#define WORLD_BACKGROUND\n");
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *EEVEE_material_mesh_get(
|
|
|
|
|
struct Scene *scene, Material *ma,
|
|
|
|
|
bool use_ao, bool use_bent_normals)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *mat;
|
|
|
|
|
|
|
|
|
|
int options = VAR_MAT_MESH;
|
|
|
|
|
|
|
|
|
|
if (use_ao) options |= VAR_MAT_AO;
|
|
|
|
|
if (use_bent_normals) options |= VAR_MAT_BENT;
|
|
|
|
|
|
|
|
|
|
char *defines = eevee_get_defines(options);
|
|
|
|
|
|
|
|
|
|
mat = GPU_material_from_nodetree(
|
2017-06-04 12:12:58 +02:00
|
|
|
scene, ma->nodetree, &ma->gpumaterial, &DRW_engine_viewport_eevee_type,
|
2017-06-22 02:41:17 +02:00
|
|
|
options,
|
2017-06-04 12:12:58 +02:00
|
|
|
datatoc_lit_surface_vert_glsl, NULL, e_data.frag_shader_lib,
|
2017-06-22 02:41:17 +02:00
|
|
|
defines);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
|
|
|
|
|
|
|
|
|
return mat;
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *EEVEE_material_hair_get(
|
|
|
|
|
struct Scene *scene, Material *ma,
|
|
|
|
|
bool use_ao, bool use_bent_normals)
|
2017-06-14 12:39:57 +02:00
|
|
|
{
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *mat;
|
|
|
|
|
|
|
|
|
|
int options = VAR_MAT_MESH | VAR_MAT_HAIR;
|
|
|
|
|
|
|
|
|
|
if (use_ao) options |= VAR_MAT_AO;
|
|
|
|
|
if (use_bent_normals) options |= VAR_MAT_BENT;
|
|
|
|
|
|
|
|
|
|
char *defines = eevee_get_defines(options);
|
|
|
|
|
|
|
|
|
|
mat = GPU_material_from_nodetree(
|
2017-06-14 12:39:57 +02:00
|
|
|
scene, ma->nodetree, &ma->gpumaterial, &DRW_engine_viewport_eevee_type,
|
2017-06-22 02:41:17 +02:00
|
|
|
options,
|
2017-06-14 12:39:57 +02:00
|
|
|
datatoc_lit_surface_vert_glsl, NULL, e_data.frag_shader_lib,
|
2017-06-22 02:41:17 +02:00
|
|
|
defines);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(defines);
|
|
|
|
|
|
|
|
|
|
return mat;
|
2017-06-14 12:39:57 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-22 02:41:17 +02:00
|
|
|
static struct DRWShadingGroup *EEVEE_default_shading_group_get(
|
|
|
|
|
EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata,
|
|
|
|
|
bool is_hair, bool is_flat_normal, bool use_ao, bool use_bent_normals)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
2017-06-22 02:41:17 +02:00
|
|
|
int options = VAR_MAT_MESH;
|
|
|
|
|
|
|
|
|
|
if (is_hair) options |= VAR_MAT_HAIR;
|
|
|
|
|
if (use_ao) options |= VAR_MAT_AO;
|
|
|
|
|
if (use_bent_normals) options |= VAR_MAT_BENT;
|
|
|
|
|
if (is_flat_normal) options |= VAR_MAT_FLAT;
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
|
|
|
|
add_standard_uniforms(shgrp, sldata, vedata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EEVEE_materials_cache_init(EEVEE_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
2017-06-22 02:41:17 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
/* Global AO Switch*/
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
SceneLayer *scene_layer = draw_ctx->sl;
|
|
|
|
|
IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
|
|
|
|
|
stl->effects->use_ao = BKE_collection_engine_property_value_get_bool(props, "gtao_enable");
|
|
|
|
|
stl->effects->use_bent_normals = BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals");
|
|
|
|
|
}
|
2017-06-04 12:12:58 +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
|
|
|
{
|
|
|
|
|
psl->background_pass = DRW_pass_create("Background Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR);
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (wo) {
|
|
|
|
|
col = &wo->horr;
|
|
|
|
|
|
|
|
|
|
if (wo->use_nodes && wo->nodetree) {
|
|
|
|
|
struct GPUMaterial *gpumat = EEVEE_material_world_background_get(scene, wo);
|
|
|
|
|
grp = DRW_shgroup_material_create(gpumat, psl->background_pass);
|
|
|
|
|
|
|
|
|
|
if (grp) {
|
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);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Shader failed : pink background */
|
|
|
|
|
static float pink[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
col = pink;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2017-06-14 12:39:57 +02:00
|
|
|
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | 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
|
|
|
|
|
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK;
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
|
|
|
|
|
psl->depth_pass_clip_cull = DRW_pass_create("Depth Pass Cull Clip", state);
|
|
|
|
|
stl->g_data->depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->depth_pass_clip_cull);
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
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-04 12:12:58 +02:00
|
|
|
psl->material_pass = DRW_pass_create("Material Shader Pass", state);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-04 16:50:22 +02:00
|
|
|
#define ADD_SHGROUP_CALL(shgrp, ob, geom) do { \
|
2017-06-04 12:12:58 +02:00
|
|
|
if (is_sculpt_mode) { \
|
|
|
|
|
DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat); \
|
|
|
|
|
} \
|
|
|
|
|
else { \
|
|
|
|
|
DRW_shgroup_call_object_add(shgrp, geom, ob); \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2017-06-19 20:18:04 +10:00
|
|
|
void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sldata, Object *ob, struct Gwn_Batch *geom)
|
2017-06-04 12:12:58 +02:00
|
|
|
{
|
|
|
|
|
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
2017-06-05 22:05:21 +02:00
|
|
|
GHash *material_hash = stl->g_data->material_hash;
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
|
|
|
|
|
const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
|
|
|
|
|
const bool is_active = (ob == draw_ctx->obact);
|
|
|
|
|
const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0;
|
|
|
|
|
const bool is_default_mode_shader = is_sculpt_mode;
|
|
|
|
|
|
|
|
|
|
/* Depth Prepass */
|
|
|
|
|
DRWShadingGroup *depth_shgrp = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
|
2017-06-16 23:50:40 +02:00
|
|
|
DRWShadingGroup *depth_clip_shgrp = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
|
2017-06-04 16:50:22 +02:00
|
|
|
ADD_SHGROUP_CALL(depth_shgrp, ob, geom);
|
2017-06-16 23:50:40 +02:00
|
|
|
ADD_SHGROUP_CALL(depth_clip_shgrp, ob, geom);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
/* Get per-material split surface */
|
2017-06-19 20:18:04 +10:00
|
|
|
struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob);
|
2017-06-04 12:12:58 +02:00
|
|
|
if (mat_geom) {
|
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) {
|
|
|
|
|
if (is_sculpt_mode) {
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < MAX2(1, (is_sculpt_mode ? 1 : ob->totcol)); ++i) {
|
|
|
|
|
DRWShadingGroup *shgrp = NULL;
|
|
|
|
|
Material *ma = give_current_material(ob, i + 1);
|
|
|
|
|
|
|
|
|
|
if (ma == NULL)
|
|
|
|
|
ma = &defmaterial;
|
|
|
|
|
|
|
|
|
|
float *color_p = &ma->r;
|
|
|
|
|
float *metal_p = &ma->ray_mirror;
|
|
|
|
|
float *spec_p = &ma->spec;
|
|
|
|
|
float *rough_p = &ma->gloss_mir;
|
|
|
|
|
|
2017-06-05 22:05:21 +02:00
|
|
|
shgrp = BLI_ghash_lookup(material_hash, (const void *)ma);
|
|
|
|
|
if (shgrp) {
|
|
|
|
|
ADD_SHGROUP_CALL(shgrp, ob, mat_geom[i]);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-04 12:12:58 +02:00
|
|
|
if (ma->use_nodes && ma->nodetree) {
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *gpumat = EEVEE_material_mesh_get(scene, ma,
|
|
|
|
|
stl->effects->use_ao, stl->effects->use_bent_normals);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
|
|
|
|
shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
|
|
|
|
|
if (shgrp) {
|
2017-06-17 00:08:03 +02:00
|
|
|
add_standard_uniforms(shgrp, sldata, vedata);
|
2017-06-04 12:12:58 +02:00
|
|
|
|
2017-06-05 22:05:21 +02:00
|
|
|
BLI_ghash_insert(material_hash, ma, shgrp);
|
|
|
|
|
|
2017-06-04 16:50:22 +02:00
|
|
|
ADD_SHGROUP_CALL(shgrp, ob, mat_geom[i]);
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Shader failed : pink color */
|
|
|
|
|
static float col[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
static float half = 0.5f;
|
|
|
|
|
|
|
|
|
|
color_p = col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fallback to default shader */
|
|
|
|
|
if (shgrp == NULL) {
|
2017-06-22 02:41:17 +02:00
|
|
|
shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor,
|
|
|
|
|
stl->effects->use_ao, stl->effects->use_bent_normals);
|
2017-06-04 12:12:58 +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-06-05 22:05:21 +02:00
|
|
|
BLI_ghash_insert(material_hash, ma, shgrp);
|
|
|
|
|
|
2017-06-04 16:50:22 +02:00
|
|
|
ADD_SHGROUP_CALL(shgrp, ob, mat_geom[i]);
|
2017-06-04 12:12:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-14 12:39:57 +02:00
|
|
|
|
|
|
|
|
if (ob->type == OB_MESH) {
|
|
|
|
|
if (ob != draw_ctx->scene->obedit) {
|
|
|
|
|
material_hash = stl->g_data->hair_material_hash;
|
|
|
|
|
|
|
|
|
|
for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
|
|
|
|
|
if (psys_check_enabled(ob, psys, false)) {
|
|
|
|
|
ParticleSettings *part = psys->part;
|
|
|
|
|
int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
|
|
|
|
|
|
|
|
|
|
if (draw_as == PART_DRAW_PATH && (psys->pathcache || psys->childcache)) {
|
2017-06-19 20:18:04 +10:00
|
|
|
struct Gwn_Batch *hair_geom = DRW_cache_particles_get_hair(psys);
|
2017-06-14 12:39:57 +02:00
|
|
|
DRWShadingGroup *shgrp = NULL;
|
|
|
|
|
Material *ma = give_current_material(ob, part->omat);
|
|
|
|
|
static float mat[4][4];
|
|
|
|
|
|
|
|
|
|
unit_m4(mat);
|
|
|
|
|
|
|
|
|
|
if (ma == NULL) {
|
|
|
|
|
ma = &defmaterial;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float *color_p = &ma->r;
|
|
|
|
|
float *metal_p = &ma->ray_mirror;
|
|
|
|
|
float *spec_p = &ma->spec;
|
|
|
|
|
float *rough_p = &ma->gloss_mir;
|
|
|
|
|
|
|
|
|
|
DRW_shgroup_call_add(stl->g_data->depth_shgrp, hair_geom, mat);
|
2017-06-16 23:50:40 +02:00
|
|
|
DRW_shgroup_call_add(stl->g_data->depth_shgrp_clip, hair_geom, mat);
|
2017-06-14 12:39:57 +02:00
|
|
|
|
|
|
|
|
shgrp = BLI_ghash_lookup(material_hash, (const void *)ma);
|
|
|
|
|
|
|
|
|
|
if (shgrp) {
|
|
|
|
|
DRW_shgroup_call_add(shgrp, hair_geom, mat);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (ma->use_nodes && ma->nodetree) {
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
2017-06-22 02:41:17 +02:00
|
|
|
struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma,
|
|
|
|
|
stl->effects->use_ao, stl->effects->use_bent_normals);
|
2017-06-14 12:39:57 +02:00
|
|
|
|
|
|
|
|
shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
|
|
|
|
|
if (shgrp) {
|
2017-06-17 00:08:03 +02:00
|
|
|
add_standard_uniforms(shgrp, sldata, vedata);
|
2017-06-14 12:39:57 +02:00
|
|
|
|
|
|
|
|
BLI_ghash_insert(material_hash, ma, shgrp);
|
|
|
|
|
|
|
|
|
|
DRW_shgroup_call_add(shgrp, hair_geom, mat);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Shader failed : pink color */
|
|
|
|
|
static float col[3] = {1.0f, 0.0f, 1.0f};
|
|
|
|
|
static float half = 0.5f;
|
|
|
|
|
|
|
|
|
|
color_p = col;
|
|
|
|
|
metal_p = spec_p = rough_p = ½
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fallback to default shader */
|
|
|
|
|
if (shgrp == NULL) {
|
2017-06-22 02:41:17 +02:00
|
|
|
shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false,
|
|
|
|
|
stl->effects->use_ao, stl->effects->use_bent_normals);
|
2017-06-14 12:39:57 +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);
|
|
|
|
|
|
|
|
|
|
BLI_ghash_insert(material_hash, ma, shgrp);
|
|
|
|
|
|
|
|
|
|
DRW_shgroup_call_add(shgrp, hair_geom, mat);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
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;
|
|
|
|
|
|
|
|
|
|
BLI_ghash_free(stl->g_data->material_hash, NULL, NULL);
|
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]);
|
|
|
|
|
}
|
2017-06-04 12:12:58 +02:00
|
|
|
MEM_SAFE_FREE(e_data.frag_shader_lib);
|
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);
|
|
|
|
|
DRW_TEXTURE_FREE_SAFE(e_data.util_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]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|