Refactor: Improve readability of function signatures and calls in advanced rendering modules

This commit is contained in:
2026-04-26 05:38:23 +02:00
parent c685075efd
commit c550ca7634
4 changed files with 218 additions and 100 deletions

View File

@@ -96,8 +96,17 @@ class RenderLayerPass extends RenderPass {
deltaTime?: number,
stencilTest?: boolean
) {
renderWithCameraLayerMask(this.renderLayerCamera, this.renderLayerMask, () =>
super.render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest)
renderWithCameraLayerMask(
this.renderLayerCamera,
this.renderLayerMask,
() =>
super.render(
renderer,
inputBuffer,
outputBuffer,
deltaTime,
stencilTest
)
);
}
}
@@ -119,8 +128,17 @@ class RenderLayerNormalPass extends NormalPass {
deltaTime?: number,
stencilTest?: boolean
) {
renderWithCameraLayerMask(this.renderLayerCamera, this.renderLayerMask, () =>
super.render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest)
renderWithCameraLayerMask(
this.renderLayerCamera,
this.renderLayerMask,
() =>
super.render(
renderer,
inputBuffer,
outputBuffer,
deltaTime,
stencilTest
)
);
}
}
@@ -156,7 +174,9 @@ export interface ResolvedBoxVolumeRenderPaths {
water: BoxVolumeRenderPath;
}
export function resolveBoxVolumeRenderPaths(settings: AdvancedRenderingSettings): ResolvedBoxVolumeRenderPaths {
export function resolveBoxVolumeRenderPaths(
settings: AdvancedRenderingSettings
): ResolvedBoxVolumeRenderPaths {
if (!settings.enabled) {
return {
fog: "performance",
@@ -170,7 +190,9 @@ export function resolveBoxVolumeRenderPaths(settings: AdvancedRenderingSettings)
};
}
export function getAdvancedRenderingShadowMapType(shadowType: AdvancedRenderingShadowType) {
export function getAdvancedRenderingShadowMapType(
shadowType: AdvancedRenderingShadowType
) {
switch (shadowType) {
case "basic":
return BasicShadowMap;
@@ -181,7 +203,9 @@ export function getAdvancedRenderingShadowMapType(shadowType: AdvancedRenderingS
}
}
export function getAdvancedRenderingToneMappingMode(mode: AdvancedRenderingToneMappingMode): ToneMappingMode {
export function getAdvancedRenderingToneMappingMode(
mode: AdvancedRenderingToneMappingMode
): ToneMappingMode {
switch (mode) {
case "none":
return ToneMappingMode.LINEAR;
@@ -196,15 +220,23 @@ export function getAdvancedRenderingToneMappingMode(mode: AdvancedRenderingToneM
}
}
export function configureAdvancedRenderingRenderer(renderer: WebGLRenderer, settings: AdvancedRenderingSettings) {
export function configureAdvancedRenderingRenderer(
renderer: WebGLRenderer,
settings: AdvancedRenderingSettings
) {
renderer.shadowMap.enabled = settings.enabled && settings.shadows.enabled;
renderer.shadowMap.type = getAdvancedRenderingShadowMapType(settings.shadows.type);
renderer.shadowMap.type = getAdvancedRenderingShadowMapType(
settings.shadows.type
);
renderer.toneMapping = NoToneMapping;
renderer.toneMappingExposure = settings.toneMapping.exposure;
}
function clampAmbientOcclusionEffectRadius(radius: number) {
return Math.min(Math.max(radius, MIN_AMBIENT_OCCLUSION_EFFECT_RADIUS), MAX_AMBIENT_OCCLUSION_EFFECT_RADIUS);
return Math.min(
Math.max(radius, MIN_AMBIENT_OCCLUSION_EFFECT_RADIUS),
MAX_AMBIENT_OCCLUSION_EFFECT_RADIUS
);
}
function getAmbientOcclusionSampleCount(samples: number) {
@@ -224,7 +256,9 @@ export function createAdvancedRenderingComposer(
depthBuffer: true,
stencilBuffer: false,
multisampling: 0,
frameBufferType: renderer.capabilities.isWebGL2 ? HalfFloatType : UnsignedByteType
frameBufferType: renderer.capabilities.isWebGL2
? HalfFloatType
: UnsignedByteType
});
const mainRenderLayerMask = settings.ambientOcclusion.enabled
? AO_WORLD_RENDER_LAYER_MASK
@@ -243,7 +277,9 @@ export function createAdvancedRenderingComposer(
);
}
const effects: Array<BloomEffect | DepthOfFieldEffect | ToneMappingEffect | SMAAEffect> = [];
const effects: Array<
BloomEffect | DepthOfFieldEffect | ToneMappingEffect | SMAAEffect
> = [];
if (settings.ambientOcclusion.enabled) {
// postprocessing's internal depth-downsampling path writes zero normals unless
@@ -255,8 +291,12 @@ export function createAdvancedRenderingComposer(
);
composer.addPass(normalPass);
const ambientOcclusionRadius = clampAmbientOcclusionEffectRadius(settings.ambientOcclusion.radius);
const ambientOcclusionSamples = getAmbientOcclusionSampleCount(settings.ambientOcclusion.samples);
const ambientOcclusionRadius = clampAmbientOcclusionEffectRadius(
settings.ambientOcclusion.radius
);
const ambientOcclusionSamples = getAmbientOcclusionSampleCount(
settings.ambientOcclusion.samples
);
const detailAmbientOcclusionRadius = Math.max(
ambientOcclusionRadius * DETAIL_AMBIENT_OCCLUSION_RADIUS_SCALE,
MIN_AMBIENT_OCCLUSION_EFFECT_RADIUS
@@ -271,7 +311,9 @@ export function createAdvancedRenderingComposer(
resolutionScale: COARSE_AMBIENT_OCCLUSION_RESOLUTION_SCALE,
samples: ambientOcclusionSamples,
radius: ambientOcclusionRadius,
intensity: settings.ambientOcclusion.intensity * COARSE_AMBIENT_OCCLUSION_INTENSITY_SCALE
intensity:
settings.ambientOcclusion.intensity *
COARSE_AMBIENT_OCCLUSION_INTENSITY_SCALE
}),
new SSAOEffect(camera, normalPass.texture, {
depthAwareUpsampling: true,
@@ -279,7 +321,9 @@ export function createAdvancedRenderingComposer(
resolutionScale: DETAIL_AMBIENT_OCCLUSION_RESOLUTION_SCALE,
samples: ambientOcclusionSamples,
radius: detailAmbientOcclusionRadius,
intensity: settings.ambientOcclusion.intensity * DETAIL_AMBIENT_OCCLUSION_INTENSITY_SCALE
intensity:
settings.ambientOcclusion.intensity *
DETAIL_AMBIENT_OCCLUSION_INTENSITY_SCALE
})
)
);
@@ -336,7 +380,10 @@ export function createAdvancedRenderingComposer(
return composer;
}
export function applyAdvancedRenderingRenderableShadowFlags(root: Object3D, enabled: boolean) {
export function applyAdvancedRenderingRenderableShadowFlags(
root: Object3D,
enabled: boolean
) {
root.traverse((object) => {
if ((object as Mesh).isMesh === true) {
const mesh = object as Mesh;

View File

@@ -497,12 +497,15 @@ function smoothStep01(value: number) {
}
function normalizeDegrees(value: number) {
const wrapped = ((value + 180) % 360 + 360) % 360 - 180;
const wrapped = ((((value + 180) % 360) + 360) % 360) - 180;
return wrapped === -180 ? 180 : wrapped;
}
function resolveShortestAngleDeltaDegrees(fromDegrees: number, toDegrees: number) {
function resolveShortestAngleDeltaDegrees(
fromDegrees: number,
toDegrees: number
) {
return normalizeDegrees(toDegrees - fromDegrees);
}
@@ -602,7 +605,11 @@ type RuntimeResolvedCameraSource =
state: RuntimeDialogueAttentionState;
};
type TargetingLuxFlightState = "hidden" | "outbound" | "following" | "returning";
type TargetingLuxFlightState =
| "hidden"
| "outbound"
| "following"
| "returning";
export class RuntimeHost {
private readonly scene = new Scene();
@@ -635,7 +642,11 @@ export class RuntimeHost {
private readonly targetingActiveCameraUp = new Vector3();
private readonly targetingActiveArrowDirection = new Vector3();
private readonly targetingActiveArrowLocalTipAxis = new Vector3(0, 1, 0);
private readonly targetingActiveArrowGeometry = new ConeGeometry(0.16, 0.38, 16);
private readonly targetingActiveArrowGeometry = new ConeGeometry(
0.16,
0.38,
16
);
private readonly targetingActiveArrowMaterial = new MeshBasicMaterial({
color: 0xfff2a2,
depthTest: false,
@@ -648,7 +659,11 @@ export class RuntimeHost {
MeshBasicMaterial
>[] = Array.from(
{ length: TARGETING_ACTIVE_ARROW_COUNT },
() => new Mesh(this.targetingActiveArrowGeometry, this.targetingActiveArrowMaterial)
() =>
new Mesh(
this.targetingActiveArrowGeometry,
this.targetingActiveArrowMaterial
)
);
private readonly targetingLuxMesh = new Mesh(
new PlaneGeometry(0.32, 0.32),
@@ -767,8 +782,10 @@ export class RuntimeHost {
private activeCameraRigOverrideEntityId: string | null = null;
private activeCameraSourceKey: RuntimeCameraSourceKey | null = null;
private activeRuntimeCameraRig: RuntimeCameraRig | null = null;
private activeDialogueAttentionState: RuntimeDialogueAttentionState | null = null;
private dialogueParticipantState: RuntimeDialogueParticipantState | null = null;
private activeDialogueAttentionState: RuntimeDialogueAttentionState | null =
null;
private dialogueParticipantState: RuntimeDialogueParticipantState | null =
null;
private cameraTransitionState: RuntimeCameraTransitionState | null = null;
private suppressNextCameraSourceTransition = false;
private cameraRigLookYawRadians = 0;
@@ -1611,14 +1628,13 @@ export class RuntimeHost {
return null;
}
const eyePosition =
this.currentPlayerControllerTelemetry?.eyePosition ?? {
x: this.runtimeScene.spawn.position.x,
y:
this.runtimeScene.spawn.position.y +
this.runtimeScene.playerCollider.eyeHeight,
z: this.runtimeScene.spawn.position.z
};
const eyePosition = this.currentPlayerControllerTelemetry?.eyePosition ?? {
x: this.runtimeScene.spawn.position.x,
y:
this.runtimeScene.spawn.position.y +
this.runtimeScene.playerCollider.eyeHeight,
z: this.runtimeScene.spawn.position.z
};
const feetPosition =
this.currentPlayerControllerTelemetry?.feetPosition ??
this.runtimeScene.spawn.position;
@@ -1661,7 +1677,9 @@ export class RuntimeHost {
}
this.camera.getWorldDirection(this.cameraForward);
return (Math.atan2(this.cameraForward.x, this.cameraForward.z) * 180) / Math.PI;
return (
(Math.atan2(this.cameraForward.x, this.cameraForward.z) * 180) / Math.PI
);
}
private resolvePlayerShapeHorizontalRadius() {
@@ -1798,9 +1816,13 @@ export class RuntimeHost {
for (let step = 1; step <= 8; step += 1) {
const t = step / 8;
const candidate = {
x: playerFeetPosition.x + (desiredFeetPosition.x - playerFeetPosition.x) * t,
x:
playerFeetPosition.x +
(desiredFeetPosition.x - playerFeetPosition.x) * t,
y: playerFeetPosition.y,
z: playerFeetPosition.z + (desiredFeetPosition.z - playerFeetPosition.z) * t
z:
playerFeetPosition.z +
(desiredFeetPosition.z - playerFeetPosition.z) * t
};
if (
@@ -1953,7 +1975,10 @@ export class RuntimeHost {
position: playerFeetPosition,
yawDegrees: state.playerCurrentYawDegrees
});
this.setRuntimeNpcYawDegrees(state.npcEntityId, state.npcCurrentYawDegrees);
this.setRuntimeNpcYawDegrees(
state.npcEntityId,
state.npcCurrentYawDegrees
);
return;
}
@@ -1973,7 +1998,10 @@ export class RuntimeHost {
)
) <= DIALOGUE_PARTICIPANT_RESTORE_EPSILON_DEGREES
) {
this.setRuntimeNpcYawDegrees(state.npcEntityId, state.npcRestoreYawDegrees);
this.setRuntimeNpcYawDegrees(
state.npcEntityId,
state.npcRestoreYawDegrees
);
this.dialogueParticipantState = null;
}
}
@@ -2044,10 +2072,14 @@ export class RuntimeHost {
railEndProgress: rig.railEndProgress
});
return sampleResolvedScenePathPosition(path, mappedProgress.railProgress);
return sampleResolvedScenePathPosition(
path,
mappedProgress.railProgress
);
}
return resolveNearestPointOnResolvedScenePath(path, targetPosition).position;
return resolveNearestPointOnResolvedScenePath(path, targetPosition)
.position;
}
}
}
@@ -2269,19 +2301,20 @@ export class RuntimeHost {
return pose;
}
const resolvedPosition = this.collisionWorld?.resolveThirdPersonCameraCollision(
{
x: pose.collisionPivot.x,
y: pose.collisionPivot.y,
z: pose.collisionPivot.z
},
{
x: pose.position.x,
y: pose.position.y,
z: pose.position.z
},
pose.collisionRadius
);
const resolvedPosition =
this.collisionWorld?.resolveThirdPersonCameraCollision(
{
x: pose.collisionPivot.x,
y: pose.collisionPivot.y,
z: pose.collisionPivot.z
},
{
x: pose.position.x,
y: pose.position.y,
z: pose.position.z
},
pose.collisionRadius
);
if (resolvedPosition === undefined) {
this.resetRuntimeCameraCollisionSmoothing();
@@ -2308,7 +2341,8 @@ export class RuntimeHost {
private isActiveExternalCameraSource() {
return (
this.activeCameraSourceKey !== null && this.activeCameraSourceKey !== "gameplay"
this.activeCameraSourceKey !== null &&
this.activeCameraSourceKey !== "gameplay"
);
}
@@ -2459,7 +2493,8 @@ export class RuntimeHost {
return {
kind: "dialogue",
state:
this.activeDialogueAttentionState?.npcEntityId === dialogueNpc.entityId
this.activeDialogueAttentionState?.npcEntityId ===
dialogueNpc.entityId
? this.activeDialogueAttentionState
: {
npcEntityId: dialogueNpc.entityId,
@@ -4376,22 +4411,21 @@ export class RuntimeHost {
y: this.camera.position.y,
z: this.camera.position.z
});
const fogTelemetry =
this.isActiveExternalCameraSource()
? {
cameraSubmerged:
cameraVolumeState.inWater &&
cameraVolumeState.waterSurfaceHeight !== null &&
this.camera.position.y < cameraVolumeState.waterSurfaceHeight,
eyePosition: {
x: this.camera.position.x,
y: this.camera.position.y,
z: this.camera.position.z
}
const fogTelemetry = this.isActiveExternalCameraSource()
? {
cameraSubmerged:
cameraVolumeState.inWater &&
cameraVolumeState.waterSurfaceHeight !== null &&
this.camera.position.y < cameraVolumeState.waterSurfaceHeight,
eyePosition: {
x: this.camera.position.x,
y: this.camera.position.y,
z: this.camera.position.z
}
: this.activeController === this.firstPersonController
? this.currentPlayerControllerTelemetry
: null;
}
: this.activeController === this.firstPersonController
? this.currentPlayerControllerTelemetry
: null;
const fogState = resolveUnderwaterFogState(this.runtimeScene, fogTelemetry);
if (fogState === null) {
@@ -4974,7 +5008,10 @@ export class RuntimeHost {
this.activeController?.update(simulationDt);
this.refreshRuntimeTargetingState();
this.updateActiveRuntimeTargetLockState(cameraDt);
const activeCameraRig = this.applyActiveCameraRig(cameraDt, previousCameraPose);
const activeCameraRig = this.applyActiveCameraRig(
cameraDt,
previousCameraPose
);
this.updateRuntimeTargetingVisuals(cameraDt);
if (!this.isActiveExternalCameraSource() && activeCameraRig === null) {
@@ -5648,7 +5685,9 @@ export class RuntimeHost {
);
}
private setActiveRuntimeTargetReference(reference: RuntimeTargetReference | null) {
private setActiveRuntimeTargetReference(
reference: RuntimeTargetReference | null
) {
this.activeRuntimeTargetReference = reference;
this.activeRuntimeTargetOcclusionSeconds = 0;
this.runtimeTargetSwitchInputHeld = false;
@@ -5669,8 +5708,10 @@ export class RuntimeHost {
switch (npc.collider.mode) {
case "capsule":
return (
Math.max(npc.collider.radius, TARGETING_VISIBILITY_TARGET_CLEARANCE) +
TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING
Math.max(
npc.collider.radius,
TARGETING_VISIBILITY_TARGET_CLEARANCE
) + TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING
);
case "box":
return (
@@ -5682,8 +5723,7 @@ export class RuntimeHost {
) * 0.25,
0.35,
0.75
) +
TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING
) + TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING
);
case "none":
return 0.9 + TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING;
@@ -5717,7 +5757,8 @@ export class RuntimeHost {
point: { x: number; y: number; z: number };
targetClearance: number;
}> {
const targetClearance = this.resolveRuntimeTargetVisibilityClearance(target);
const targetClearance =
this.resolveRuntimeTargetVisibilityClearance(target);
if (this.runtimeScene !== null && target.kind === "npc") {
const npc =
@@ -5730,10 +5771,8 @@ export class RuntimeHost {
case "capsule": {
const collider = npc.collider;
const sampleClearance =
Math.max(
collider.radius,
TARGETING_VISIBILITY_TARGET_CLEARANCE
) + TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING;
Math.max(collider.radius, TARGETING_VISIBILITY_TARGET_CLEARANCE) +
TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING;
const yAt = (factor: number) =>
npc.position.y + collider.height * factor;
@@ -5757,11 +5796,8 @@ export class RuntimeHost {
const collider = npc.collider;
const sampleClearance =
clampScalar(
Math.max(
collider.size.x,
collider.size.y,
collider.size.z
) * 0.25,
Math.max(collider.size.x, collider.size.y, collider.size.z) *
0.25,
0.35,
0.75
) + TARGETING_VISIBILITY_TARGET_CLEARANCE_PADDING;
@@ -5855,7 +5891,8 @@ export class RuntimeHost {
center: { x: number; y: number; z: number };
range: number;
}): boolean {
const playerEyePosition = this.currentPlayerControllerTelemetry?.eyePosition;
const playerEyePosition =
this.currentPlayerControllerTelemetry?.eyePosition;
if (playerEyePosition === undefined) {
return false;
@@ -6034,7 +6071,9 @@ export class RuntimeHost {
y: number;
z: number;
}) {
const projected = new Vector3(point.x, point.y, point.z).project(this.camera);
const projected = new Vector3(point.x, point.y, point.z).project(
this.camera
);
if (
!Number.isFinite(projected.x) ||
@@ -6139,7 +6178,7 @@ export class RuntimeHost {
const playerEyePosition =
maxDistanceFromPlayer === null && !requirePlayerVisibility
? null
: this.currentPlayerControllerTelemetry?.eyePosition ?? null;
: (this.currentPlayerControllerTelemetry?.eyePosition ?? null);
let bestCandidate: RuntimeTargetCandidate | null = null;
let bestScreenDistanceSquared = Number.POSITIVE_INFINITY;
@@ -6169,7 +6208,9 @@ export class RuntimeHost {
continue;
}
const screenPoint = this.resolveRuntimeTargetScreenPoint(candidate.center);
const screenPoint = this.resolveRuntimeTargetScreenPoint(
candidate.center
);
if (
screenPoint === null ||
@@ -6354,7 +6395,9 @@ export class RuntimeHost {
visualPlacement.activeMarkerPosition.z
);
this.targetingActiveGroup.quaternion.identity();
this.targetingActiveGroup.scale.setScalar(visualPlacement.activeMarkerScale);
this.targetingActiveGroup.scale.setScalar(
visualPlacement.activeMarkerScale
);
this.targetingActiveCameraRight
.setFromMatrixColumn(this.camera.matrixWorld, 0)
.normalize();
@@ -6377,7 +6420,9 @@ export class RuntimeHost {
this.targetingActiveCameraUp,
Math.sin(angle) * localRadius
);
this.targetingActiveArrowDirection.copy(arrow.position).multiplyScalar(-1);
this.targetingActiveArrowDirection
.copy(arrow.position)
.multiplyScalar(-1);
if (this.targetingActiveArrowDirection.lengthSq() > Number.EPSILON) {
this.targetingActiveArrowDirection.normalize();
@@ -6447,7 +6492,8 @@ export class RuntimeHost {
this.targetingVisualTime += dtSeconds;
const visualPlacement = resolveRuntimeTargetVisualPlacement(visualTarget);
const bob = Math.sin(this.targetingVisualTime * TARGETING_LUX_BOB_RATE) * 0.08;
const bob =
Math.sin(this.targetingVisualTime * TARGETING_LUX_BOB_RATE) * 0.08;
const sway =
Math.sin(this.targetingVisualTime * TARGETING_LUX_SWAY_RATE) *
TARGETING_LUX_SWAY_DISTANCE;
@@ -6486,7 +6532,10 @@ export class RuntimeHost {
? TARGETING_LUX_FLIGHT_RATE
: TARGETING_LUX_FOLLOW_RATE) * dtSeconds
);
this.targetingLuxGroup.position.lerp(this.targetingLuxTargetPosition, alpha);
this.targetingLuxGroup.position.lerp(
this.targetingLuxTargetPosition,
alpha
);
if (
this.targetingLuxFlightState === "outbound" &&
@@ -6598,7 +6647,9 @@ export class RuntimeHost {
return;
}
if (event.code === this.runtimeScene.playerInputBindings.keyboard.pauseTime) {
if (
event.code === this.runtimeScene.playerInputBindings.keyboard.pauseTime
) {
event.preventDefault();
this.toggleManualPause();
this.previousPauseInputActive = true;

View File

@@ -4861,7 +4861,10 @@ export class ViewportHost {
}
private isSelectedRailCameraRigPathPreviewed(pathId: string): boolean {
if (this.currentDocument === null || this.currentSelection.kind !== "entities") {
if (
this.currentDocument === null ||
this.currentSelection.kind !== "entities"
) {
return false;
}