Give a shader room to draw around the picture it wears (#69)
A shader ran only inside the rectangle of what wears it: the quad has the size of the sprite, and outside of it no fragment runs. An outline or a glow built with Sample texture was cut off at the border. The issue still spoke of Filter.padding, but since #77 the shader is no filter any more, the limit is the geometry. - The Output node has a number Padding next to Edge: so many pixels of the picture per side the wearer draws beyond it. 0 is the default and draws as before, 256 is the most. - The quad grows and its UVs grow with it, so the picture keeps its place and size. In the margin the UVs run on below 0 and above 1. - Transparent is a fourth Edge mode: outside of the picture there is nothing. It is cut in the fragment (texelAt), so it needs no copy of the picture with an address mode of its own. - Edge holds everywhere alike, also for Texture color, Texture alpha and unconnected inputs. - Padding above 0 with Edge on Clamp puts the hint "Padding with Clamp smears the border" on the Output. The shader still compiles. A chosen Clamp and the default cannot be told apart. - All four wearers draw the margin. A sprite counts in pixels of its frame, a text in its units, a particle source grows every particle about its centre. - A nine-slice sprite gets a ring around its nine fields, as wide as so many border pixels. The fields themselves stay. - Without a picture a pixel is one unit of the wearer's own size, or of the particle size. - Particles now take the Edge mode of their shader. It had no effect on them before. - An object wearing a padded shader is never culled, or its margin would vanish at the edge of the screen. - The preview in the shader tab shows the margin and leaves room for it. - Picking, the selection frame, the size and the collider stay with the rectangle without the margin. Tests: - Gate on melektaus-atx right before this commit: 216 files, 3336 tests (3319 + 17), exit 0. - e2e 28,30,31,37,41 on melektaus-atx: 178 checks, all pass. e2e 1-37,47,48,58 ran before the last change (no culling with padding): 1281 checks, all pass. - 17 new unit tests: the compiler (padding, Transparent, the hint) and the geometry (quad, nine-slice ring). - Seven new e2e checks: four at the sprite in module 28, one each for text, particles and nine-slice. - 17 unit counter-probes all fail their tests. Three browser counter-probes fail their checks (5, 3 and 1 of them). - Three screenshots looked at: the sprite with Clamp and margin in the scene, the preview in the shader tab, the text. - The e2e sum of 1687 is counted (1680 + 7), the full suite and the smokes did not run. - Not seen: the hint at the node in a picture, particles and nine-slice in a picture, the game view while playing, sprites without a picture, vector and pixel art pictures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
46c620ae3b
commit
e933fad446
20 files changed
+644
-55
No files matched your search
@@ -9,6 +9,7 @@ import { crisp, hairline, type Size, Theme, Widget } from '../../ui';
|
||||
import { ParticleField } from '../../viewport/particles';
|
||||
import { particleLibrary } from '../../viewport/ParticleLibrary';
|
||||
import { shaderLibrary } from '../../viewport/ShaderLibrary';
|
||||
import { wornShader } from '../../viewport/shaders';
|
||||
import { textureLibrary } from '../../viewport/TextureLibrary';
|
||||
import type { EditorState } from '../state';
|
||||
|
||||
@@ -89,11 +90,12 @@ export class ParticlePreview extends Widget {
|
||||
const props = previewProps(this.asset, rows);
|
||||
const params = rows.map((row) => Number(props[row.key] ?? row.default));
|
||||
const ref = resolveTexture(this.state.project, props);
|
||||
const texture = ref ? textureLibrary.get(ref, SHEET_EDGE) : null;
|
||||
const shaders = shaderLibrary.source(this.state.project);
|
||||
const texture = ref ? textureLibrary.get(ref, wornShader(props, shaders)?.edge ?? SHEET_EDGE) : null;
|
||||
// The source sits in the middle of the panel; a fountain then has room above and below it.
|
||||
const m = translation(this.w / 2, this.h / 2);
|
||||
this.field.hold(this.held);
|
||||
this.field.wear(props, shaderLibrary.source(this.state.project));
|
||||
this.field.wear(props, shaders, texture);
|
||||
this.field.sync(build.compiled, props, params, m, texture ?? Texture.WHITE, particleLibrary.now());
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user