TilemapGPULayer steps between tiles by the tileset's margin instead of its spacing
Maintainer thường phản hồi trong vòng 3 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 1/5
- Thời gian dự kiến
- Dưới một giờ
- Mức phù hợp với người mới
- 80/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- javascript
- Lĩnh vực
- computer-graphics
Hướng nghiên cứu
src/renderer/webgl/shaders/src/TilemapGPULayer.vert dòng 24 (được build vào TilemapGPULayer-vert.js) tính outTileStride từ .zz (margin) thay vì .ww (spacing); đọc dòng đó cùng với getFrameCorner trong fragment shader để xác nhận rằng stride cấp dữ liệu cho việc đặt tile. Sửa component, build lại shader bundle và chạy ví dụ HTML của issue với margin 2 / spacing 4 để dải trắng của hàng GPU thẳng hàng sát như hàng TilemapLayer.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- JavaScript
- Star
- 40.7k
- Fork
- 7.2k
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của phaserjs/phaser
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 80/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Type definition for TilemapLayer.getTileAt is wrongCó thể đã có người làm @hkbughk đã nhận 34 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Shader.preDestroy leaks its ShaderQuad's vertex buffer and VAO on every create/destroy cycle (4.2.1)Có thể đã có người làm @k1epg01ng129-eng đã nhận 32 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Black opaque background on transparent Phaser.Text textures in Phaser 4.2.1 on older iOS WebGLCó thể đã có người làm @SamuelMalmfors đã nhận 14 ngày trước. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
phaserjs/phaser#7392 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
flipY renders tile incorrectlyCó thể đã có người làm @vtxe02023274 đã nhận 26 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của phaserjs/phaser
Issue tương tự
-
Out of order / duplicate key error shows the key bytes as decimal or UTF-8, not hexCó thể đã có người làm @bardrop đã nhận hôm nay. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 86/100
-
`remix-hook-form/middleware` imports `unstable_createContext`, breaking on `react-router` >= 7.9.0Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
code-forge-io/remix-hook-form#189 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
webtorrent/webtorrent#3131 ·