diff options
Diffstat (limited to 'source/blender/draw/engines/eevee')
10 files changed, 136 insertions, 14 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index c6436d5b923..37b33e21021 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -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); diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index bd6c4b9ccc0..ab56b908416 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -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); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 5e0d3ea177b..eb420e2a8c7 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -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); diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 5aac853da00..ceed99a7b80 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -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 diff --git a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl index f921d56e3bc..cf59b29548a 100644 --- a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl @@ -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 } diff --git a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl index 3fc3c146c66..df6fbc4c2fe 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl @@ -1,6 +1,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; + mat4 FaceViewMatrix[6]; vec4 lampPosition; int layer; float exponent; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl index afc78c4a8f8..d9d30c4d9e6 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl @@ -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(); } diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl index 40b980b3904..6782922a2e4 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl @@ -1,6 +1,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; + mat4 FaceViewMatrix[6]; vec4 lampPosition; int layer; float exponent; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl index 1d456095e02..78ccb025ce6 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl @@ -1,6 +1,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; + mat4 FaceViewMatrix[6]; vec4 lampPosition; int layer; float exponent; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl index 288098ba771..777902ccba8 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl @@ -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; -}
\ No newline at end of file + +#ifdef MESH_SHADER + vNor = WorldNormalMatrix * nor; +#ifdef ATTRIB + pass_attrib(pos); +#endif +#endif +} |