diff options
Diffstat (limited to 'servers/rendering/rasterizer_rd')
6 files changed, 112 insertions, 110 deletions
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp index 71acd4ceb6..0a3a863ee7 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp @@ -389,14 +389,14 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { +void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { zeromem(©.push_constant, sizeof(CopyPushConstant)); CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; uint32_t base_flags = 0; - int32_t x_groups = (p_size.width - 1) / 8 + 1; - int32_t y_groups = (p_size.height - 1) / 8 + 1; + int32_t x_groups = (p_size.width + 7) / 8; + int32_t y_groups = (p_size.height + 7) / 8; copy.push_constant.section[2] = p_size.x; copy.push_constant.section[3] = p_size.y; @@ -411,29 +411,15 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, copy.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also - //HORIZONTAL RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3); if (p_auto_exposure.is_valid() && p_first_pass) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_auto_exposure), 1); } - copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); - RD::get_singleton()->compute_list_add_barrier(compute_list); - - copy_mode = COPY_MODE_GAUSSIAN_GLOW; - - //VERTICAL - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3); - - copy.push_constant.flags = base_flags; + copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); @@ -692,7 +678,13 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, tonemap.push_constant.use_glow = p_settings.use_glow; tonemap.push_constant.glow_intensity = p_settings.glow_intensity; - tonemap.push_constant.glow_level_flags = p_settings.glow_level_flags; + tonemap.push_constant.glow_levels[0] = p_settings.glow_levels[0]; // clean this up to just pass by pointer or something + tonemap.push_constant.glow_levels[1] = p_settings.glow_levels[1]; + tonemap.push_constant.glow_levels[2] = p_settings.glow_levels[2]; + tonemap.push_constant.glow_levels[3] = p_settings.glow_levels[3]; + tonemap.push_constant.glow_levels[4] = p_settings.glow_levels[4]; + tonemap.push_constant.glow_levels[5] = p_settings.glow_levels[5]; + tonemap.push_constant.glow_levels[6] = p_settings.glow_levels[6]; tonemap.push_constant.glow_texture_size[0] = p_settings.glow_texture_size.x; tonemap.push_constant.glow_texture_size[1] = p_settings.glow_texture_size.y; tonemap.push_constant.glow_mode = p_settings.glow_mode; diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h index e434bbc372..8607a6ee67 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h @@ -175,14 +175,16 @@ class RasterizerEffectsRD { uint32_t tonemapper; uint32_t glow_texture_size[2]; - float glow_intensity; - uint32_t glow_level_flags; + uint32_t pad3; + uint32_t glow_mode; + float glow_levels[7]; float exposure; float white; float auto_exposure_grey; + uint32_t pad2; float pixel_size[2]; uint32_t use_fxaa; @@ -607,7 +609,7 @@ public: void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false); - void gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); + void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); @@ -627,7 +629,7 @@ public: GlowMode glow_mode = GLOW_MODE_ADD; float glow_intensity = 1.0; - uint32_t glow_level_flags = 0; + float glow_levels[7] = { 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0 }; Vector2i glow_texture_size; bool glow_use_bicubic_upscale = false; RID glow_texture; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index ce823b7198..4854ed3337 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -2933,11 +2933,12 @@ void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMa env->auto_exp_scale = p_auto_exp_scale; } -void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { +void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); + ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); env->glow_enabled = p_enable; - env->glow_levels = p_level_flags; + env->glow_levels = p_levels; env->glow_intensity = p_intensity; env->glow_strength = p_strength; env->glow_mix = p_mix; @@ -5245,25 +5246,21 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu } int max_glow_level = -1; - int glow_mask = 0; if (can_use_effects && env && env->glow_enabled) { /* see that blur textures are allocated */ - if (rb->blur[0].texture.is_null()) { + if (rb->blur[1].texture.is_null()) { _allocate_blur_textures(rb); _render_buffers_uniform_set_changed(p_render_buffers); } for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { - if (env->glow_levels & (1 << i)) { + if (env->glow_levels[i] > 0.0) { if (i >= rb->blur[1].mipmaps.size()) { max_glow_level = rb->blur[1].mipmaps.size() - 1; - glow_mask |= 1 << max_glow_level; - } else { max_glow_level = i; - glow_mask |= (1 << i); } } } @@ -5277,9 +5274,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu if (env->auto_exposure && rb->luminance.current.is_valid()) { luminance_texture = rb->luminance.current; } - storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + storage->get_effects()->gaussian_glow(rb->texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); } else { - storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); } } } @@ -5302,7 +5299,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu tonemap.use_glow = true; tonemap.glow_mode = RasterizerEffectsRD::TonemapSettings::GlowMode(env->glow_blend_mode); tonemap.glow_intensity = env->glow_blend_mode == RS::ENV_GLOW_BLEND_MODE_MIX ? env->glow_mix : env->glow_intensity; - tonemap.glow_level_flags = glow_mask; + for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { + tonemap.glow_levels[i] = env->glow_levels[i]; + } tonemap.glow_texture_size.x = rb->blur[1].mipmaps[0].width; tonemap.glow_texture_size.y = rb->blur[1].mipmaps[0].height; tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index 50647d54bf..8a14598250 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -723,7 +723,7 @@ private: /// Glow bool glow_enabled = false; - int glow_levels = (1 << 2) | (1 << 4); + Vector<float> glow_levels; float glow_intensity = 0.8; float glow_strength = 1.0; float glow_bloom = 0.0; @@ -1532,7 +1532,7 @@ public: bool is_environment(RID p_env) const; - void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap); + void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap); void environment_glow_set_use_bicubic_upscale(bool p_enable); void environment_glow_set_use_high_quality(bool p_enable); diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl index e565bd8e3d..355a2b9d75 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl @@ -58,12 +58,20 @@ layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buff layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; #endif +#ifdef MODE_GAUSSIAN_GLOW +shared vec4 local_cache[256]; +shared vec4 temp_cache[128]; +#endif + void main() { // Pixel being shaded ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + +#ifndef MODE_GAUSSIAN_GLOW // Glow needs the extra threads if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing return; } +#endif #ifdef MODE_MIPMAP @@ -104,70 +112,69 @@ void main() { #ifdef MODE_GAUSSIAN_GLOW - //Glow uses larger sigma 1 for a more rounded blur effect + // First pass copy texture into 16x16 local memory for every 8x8 thread block + vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); + uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16; + + if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) { + vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); -#define GLOW_ADD(m_ofs, m_mult) \ - { \ - ivec2 ofs = base_pos + m_ofs; \ - if (all(greaterThanEqual(ofs, section_begin)) && all(lessThan(ofs, section_end))) { \ - color += texelFetch(source_color, ofs, 0) * m_mult; \ - } \ + local_cache[dest_index] = (textureLod(source_color, quad_center_uv, 0) + textureLod(source_color, quad_offset_uv, 0)) * 0.5; + local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5; + local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5; + local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5; + } else { + local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0); + local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0); + local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0); + local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0); } + memoryBarrierShared(); + barrier(); + + // Horizontal pass. Needs to copy into 8x16 chunk of local memory so vertical pass has full resolution + uint read_index = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 32 + 4; + vec4 color_top = vec4(0.0); + color_top += local_cache[read_index] * 0.174938; + color_top += local_cache[read_index + 1] * 0.165569; + color_top += local_cache[read_index + 2] * 0.140367; + color_top += local_cache[read_index + 3] * 0.106595; + color_top += local_cache[read_index - 1] * 0.165569; + color_top += local_cache[read_index - 2] * 0.140367; + color_top += local_cache[read_index - 3] * 0.106595; + + vec4 color_bottom = vec4(0.0); + color_bottom += local_cache[read_index + 16] * 0.174938; + color_bottom += local_cache[read_index + 1 + 16] * 0.165569; + color_bottom += local_cache[read_index + 2 + 16] * 0.140367; + color_bottom += local_cache[read_index + 3 + 16] * 0.106595; + color_bottom += local_cache[read_index - 1 + 16] * 0.165569; + color_bottom += local_cache[read_index - 2 + 16] * 0.140367; + color_bottom += local_cache[read_index - 3 + 16] * 0.106595; + + // rotate samples to take advantage of cache coherency + uint write_index = gl_LocalInvocationID.y * 2 + gl_LocalInvocationID.x * 16; + + temp_cache[write_index] = color_top; + temp_cache[write_index + 1] = color_bottom; + + memoryBarrierShared(); + barrier(); + + // Vertical pass + uint index = gl_LocalInvocationID.y + gl_LocalInvocationID.x * 16 + 4; vec4 color = vec4(0.0); - if (bool(params.flags & FLAG_HORIZONTAL)) { - ivec2 base_pos = ((pos + params.section.xy) << 1) + ivec2(1); - ivec2 section_begin = params.section.xy << 1; - ivec2 section_end = section_begin + (params.section.zw << 1); - - if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) { - //Sample from two lines to capture single pixel features - GLOW_ADD(ivec2(0, 0), 0.152781); - GLOW_ADD(ivec2(1, 0), 0.144599); - GLOW_ADD(ivec2(2, 0), 0.122589); - GLOW_ADD(ivec2(3, 0), 0.093095); - GLOW_ADD(ivec2(4, 0), 0.063327); - GLOW_ADD(ivec2(-1, 0), 0.144599); - GLOW_ADD(ivec2(-2, 0), 0.122589); - GLOW_ADD(ivec2(-3, 0), 0.093095); - GLOW_ADD(ivec2(-4, 0), 0.063327); - - GLOW_ADD(ivec2(0, 1), 0.152781); - GLOW_ADD(ivec2(1, 1), 0.144599); - GLOW_ADD(ivec2(2, 1), 0.122589); - GLOW_ADD(ivec2(3, 1), 0.093095); - GLOW_ADD(ivec2(4, 1), 0.063327); - GLOW_ADD(ivec2(-1, 1), 0.144599); - GLOW_ADD(ivec2(-2, 1), 0.122589); - GLOW_ADD(ivec2(-3, 1), 0.093095); - GLOW_ADD(ivec2(-4, 1), 0.063327); - color *= 0.5; - } else { - GLOW_ADD(ivec2(0, 0), 0.174938); - GLOW_ADD(ivec2(1, 0), 0.165569); - GLOW_ADD(ivec2(2, 0), 0.140367); - GLOW_ADD(ivec2(3, 0), 0.106595); - GLOW_ADD(ivec2(-1, 0), 0.165569); - GLOW_ADD(ivec2(-2, 0), 0.140367); - GLOW_ADD(ivec2(-3, 0), 0.106595); - } - - color *= params.glow_strength; - } else { - ivec2 base_pos = pos + params.section.xy; - ivec2 section_begin = params.section.xy; - ivec2 section_end = section_begin + params.section.zw; - - GLOW_ADD(ivec2(0, 0), 0.288713); - GLOW_ADD(ivec2(0, 1), 0.233062); - GLOW_ADD(ivec2(0, 2), 0.122581); - GLOW_ADD(ivec2(0, -1), 0.233062); - GLOW_ADD(ivec2(0, -2), 0.122581); - color *= params.glow_strength; - } + color += temp_cache[index] * 0.174938; + color += temp_cache[index + 1] * 0.165569; + color += temp_cache[index + 2] * 0.140367; + color += temp_cache[index + 3] * 0.106595; + color += temp_cache[index - 1] * 0.165569; + color += temp_cache[index - 2] * 0.140367; + color += temp_cache[index - 3] * 0.106595; -#undef GLOW_ADD + color *= params.glow_strength; if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) { #ifdef GLOW_USE_AUTO_EXPOSURE diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl index b7c46a7d0e..74449496f6 100644 --- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl +++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl @@ -37,12 +37,14 @@ layout(push_constant, binding = 1, std430) uniform Params { uvec2 glow_texture_size; float glow_intensity; - uint glow_level_flags; + uint pad3; uint glow_mode; + float glow_levels[7]; float exposure; float white; float auto_exposure_grey; + uint pad2; vec2 pixel_size; bool use_fxaa; @@ -186,32 +188,32 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels vec3 glow = vec3(0.0f); - if (bool(params.glow_level_flags & (1 << 0))) { - glow += GLOW_TEXTURE_SAMPLE(tex, uv, 0).rgb; + if (params.glow_levels[0] > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 0).rgb * params.glow_levels[0]; } - if (bool(params.glow_level_flags & (1 << 1))) { - glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb; + if (params.glow_levels[1] > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb * params.glow_levels[1]; } - if (bool(params.glow_level_flags & (1 << 2))) { - glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb; + if (params.glow_levels[2] > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb * params.glow_levels[2]; } - if (bool(params.glow_level_flags & (1 << 3))) { - glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb; + if (params.glow_levels[3] > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb * params.glow_levels[3]; } - if (bool(params.glow_level_flags & (1 << 4))) { - glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb; + if (params.glow_levels[4] > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb * params.glow_levels[4]; } - if (bool(params.glow_level_flags & (1 << 5))) { - glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb; + if (params.glow_levels[5] > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb * params.glow_levels[5]; } - if (bool(params.glow_level_flags & (1 << 6))) { - glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb; + if (params.glow_levels[6] > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb * params.glow_levels[6]; } return glow; |