Fix GPU collision missing sprites flipped with negative scale - #2907
Merged
Merged
Conversation
The GPU collision geometry shaders compared sizes with max(size[0], check_size). A sprite flipped with a negative scale has a negative width or height, so max() picked the other sprite's size and the flipped sprite could be rejected even when the two overlapped. This is the GPU counterpart of #2892. Use abs() on both sizes, in the buffer and texture versions of the shader. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The GPU collision path (
CollisionMethod.GPU, also used automatically byAUTOfor lists over 1500 sprites without a spatial hash) finds nearby sprites with a geometry shader that compared sizes with:A sprite flipped with a negative scale has a negative width or height. So
max()picked the other sprite's size, and a flipped sprite could be dropped even when it overlapped. This is the GPU counterpart of the CPU fix in #2892.Fix
max(abs(size[0]), abs(check_size))in both versions of the shader:col_trans_gs.glsl: the buffer version, used by desktop OpenGL sprite lists.col_tex_trans_gs.glsl: the texture version, only used by the texture-based sprite list storage. That storage is currently only used on WebGL, where GPU collision is disabled, so nothing reaches this shader today. I fixed it anyway so the two stay in sync.Tests
test_gpu_collision_flipped_sprites: a long wall and a small bullet near its end, usingget_nearby_sprites_gpuandcheck_for_collision_with_list(method=GPU). It covers six scale combinations: not flipped, the wall flipped in x, y, or both, the bullet flipped, and both flipped. It also checks that a far-away bullet still isn't found. It's skipped on WebGL.developmentthe three cases with the wall flipped horizontally fail. The others already passed, because the wall's height or the bullet's size happened to be large enough, so they're kept as coverage.SpriteListTextureDatastorage into a sprite list on desktop GL and calledget_nearby_sprites_gpu. With the old shader, the flipped walls were missed (0 found); with the fix, they're found (1 found), and a far-away point still finds nothing.🤖 Generated with Claude Code