Skip to content

Commit

Permalink
J3D: More cleanups related to cameras
Browse files Browse the repository at this point in the history
* Add dCamera_c to Wind Waker
* Replace fillSceneParams with manual coding in most places
* Use new `transfer` method to realloc ArrayBuffers rather than creating and copying
  • Loading branch information
magcius committed Dec 24, 2024
1 parent fbceb42 commit 562d726
Show file tree
Hide file tree
Showing 30 changed files with 438 additions and 379 deletions.
14 changes: 1 addition & 13 deletions src/DebugJunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { ReadonlyMat4, ReadonlyVec3, ReadonlyVec4, mat4, vec3, vec4 } from "gl-matrix";
import ArrayBufferSlice from "./ArrayBufferSlice.js";
import { ScreenSpaceProjection, divideByW } from "./Camera.js";
import { divideByW } from "./Camera.js";
import { Blue, Color, Green, Magenta, OpaqueBlack, Red, colorToCSS } from "./Color.js";
import { downloadBuffer, downloadBufferSlice } from "./DownloadUtils.js";
import { AABB } from "./Geometry.js";
Expand Down Expand Up @@ -317,18 +317,6 @@ export function drawScreenSpaceBox(ctx: CanvasRenderingContext2D, x1: number, y1
ctx.stroke();
}

export function drawScreenSpaceProjection(ctx: CanvasRenderingContext2D, proj: ScreenSpaceProjection, color: Color = Magenta): void {
const cw = ctx.canvas.width;
const ch = ctx.canvas.height;

const x1 = (proj.projectedMinX + 1) * cw / 2;
const x2 = (proj.projectedMaxX + 1) * cw / 2;
const y1 = (-proj.projectedMinY + 1) * ch / 2;
const y2 = (-proj.projectedMaxY + 1) * ch / 2;

drawScreenSpaceBox(ctx, x1, y1, x2, y2, color);
}

