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:
authorBrecht Van Lommel <brecht>2020-03-11 15:56:28 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-03-11 16:42:46 +0300
commitc8acb6dd6c58c6a85ab18d26f02973437cb2f700 (patch)
treec45a1b47d8692b7b633507d97f325fa5c2f5a3c8 /source/blender/gpu
parentf3a33a92987fd648f194898c3789f573fdadca6f (diff)
Smoke: put density/color in separate textures, fixes for workbench shader
This is more in line with standard grids and means we don't have to make many special exceptions in the upcoming change for arbitrary number of volume grids support in Eevee. The workbench shader was also changed to fix bugs where squared density was used, and the smoke color would affect the density so that black smoke would be invisible. This can change the look of smoke in workbench significantly. When using the color grid when smoke has a constant color, the color grid will no longer be premultiplied by the density. If the color is constant we want to be able not to store a grid at all. This breaks one test for Cycles and Eevee, but the setup in that test using a color without density does not make sense. It suffers from artifacts since the unpremultiplied color grid by itself will not have smooth boundaries. Differential Revision: https://developer.blender.org/D6951
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/GPU_material.h11
-rw-r--r--source/blender/gpu/GPU_texture.h1
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c6
-rw-r--r--source/blender/gpu/intern/gpu_draw_smoke.c110
-rw-r--r--source/blender/gpu/intern/gpu_texture.c11
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl19
6 files changed, 90 insertions, 68 deletions
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 37fe30bc96b..7107748e62a 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -99,11 +99,12 @@ typedef enum eGPUBuiltin {
GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14),
GPU_OBJECT_INFO = (1 << 15),
GPU_VOLUME_DENSITY = (1 << 16),
- GPU_VOLUME_FLAME = (1 << 17),
- GPU_VOLUME_TEMPERATURE = (1 << 18),
- GPU_BARYCENTRIC_TEXCO = (1 << 19),
- GPU_BARYCENTRIC_DIST = (1 << 20),
- GPU_WORLD_NORMAL = (1 << 21),
+ GPU_VOLUME_COLOR = (1 << 17),
+ GPU_VOLUME_FLAME = (1 << 18),
+ GPU_VOLUME_TEMPERATURE = (1 << 19),
+ GPU_BARYCENTRIC_TEXCO = (1 << 20),
+ GPU_BARYCENTRIC_DIST = (1 << 21),
+ GPU_WORLD_NORMAL = (1 << 22),
} eGPUBuiltin;
typedef enum eGPUMatFlag {
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 50b7c23059d..bd15030d135 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -238,6 +238,7 @@ void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat);
void GPU_texture_filters(GPUTexture *tex,
eGPUFilterFunction min_filter,
eGPUFilterFunction mag_filter);
+void GPU_texture_swizzle_channel_auto(GPUTexture *tex, int channels);
void GPU_texture_attach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb, int attachment);
int GPU_texture_detach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 553ecb65529..e8616c1e256 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -272,6 +272,9 @@ static const char *gpu_builtin_name(eGPUBuiltin builtin)
else if (builtin == GPU_VOLUME_DENSITY) {
return "sampdensity";
}
+ else if (builtin == GPU_VOLUME_COLOR) {
+ return "sampcolor";
+ }
else if (builtin == GPU_VOLUME_FLAME) {
return "sampflame";
}
@@ -351,7 +354,8 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
name = gpu_builtin_name(input->builtin);
if (BLI_str_startswith(name, "samp")) {
- if ((input->builtin == GPU_VOLUME_DENSITY) || (input->builtin == GPU_VOLUME_FLAME)) {
+ if ((input->builtin == GPU_VOLUME_DENSITY) || (input->builtin == GPU_VOLUME_COLOR) ||
+ (input->builtin == GPU_VOLUME_FLAME)) {
BLI_dynstr_appendf(ds, "uniform sampler3D %s;\n", name);
}
}
diff --git a/source/blender/gpu/intern/gpu_draw_smoke.c b/source/blender/gpu/intern/gpu_draw_smoke.c
index 5cca472148a..aa7789b3342 100644
--- a/source/blender/gpu/intern/gpu_draw_smoke.c
+++ b/source/blender/gpu/intern/gpu_draw_smoke.c
@@ -122,13 +122,10 @@ static GPUTexture *create_transfer_function(int type, const struct ColorBand *co
return tex;
}
-static void swizzle_texture_channel_rrrr(GPUTexture *tex)
+static void swizzle_texture_channel_single(GPUTexture *tex)
{
GPU_texture_bind(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_swizzle_channel_auto(tex, 1);
GPU_texture_unbind(tex);
}
@@ -186,60 +183,59 @@ static GPUTexture *create_field_texture(FluidDomainSettings *mds)
GPUTexture *tex = GPU_texture_create_nD(
mds->res[0], mds->res[1], mds->res[2], 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
- swizzle_texture_channel_rrrr(tex);
+ swizzle_texture_channel_single(tex);
return tex;
}
static GPUTexture *create_density_texture(FluidDomainSettings *mds, int highres)
{
- float *data = NULL, *source;
- int cell_count = (highres) ? manta_smoke_turbulence_get_cells(mds->fluid) : mds->total_cells;
+ int *dim = (highres) ? mds->res_noise : mds->res;
+
+ float *data;
+ if (highres) {
+ data = manta_smoke_turbulence_get_density(mds->fluid);
+ }
+ else {
+ data = manta_smoke_get_density(mds->fluid);
+ }
+
+ GPUTexture *tex = GPU_texture_create_nD(
+ dim[0], dim[1], dim[2], 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
+
+ swizzle_texture_channel_single(tex);
+
+ return tex;
+}
+
+static GPUTexture *create_color_texture(FluidDomainSettings *mds, int highres)
+{
const bool has_color = (highres) ? manta_smoke_turbulence_has_colors(mds->fluid) :
manta_smoke_has_colors(mds->fluid);
+
+ if (!has_color) {
+ return NULL;
+ }
+
+ int cell_count = (highres) ? manta_smoke_turbulence_get_cells(mds->fluid) : mds->total_cells;
int *dim = (highres) ? mds->res_noise : mds->res;
- eGPUTextureFormat format = (has_color) ? GPU_RGBA8 : GPU_R8;
+ float *data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
- if (has_color) {
- data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
+ if (data == NULL) {
+ return NULL;
}
if (highres) {
- if (has_color) {
- manta_smoke_turbulence_get_rgba(mds->fluid, data, 0);
- }
- else {
- source = manta_smoke_turbulence_get_density(mds->fluid);
- }
+ manta_smoke_turbulence_get_rgba(mds->fluid, data, 0);
}
else {
- if (has_color) {
- manta_smoke_get_rgba(mds->fluid, data, 0);
- }
- else {
- source = manta_smoke_get_density(mds->fluid);
- }
+ manta_smoke_get_rgba(mds->fluid, data, 0);
}
- GPUTexture *tex = GPU_texture_create_nD(dim[0],
- dim[1],
- dim[2],
- 3,
- (has_color) ? data : source,
- format,
- GPU_DATA_FLOAT,
- 0,
- true,
- NULL);
- if (data) {
- MEM_freeN(data);
- }
+ GPUTexture *tex = GPU_texture_create_nD(
+ dim[0], dim[1], dim[2], 3, data, GPU_RGBA8, GPU_DATA_FLOAT, 0, true, NULL);
+
+ MEM_freeN(data);
- if (format == GPU_R8) {
- /* Swizzle the RGBA components to read the Red channel so
- * that the shader stay the same for colored and non color
- * density textures. */
- swizzle_texture_channel_rrrr(tex);
- }
return tex;
}
@@ -264,7 +260,7 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *mds, int highres)
GPUTexture *tex = GPU_texture_create_nD(
dim[0], dim[1], dim[2], 3, source, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
- swizzle_texture_channel_rrrr(tex);
+ swizzle_texture_channel_single(tex);
return tex;
}
@@ -280,35 +276,40 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *mds, int highres)
void GPU_free_smoke(FluidModifierData *mmd)
{
if (mmd->type & MOD_FLUID_TYPE_DOMAIN && mmd->domain) {
- if (mmd->domain->tex) {
- GPU_texture_free(mmd->domain->tex);
+ if (mmd->domain->tex_density) {
+ GPU_texture_free(mmd->domain->tex_density);
+ mmd->domain->tex_density = NULL;
+ }
+
+ if (mmd->domain->tex_color) {
+ GPU_texture_free(mmd->domain->tex_color);
+ mmd->domain->tex_color = NULL;
}
- mmd->domain->tex = NULL;
if (mmd->domain->tex_shadow) {
GPU_texture_free(mmd->domain->tex_shadow);
+ mmd->domain->tex_shadow = NULL;
}
- mmd->domain->tex_shadow = NULL;
if (mmd->domain->tex_flame) {
GPU_texture_free(mmd->domain->tex_flame);
+ mmd->domain->tex_flame = NULL;
}
- mmd->domain->tex_flame = NULL;
if (mmd->domain->tex_flame_coba) {
GPU_texture_free(mmd->domain->tex_flame_coba);
+ mmd->domain->tex_flame_coba = NULL;
}
- mmd->domain->tex_flame_coba = NULL;
if (mmd->domain->tex_coba) {
GPU_texture_free(mmd->domain->tex_coba);
+ mmd->domain->tex_coba = NULL;
}
- mmd->domain->tex_coba = NULL;
if (mmd->domain->tex_field) {
GPU_texture_free(mmd->domain->tex_field);
+ mmd->domain->tex_field = NULL;
}
- mmd->domain->tex_field = NULL;
}
}
@@ -338,8 +339,11 @@ void GPU_create_smoke(FluidModifierData *mmd, int highres)
if (mmd->type & MOD_FLUID_TYPE_DOMAIN) {
FluidDomainSettings *mds = mmd->domain;
- if (!mds->tex) {
- mds->tex = create_density_texture(mds, highres);
+ if (!mds->tex_density) {
+ mds->tex_density = create_density_texture(mds, highres);
+ }
+ if (!mds->tex_color) {
+ mds->tex_color = create_color_texture(mds, highres);
}
if (!mds->tex_flame) {
mds->tex_flame = create_flame_texture(mds, highres);
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 9ef42592b55..2fd3e618664 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -1648,6 +1648,17 @@ void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat)
}
}
+void GPU_texture_swizzle_channel_auto(GPUTexture *tex, int channels)
+{
+ WARN_NOT_BOUND(tex);
+
+ glActiveTexture(GL_TEXTURE0 + tex->number);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, (channels >= 2) ? GL_GREEN : GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, (channels >= 3) ? GL_BLUE : GL_RED);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, (channels >= 4) ? GL_ALPHA : GL_ONE);
+}
+
static GLenum gpu_get_gl_filterfunction(eGPUFilterFunction filter)
{
switch (filter) {
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl
index 501aeb6f34e..0fecb5bd1f9 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl
@@ -5,9 +5,9 @@ void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outv
#else
vec3 cos = vec3(0.0);
#endif
- outvec = texture(tex, cos).aaa;
- outcol = vec4(outvec, 1.0);
- outf = avg(outvec);
+ outf = texture(tex, cos).r;
+ outvec = vec3(outf, outf, outf);
+ outcol = vec4(outf, outf, outf, 1.0);
}
uniform vec3 volumeColor = vec3(1.0);
@@ -59,6 +59,7 @@ void node_attribute_volume_temperature(
}
void node_volume_info(sampler3D densitySampler,
+ sampler3D colorSampler,
sampler3D flameSampler,
vec2 temperature,
out vec4 outColor,
@@ -72,14 +73,14 @@ void node_volume_info(sampler3D densitySampler,
vec3 p = vec3(0.0);
#endif
- vec4 density = texture(densitySampler, p);
- outDensity = density.a;
+ outDensity = texture(densitySampler, p).r;
- /* Density is premultiplied for interpolation, divide it out here. */
- if (density.a > 1e-8) {
- density.rgb /= density.a;
+ /* Color is premultiplied for interpolation, divide it out here. */
+ vec4 color = texture(colorSampler, p);
+ if (color.a > 1e-8) {
+ color.rgb /= color.a;
}
- outColor = vec4(density.rgb * volumeColor, 1.0);
+ outColor = vec4(color.rgb * volumeColor, 1.0);
float flame = texture(flameSampler, p).r;
outFlame = flame;