Skip to content

Port Scrolling Texture Interpolation over from 2Ship#6224

Merged
serprex merged 16 commits intoHarbourMasters:developfrom
leggettc18:feat/interpolation/scrolling-texture
Feb 26, 2026
Merged

Port Scrolling Texture Interpolation over from 2Ship#6224
serprex merged 16 commits intoHarbourMasters:developfrom
leggettc18:feat/interpolation/scrolling-texture

Conversation

@leggettc18
Copy link
Copy Markdown
Contributor

@leggettc18 leggettc18 commented Feb 2, 2026

Big thanks to @Eblo and @NEstelami, this is porting over the implementation by @NEstelami from 2ship and applying to Ship's code.

Known issues with the current implementation, some of these may just be errors on my part, some are deeper issues:

  • Deku Tree kind of "shimmers" best I can tell he has a scrolling texture for his death animation and it keeps trying to interpolate to the next frame, but in game the texture doesn't actually start scrolling until later.
  • Like Likes have a similar thing going on when they are stunned.
  • Great Fairy Fountain walls need to be double checked. They might be fine but they are visually busy so it's hard to tell. (Now that I've had a chance to directly compare these, they are interpolating fine after all)
  • Same for Spiritual Stones, they might be fine but I can't even really tell where the scrolling texture even is.
  • Water Temple Waterfall room before Dark Link, water does not appear to be interpolated correctly.
  • Water Spouts (like the one covering the map chest in Water Temple) aren't interpolating correctly.
  • Logo Screens (LUS and N64 logos) have weird flickering happening when you soft-reset the game. I either accidentally fixed this or it is Debug build exclusive, need to do more investigation.
  • Blue Warps need to be double checked, they might be fine but something seemed off when I last looked at one. I copied what 2ship did. It looks fine in game as far as I can tell.
  • Morpha's inner core looks fine but the outer shell looks off. (Did a direct comparison, Morpha just always looked like that)
  • Boss Souls may not look right, I haven't checked them yet but I have a feeling I made a mistake there somewhere.

Might be more too, haven't finished my vanilla playthrough for playtesting. Overall my playtest playthrough has been going well, and seeing all the smoothed out scrolling textures is very pleasing on the eyes. Areas like Zora's Domain and Water temple are quite stunning with the scrolling textures interpolated. Wanted to go ahead and get the PR opened for this so other people could have a gander and see if they can find any issues I haven't noticed.

Build Artifacts

@leggettc18 leggettc18 added the do not merge Not ready or not valid changes label Feb 2, 2026
@leggettc18 leggettc18 removed the do not merge Not ready or not valid changes label Feb 2, 2026
@leggettc18
Copy link
Copy Markdown
Contributor Author

Removing do-not-merge as I think the "issues" that are left are either fixed or not actually issues, just me having trouble actually verifying if they are correct visually. Playtesting and feedback encouraged!

It looks like they have a scrolling texture that just doesn't actually move, or maybe this makes it so the texture doesn't actually rotate with the gem? Not sure but it looks more correct to me this way.
Not 100% sure if it's correct but it looks right.
@leggettc18
Copy link
Copy Markdown
Contributor Author

Found some minor issues with Phantom Ganon and the fire in the cutscene with the deku tree sprout afterwards, have PG already fixed locally but the fire in the cutscene is giving me a hard time.

@leggettc18
Copy link
Copy Markdown
Contributor Author

On closer inspection I think the fire might have been fine, everything I've tried to do to fix it has looked worse. I think it looking choppy to me before might have been an optical illusion since there is a low enough offscreen that I only see the points of the animation where flames are higher.

@serprex
Copy link
Copy Markdown
Member

serprex commented Feb 26, 2026

for reference: HarbourMasters/2ship2harkinian#1332

@Malkierian seems pretty impactful to base code, but consistency with 2ship seems good, would like your take

@Malkierian
Copy link
Copy Markdown
Contributor

I don't think we really have to worry about the affect on base, because it's not really adding anything, but instead changing things that were already changed previously.

Copy link
Copy Markdown
Contributor

@Malkierian Malkierian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preliminary approval, though I think I might want to test it myself first.

@Malkierian
Copy link
Copy Markdown
Contributor

I think the biggest showcase of this experience is the torch fire. Holy crap, what a difference that interpolation makes.

:shipit:

