From 91c7a213bfa746e22cd0848ec846a8c3a3377386 Mon Sep 17 00:00:00 2001 From: noname Date: Thu, 6 Nov 2025 08:15:52 +0900 Subject: [PATCH 1/3] Fix picking ID precision issues in GPU picker --- packages/dev/core/src/Collisions/gpuPicker.ts | 4 +--- packages/dev/core/src/Shaders/picking.fragment.fx | 2 +- packages/dev/core/src/ShadersWGSL/picking.fragment.fx | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/dev/core/src/Collisions/gpuPicker.ts b/packages/dev/core/src/Collisions/gpuPicker.ts index bc523b2d4b3..025eff244ab 100644 --- a/packages/dev/core/src/Collisions/gpuPicker.ts +++ b/packages/dev/core/src/Collisions/gpuPicker.ts @@ -51,7 +51,7 @@ export interface IGPUMultiPickingInfo { */ export class GPUPicker { private static readonly _AttributeName = "instanceMeshID"; - private static readonly _MaxPickingId = 0x00ffffff; // 24 bits unsigned integer max + private static readonly _MaxPickingId = 0x003fffff; // 24 bits unsigned integer max - 2 (for handle precision issues) private _pickingTexture: Nullable = null; @@ -219,8 +219,6 @@ export class GPUPicker { return; } - this._pickableMeshes = list as Array; - // Prepare target const scene = ("mesh" in list[0] ? list[0].mesh : list[0]).getScene(); if (!this._cachedScene || this._cachedScene !== scene) { diff --git a/packages/dev/core/src/Shaders/picking.fragment.fx b/packages/dev/core/src/Shaders/picking.fragment.fx index 798024bc86d..ed2d84c5dd3 100644 --- a/packages/dev/core/src/Shaders/picking.fragment.fx +++ b/packages/dev/core/src/Shaders/picking.fragment.fx @@ -15,7 +15,7 @@ void main(void) { #endif #if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE) - int castedId = int(id); + int castedId = int(id + 0.5); // + 0.5 to avoid precision issues //decompose it into 3 bytes vec3 color = vec3( float((castedId >> 16) & 0xFF), diff --git a/packages/dev/core/src/ShadersWGSL/picking.fragment.fx b/packages/dev/core/src/ShadersWGSL/picking.fragment.fx index 9f7176bb9a1..e4df3971f0f 100644 --- a/packages/dev/core/src/ShadersWGSL/picking.fragment.fx +++ b/packages/dev/core/src/ShadersWGSL/picking.fragment.fx @@ -9,9 +9,9 @@ uniform meshID: f32; fn main(input: FragmentInputs) -> FragmentOutputs { var id: i32; #if defined(INSTANCES) - id = i32(input.vMeshID); + id = i32(input.vMeshID + 0.5); // + 0.5 to avoid precision issues #else - id = i32(uniforms.meshID); + id = i32(uniforms.meshID + 0.5); // + 0.5 to avoid precision issues #endif var color = vec3f( f32((id >> 16) & 0xFF), From f0a6f01ca3cc47a28a83440276dd18fcdda32063 Mon Sep 17 00:00:00 2001 From: noname Date: Thu, 6 Nov 2025 17:41:11 +0900 Subject: [PATCH 2/3] Use flat varying for vMeshID and remove rounding in picking shaders --- packages/dev/core/src/Collisions/gpuPicker.ts | 2 +- packages/dev/core/src/Shaders/picking.fragment.fx | 4 ++-- packages/dev/core/src/Shaders/picking.vertex.fx | 2 +- packages/dev/core/src/ShadersWGSL/picking.fragment.fx | 6 +++--- packages/dev/core/src/ShadersWGSL/picking.vertex.fx | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/dev/core/src/Collisions/gpuPicker.ts b/packages/dev/core/src/Collisions/gpuPicker.ts index 025eff244ab..e0fe7b17373 100644 --- a/packages/dev/core/src/Collisions/gpuPicker.ts +++ b/packages/dev/core/src/Collisions/gpuPicker.ts @@ -51,7 +51,7 @@ export interface IGPUMultiPickingInfo { */ export class GPUPicker { private static readonly _AttributeName = "instanceMeshID"; - private static readonly _MaxPickingId = 0x003fffff; // 24 bits unsigned integer max - 2 (for handle precision issues) + private static readonly _MaxPickingId = 0x00ffffff; // 24 bits unsigned integer max private _pickingTexture: Nullable = null; diff --git a/packages/dev/core/src/Shaders/picking.fragment.fx b/packages/dev/core/src/Shaders/picking.fragment.fx index ed2d84c5dd3..9b1214e2a1a 100644 --- a/packages/dev/core/src/Shaders/picking.fragment.fx +++ b/packages/dev/core/src/Shaders/picking.fragment.fx @@ -1,6 +1,6 @@  #if defined(INSTANCES) -varying float vMeshID; +flat varying float vMeshID; #else uniform float meshID; #endif @@ -15,7 +15,7 @@ void main(void) { #endif #if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE) - int castedId = int(id + 0.5); // + 0.5 to avoid precision issues + int castedId = int(id); //decompose it into 3 bytes vec3 color = vec3( float((castedId >> 16) & 0xFF), diff --git a/packages/dev/core/src/Shaders/picking.vertex.fx b/packages/dev/core/src/Shaders/picking.vertex.fx index c792eef889b..cf921bc506f 100644 --- a/packages/dev/core/src/Shaders/picking.vertex.fx +++ b/packages/dev/core/src/Shaders/picking.vertex.fx @@ -16,7 +16,7 @@ uniform mat4 viewProjection; // Output #if defined(INSTANCES) -varying float vMeshID; +flat varying float vMeshID; #endif void main(void) { diff --git a/packages/dev/core/src/ShadersWGSL/picking.fragment.fx b/packages/dev/core/src/ShadersWGSL/picking.fragment.fx index e4df3971f0f..79c5b8d75c3 100644 --- a/packages/dev/core/src/ShadersWGSL/picking.fragment.fx +++ b/packages/dev/core/src/ShadersWGSL/picking.fragment.fx @@ -1,6 +1,6 @@ #if defined(INSTANCES) -varying vMeshID: f32; +flat varying vMeshID: f32; #else uniform meshID: f32; #endif @@ -9,9 +9,9 @@ uniform meshID: f32; fn main(input: FragmentInputs) -> FragmentOutputs { var id: i32; #if defined(INSTANCES) - id = i32(input.vMeshID + 0.5); // + 0.5 to avoid precision issues + id = i32(input.vMeshID); #else - id = i32(uniforms.meshID + 0.5); // + 0.5 to avoid precision issues + id = i32(uniforms.meshID); #endif var color = vec3f( f32((id >> 16) & 0xFF), diff --git a/packages/dev/core/src/ShadersWGSL/picking.vertex.fx b/packages/dev/core/src/ShadersWGSL/picking.vertex.fx index d9ea7b8096f..12b1d53d245 100644 --- a/packages/dev/core/src/ShadersWGSL/picking.vertex.fx +++ b/packages/dev/core/src/ShadersWGSL/picking.vertex.fx @@ -16,7 +16,7 @@ uniform viewProjection: mat4x4f; // Output #if defined(INSTANCES) -varying vMeshID: f32; +flat varying vMeshID: f32; #endif @vertex From 263c09d099d97a03926c0a4248095f67604cd3c6 Mon Sep 17 00:00:00 2001 From: noname Date: Thu, 6 Nov 2025 17:42:29 +0900 Subject: [PATCH 3/3] Update picking.fragment.fx --- packages/dev/core/src/ShadersWGSL/picking.fragment.fx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dev/core/src/ShadersWGSL/picking.fragment.fx b/packages/dev/core/src/ShadersWGSL/picking.fragment.fx index 79c5b8d75c3..1eb7550c65f 100644 --- a/packages/dev/core/src/ShadersWGSL/picking.fragment.fx +++ b/packages/dev/core/src/ShadersWGSL/picking.fragment.fx @@ -9,7 +9,7 @@ uniform meshID: f32; fn main(input: FragmentInputs) -> FragmentOutputs { var id: i32; #if defined(INSTANCES) - id = i32(input.vMeshID); + id = i32(input.vMeshID); #else id = i32(uniforms.meshID); #endif