Skip to content

Commit 26025f7

Browse files
committed
fix flickering
1 parent 078ecc6 commit 26025f7

File tree

5 files changed

+28
-33
lines changed

5 files changed

+28
-33
lines changed

packages/uikit/src/components/root.ts

+7-13
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
setupNode,
3737
} from './utils.js'
3838
import { computedClippingRect } from '../clipping.js'
39-
import { ElementType, WithCameraDistance, computedOrderInfo } from '../order.js'
39+
import { ElementType, WithReversePainterSortStableCache, computedOrderInfo } from '../order.js'
4040
import { Camera, Matrix4, Object3D, Plane, Vector2Tuple, Vector3, WebGLRenderer } from 'three'
4141
import { GlyphGroupManager } from '../text/render/instanced-glyph-group.js'
4242
import { createActivePropertyTransfomers } from '../active.js'
@@ -112,8 +112,8 @@ export function createRootState<EM extends ThreeEventMap = ThreeEventMap>(
112112
},
113113
)
114114

115-
const ctx: WithCameraDistance & Pick<RootContext, 'requestFrame' | 'requestRender' | 'onFrameSet' | 'pixelSize'> = {
116-
cameraDistance: 0,
115+
const ctx: WithReversePainterSortStableCache &
116+
Pick<RootContext, 'requestFrame' | 'requestRender' | 'onFrameSet' | 'pixelSize'> = {
117117
onFrameSet,
118118
requestRender,
119119
requestFrame,
@@ -201,16 +201,10 @@ export function setupRoot<EM extends ThreeEventMap = ThreeEventMap>(
201201

202202
setupObjectTransform(state.root, object, state.globalMatrix, abortSignal)
203203

204-
const onCameraDistanceFrame = () => {
205-
state.root.reversePainterSortStableCache = undefined
206-
planeHelper.normal.set(0, 0, 1)
207-
planeHelper.constant = 0
208-
planeHelper.applyMatrix4(object.matrixWorld)
209-
vectorHelper.setFromMatrixPosition(state.getCamera().matrixWorld)
210-
state.root.cameraDistance = planeHelper.distanceToPoint(vectorHelper)
211-
}
212-
state.root.onFrameSet.add(onCameraDistanceFrame)
213-
abortSignal.addEventListener('abort', () => state.root.onFrameSet.delete(onCameraDistanceFrame))
204+
const onFrame = () => void (state.root.reversePainterSortStableCache = undefined)
205+
206+
state.root.onFrameSet.add(onFrame)
207+
abortSignal.addEventListener('abort', () => state.root.onFrameSet.delete(onFrame))
214208

215209
setupInstancedPanel(
216210
state.mergedProperties,

packages/uikit/src/context.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { signal, Signal } from '@preact/signals-core'
22
import { Matrix4, Object3D, Vector2Tuple, WebGLRenderer } from 'three'
33
import { ClippingRect } from './clipping.js'
4-
import { OrderInfo, WithCameraDistance } from './order.js'
4+
import { OrderInfo, WithReversePainterSortStableCache } from './order.js'
55
import { GlyphGroupManager } from './text/render/instanced-glyph-group.js'
66
import { PanelGroupManager } from './panel/instanced-panel-group.js'
77
import { FlexNode } from './flex/index.js'
@@ -16,7 +16,7 @@ export type ParentContext = Readonly<{
1616
root: RootContext
1717
}>
1818

19-
export type RootContext = WithCameraDistance &
19+
export type RootContext = WithReversePainterSortStableCache &
2020
Readonly<{
2121
requestCalculateLayout: () => void
2222
objectRef: { current?: Object3D | null }

packages/uikit/src/order.ts

+13-12
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { MergedProperties } from './properties/merged.js'
44
import { computedInheritableProperty } from './properties/index.js'
55
import { readReactive } from './utils.js'
66

7-
export type WithCameraDistance = { cameraDistance: number; reversePainterSortStableCache?: number }
7+
export type WithReversePainterSortStableCache = { reversePainterSortStableCache?: number }
88

9-
export const cameraDistanceKey = Symbol('camera-distance-key')
9+
export const reversePainterSortStableCacheKey = Symbol('reverse-painter-sort-stable-cache-key')
1010
export const orderInfoKey = Symbol('order-info-key')
1111

1212
export function reversePainterSortStable(a: RenderItem, b: RenderItem) {
@@ -18,8 +18,12 @@ export function reversePainterSortStable(a: RenderItem, b: RenderItem) {
1818
}
1919
let az = a.z
2020
let bz = b.z
21-
const aDistanceRef = (a.object as any)[cameraDistanceKey] as WithCameraDistance | undefined
22-
const bDistanceRef = (b.object as any)[cameraDistanceKey] as WithCameraDistance | undefined
21+
const aDistanceRef = (a.object as any)[reversePainterSortStableCacheKey] as
22+
| WithReversePainterSortStableCache
23+
| undefined
24+
const bDistanceRef = (b.object as any)[reversePainterSortStableCacheKey] as
25+
| WithReversePainterSortStableCache
26+
| undefined
2327
if (aDistanceRef != null) {
2428
aDistanceRef.reversePainterSortStableCache ??= az
2529
az = aDistanceRef.reversePainterSortStableCache
@@ -28,14 +32,11 @@ export function reversePainterSortStable(a: RenderItem, b: RenderItem) {
2832
bDistanceRef.reversePainterSortStableCache ??= bz
2933
bz = bDistanceRef.reversePainterSortStableCache
3034
}
31-
if (aDistanceRef == null || bDistanceRef == null) {
32-
//default z comparison
33-
return az !== bz ? bz - az : a.id - b.id
34-
}
35-
if (aDistanceRef === bDistanceRef) {
35+
if (aDistanceRef != null && aDistanceRef === bDistanceRef) {
3636
return compareOrderInfo((a.object as any)[orderInfoKey].value, (b.object as any)[orderInfoKey].value)
3737
}
38-
return bDistanceRef.cameraDistance - aDistanceRef.cameraDistance
38+
//default z comparison
39+
return az !== bz ? bz - az : a.id - b.id
3940
}
4041

4142
//the following order tries to represent the most common element order of the respective element types (e.g. panels are most likely the background element)
@@ -163,10 +164,10 @@ function shallowEqualRecord(r1: Record<string, any> | undefined, r2: Record<stri
163164

164165
export function setupRenderOrder<T>(
165166
result: T,
166-
rootCameraDistance: WithCameraDistance,
167+
rootCameraDistance: WithReversePainterSortStableCache,
167168
orderInfo: { value: OrderInfo | undefined },
168169
): T {
169-
;(result as any)[cameraDistanceKey] = rootCameraDistance
170+
;(result as any)[reversePainterSortStableCacheKey] = rootCameraDistance
170171
;(result as any)[orderInfoKey] = orderInfo
171172
return result
172173
}

packages/uikit/src/panel/instanced-panel-group.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { MaterialClass, createPanelMaterial } from './panel-material.js'
1010
import { InstancedPanel } from './instanced-panel.js'
1111
import { InstancedPanelMesh } from './instanced-panel-mesh.js'
12-
import { ElementType, OrderInfo, WithCameraDistance, setupRenderOrder } from '../order.js'
12+
import { ElementType, OrderInfo, WithReversePainterSortStableCache, setupRenderOrder } from '../order.js'
1313
import { Signal, computed } from '@preact/signals-core'
1414
import { MergedProperties } from '../properties/merged.js'
1515
import { RootContext } from '../context.js'
@@ -48,7 +48,7 @@ export class PanelGroupManager {
4848
private map = new Map<MaterialClass, Map<string, InstancedPanelGroup>>()
4949

5050
constructor(
51-
private readonly root: WithCameraDistance &
51+
private readonly root: WithReversePainterSortStableCache &
5252
Pick<RootContext, 'onFrameSet' | 'requestFrame' | 'requestRender' | 'pixelSize'>,
5353
private readonly objectRef: { current?: Object3D | null },
5454
) {}
@@ -149,7 +149,7 @@ export class InstancedPanelGroup {
149149

150150
constructor(
151151
private readonly object: Object3D,
152-
public readonly root: WithCameraDistance & Pick<RootContext, 'requestFrame' | 'requestRender' | 'pixelSize'>,
152+
public readonly root: WithReversePainterSortStableCache & Pick<RootContext, 'requestFrame' | 'requestRender' | 'pixelSize'>,
153153
private readonly orderInfo: OrderInfo,
154154
private readonly panelGroupProperties: Required<PanelGroupProperties>,
155155
) {

packages/uikit/src/text/render/instanced-glyph-group.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { InstancedGlyph } from './instanced-glyph.js'
33
import { InstancedGlyphMesh } from './instanced-glyph-mesh.js'
44
import { InstancedGlyphMaterial } from './instanced-gylph-material.js'
55
import { Font } from '../font.js'
6-
import { ElementType, OrderInfo, WithCameraDistance, setupRenderOrder } from '../../order.js'
6+
import { ElementType, OrderInfo, WithReversePainterSortStableCache, setupRenderOrder } from '../../order.js'
77
import { RootContext } from '../../context.js'
88

99
export class GlyphGroupManager {
1010
private map = new Map<Font, Map<string, InstancedGlyphGroup>>()
1111
constructor(
12-
private readonly root: WithCameraDistance &
12+
private readonly root: WithReversePainterSortStableCache &
1313
Pick<RootContext, 'requestFrame' | 'requestRender' | 'onFrameSet' | 'pixelSize'>,
1414
private readonly objectRef: { current?: Object3D | null },
1515
) {}
@@ -78,7 +78,7 @@ export class InstancedGlyphGroup {
7878
constructor(
7979
private objectRef: { current?: Object3D | null },
8080
font: Font,
81-
public readonly root: WithCameraDistance & Pick<RootContext, 'requestFrame' | 'requestRender' | 'pixelSize'>,
81+
public readonly root: WithReversePainterSortStableCache & Pick<RootContext, 'requestFrame' | 'requestRender' | 'pixelSize'>,
8282
private orderInfo: OrderInfo,
8383
depthTest: boolean,
8484
depthWrite: boolean,

0 commit comments

Comments
 (0)