From 116bab702e009ce8043b976b4a9c4afa4c7ff5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 28 Aug 2016 16:50:49 +0200 Subject: Fix T47639: OpenGL render with smoke and fire incorrect when using transparency. The issue is that we are rendering to a 0..1 clamped sRGB buffer with unpremultiplied alpha, where the correct thing to do would be to render to an unclamped linear premultiplied alpha buffer. Then we would just make fire purely emissive without affecting the alpha channel at all, but that doesn't work here. So for now, draw fire and smoke separately using different shaders and blend modes, like it used to before the smoke programs were rewritten (see rB0372b642). --- source/blender/gpu/CMakeLists.txt | 2 ++ source/blender/gpu/intern/gpu_shader.c | 5 +++-- source/blender/gpu/shaders/gpu_shader_fire_frag.glsl | 17 +++++++++++++++++ source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl | 12 ------------ 4 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 source/blender/gpu/shaders/gpu_shader_fire_frag.glsl (limited to 'source/blender/gpu') diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index cfa083116f2..8885209ce01 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -78,6 +78,7 @@ set(SRC shaders/gpu_shader_vsm_store_frag.glsl shaders/gpu_shader_vsm_store_vert.glsl shaders/gpu_shader_fx_depth_resolve.glsl + shaders/gpu_shader_fire_frag.glsl shaders/gpu_shader_smoke_frag.glsl shaders/gpu_shader_smoke_vert.glsl @@ -99,6 +100,7 @@ set(SRC ) data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC) +data_to_c_simple(shaders/gpu_shader_fire_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_smoke_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_smoke_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_material.glsl SRC) diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index df1213b01e2..5cfb323bc4b 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -45,6 +45,7 @@ #define MAX_EXT_DEFINE_LENGTH 1024 /* Non-generated shaders */ +extern char datatoc_gpu_shader_fire_frag_glsl[]; extern char datatoc_gpu_shader_smoke_vert_glsl[]; extern char datatoc_gpu_shader_smoke_frag_glsl[]; extern char datatoc_gpu_shader_vsm_store_vert_glsl[]; @@ -618,8 +619,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) case GPU_SHADER_SMOKE_FIRE: if (!GG.shaders.smoke_fire) GG.shaders.smoke_fire = GPU_shader_create( - datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl, - NULL, NULL, "#define USE_FIRE;\n", 0, 0, 0); + datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_fire_frag_glsl, + NULL, NULL, NULL, 0, 0, 0); retval = GG.shaders.smoke_fire; break; } diff --git a/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl new file mode 100644 index 00000000000..3819203bcd9 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl @@ -0,0 +1,17 @@ + +varying vec3 coords; + +uniform sampler3D flame_texture; +uniform sampler1D spectrum_texture; + +void main() +{ + float flame = texture3D(flame_texture, coords).r; + vec4 emission = texture1D(spectrum_texture, flame); + + vec4 color; + color.rgb = emission.a * emission.rgb; + color.a = emission.a; + + gl_FragColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl index 4d1feb5c83e..fd790009e02 100644 --- a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl @@ -8,11 +8,6 @@ uniform float density_scale; uniform sampler3D soot_texture; uniform sampler3D shadow_texture; -#ifdef USE_FIRE -uniform sampler3D flame_texture; -uniform sampler1D spectrum_texture; -#endif - void main() { /* compute color and density from volume texture */ @@ -37,12 +32,5 @@ void main() /* premultiply alpha */ vec4 color = vec4(soot_alpha * soot_color, soot_alpha); -#ifdef USE_FIRE - /* fire */ - float flame = texture3D(flame_texture, coords).r; - vec4 emission = texture1D(spectrum_texture, flame); - color.rgb += (1 - color.a) * emission.a * emission.rgb; -#endif - gl_FragColor = color; } -- cgit v1.2.3