Eevee: Transparency: Add support for Clip and Stochastic shadows.
This commit is contained in:
parent
a57bc75576
commit
91d324b3dc
|
@ -196,6 +196,30 @@ void EEVEE_lights_cache_shcaster_add(EEVEE_SceneLayerData *sldata, EEVEE_PassLis
|
|||
DRW_shgroup_call_dynamic_add_empty(grp);
|
||||
}
|
||||
|
||||
void EEVEE_lights_cache_shcaster_material_add(
|
||||
EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, struct GPUMaterial *gpumat, struct Gwn_Batch *geom, float (*obmat)[4], float *alpha_threshold)
|
||||
{
|
||||
DRWShadingGroup *grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cube_pass, geom);
|
||||
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
|
||||
DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
|
||||
|
||||
if (alpha_threshold != NULL)
|
||||
DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
DRW_shgroup_call_dynamic_add_empty(grp);
|
||||
|
||||
grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cascade_pass, geom);
|
||||
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
|
||||
DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
|
||||
|
||||
if (alpha_threshold != NULL)
|
||||
DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
|
||||
|
||||
for (int i = 0; i < MAX_CASCADE_NUM; ++i)
|
||||
DRW_shgroup_call_dynamic_add_empty(grp);
|
||||
}
|
||||
|
||||
void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
|
||||
{
|
||||
EEVEE_LampsInfo *linfo = sldata->lamps;
|
||||
|
@ -727,6 +751,12 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
|
|||
srd->exponent = la->bleedexp;
|
||||
copy_v3_v3(srd->position, ob->obmat[3]);
|
||||
for (int j = 0; j < 6; ++j) {
|
||||
float tmp[4][4];
|
||||
|
||||
unit_m4(tmp);
|
||||
negate_v3_v3(tmp[3], ob->obmat[3]);
|
||||
mul_m4_m4m4(srd->viewmat[j], cubefacemat[i], tmp);
|
||||
|
||||
copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]);
|
||||
}
|
||||
DRW_uniformbuffer_update(sldata->shadow_render_ubo, &linfo->shadow_render_data);
|
||||
|
|
|
@ -94,9 +94,8 @@ extern char datatoc_irradiance_lib_glsl[];
|
|||
extern char datatoc_octahedron_lib_glsl[];
|
||||
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[];
|
||||
extern char datatoc_shadow_geom_glsl[];
|
||||
extern char datatoc_lightprobe_geom_glsl[];
|
||||
extern char datatoc_lightprobe_vert_glsl[];
|
||||
extern char datatoc_background_vert_glsl[];
|
||||
|
@ -203,6 +202,9 @@ static char *eevee_get_defines(int options)
|
|||
if ((options & VAR_MAT_CLIP) != 0) {
|
||||
BLI_dynstr_appendf(ds, "#define USE_ALPHA_CLIP\n");
|
||||
}
|
||||
if ((options & VAR_MAT_SHADOW) != 0) {
|
||||
BLI_dynstr_appendf(ds, "#define SHADOW_SHADER\n");
|
||||
}
|
||||
if ((options & VAR_MAT_HASH) != 0) {
|
||||
BLI_dynstr_appendf(ds, "#define USE_ALPHA_HASH\n");
|
||||
}
|
||||
|
@ -503,7 +505,9 @@ struct GPUMaterial *EEVEE_material_mesh_get(
|
|||
return mat;
|
||||
}
|
||||
|
||||
struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha)
|
||||
struct GPUMaterial *EEVEE_material_mesh_depth_get(
|
||||
struct Scene *scene, Material *ma,
|
||||
bool use_hashed_alpha, bool is_shadow)
|
||||
{
|
||||
const void *engine = &DRW_engine_viewport_eevee_type;
|
||||
int options = VAR_MAT_MESH;
|
||||
|
@ -515,6 +519,9 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material
|
|||
options |= VAR_MAT_CLIP;
|
||||
}
|
||||
|
||||
if (is_shadow)
|
||||
options |= VAR_MAT_SHADOW;
|
||||
|
||||
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
|
||||
if (mat) {
|
||||
return mat;
|
||||
|
@ -530,7 +537,9 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material
|
|||
|
||||
mat = GPU_material_from_nodetree(
|
||||
scene, ma->nodetree, &ma->gpumaterial, engine, options,
|
||||
datatoc_lit_surface_vert_glsl, NULL, frag_str,
|
||||
(is_shadow) ? datatoc_shadow_vert_glsl : datatoc_lit_surface_vert_glsl,
|
||||
(is_shadow) ? datatoc_shadow_geom_glsl : NULL,
|
||||
frag_str,
|
||||
defines);
|
||||
|
||||
MEM_freeN(frag_str);
|
||||
|
@ -758,7 +767,7 @@ static void material_opaque(
|
|||
*gpumat = (use_gpumat) ? EEVEE_material_mesh_get(
|
||||
scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false) : NULL;
|
||||
*gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get(
|
||||
scene, ma, (ma->blend_method == MA_BM_HASHED)) : NULL;
|
||||
scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -784,7 +793,7 @@ static void material_opaque(
|
|||
* fail the depth test for shading. */
|
||||
if (ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED)) {
|
||||
*gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma,
|
||||
(ma->blend_method == MA_BM_HASHED));
|
||||
(ma->blend_method == MA_BM_HASHED), false);
|
||||
|
||||
*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);
|
||||
|
@ -911,6 +920,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
|
|||
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
||||
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = draw_ctx->scene;
|
||||
GHash *material_hash = stl->g_data->material_hash;
|
||||
|
||||
IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
|
||||
|
@ -974,6 +984,11 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
|
|||
struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
|
||||
if (mat_geom) {
|
||||
for (int i = 0; i < materials_len; ++i) {
|
||||
Material *ma = give_current_material(ob, i + 1);
|
||||
|
||||
if (ma == NULL)
|
||||
ma = &defmaterial;
|
||||
|
||||
/* Shading pass */
|
||||
ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]);
|
||||
|
||||
|
@ -982,7 +997,16 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
|
|||
ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i]);
|
||||
|
||||
/* Shadow Pass */
|
||||
EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat);
|
||||
if (ma->blend_method == MA_BM_SOLID)
|
||||
EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat);
|
||||
else if (ma->blend_method == MA_BM_HASHED) {
|
||||
struct GPUMaterial *gpumat = EEVEE_material_mesh_depth_get(scene, ma, true, true);
|
||||
EEVEE_lights_cache_shcaster_material_add(sldata, psl, gpumat, mat_geom[i], ob->obmat, NULL);
|
||||
}
|
||||
else if (ma->blend_method == MA_BM_CLIP) {
|
||||
struct GPUMaterial *gpumat = EEVEE_material_mesh_depth_get(scene, ma, false, true);
|
||||
EEVEE_lights_cache_shcaster_material_add(sldata, psl, gpumat, mat_geom[i], ob->obmat, &ma->alpha_threshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1026,7 +1050,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
|
|||
}
|
||||
else {
|
||||
if (ma->use_nodes && ma->nodetree) {
|
||||
Scene *scene = draw_ctx->scene;
|
||||
struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma,
|
||||
stl->effects->use_ao, stl->effects->use_bent_normals);
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ enum {
|
|||
VAR_MAT_CLIP = (1 << 8),
|
||||
VAR_MAT_HASH = (1 << 9),
|
||||
VAR_MAT_MULT = (1 << 10),
|
||||
VAR_MAT_SHADOW = (1 << 11),
|
||||
};
|
||||
|
||||
typedef struct EEVEE_PassList {
|
||||
|
@ -187,6 +188,7 @@ typedef struct EEVEE_ShadowCascade {
|
|||
|
||||
typedef struct EEVEE_ShadowRender {
|
||||
float shadowmat[6][4][4]; /* World->Lamp->NDC : used to render the shadow map. 6 frustrum for cubemap shadow */
|
||||
float viewmat[6][4][4]; /* World->Lamp : used to render the shadow map. 6 viewmat for cubemap shadow */
|
||||
float position[3];
|
||||
float pad;
|
||||
int layer;
|
||||
|
@ -453,7 +455,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(
|
|||
struct Scene *scene, struct World *wo, bool use_lights, bool use_volume_shadows, bool is_homogeneous, bool use_color_transmit);
|
||||
struct GPUMaterial *EEVEE_material_mesh_get(
|
||||
struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals, bool use_blend, bool use_multiply);
|
||||
struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha);
|
||||
struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha, bool is_shadow);
|
||||
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals);
|
||||
void EEVEE_materials_free(void);
|
||||
void EEVEE_draw_default_passes(EEVEE_PassList *psl);
|
||||
|
@ -463,6 +465,9 @@ void EEVEE_lights_init(EEVEE_SceneLayerData *sldata);
|
|||
void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
|
||||
void EEVEE_lights_cache_add(EEVEE_SceneLayerData *sldata, struct Object *ob);
|
||||
void EEVEE_lights_cache_shcaster_add(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, struct Gwn_Batch *geom, float (*obmat)[4]);
|
||||
void EEVEE_lights_cache_shcaster_material_add(
|
||||
EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl,
|
||||
struct GPUMaterial *gpumat, struct Gwn_Batch *geom, float (*obmat)[4], float *alpha_threshold);
|
||||
void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata);
|
||||
void EEVEE_lights_update(EEVEE_SceneLayerData *sldata);
|
||||
void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
|
||||
|
|
|
@ -10,12 +10,26 @@
|
|||
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrixInverse;
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform vec4 viewvecs[2];
|
||||
#ifndef SHADOW_SHADER
|
||||
uniform mat4 ViewMatrix;
|
||||
#else
|
||||
layout(std140) uniform shadow_render_block {
|
||||
mat4 ShadowMatrix[6];
|
||||
mat4 FaceViewMatrix[6];
|
||||
vec4 lampPosition;
|
||||
int layer;
|
||||
float exponent;
|
||||
};
|
||||
|
||||
flat in int shFace; /* Shadow layer we are rendering to. */
|
||||
#define ViewMatrix FaceViewMatrix[shFace]
|
||||
#endif
|
||||
|
||||
#define cameraForward normalize(ViewMatrixInverse[2].xyz)
|
||||
#define cameraPos ViewMatrixInverse[3].xyz
|
||||
|
||||
|
||||
/* ------- Structures -------- */
|
||||
#ifdef VOLUMETRICS
|
||||
|
||||
|
|
|
@ -62,6 +62,10 @@ float hashed_alpha_threshold(vec3 co)
|
|||
uniform float alphaThreshold;
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_SHADER
|
||||
out vec4 FragColor;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
/* For now do nothing.
|
||||
|
@ -82,4 +86,9 @@ void main()
|
|||
discard;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_SHADER
|
||||
float dist = distance(lampPosition.xyz, worldPosition.xyz);
|
||||
FragColor = vec4(dist, 0.0, 0.0, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
layout(std140) uniform shadow_render_block {
|
||||
mat4 ShadowMatrix[6];
|
||||
mat4 FaceViewMatrix[6];
|
||||
vec4 lampPosition;
|
||||
int layer;
|
||||
float exponent;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
layout(std140) uniform shadow_render_block {
|
||||
mat4 ShadowMatrix[6];
|
||||
mat4 FaceViewMatrix[6];
|
||||
vec4 lampPosition;
|
||||
int layer;
|
||||
float exponent;
|
||||
|
@ -12,15 +13,36 @@ layout(triangle_strip, max_vertices=3) out;
|
|||
in vec4 vPos[];
|
||||
flat in int face[];
|
||||
|
||||
#ifdef MESH_SHADER
|
||||
in vec3 vNor[];
|
||||
in vec3 vNor[];
|
||||
#endif
|
||||
|
||||
out vec3 worldPosition;
|
||||
#ifdef MESH_SHADER
|
||||
out vec3 viewPosition; /* Required. otherwise generate linking error. */
|
||||
out vec3 worldNormal; /* Required. otherwise generate linking error. */
|
||||
out vec3 viewNormal; /* Required. otherwise generate linking error. */
|
||||
flat out int shFace;
|
||||
#else
|
||||
int shFace;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
int f = face[0];
|
||||
gl_Layer = f;
|
||||
shFace = face[0];
|
||||
gl_Layer = shFace;
|
||||
|
||||
for (int v = 0; v < 3; ++v) {
|
||||
gl_Position = ShadowMatrix[f] * vPos[v];
|
||||
gl_Position = ShadowMatrix[shFace] * vPos[v];
|
||||
worldPosition = vPos[v].xyz;
|
||||
#ifdef MESH_SHADER
|
||||
worldNormal = vNor[v];
|
||||
viewPosition = (FaceViewMatrix[shFace] * vec4(worldPosition, 1.0)).xyz;
|
||||
viewNormal = (FaceViewMatrix[shFace] * vec4(worldNormal, 0.0)).xyz;
|
||||
#ifdef ATTRIB
|
||||
pass_attrib(v);
|
||||
#endif
|
||||
#endif
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
layout(std140) uniform shadow_render_block {
|
||||
mat4 ShadowMatrix[6];
|
||||
mat4 FaceViewMatrix[6];
|
||||
vec4 lampPosition;
|
||||
int layer;
|
||||
float exponent;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
layout(std140) uniform shadow_render_block {
|
||||
mat4 ShadowMatrix[6];
|
||||
mat4 FaceViewMatrix[6];
|
||||
vec4 lampPosition;
|
||||
int layer;
|
||||
float exponent;
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
|
||||
uniform mat4 ShadowModelMatrix;
|
||||
#ifdef MESH_SHADER
|
||||
uniform mat3 WorldNormalMatrix;
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
#ifdef MESH_SHADER
|
||||
in vec3 nor;
|
||||
#endif
|
||||
|
||||
out vec4 vPos;
|
||||
#ifdef MESH_SHADER
|
||||
out vec3 vNor;
|
||||
#endif
|
||||
|
||||
flat out int face;
|
||||
|
||||
void main() {
|
||||
vPos = ShadowModelMatrix * vec4(pos, 1.0);
|
||||
face = gl_InstanceID;
|
||||
}
|
||||
|
||||
#ifdef MESH_SHADER
|
||||
vNor = WorldNormalMatrix * nor;
|
||||
#ifdef ATTRIB
|
||||
pass_attrib(pos);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue