Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions native/shared/src/postfx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,24 @@ struct VertexOutput {
@fragment
fn fs_outline(in: VertexOutput) -> @location(0) vec4<f32> {
let color = textureSample(scene_color, tex_sampler, in.uv);
let center_id = textureSample(object_id_tex, tex_sampler, in.uv).r;

let pixel = vec2<f32>(1.0 / params.screen_size.x, 1.0 / params.screen_size.y);
let t = params.thickness.x;
// Object IDs must not be filtered — interpolating IDs produces nonsense
// values at edges. Use textureLoad with integer coords; this also avoids
// requiring the FLOAT32_FILTERABLE wgpu feature (not advertised on Apple GPUs).
let dim = vec2<i32>(textureDimensions(object_id_tex));
let max_xy = dim - vec2<i32>(1, 1);
let center_pix = clamp(vec2<i32>(in.uv * vec2<f32>(dim)), vec2<i32>(0, 0), max_xy);
let center_id = textureLoad(object_id_tex, center_pix, 0).r;

let t = max(1, i32(round(params.thickness.x)));

// Sample neighbors for edge detection
var edge = 0.0;
for (var dy = -1; dy <= 1; dy++) {
for (var dx = -1; dx <= 1; dx++) {
if (dx == 0 && dy == 0) { continue; }
let offset = vec2<f32>(f32(dx), f32(dy)) * pixel * t;
let neighbor_id = textureSample(object_id_tex, tex_sampler, in.uv + offset).r;
let neighbor_pix = clamp(center_pix + vec2<i32>(dx, dy) * t, vec2<i32>(0, 0), max_xy);
let neighbor_id = textureLoad(object_id_tex, neighbor_pix, 0).r;
if (abs(neighbor_id - center_id) > 0.001) {
edge += 1.0;
}
Expand Down Expand Up @@ -169,7 +175,9 @@ impl PostFxPipeline {
label: Some("outline_bg_layout"),
entries: &[
bgl_texture(0, wgpu::TextureSampleType::Float { filterable: true }),
bgl_texture(1, wgpu::TextureSampleType::Float { filterable: true }),
// R32Float — non-filterable on adapters without FLOAT32_FILTERABLE
// (e.g. Apple GPUs). Sampled via textureLoad in OUTLINE_FRAG.
bgl_texture(1, wgpu::TextureSampleType::Float { filterable: false }),
bgl_sampler(2),
bgl_uniform(3),
],
Expand Down
61 changes: 34 additions & 27 deletions src/core/colors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Color } from './types';
import { Color as ColorType } from './types';

export const ColorConstants: Record<string, Color> = {
// Canonical color palette. Re-exported as `Color` from `bloom/core` and
// declared as a real top-level binding (not an alias re-export) so Perry
// emits a `_perry_fn_src_core_colors_ts__Color` symbol that examples
// importing `Color` from `bloom/core` can link against.
export const Color: Record<string, ColorType> = {
RayWhite: { r: 245, g: 245, b: 245, a: 255 },
White: { r: 255, g: 255, b: 255, a: 255 },
Black: { r: 0, g: 0, b: 0, a: 255 },
Expand All @@ -27,30 +31,33 @@ export const ColorConstants: Record<string, Color> = {
Blank: { r: 0, g: 0, b: 0, a: 0 },
};

// Backward-compatible alias — same object, kept for older imports.
export const ColorConstants = Color;

// Backward-compatible alias with SCREAMING_SNAKE keys
export const Colors: Record<string, Color> = {
WHITE: ColorConstants.White,
BLACK: ColorConstants.Black,
RED: ColorConstants.Red,
GREEN: ColorConstants.Green,
BLUE: ColorConstants.Blue,
YELLOW: ColorConstants.Yellow,
ORANGE: ColorConstants.Orange,
PINK: ColorConstants.Pink,
PURPLE: ColorConstants.Purple,
DARKGRAY: ColorConstants.DarkGray,
LIGHTGRAY: ColorConstants.LightGray,
GRAY: ColorConstants.Gray,
DARKBLUE: ColorConstants.DarkBlue,
SKYBLUE: ColorConstants.SkyBlue,
LIME: ColorConstants.Lime,
DARKGREEN: ColorConstants.DarkGreen,
GOLD: ColorConstants.Gold,
MAROON: ColorConstants.Maroon,
BROWN: ColorConstants.Brown,
BEIGE: ColorConstants.Beige,
MAGENTA: ColorConstants.Magenta,
VIOLET: ColorConstants.Violet,
RAYWHITE: ColorConstants.RayWhite,
BLANK: ColorConstants.Blank,
export const Colors: Record<string, ColorType> = {
WHITE: Color.White,
BLACK: Color.Black,
RED: Color.Red,
GREEN: Color.Green,
BLUE: Color.Blue,
YELLOW: Color.Yellow,
ORANGE: Color.Orange,
PINK: Color.Pink,
PURPLE: Color.Purple,
DARKGRAY: Color.DarkGray,
LIGHTGRAY: Color.LightGray,
GRAY: Color.Gray,
DARKBLUE: Color.DarkBlue,
SKYBLUE: Color.SkyBlue,
LIME: Color.Lime,
DARKGREEN: Color.DarkGreen,
GOLD: Color.Gold,
MAROON: Color.Maroon,
BROWN: Color.Brown,
BEIGE: Color.Beige,
MAGENTA: Color.Magenta,
VIOLET: Color.Violet,
RAYWHITE: Color.RayWhite,
BLANK: Color.Blank,
};
3 changes: 1 addition & 2 deletions src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Color, Camera2D, Camera3D } from './types';

export type { Color, Vec2, Vec3, Vec4, Rect, Camera2D, Camera3D, Texture, Font, Sound, Music, Quat, Ray, BoundingBox, Model, Mat4, RayHit, FrustumPlanes } from './types';
export { ColorConstants, Colors } from './colors';
export { ColorConstants as Color } from './colors';
export { Color, ColorConstants, Colors } from './colors';
export { Key, MouseButton } from './keys';

// FFI declarations
Expand Down
Loading