From bc7c0335dc7e1cae93c3f4b7bfdaa02f2cae6128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Oct 2017 22:35:48 +0200 Subject: 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. --- source/blender/gpu/GPU_material.h | 11 ++++--- source/blender/gpu/intern/gpu_codegen.c | 16 ++++++++- source/blender/gpu/intern/gpu_draw.c | 20 ++++++++++++ source/blender/gpu/intern/gpu_material.c | 2 ++ .../blender/gpu/shaders/gpu_shader_material.glsl | 38 +++++++++++++++++++++- 5 files changed, 81 insertions(+), 6 deletions(-) (limited to 'source/blender/gpu') 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) -- cgit v1.2.3