Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-10-27 23:35:48 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-10-27 23:49:15 +0300
commitbc7c0335dc7e1cae93c3f4b7bfdaa02f2cae6128 (patch)
treeb4572a93fbabe2956d14eec5f6dd69590bb53ac4 /source/blender
parent4f7665c84410e9e25360b0d80ce073c54242e5d4 (diff)
Eevee: Volumetrics: Support Smoke simulation textures.
It should behave like cycles. Even if not efficient at all, we still do the same create - draw - free process that was done in the old viewport to save vram (maybe not really the case now) and not care about simulation's GPU texture state sync.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c60
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h1
-rw-r--r--source/blender/gpu/GPU_material.h11
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c16
-rw-r--r--source/blender/gpu/intern/gpu_draw.c20
-rw-r--r--source/blender/gpu/intern/gpu_material.c2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl38
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_attribute.c19
9 files changed, 158 insertions, 11 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index d3c22ed29f4..f5e47cb0a9d 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -30,12 +30,15 @@
#include "DNA_anim_types.h"
#include "DNA_camera_types.h"
+#include "DNA_object_force.h"
#include "DNA_screen_types.h"
+#include "DNA_smoke_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "BKE_global.h" /* for G.debug_value */
#include "BKE_camera.h"
+#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_animsys.h"
@@ -49,6 +52,7 @@
#include "BLI_rand.h"
#include "eevee_private.h"
+#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_texture.h"
@@ -117,6 +121,9 @@ static struct {
struct GPUTexture *depth_src;
struct GPUTexture *color_src;
+ /* List of all smoke domains rendered within this frame. */
+ ListBase smoke_domains;
+
int depth_src_layer;
float cube_texel_size;
} e_data = {NULL}; /* Engine data */
@@ -265,6 +272,8 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
const float *viewport_size = DRW_viewport_size_get();
+ BLI_listbase_clear(&e_data.smoke_domains);
+
/* Shaders */
if (!e_data.motion_blur_sh) {
DynStr *ds_frag = BLI_dynstr_new();
@@ -721,11 +730,17 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
double ht_point[3];
double ht_offset[3] = {0.0, 0.0};
unsigned int ht_primes[3] = {3, 7, 2};
- struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
unsigned int current_sample = 0;
- if (((effects->enabled_effects & EFFECT_TAA) != 0) && (ED_screen_animation_no_scrub(wm) == NULL)) {
- /* If TAA is in use do not use the history buffer. */
+ /* If TAA is in use do not use the history buffer. */
+ bool do_taa = ((effects->enabled_effects & EFFECT_TAA) != 0);
+
+ if (draw_ctx->evil_C != NULL) {
+ struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
+ do_taa = do_taa && (ED_screen_animation_no_scrub(wm) == NULL);
+ }
+
+ if (do_taa) {
volumetrics->history_alpha = 0.0f;
current_sample = effects->taa_current_sample - 1;
effects->volume_current_sample = -1;
@@ -1043,6 +1058,7 @@ void EEVEE_effects_cache_volume_object_add(EEVEE_SceneLayerData *sldata, EEVEE_D
{
float *texcoloc = NULL;
float *texcosize = NULL;
+ struct ModifierData *md = NULL;
EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
Material *ma = give_current_material(ob, 1);
@@ -1069,6 +1085,34 @@ void EEVEE_effects_cache_volume_object_add(EEVEE_SceneLayerData *sldata, EEVEE_D
DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
}
+
+ /* Smoke Simulation */
+ if (((ob->base_flag & BASE_FROMDUPLI) == 0) &&
+ (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
+ (modifier_isEnabled(scene, md, eModifierMode_Realtime)))
+ {
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+ SmokeDomainSettings *sds = smd->domain;
+ /* Don't show smoke before simulation starts, this could be made an option in the future. */
+ const bool show_smoke = (CFRA >= sds->point_cache[0]->startframe);
+
+ if (sds->fluid && show_smoke) {
+ if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
+ GPU_create_smoke(smd, 0);
+ }
+ else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
+ GPU_create_smoke(smd, 1);
+ }
+ BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(smd));
+ }
+
+ if (sds->tex != NULL) {
+ DRW_shgroup_uniform_buffer(grp, "sampdensity", &sds->tex);
+ }
+ if (sds->tex_flame != NULL) {
+ DRW_shgroup_uniform_buffer(grp, "sampflame", &sds->tex_flame);
+ }
+ }
}
void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
@@ -1887,6 +1931,16 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
}
}
+void EEVEE_effects_free_smoke_texture(void)
+{
+ /* Free Smoke Textures after rendering */
+ for (LinkData *link = e_data.smoke_domains.first; link; link = link->next) {
+ SmokeModifierData *smd = (SmokeModifierData *)link->data;
+ GPU_free_smoke(smd);
+ }
+ BLI_freelistN(&e_data.smoke_domains);
+}
+
void EEVEE_effects_free(void)
{
MEM_SAFE_FREE(e_data.volumetric_common_lib);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 4617d44ef45..12e4c12b148 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -277,6 +277,8 @@ static void EEVEE_draw_scene(void *vedata)
}
}
+ EEVEE_effects_free_smoke_texture();
+
stl->g_data->view_updated = false;
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 20353fdc512..38d4a4b52e1 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -643,6 +643,7 @@ void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_do_refraction(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_do_gtao(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_draw_effects(EEVEE_Data *vedata);
+void EEVEE_effects_free_smoke_texture(void);
void EEVEE_effects_free(void);
/* Shadow Matrix */
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 1508941f706..de274b87f9e 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -82,11 +82,12 @@ typedef enum GPUType {
/* Values not in GPU_DATATYPE_STR */
GPU_TEX2D = 1002,
- GPU_SHADOW2D = 1003,
- GPU_TEXCUBE = 1004,
+ GPU_TEX3D = 1003,
+ GPU_SHADOW2D = 1004,
+ GPU_TEXCUBE = 1005,
/* GLSL Struct types */
- GPU_CLOSURE = 1005,
+ GPU_CLOSURE = 1006,
/* Opengl Attributes */
GPU_ATTRIB = 3001
@@ -108,7 +109,9 @@ typedef enum GPUBuiltin {
GPU_PARTICLE_ANG_VELOCITY = (1 << 12),
GPU_LOC_TO_VIEW_MATRIX = (1 << 13),
GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14),
- GPU_OBJECT_INFO = (1 << 15)
+ GPU_OBJECT_INFO = (1 << 15),
+ GPU_VOLUME_DENSITY = (1 << 16),
+ GPU_VOLUME_FLAME = (1 << 17)
} GPUBuiltin;
typedef enum GPUOpenGLBuiltin {
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index b5a7d751f2a..bc91df895c8 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -190,6 +190,9 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
if (!type && gpu_str_prefix(code, "sampler2D")) {
type = GPU_TEX2D;
}
+ if (!type && gpu_str_prefix(code, "sampler3D")) {
+ type = GPU_TEX3D;
+ }
if (!type && gpu_str_prefix(code, "Closure")) {
type = GPU_CLOSURE;
@@ -420,6 +423,10 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
return "unfparticleangvel";
else if (builtin == GPU_OBJECT_INFO)
return "unfobjectinfo";
+ else if (builtin == GPU_VOLUME_DENSITY)
+ return "sampdensity";
+ else if (builtin == GPU_VOLUME_FLAME)
+ return "sampflame";
else
return "";
}
@@ -537,7 +544,14 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
builtins |= input->builtin;
name = GPU_builtin_name(input->builtin);
- if (gpu_str_prefix(name, "unf")) {
+ if (gpu_str_prefix(name, "samp")) {
+ if ((input->builtin == GPU_VOLUME_DENSITY) ||
+ (input->builtin == GPU_VOLUME_FLAME))
+ {
+ BLI_dynstr_appendf(ds, "uniform sampler3D %s;\n", name);
+ }
+ }
+ else if (gpu_str_prefix(name, "unf")) {
BLI_dynstr_appendf(ds, "uniform %s %s;\n",
GPU_DATATYPE_STR[input->type], name);
}
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index cc6afe983ca..9f1fdcfe551 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -1259,6 +1259,16 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres)
else {
sds->tex = GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
GPU_R8, smoke_get_density(sds->fluid), NULL);
+
+ /* Swizzle the RGBA components to read the Red channel so
+ * that the shader stay the same for colored and non color
+ * density textures. */
+ GPU_texture_bind(sds->tex, 0);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_RED);
+ GPU_texture_unbind(sds->tex);
}
sds->tex_flame = (smoke_has_fuel(sds->fluid)) ?
GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
@@ -1277,6 +1287,16 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres)
else {
sds->tex = GPU_texture_create_3D_custom(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1,
GPU_R8, smoke_turbulence_get_density(sds->wt), NULL);
+
+ /* Swizzle the RGBA components to read the Red channel so
+ * that the shader stay the same for colored and non color
+ * density textures. */
+ GPU_texture_bind(sds->tex, 0);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_RED);
+ GPU_texture_unbind(sds->tex);
}
sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ?
GPU_texture_create_3D_custom(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1,
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 312cd7bc20a..cdd3f789cca 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -2401,6 +2401,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
break;
case GPU_NONE:
+ case GPU_TEX3D:
case GPU_TEXCUBE:
case GPU_FLOAT:
case GPU_VEC2:
@@ -2439,6 +2440,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
case GPU_NONE:
case GPU_CLOSURE:
case GPU_TEX2D:
+ case GPU_TEX3D:
case GPU_TEXCUBE:
case GPU_SHADOW2D:
case GPU_ATTRIB:
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 0dd8e6643b2..afb5eca5263 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -3093,11 +3093,47 @@ void node_gamma(vec4 col, float gamma, out vec4 outcol)
/* geometry */
+void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
+{
+#if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ outvec = texture(tex, cos).aaa;
+ outcol = vec4(outvec, 1.0);
+ outf = dot(vec3(1.0 / 3.0), outvec);
+}
+
+void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
+{
+#if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ outvec = texture(tex, cos).rgb;
+ outcol = vec4(outvec, 1.0);
+ outf = dot(vec3(1.0 / 3.0), outvec);
+}
+
+void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
+{
+#if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ outvec = texture(tex, cos).rrr;
+ outcol = vec4(outvec, 1.0);
+ outf = dot(vec3(1.0 / 3.0), outvec);
+}
+
void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
{
outcol = vec4(attr, 1.0);
outvec = attr;
- outf = (attr.x + attr.y + attr.z) / 3.0;
+ outf = dot(vec3(1.0 / 3.0), attr);
}
void node_uvmap(vec3 attr_uv, out vec3 outvec)
diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.c
index 3c9b21a4198..5f3699e52eb 100644
--- a/source/blender/nodes/shader/nodes/node_shader_attribute.c
+++ b/source/blender/nodes/shader/nodes/node_shader_attribute.c
@@ -45,9 +45,24 @@ static void node_shader_init_attribute(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_attribute(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
NodeShaderAttribute *attr = node->storage;
- GPUNodeLink *cd_attr = GPU_attribute(CD_AUTO_FROM_NAME, attr->name);
- return GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
+ /* FIXME : if an attribute layer (like vertex color) has one of theses name, it will not work as expected. */
+ if (strcmp(attr->name, "density") == 0) {
+ return GPU_stack_link(mat, node, "node_attribute_volume_density", in, out,
+ GPU_builtin(GPU_VOLUME_DENSITY));
+ }
+ else if (strcmp(attr->name, "color") == 0) {
+ return GPU_stack_link(mat, node, "node_attribute_volume_color", in, out,
+ GPU_builtin(GPU_VOLUME_DENSITY));
+ }
+ else if (strcmp(attr->name, "flame") == 0) {
+ return GPU_stack_link(mat, node, "node_attribute_volume_flame", in, out,
+ GPU_builtin(GPU_VOLUME_FLAME));
+ }
+ else {
+ GPUNodeLink *cd_attr = GPU_attribute(CD_AUTO_FROM_NAME, attr->name);
+ return GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
+ }
}
/* node type definition */