diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_material.h | 11 | ||||
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw_smoke.c | 110 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 11 | ||||
-rw-r--r-- | source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl | 19 |
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; |