diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-10-27 17:20:33 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-10-27 23:49:15 +0300 |
commit | 4f7665c84410e9e25360b0d80ce073c54242e5d4 (patch) | |
tree | 58b248d3fd41d1312e6f7bfd455cb583f251137b /source/blender/draw/engines/eevee/eevee_materials.c | |
parent | 18ba7e26ad445981fb2750ec4bef1273f11d1554 (diff) |
Eevee: Volumetrics: Add Volume object support.
This is quite basic as it only support boundbing boxes.
But the material can refine the volume shape in anyway the user like.
To overcome this limitation, a voxelisation should be done on the mesh (generating a SDF maybe?) and tested against every volumetric cell.
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_materials.c')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_materials.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index f5d3898d1bc..1d551796a60 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -318,7 +318,7 @@ static char *eevee_get_defines(int options) return str; } -static char *eevee_get_volume_defines(int UNUSED(options)) +static char *eevee_get_volume_defines(int options) { char *str = NULL; @@ -326,6 +326,10 @@ static char *eevee_get_volume_defines(int UNUSED(options)) BLI_dynstr_appendf(ds, SHADER_DEFINES); BLI_dynstr_appendf(ds, "#define VOLUMETRICS\n"); + if ((options & VAR_MAT_VOLUME) != 0) { + BLI_dynstr_appendf(ds, "#define MESH_SHADER\n"); + } + str = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); @@ -656,6 +660,28 @@ struct GPUMaterial *EEVEE_material_mesh_get( return mat; } +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; + + GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options); + if (mat != NULL) { + return mat; + } + + char *defines = eevee_get_volume_defines(options); + + mat = GPU_material_from_nodetree( + scene, ma->nodetree, &ma->gpumaterial, engine, options, + datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib, + defines); + + MEM_freeN(defines); + + return mat; +} + struct GPUMaterial *EEVEE_material_mesh_depth_get( struct Scene *scene, Material *ma, bool use_hashed_alpha, bool is_shadow) @@ -1200,6 +1226,12 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl DRW_cache_mesh_sculpt_coords_ensure(ob); } + /* 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])); + /* Get per-material split surface */ struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len); if (mat_geom) { @@ -1209,6 +1241,14 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl if (ma == NULL) ma = &defmaterial; + /* Do not render surface if we are rendering a volume object + * and do not have a surface closure. */ + if (use_volume_material && + (gpumat_array[i] && !GPU_material_use_domain_surface(gpumat_array[i]))) + { + continue; + } + /* Shading pass */ ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]); @@ -1241,6 +1281,11 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl } } } + + /* Volumetrics */ + if (vedata->stl->effects->use_volumetrics && use_volume_material) { + EEVEE_effects_cache_volume_object_add(sldata, vedata, scene, ob); + } } if (ob->type == OB_MESH) { |