diff --git a/compositor.cm b/compositor.cm index 2fa90ee3..d201beeb 100644 --- a/compositor.cm +++ b/compositor.cm @@ -221,7 +221,7 @@ function apply_effect(ctx, effect, input, params) { } // Blur passes - blur_passes = effect.blur_passes || 2 + blur_passes = effect.blur_passes != null ? effect.blur_passes : 2 blur_in = bright for (p = 0; p < blur_passes; p++) { ctx.passes[] = {type: 'shader_pass', shader: 'blur', input: blur_in, output: blur1, uniforms: {direction: {x: 1, y: 0}, texel_size: {x: 1/size.width, y: 1/size.height}}} @@ -230,12 +230,13 @@ function apply_effect(ctx, effect, input, params) { } // Composite bloom - ctx.passes[] = {type: 'composite_textures', base: input, overlay: blur2, output: output, mode: 'add'} + ctx.passes[] = {type: 'composite_textures', base: input, overlay: blur_in, output: output, mode: 'add'} } else if (effect.type == 'mask') { mask_group = effect.mask_group // Query masks within the same plane to avoid cross-plane mask issues mask_sprites = film2d.query({group: mask_group, plane: current_plane}) + log.compositor("mask effect: group=" + mask_group + " plane=" + current_plane + " sprites=" + text(length(mask_sprites))) if (length(mask_sprites) > 0) { mask_target = ctx.alloc(size.width, size.height, hint + '_mask') diff --git a/film2d.cm b/film2d.cm index 4316b91b..132527ce 100644 --- a/film2d.cm +++ b/film2d.cm @@ -176,13 +176,13 @@ film2d.unregister = function(id) { film2d.index_group = function(id, group) { if (!group_index[group]) group_index[group] = [] - if (search(group_index[group], text(id)) == null) + if (find(group_index[group], text(id)) == null) group_index[group][] = text(id) } film2d.unindex_group = function(id, group) { if (!group_index[group]) return - var idx = search(group_index[group], text(id)) + var idx = find(group_index[group], text(id)) if (idx != null) group_index[group] = array(array(group_index[group], 0, idx), array(group_index[group], idx+1)) } @@ -218,7 +218,7 @@ film2d.query = function(selector) { // If also filtering by group, check membership if (selector.group) { groups = d.groups || [] - if (search(groups, selector.group) != null) result[] = d + if (find(groups, selector.group) != null) result[] = d } else { result[] = d } diff --git a/sdl_gpu.cm b/sdl_gpu.cm index 11614d9e..7f1381cc 100644 --- a/sdl_gpu.cm +++ b/sdl_gpu.cm @@ -208,7 +208,7 @@ function _load_shaders() { stage: "fragment", format: "msl", entrypoint: "fragment_main", - num_uniform_buffers: 2, + num_uniform_buffers: 1, num_samplers: 2 }) } @@ -452,20 +452,12 @@ function _create_pipelines() { target: { color_targets: [{ format: _swapchain_format, - blend: { - enabled: true, - src_rgb: "src_alpha", - dst_rgb: "one_minus_src_alpha", - op_rgb: "add", - src_alpha: "one", - dst_alpha: "one_minus_src_alpha", - op_alpha: "add" - } + blend: {enabled: false} }] } }) } - + // CRT pipeline if (_blit_vert && _crt_frag) { _pipelines.crt =gpu_mod.graphics_pipeline(_gpu, { @@ -2077,10 +2069,10 @@ function _do_mask(cmd_buffer, cmd) { var mode = cmd.mode || 'alpha' var invert = cmd.invert || false - if (!content || !content.texture) return - if (!mask || !mask.texture) return - if (!output || !output.texture) return - + if (!content || !content.texture) { log.graphics("mask: missing content texture"); return } + if (!mask || !mask.texture) { log.graphics("mask: missing mask texture"); return } + if (!output || !output.texture) { log.graphics("mask: missing output texture"); return } + // Check if mask pipeline is available if (!_pipelines.mask) { log.console("sdl_gpu: Mask pipeline not available, falling back to blit") diff --git a/shaders/msl/mask.frag.msl b/shaders/msl/mask.frag.msl index 34120951..098057f1 100644 --- a/shaders/msl/mask.frag.msl +++ b/shaders/msl/mask.frag.msl @@ -35,6 +35,8 @@ fragment float4 fragment_main( mask_value = 1.0 - mask_value; } - // Apply mask to content alpha - return float4(content.rgb, content.a * mask_value); + // Content is premultiplied alpha from render pass blending. + // Un-premultiply before masking so downstream blit (src_alpha blend) works correctly. + float3 rgb = content.a > 0.001 ? content.rgb / content.a : float3(0); + return float4(rgb, content.a * mask_value); }