TilemapGPULayer steps between tiles by the tileset's margin instead of its spacing
维护者通常 3 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 1/5
- 预计耗时
- 1 小时以内
- 新手友好度
- 80/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- javascript
调研方向
src/renderer/webgl/shaders/src/TilemapGPULayer.vert 第 24 行(构建到 TilemapGPULayer-vert.js 中)从 .zz(margin)而不是 .ww(spacing)计算 outTileStride;请结合片段着色器中的 getFrameCorner 阅读该行,以确认 stride 会参与 tile 放置。修改该组件,重新构建 shader bundle,并使用 margin 2 / spacing 4 运行 issue 的 HTML 示例,使 GPU 行的白色条纹像 TilemapLayer 行一样齐平对齐。
由索引模型根据 Issue 内容生成。
描述
Version
- Phaser Version: 4.2.1 (also on
mastertoday) - Operating system: Linux
- Browser: Chrome 149 (WebGL 2 via ANGLE)
Description
TilemapGPULayer steps from one tile to the next in the tileset by the tileset's margin instead of its spacing. In src/renderer/webgl/shaders/src/TilemapGPULayer.vert (TilemapGPULayer-vert.js, line 24):
outTileStride = uTileWidthHeightMarginSpacing.xy + uTileWidthHeightMarginSpacing.zz;
.zz is the margin; .ww is the spacing. The fragment shader then places a tile at index * outTileStride + margin (getFrameCorner), so whenever margin ≠ spacing, tile n is sampled n × (spacing − margin) pixels to the left of where it is. With the common extruded layout (margin 2, spacing 4, i.e. 2 px of extrusion round every tile), each tile along a row is sampled 2 px further off than the last: the layer shows a growing sliver of the gap or the neighbouring tile, which reads as seams or a dotted grid.
When margin = spacing (including both 0) the bug doesn't show, which is probably why it hasn't been reported. It may be part of what's seen in #7317, which uses tilesets with margin and spacing. I saw the comment there that margin and spacing shouldn't be needed with TilemapGPULayer, but the shaders do read both, and TilemapLayer handles the same tileset correctly, so either fixing the stride or warning that margin/spacing are unsupported would help.
Expected: a TilemapGPULayer draws the same tiles as a TilemapLayer with the same tileset.
Actual: tile n is offset by n × (spacing − margin) px.
Fix (tested against the example below with a patched dist/phaser.js):
outTileStride = uTileWidthHeightMarginSpacing.xy + uTileWidthHeightMarginSpacing.ww;
Example Test Code
A tileset of four tiles with margin 2 and spacing 4, each a colour with a white stripe down its left edge. Top row: TilemapGPULayer; bottom row: TilemapLayer. In the GPU row the white stripe moves 2 px right per tile index, with a dark gap opening to its left; in the TilemapLayer row it's flush on every tile. (The GPU layer is at 0,0 because of a separate position bug, #7422.)
<!doctype html>
<html><body style="margin:0">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script>
<script>
const TILE = 32, MARGIN = 2, SPACING = 4, COLOURS = ['#e33', '#3c3', '#36f', '#fc2'];
class Demo extends Phaser.Scene {
create() {
const tex = this.textures.createCanvas('tiles', MARGIN * 2 + COLOURS.length * TILE + (COLOURS.length - 1) * SPACING, TILE + MARGIN * 2);
const ctx = tex.getContext();
COLOURS.forEach((colour, i) => {
const x = MARGIN + i * (TILE + SPACING);
ctx.fillStyle = colour; ctx.fillRect(x, MARGIN, TILE, TILE);
ctx.fillStyle = '#fff'; ctx.fillRect(x, MARGIN, 4, TILE);
});
tex.refresh();
const data = [[0, 1, 2, 3, 0, 1, 2, 3]];
for (const [gpu, y] of [[true, 0], [false, 60]]) {
const map = this.make.tilemap({ data, tileWidth: TILE, tileHeight: TILE });
map.createLayer(0, map.addTilesetImage('tiles', 'tiles', TILE, TILE, MARGIN, SPACING), 0, y, gpu);
}
}
}
new Phaser.Game({ type: Phaser.WEBGL, width: 300, height: 100, backgroundColor: '#222', scene: Demo });
</script>
</body></html>
Additional Information
Workaround until it's fixed: lay the tileset out with margin equal to spacing (e.g. margin 4, spacing 4 for 2 px of extrusion each side), which gives the same stride either way.
- 主要语言
- JavaScript
- 星标
- 40.7k
- 派生
- 7.2k
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
phaserjs/phaser 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 80/100
维护者通常 3 天内回复
-
Type definition for TilemapLayer.getTileAt is wrong可能已有人在做 @hkbughk 于 34 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 3 天内回复
-
Shader.preDestroy leaks its ShaderQuad's vertex buffer and VAO on every create/destroy cycle (4.2.1)可能已有人在做 @k1epg01ng129-eng 于 32 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 86/100
维护者通常 3 天内回复
-
Black opaque background on transparent Phaser.Text textures in Phaser 4.2.1 on older iOS WebGL可能已有人在做 @SamuelMalmfors 于 14 天前认领。 未关闭
难度 1/5 1 小时以内 新手友好度 85/100
phaserjs/phaser#7392 · 1 条评论 ·
维护者通常 3 天内回复
-
flipY renders tile incorrectly可能已有人在做 @vtxe02023274 于 26 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 3 天内回复
相似的 Issue
-
enhancement ready
难度 2/5 1-3 小时 新手友好度 84/100
-
enhancement
难度 2/5 1-3 小时 新手友好度 75/100
DCGM/semant-demo#708 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
-
agents area: runtime automation chore cli consistency dependencies developer-experience difficulty: easy documentation enhancement good first issue help wanted hygiene json-output priority: P3 starters tests
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
Client codegen: an import repeated in an impl file is emitted twice, and the browser rejects the module可能已有人在做 @MalithaPrabhashana 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 64/100
jaseci-labs/jac#10756 ·
维护者通常 1 天内回复