function flashItem(item: any, fieldName: string, step: number = 0) {
item[fieldName] = step % 2 === 1;
if (step < 7)
Expand Down
7 changes: 5 additions & 2 deletions src/PaperMarioTTYD/render.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import { BasicGXRendererHelper, ColorKind, DrawParams, fillSceneParams, fillSceneParamsData, fillSceneParamsDataOnTemplate, GXMaterialHelperGfx, GXShapeHelperGfx, GXTextureHolder, loadedDataCoalescerComboGfx, MaterialParams, SceneParams, translateWrapModeGfx, ub_SceneParamsBufferSize } from '../gx/gx_render.js';
import { BasicGXRendererHelper, calcLODBias, ColorKind, DrawParams, fillSceneParamsData, fillSceneParamsDataOnTemplate, GXMaterialHelperGfx, GXShapeHelperGfx, GXTextureHolder, loadedDataCoalescerComboGfx, MaterialParams, SceneParams, translateWrapModeGfx, ub_SceneParamsBufferSize } from '../gx/gx_render.js';

import * as TPL from './tpl.js';
import { AnimationEntry, Batch, bindMaterialAnimator, bindMeshAnimator, CollisionFlags, DrawModeFlags, Material, MaterialAnimator, MaterialLayer, MeshAnimator, Sampler, SceneGraphNode, SceneGraphPart, TTYDWorld } from './world.js';
Expand Down Expand Up @@ -321,6 +321,8 @@ class NodeInstance {
template.setMegaStateFlags(this.megaStateFlags);

if (this.isDecal) {
// TODO(jstpierre): Fix this math.
//
// The game will actually adjust the projection matrix based on the child index, if the decal flag
// is set. This happens in _mapDispMapObj.
//
Expand All @@ -340,7 +342,8 @@ class NodeInstance {
if (depthBias !== 1.0) {
let offs = template.allocateUniformBuffer(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize);
const d = template.mapUniformBufferF32(GX_Program.ub_SceneParams);
fillSceneParams(sceneParams, viewerInput.camera.projectionMatrix, viewerInput.backbufferWidth, viewerInput.backbufferHeight);
mat4.copy(sceneParams.u_Projection, viewerInput.camera.projectionMatrix);
sceneParams.u_SceneTextureLODBias = calcLODBias(viewerInput.backbufferWidth, viewerInput.backbufferHeight);

projectionMatrixConvertClipSpaceNearZ(sceneParams.u_Projection, GfxClipSpaceNearZ.Zero, camera.clipSpaceNearZ);
sceneParams.u_Projection[10] *= depthBias;
Expand Down
5 changes: 1 addition & 4 deletions src/SourceEngine/BSPFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -978,10 +978,7 @@ class ResizableArrayBuffer {

if (byteSize > this.byteCapacity) {
this.byteCapacity = Math.max(byteSize, this.byteCapacity * 2);
const oldBuffer = this.buffer;
const newBuffer = new ArrayBuffer(this.byteCapacity);
new Uint8Array(newBuffer).set(new Uint8Array(oldBuffer));
this.buffer = newBuffer;
this.buffer = this.buffer.transfer(this.byteCapacity);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/StarFoxAdventures/Sky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TDDraw } from "../SuperMarioGalaxy/DDraw.js";
import * as GX from '../gx/gx_enum.js';
import * as GX_Material from '../gx/gx_material.js';
import { GXMaterialBuilder } from '../gx/GXMaterialBuilder.js';
import { DrawParams, GXMaterialHelperGfx, MaterialParams, fillSceneParamsDataOnTemplate, SceneParams, fillSceneParams, fillSceneParamsData, GXRenderHelperGfx } from '../gx/gx_render.js';
import { DrawParams, GXMaterialHelperGfx, MaterialParams, fillSceneParamsDataOnTemplate, SceneParams, fillSceneParamsData, GXRenderHelperGfx, calcLODBias } from '../gx/gx_render.js';
import { getMatrixAxisZ } from '../MathHelpers.js';

import { ObjectRenderContext } from './objects.js';
Expand Down Expand Up @@ -55,7 +55,8 @@ export class Sky {
const template = renderHelper.pushTemplateRenderInst();

// Setup to draw in clip space
fillSceneParams(scratchSceneParams, mat4.create(), sceneCtx.viewerInput.backbufferWidth, sceneCtx.viewerInput.backbufferHeight);
mat4.identity(scratchSceneParams.u_Projection);
scratchSceneParams.u_SceneTextureLODBias = calcLODBias(sceneCtx.viewerInput.backbufferWidth, sceneCtx.viewerInput.backbufferHeight);
projectionMatrixConvertClipSpaceNearZ(scratchSceneParams.u_Projection, device.queryVendorInfo().clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne);
let offs = template.getUniformBufferOffset(GX_Material.GX_Program.ub_SceneParams);
const d = template.mapUniformBufferF32(GX_Material.GX_Program.ub_SceneParams);
Expand Down
7 changes: 3 additions & 4 deletions src/StarFoxAdventures/SphereMaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GfxrAttachmentSlot, GfxrGraphBuilder, GfxrPass, GfxrPassScope, GfxrRend
import { GfxRenderInstList, GfxRenderInstManager } from '../gfx/render/GfxRenderInstManager.js';
import * as GX from '../gx/gx_enum.js';
import * as GX_Material from '../gx/gx_material.js';
import { ColorKind, DrawParams, fillSceneParams, fillSceneParamsData, gxBindingLayouts, GXRenderHelperGfx, MaterialParams, SceneParams, ub_SceneParamsBufferSize } from '../gx/gx_render.js';
import { ColorKind, DrawParams, fillSceneParamsData, gxBindingLayouts, GXRenderHelperGfx, MaterialParams, SceneParams, ub_SceneParamsBufferSize } from '../gx/gx_render.js';
import { projectionMatrixForCuboid, setMatrixTranslation, Vec3Zero } from '../MathHelpers.js';
import { TSDraw } from "../SuperMarioGalaxy/DDraw.js";
import { TextureMapping } from '../TextureHolder.js';
Expand Down Expand Up @@ -55,8 +55,6 @@ function setSpecularLightAtten(light: GX_Material.Light, atten: number) {
}

const SPHERE_MAP_DIM = 32;
const SPHERE_MAP_PROJECTION_MTX = mat4.create();
projectionMatrixForCuboid(SPHERE_MAP_PROJECTION_MTX, 1.0, -1.0, -1.0, 1.0, 1.0, 15.0); // Yes, left and right are meant to be 1 and -1, respectively.

function createHemisphericProbeMaterial(materialFactory: MaterialFactory): SFAMaterialBuilder<World> {
const mb = new SFAMaterialBuilder<World>('Ambient Hemispheric Probe Material');
Expand Down Expand Up @@ -282,7 +280,8 @@ export class SphereMapManager {
renderInst.setBindingLayouts(gxBindingLayouts);

// Setup to draw in clip space
fillSceneParams(scratchSceneParams, SPHERE_MAP_PROJECTION_MTX, SPHERE_MAP_DIM, SPHERE_MAP_DIM);
projectionMatrixForCuboid(scratchSceneParams.u_Projection, 1.0, -1.0, -1.0, 1.0, 1.0, 15.0); // Yes, left and right are meant to be 1 and -1, respectively.
scratchSceneParams.u_SceneTextureLODBias = 0;
projectionMatrixConvertClipSpaceNearZ(scratchSceneParams.u_Projection, device.queryVendorInfo().clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne);
let offs = renderInst.allocateUniformBuffer(GX_Material.GX_Program.ub_SceneParams, ub_SceneParamsBufferSize);
const d = renderInst.mapUniformBufferF32(GX_Material.GX_Program.ub_SceneParams);
Expand Down
10 changes: 4 additions & 6 deletions src/StarFoxAdventures/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GfxrAttachmentSlot, GfxrGraphBuilder, GfxrPass, GfxrPassScope, GfxrRend
import { GfxRenderInst, GfxRenderInstList, GfxRenderInstManager } from "../gfx/render/GfxRenderInstManager.js";
import * as GX from '../gx/gx_enum.js';
import * as GX_Material from '../gx/gx_material.js';
import { DrawParams, fillSceneParams, fillSceneParamsData, GXMaterialHelperGfx, GXRenderHelperGfx, MaterialParams, SceneParams } from '../gx/gx_render.js';
import { DrawParams, fillSceneParamsData, fillSceneParamsDataOnTemplate, GXMaterialHelperGfx, GXRenderHelperGfx, MaterialParams, SceneParams } from '../gx/gx_render.js';
import { TDDraw } from '../SuperMarioGalaxy/DDraw.js';
import { TextureMapping } from '../TextureHolder.js';
import { nArray } from '../util.js';
Expand Down Expand Up @@ -38,9 +38,6 @@ export interface SceneRenderContext {

const BACKGROUND_COLOR = colorNewFromRGBA8(0xCCCCCCFF);

const SCREENSPACE_ORTHO_MTX = mat4.create();
mat4.ortho(SCREENSPACE_ORTHO_MTX, 0.0, 640.0, 0.0, 480.0, 1.0, 100.0);

export interface SFARenderLists {
skyscape: GfxRenderInstList;
world: GfxRenderInstList[/* 3 */];
Expand Down Expand Up @@ -142,11 +139,12 @@ export class SFARenderer implements Viewer.SceneGfx {
const template = this.renderHelper.pushTemplateRenderInst();

// Setup to draw in screen space
fillSceneParams(scratchSceneParams, SCREENSPACE_ORTHO_MTX, sceneCtx.viewerInput.backbufferWidth, sceneCtx.viewerInput.backbufferHeight);
mat4.ortho(scratchSceneParams.u_Projection, 0.0, 640.0, 0.0, 480.0, 1.0, 100.0);
scratchSceneParams.u_SceneTextureLODBias = 0;
let offs = template.getUniformBufferOffset(GX_Material.GX_Program.ub_SceneParams);
const d = template.mapUniformBufferF32(GX_Material.GX_Program.ub_SceneParams);
fillSceneParamsData(d, offs, scratchSceneParams);

// Extract pitch
const cameraFwd = scratchVec0;
getMatrixAxisZ(cameraFwd, sceneCtx.viewerInput.camera.worldMatrix);
Expand Down
14 changes: 7 additions & 7 deletions src/SuperMarioGalaxy/Actors/GalaxyMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { GfxClipSpaceNearZ, GfxFormat } from "../../gfx/platform/GfxPlatform.js"
import { GfxRenderInstList, GfxRenderInstManager } from "../../gfx/render/GfxRenderInstManager.js";
import { GfxrAttachmentSlot, GfxrRenderTargetDescription, GfxrRenderTargetID } from "../../gfx/render/GfxRenderGraph.js";
import { GX_Program } from "../../gx/gx_material.js";
import { fillSceneParams, fillSceneParamsData, SceneParams, ub_SceneParamsBufferSize } from "../../gx/gx_render.js";
import { calcLODBias, fillSceneParamsData, SceneParams, ub_SceneParamsBufferSize } from "../../gx/gx_render.js";
import { projectionMatrixForCuboid, getMatrixTranslation } from "../../MathHelpers.js";
import { assertExists } from "../../util.js";
import { connectToScene } from "../ActorUtil.js";
Expand Down Expand Up @@ -396,15 +396,15 @@ export class GalaxyMapController extends LayoutActor<GalaxyMapControllerNrv> {

const template = renderInstManager.pushTemplate();

let offs = template.allocateUniformBuffer(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize);
const d = template.mapUniformBufferF32(GX_Program.ub_SceneParams);
const d = template.allocateUniformBufferF32(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize);

const sceneParams = new SceneParams();
const w = 604, h = 456;
projectionMatrixForCuboid(scratchMatrix, -w / 2, w / 2, -h / 2, h / 2, -10000.0, 10000.0);
projectionMatrixForCuboid(sceneParams.u_Projection, -w / 2, w / 2, -h / 2, h / 2, -10000.0, 10000.0);
const clipSpaceNearZ = renderInstManager.gfxRenderCache.device.queryVendorInfo().clipSpaceNearZ;
projectionMatrixConvertClipSpaceNearZ(scratchMatrix, clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne);
fillSceneParams(sceneParams, scratchMatrix, desc.width, desc.height);
fillSceneParamsData(d, offs, sceneParams);
projectionMatrixConvertClipSpaceNearZ(sceneParams.u_Projection, clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne);
sceneParams.u_SceneTextureLODBias = calcLODBias(desc.width, desc.height);
fillSceneParamsData(d, 0, sceneParams);

scratchDrawInfo.aspectAdjust = true;
scratchDrawInfo.aspectAdjustScaleX = 0.75;
Expand Down
5 changes: 2 additions & 3 deletions src/SuperMarioGalaxy/ClipArea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -709,9 +709,8 @@ export class FallOutFieldDraw extends NameObj {
}

private allocateParameterBuffer(renderInst: GfxRenderInst) {
let offs = renderInst.allocateUniformBuffer(0, 8);
const d = renderInst.mapUniformBufferF32(0);

const d = renderInst.allocateUniformBufferF32(0, 8);
let offs = 0;
offs += fillColor(d, offs, this.edgeColor);
offs += fillVec4(d, offs, this.invert ? 1.0 : 0.0);
}
Expand Down
13 changes: 7 additions & 6 deletions src/SuperMarioGalaxy/ImageEffect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@ export class BloomEffect extends ImageEffectBase {
}

private allocateParameterBuffer(renderInst: GfxRenderInst) {
let offs = renderInst.allocateUniformBuffer(0, 4);
const d = renderInst.mapUniformBufferF32(0);
const d = renderInst.allocateUniformBufferF32(0, 4);

const bloomIntensity = (this.bloomIntensity * this.strength) / 0xFF;
const threshold = this.threshold / 0xFF;
const intensity1 = this.intensity1 / 0xFF;
const intensity2 = this.intensity2 / 0xFF;

let offs = 0;
offs += fillVec4(d, offs, bloomIntensity, threshold, intensity1, intensity2);
}

Expand Down Expand Up @@ -490,13 +490,13 @@ export class BloomEffectSimple extends ImageEffectBase {
}

private allocateParameterBuffer(renderInst: GfxRenderInst) {
let offs = renderInst.allocateUniformBuffer(0, 4);
const d = renderInst.mapUniformBufferF32(0);
const d = renderInst.allocateUniformBufferF32(0, 4);

const maskFilter = this.maskFilter;
const threshold = this.threshold / 0xFF;
const intensity = (this.intensity * this.strength);

let offs = 0;
offs += fillVec4(d, offs, maskFilter, threshold, intensity);
}

Expand Down Expand Up @@ -656,12 +656,13 @@ export class DepthOfFieldBlur extends ImageEffectBase {
}

private allocateParameterBuffer(renderInst: GfxRenderInst) {
let offs = renderInst.allocateUniformBuffer(0, 4);
const d = renderInst.mapUniformBufferF32(0);
const d = renderInst.allocateUniformBufferF32(0, 4);

const intensity = this.intensity * this.strength;
const blurMaxDist = fallback(this.blurMaxDist, 0xF8) / 0xFF;
const blurMinDist = fallback(this.blurMinDist, 0xF2) / 0xFF;

let offs = 0;
offs += fillVec4(d, offs, intensity, blurMaxDist, blurMinDist, IsDepthReversed ? 1.0 : 0.0);
}

Expand Down
11 changes: 6 additions & 5 deletions src/SuperMarioGalaxy/Main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { setBackbufferDescSimple, standardFullClearRenderPassDescriptor } from '
import { gfxDeviceNeedsFlipY } from '../gfx/helpers/GfxDeviceHelpers.js';
import { projectionMatrixConvertClipSpaceNearZ } from '../gfx/helpers/ProjectionHelpers.js';

import { SceneParams, fillSceneParams, ub_SceneParamsBufferSize, fillSceneParamsData } from '../gx/gx_render.js';
import { SceneParams, ub_SceneParamsBufferSize, fillSceneParamsData, calcLODBias } from '../gx/gx_render.js';
import { EFB_WIDTH, EFB_HEIGHT, GX_Program } from '../gx/gx_material.js';
import { GXRenderHelperGfx } from '../gx/gx_render.js';

Expand Down Expand Up @@ -427,16 +427,17 @@ export class SMGRenderer implements Viewer.SceneGfx {
this.executeMovementList();
this.executeCalcAnimList();

sceneParams.u_SceneTextureLODBias = calcLODBias(viewerInput.backbufferWidth, viewerInput.backbufferHeight);

// Prepare our two scene params buffers.
const sceneParamsOffs3D = this.renderHelper.uniformBuffer.allocateChunk(ub_SceneParamsBufferSize);
fillSceneParams(sceneParams, viewerInput.camera.projectionMatrix, viewerInput.backbufferWidth, viewerInput.backbufferHeight);
mat4.copy(sceneParams.u_Projection, viewerInput.camera.projectionMatrix);
fillSceneParamsData(this.renderHelper.uniformBuffer.mapBufferF32(), sceneParamsOffs3D, sceneParams);
sceneObjHolder.renderParams.sceneParamsOffs3D = sceneParamsOffs3D;

const sceneParamsOffs2D = this.renderHelper.uniformBuffer.allocateChunk(ub_SceneParamsBufferSize);
projectionMatrixForCuboid(scratchMatrix, 0, viewerInput.backbufferWidth, 0, viewerInput.backbufferHeight, -10000.0, 10000.0);
projectionMatrixConvertClipSpaceNearZ(scratchMatrix, viewerInput.camera.clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne);
fillSceneParams(sceneParams, scratchMatrix, viewerInput.backbufferWidth, viewerInput.backbufferHeight);
projectionMatrixForCuboid(sceneParams.u_Projection, 0, viewerInput.backbufferWidth, 0, viewerInput.backbufferHeight, -10000.0, 10000.0);
projectionMatrixConvertClipSpaceNearZ(sceneParams.u_Projection, viewerInput.camera.clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne);
fillSceneParamsData(this.renderHelper.uniformBuffer.mapBufferF32(), sceneParamsOffs2D, sceneParams);
sceneObjHolder.renderParams.sceneParamsOffs2D = sceneParamsOffs2D;

Expand Down
4 changes: 2 additions & 2 deletions src/SuperMarioGalaxy/Shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1082,8 +1082,8 @@ class AlphaShadow extends NameObj {

// Blend onto main screen.
const renderInst = renderInstManager.newRenderInst();
const sceneParamsOffs = renderInst.allocateUniformBuffer(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize);
fillSceneParamsData(renderInst.mapUniformBufferF32(GX_Program.ub_SceneParams), sceneParamsOffs, this.orthoSceneParams);
const d = renderInst.allocateUniformBufferF32(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize);
fillSceneParamsData(d, 0, this.orthoSceneParams);
this.materialHelperDrawAlpha.setOnRenderInst(renderInstManager.gfxRenderCache, renderInst);
this.materialHelperDrawAlpha.allocateMaterialParamsDataOnInst(renderInst, materialParams);
renderInst.setSamplerBindingsFromTextureMappings(materialParams.m_TextureMapping);
Expand Down
2 changes: 1 addition & 1 deletion src/ZeldaTwilightPrincess/d_kankyo_wether.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1533,7 +1533,7 @@ function dKyr_sun_move(globals: dGlobals, deltaTimeFrames: number): void {

if (sunCanGlare) {
// Original game projects the vector into viewport space, and gets distance to 320, 240.
mDoLib_project(scratchVec3, pkt.sunPos, globals.camera);
mDoLib_project(scratchVec3, pkt.sunPos, globals.camera.clipFromWorldMatrix);

const peekZ = globals.dlst.peekZ;

Expand Down
Loading

0 comments on commit 562d726

Please sign in to comment.