@serprex serprex merged commit d4d3e8b into HarbourMasters:develop Feb 26, 2026
6 checks passed
spencerduncan pushed a commit to spencerduncan/redshipblueship that referenced this pull request Apr 24, 2026
Ports upstream SOH commit d4d3e8bc0 ("Port Scrolling Texture
Interpolation over from 2Ship", HarbourMasters/Shipwright#6224) so
scrolling textures (Lost Woods water, Zora's Domain, Water Temple
currents, fire/lava effects, boss textures, etc.) interpolate smoothly
at high framerates instead of stepping once per 20 Hz game tick.

Core wire-up
- games/oot/soh/OTRGlobals.cpp: in RunCommands, reset
  Interpreter::mInterpolationIndex to 0 before the mtx-replacement
  draw loop and increment it per sub-frame.
- games/oot/soh/OTRGlobals.{cpp,h}: expose Ship_GetInterpolationFPS()
  and Ship_GetInterpolationFrameCount() (ceil(fps/20)) as extern "C"
  so C game code can ask how many interpolated sub-frames to emit.
- games/oot/soh/GbiWrap.cpp: add the gDPSetTileSizeInterp wrapper that
  emits the G_SETTILESIZE_INTERP opcode with float tile coordinates.
- games/oot/include/functions.h: declare gDPSetTileSizeInterp,
  OoT_Gfx_TexScrollEx, OoT_Gfx_TwoTexScrollEx,
  OoT_Gfx_TwoTexScrollEnvColorEx.

New RCP helpers (games/oot/src/code/z_rcp.c)
- OoT_Gfx_TexScrollEx / OoT_Gfx_TwoTexScrollEx /
  OoT_Gfx_TwoTexScrollEnvColorEx take per-axis step deltas and
  generate one gDPSetInterpolation + gDPSetTileSizeInterp pair per
  interpolated sub-frame, advancing the tile origin by step/frames
  each iteration so the renderer has fractional tile positions to
  interpolate across. The existing non-Ex helpers are kept for
  compatibility.

Call-site updates
~100 actors/effects/draw routines switch their scrolling-texture
calls from the non-interpolated helpers to the *Ex variants with
the original per-frame step values passed through (e.g. the
(-20 - flameScrollMod*-2) in En_Bb's flame scroll).

RSBS fork adjustments
All renamed helpers keep the existing OoT_ prefix used throughout
this tree (OoT_Gfx_TwoTexScroll, OoT_Matrix_Translate, etc.) so the
single-executable symbol layout stays intact; only the *Ex variants
are added alongside.

libultraship
No submodule bump required. The vendored libultraship at
d11cc8c48b already exposes Fast::Fast3dWindow::GetInterpreterWeak(),
Interpreter::mInterpolationIndex, G_SETTILESIZE_INTERP,
__gDPSetTileSizeInterp, and gDPSetInterpolation.

Scope matches upstream: 109 files, +925 / -675 — no deletions or
refactors beyond the upstream commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
spencerduncan pushed a commit to spencerduncan/redshipblueship that referenced this pull request Apr 24, 2026
Ports upstream SOH commit d4d3e8bc0 ("Port Scrolling Texture
Interpolation over from 2Ship", HarbourMasters/Shipwright#6224) so
scrolling textures (Lost Woods water, Zora's Domain, Water Temple
currents, fire/lava effects, boss textures, etc.) interpolate smoothly
at high framerates instead of stepping once per 20 Hz game tick.

Core wire-up
- games/oot/soh/OTRGlobals.cpp: in RunCommands, reset
  Interpreter::mInterpolationIndex to 0 before the mtx-replacement
  draw loop and increment it per sub-frame.
- games/oot/soh/OTRGlobals.{cpp,h}: expose Ship_GetInterpolationFPS()
  and Ship_GetInterpolationFrameCount() (ceil(fps/20)) as extern "C"
  so C game code can ask how many interpolated sub-frames to emit.
- games/oot/soh/GbiWrap.cpp: add the gDPSetTileSizeInterp wrapper that
  emits the G_SETTILESIZE_INTERP opcode with float tile coordinates.
- games/oot/include/functions.h: declare gDPSetTileSizeInterp,
  OoT_Gfx_TexScrollEx, OoT_Gfx_TwoTexScrollEx,
  OoT_Gfx_TwoTexScrollEnvColorEx.

New RCP helpers (games/oot/src/code/z_rcp.c)
- OoT_Gfx_TexScrollEx / OoT_Gfx_TwoTexScrollEx /
  OoT_Gfx_TwoTexScrollEnvColorEx take per-axis step deltas and
  generate one gDPSetInterpolation + gDPSetTileSizeInterp pair per
  interpolated sub-frame, advancing the tile origin by step/frames
  each iteration so the renderer has fractional tile positions to
  interpolate across. The existing non-Ex helpers are kept for
  compatibility.

Call-site updates
~100 actors/effects/draw routines switch their scrolling-texture
calls from the non-interpolated helpers to the *Ex variants with
the original per-frame step values passed through (e.g. the
(-20 - flameScrollMod*-2) in En_Bb's flame scroll).

RSBS fork adjustments
All renamed helpers keep the existing OoT_ prefix used throughout
this tree (OoT_Gfx_TwoTexScroll, OoT_Matrix_Translate, etc.) so the
single-executable symbol layout stays intact; only the *Ex variants
are added alongside.

libultraship
No submodule bump required. The vendored libultraship at
d11cc8c48b already exposes Fast::Fast3dWindow::GetInterpreterWeak(),
Interpreter::mInterpolationIndex, G_SETTILESIZE_INTERP,
__gDPSetTileSizeInterp, and gDPSetInterpolation.

Scope matches upstream: 109 files, +925 / -675 — no deletions or
refactors beyond the upstream commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants