From b4ab7c363aa540e40b4cc020e94bd60adaf726a8 Mon Sep 17 00:00:00 2001 From: Ruffled <105522716+RuffledPlume@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:00:29 +0000 Subject: [PATCH 1/7] Bias GroundItems to ensure they sit above surfaces --- .../renderer/zone/ModelStreamingManager.java | 4 ++++ .../rs117/hd/renderer/zone/SceneUploader.java | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java index c69078ec0b..4b22cd58e1 100644 --- a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java +++ b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java @@ -457,6 +457,7 @@ public void drawDynamic( tileObject, modelOverride, cachedModel, + r, zone, isModelPartiallyVisible, hasAlpha, @@ -486,6 +487,7 @@ public void drawDynamic( tileObject, modelOverride, m, + r, zone, isModelPartiallyVisible, hasAlpha, @@ -505,6 +507,7 @@ private void uploadDynamicModel( TileObject tileObject, ModelOverride modelOverride, Model m, + Renderable r, Zone zone, boolean isModelPartiallyVisible, boolean hasAlpha, @@ -567,6 +570,7 @@ private void uploadDynamicModel( modelOverride, preOrientation, orient, + r instanceof TileItem ? 125 : 0, isSquashed, opaqueView, alphaView diff --git a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java index d0b06b884d..30db37040f 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java @@ -1910,6 +1910,19 @@ public boolean preprocessTempModel( return shouldSort; } + public void uploadTempModel( + PrimitiveIntArray faces, + Model model, + ModelOverride modelOverride, + int preOrientation, + int orientation, + boolean isShadow, + DynamicModelVAO.View opaqueView, + DynamicModelVAO.View alphaView + ) { + uploadTempModel(faces, model, modelOverride, preOrientation, orientation, 0, isShadow, opaqueView, alphaView); + } + // temp draw public void uploadTempModel( PrimitiveIntArray faces, @@ -1917,6 +1930,7 @@ public void uploadTempModel( ModelOverride modelOverride, int preOrientation, int orientation, + int modelBias, boolean isShadow, DynamicModelVAO.View opaqueView, DynamicModelVAO.View alphaView @@ -2058,8 +2072,8 @@ else if (color3 == -1) color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); } - final int depthBias = faceOverride.depthBias != -1 ? faceOverride.depthBias : - hasBias ? bias[face] & 0xFF : 0; + final int depthBias = ((faceOverride.depthBias != -1 ? faceOverride.depthBias : + hasBias ? bias[face] : 0) + modelBias) & 0xFF; final int packedAlphaBiasHsl = transparency << 24 | depthBias << 16; final boolean hasAlpha = material.hasTransparency || transparency != 0; From 437e7d9febf4d3b80cea1c7edf86fa709efae544 Mon Sep 17 00:00:00 2001 From: Ruffled <105522716+RuffledPlume@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:29:57 +0000 Subject: [PATCH 2/7] Only apply model bias if no faceBias present --- src/main/java/rs117/hd/renderer/zone/SceneUploader.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java index 30db37040f..7c7ba0f642 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java @@ -2072,8 +2072,10 @@ else if (color3 == -1) color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); } - final int depthBias = ((faceOverride.depthBias != -1 ? faceOverride.depthBias : - hasBias ? bias[face] : 0) + modelBias) & 0xFF; + int depthBias = (faceOverride.depthBias != -1 ? faceOverride.depthBias : + hasBias ? bias[face] & 0xFF : 0); + if(depthBias == 0) + depthBias = modelBias; final int packedAlphaBiasHsl = transparency << 24 | depthBias << 16; final boolean hasAlpha = material.hasTransparency || transparency != 0; From 8aab1eff9e09d1f9d23c3c28ac91bc6be1f684bd Mon Sep 17 00:00:00 2001 From: Ruffled <105522716+RuffledPlume@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:36:30 +0000 Subject: [PATCH 3/7] Add config option which defaults to enabled --- src/main/java/rs117/hd/HdPlugin.java | 2 ++ src/main/java/rs117/hd/HdPluginConfig.java | 10 ++++++++++ .../rs117/hd/renderer/zone/ModelStreamingManager.java | 4 +++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/rs117/hd/HdPlugin.java b/src/main/java/rs117/hd/HdPlugin.java index 202a59506f..cf71fb08a5 100644 --- a/src/main/java/rs117/hd/HdPlugin.java +++ b/src/main/java/rs117/hd/HdPlugin.java @@ -406,6 +406,7 @@ public class HdPlugin extends Plugin { public boolean configPowerSaving; public boolean configUnlitFaceColors; public boolean configUndoVanillaShading; + public boolean configTileItemBiasing; public boolean configPreserveVanillaNormals; public boolean configWindDisplacement; public boolean configCharacterDisplacement; @@ -1631,6 +1632,7 @@ private void updateCachedConfigs() { configShadingMode = config.shadingMode(); configUnlitFaceColors = configShadingMode.unlitFaceColors; configUndoVanillaShading = configShadingMode.undoVanillaShading; + configTileItemBiasing = config.tileItemBiasing(); configPreserveVanillaNormals = config.preserveVanillaNormals(); configWindDisplacement = config.windDisplacement(); configCharacterDisplacement = config.characterDisplacement(); diff --git a/src/main/java/rs117/hd/HdPluginConfig.java b/src/main/java/rs117/hd/HdPluginConfig.java index 2a2a000d2b..3ebf7323a6 100644 --- a/src/main/java/rs117/hd/HdPluginConfig.java +++ b/src/main/java/rs117/hd/HdPluginConfig.java @@ -864,6 +864,16 @@ default boolean vanillaColorBanding() { return false; } + String KEY_TILE_ITEM_BIASING = "tileItemBiasing"; + @ConfigItem( + keyName = KEY_TILE_ITEM_BIASING, + name = "Bias Dropped Items", + description = + "This applies a bias to Dropped items to ensure they are visible & not intersecting with tile surfaces.", + section = miscellaneousSettings + ) + default boolean tileItemBiasing() { return true; } + String KEY_LOW_MEMORY_MODE = "lowMemoryMode"; @ConfigItem( keyName = KEY_LOW_MEMORY_MODE, diff --git a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java index 4b22cd58e1..b483ca263b 100644 --- a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java +++ b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java @@ -564,13 +564,15 @@ private void uploadDynamicModel( final DynamicModelVAO.View opaqueView = ctx.beginDraw(VAO_OPAQUE, opaqueFaceCount); final DynamicModelVAO.View alphaView = alphaFaceCount > 0 ? ctx.beginDraw(VAO_ALPHA, alphaFaceCount) : opaqueView; + final int modelBias = plugin.configTileItemBiasing && r instanceof TileItem ? 125 : 0; + sceneUploader.uploadTempModel( visibleFaces, m, modelOverride, preOrientation, orient, - r instanceof TileItem ? 125 : 0, + modelBias, isSquashed, opaqueView, alphaView From 502de02c8ad1478cbb474fa8afeb4dae906e7f38 Mon Sep 17 00:00:00 2001 From: Hooder Date: Sat, 7 Mar 2026 13:35:10 +0100 Subject: [PATCH 4/7] Rephrase config & prioritize vanilla bias --- src/main/java/rs117/hd/HdPluginConfig.java | 5 ++--- .../rs117/hd/renderer/zone/ModelStreamingManager.java | 1 - src/main/java/rs117/hd/renderer/zone/SceneUploader.java | 8 +++----- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/rs117/hd/HdPluginConfig.java b/src/main/java/rs117/hd/HdPluginConfig.java index 3ebf7323a6..ca2a516aef 100644 --- a/src/main/java/rs117/hd/HdPluginConfig.java +++ b/src/main/java/rs117/hd/HdPluginConfig.java @@ -867,9 +867,8 @@ default boolean vanillaColorBanding() { String KEY_TILE_ITEM_BIASING = "tileItemBiasing"; @ConfigItem( keyName = KEY_TILE_ITEM_BIASING, - name = "Bias Dropped Items", - description = - "This applies a bias to Dropped items to ensure they are visible & not intersecting with tile surfaces.", + name = "Fix ground item clipping", + description = "Move ground items slightly, to prevent them from clipping into the ground.", section = miscellaneousSettings ) default boolean tileItemBiasing() { return true; } diff --git a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java index 9a5942e2f1..243efa0526 100644 --- a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java +++ b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java @@ -575,7 +575,6 @@ private void uploadDynamicModel( final DynamicModelVAO.View alphaView = alphaFaceCount > 0 ? ctx.beginDraw(VAO_ALPHA, alphaFaceCount) : opaqueView; final int modelBias = plugin.configTileItemBiasing && r instanceof TileItem ? 125 : 0; - sceneUploader.uploadTempModel( visibleFaces, m, diff --git a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java index da5f68fb60..6a298e3fb4 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java @@ -1970,7 +1970,7 @@ public void uploadTempModel( final byte[] bias = model.getFaceBias(); final int[] faceNormals = isShadow ? EMPTY_NORMALS : modelNormals; - final boolean hasBias = bias != null; + final boolean hasVanillaBias = bias != null; final boolean modelHasNormals = model.getVertexNormalsX() != null && model.getVertexNormalsY() != null && @@ -2079,10 +2079,8 @@ else if (color3 == -1) color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); } - int depthBias = (faceOverride.depthBias != -1 ? faceOverride.depthBias : - hasBias ? bias[face] & 0xFF : 0); - if(depthBias == 0) - depthBias = modelBias; + int depthBias = faceOverride.depthBias != -1 ? faceOverride.depthBias : + hasVanillaBias ? bias[face] & 0xFF : modelBias; final int packedAlphaBiasHsl = transparency << 24 | depthBias << 16; final boolean hasAlpha = material.hasTransparency || transparency != 0; From 03c451f601252f602110ca8ccbbbdd57a5580fef Mon Sep 17 00:00:00 2001 From: Hooder Date: Sat, 7 Mar 2026 13:42:10 +0100 Subject: [PATCH 5/7] Preserve per-face bias on top of model bias --- src/main/java/rs117/hd/renderer/zone/SceneUploader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java index 6a298e3fb4..dc7257114d 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java @@ -2080,7 +2080,8 @@ else if (color3 == -1) } int depthBias = faceOverride.depthBias != -1 ? faceOverride.depthBias : - hasVanillaBias ? bias[face] & 0xFF : modelBias; + hasVanillaBias ? bias[face] & 0xFF : 0; + depthBias = clamp(modelBias + depthBias, 0, 0xFF); final int packedAlphaBiasHsl = transparency << 24 | depthBias << 16; final boolean hasAlpha = material.hasTransparency || transparency != 0; From bf54631781c9bf1378a82f5485442be35659119a Mon Sep 17 00:00:00 2001 From: Ruffled <105522716+RuffledPlume@users.noreply.github.com> Date: Mon, 9 Mar 2026 19:03:33 +0000 Subject: [PATCH 6/7] Only Bias TileItem if the are ground objects --- .../hd/renderer/zone/ModelStreamingManager.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java index 243efa0526..2759284cde 100644 --- a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java +++ b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java @@ -449,6 +449,17 @@ public void drawDynamic( if (renderThreadId >= 0) client.checkClickbox(projection, m, orient, x, y, z, tileObject.getHash()); + final int tileExX = (x >> Perspective.LOCAL_COORD_BITS) + ctx.sceneContext.sceneOffset; + final int tileExY = (z >> Perspective.LOCAL_COORD_BITS) + ctx.sceneContext.sceneOffset; + + final int modelBias; + if(plugin.configTileItemBiasing && r instanceof TileItem) { + Tile tile = scene.getExtendedTiles()[tileObject.getPlane()][tileExX][tileExY]; + modelBias = tile != null && tile.getGroundObject() != null ? 125 : 0; + } else { + modelBias = 0; + } + final boolean isModelPartiallyVisible = sceneManager.isRoot(ctx) && modelClassification == 0; final AsyncCachedModel asyncModelCache = obtainAvailableAsyncCachedModel(renderThreadId >= 0); if (asyncModelCache != null) { @@ -471,6 +482,7 @@ public void drawDynamic( zone, isModelPartiallyVisible, hasAlpha, + modelBias, preOrientation, orient, x, y, z ); @@ -501,6 +513,7 @@ public void drawDynamic( zone, isModelPartiallyVisible, hasAlpha, + modelBias, preOrientation, orient, x, y, z ); @@ -521,6 +534,7 @@ private void uploadDynamicModel( Zone zone, boolean isModelPartiallyVisible, boolean hasAlpha, + int modelBias, int preOrientation, int orient, int x, @@ -574,7 +588,6 @@ private void uploadDynamicModel( final DynamicModelVAO.View opaqueView = ctx.beginDraw(VAO_OPAQUE, opaqueFaceCount); final DynamicModelVAO.View alphaView = alphaFaceCount > 0 ? ctx.beginDraw(VAO_ALPHA, alphaFaceCount) : opaqueView; - final int modelBias = plugin.configTileItemBiasing && r instanceof TileItem ? 125 : 0; sceneUploader.uploadTempModel( visibleFaces, m, From 5919fe38be017b2929f907830b1b7c871a4a6f25 Mon Sep 17 00:00:00 2001 From: Ruffled <105522716+RuffledPlume@users.noreply.github.com> Date: Mon, 9 Mar 2026 19:29:43 +0000 Subject: [PATCH 7/7] Bias Actors too --- src/main/java/rs117/hd/HdPlugin.java | 4 ++-- src/main/java/rs117/hd/HdPluginConfig.java | 10 +++++----- .../hd/renderer/zone/ModelStreamingManager.java | 17 ++++++++++++++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/rs117/hd/HdPlugin.java b/src/main/java/rs117/hd/HdPlugin.java index cf71fb08a5..e87bbf8a92 100644 --- a/src/main/java/rs117/hd/HdPlugin.java +++ b/src/main/java/rs117/hd/HdPlugin.java @@ -406,7 +406,7 @@ public class HdPlugin extends Plugin { public boolean configPowerSaving; public boolean configUnlitFaceColors; public boolean configUndoVanillaShading; - public boolean configTileItemBiasing; + public boolean configTileBiasing; public boolean configPreserveVanillaNormals; public boolean configWindDisplacement; public boolean configCharacterDisplacement; @@ -1632,7 +1632,7 @@ private void updateCachedConfigs() { configShadingMode = config.shadingMode(); configUnlitFaceColors = configShadingMode.unlitFaceColors; configUndoVanillaShading = configShadingMode.undoVanillaShading; - configTileItemBiasing = config.tileItemBiasing(); + configTileBiasing = config.tileBiasing(); configPreserveVanillaNormals = config.preserveVanillaNormals(); configWindDisplacement = config.windDisplacement(); configCharacterDisplacement = config.characterDisplacement(); diff --git a/src/main/java/rs117/hd/HdPluginConfig.java b/src/main/java/rs117/hd/HdPluginConfig.java index ca2a516aef..6d22e143c5 100644 --- a/src/main/java/rs117/hd/HdPluginConfig.java +++ b/src/main/java/rs117/hd/HdPluginConfig.java @@ -864,14 +864,14 @@ default boolean vanillaColorBanding() { return false; } - String KEY_TILE_ITEM_BIASING = "tileItemBiasing"; + String KEY_TILE_BIASING = "tileBiasing"; @ConfigItem( - keyName = KEY_TILE_ITEM_BIASING, - name = "Fix ground item clipping", - description = "Move ground items slightly, to prevent them from clipping into the ground.", + keyName = KEY_TILE_BIASING, + name = "Fix ground clipping", + description = "Biases dropped items & actors to reduce the amount of ground clipping.", section = miscellaneousSettings ) - default boolean tileItemBiasing() { return true; } + default boolean tileBiasing() { return true; } String KEY_LOW_MEMORY_MODE = "lowMemoryMode"; @ConfigItem( diff --git a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java index 2759284cde..576e1833f3 100644 --- a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java +++ b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java @@ -196,6 +196,17 @@ public void drawTemp(Projection worldProjection, Scene scene, GameObject gameObj } plugin.drawnTempRenderableCount++; + final int tileExX = (x >> Perspective.LOCAL_COORD_BITS) + ctx.sceneContext.sceneOffset; + final int tileExY = (z >> Perspective.LOCAL_COORD_BITS) + ctx.sceneContext.sceneOffset; + + final int modelBias; + if(plugin.configTileBiasing && renderable instanceof Actor) { + Tile tile = scene.getExtendedTiles()[gameObject.getPlane()][tileExX][tileExY]; + modelBias = tile != null && tile.getGroundObject() != null ? 125 : 0; + } else { + modelBias = 0; + } + final boolean isModelPartiallyVisible = sceneManager.isRoot(ctx) && modelClassification == 0; final boolean hasAlpha = renderable instanceof Player || m.getFaceTransparencies() != null; final AsyncCachedModel asyncModelCache = obtainAvailableAsyncCachedModel(false); @@ -216,6 +227,7 @@ public void drawTemp(Projection worldProjection, Scene scene, GameObject gameObj modelOverride, zone, cachedModel, + modelBias, isModelPartiallyVisible, hasAlpha, orientation, x, y, z @@ -242,6 +254,7 @@ public void drawTemp(Projection worldProjection, Scene scene, GameObject gameObj modelOverride, zone, m, + modelBias, isModelPartiallyVisible, hasAlpha, orientation, x, y, z @@ -263,6 +276,7 @@ private void uploadTempModel( ModelOverride modelOverride, Zone zone, Model m, + int modelBias, boolean isModelPartiallyVisible, boolean hasAlpha, int orientation, int x, int y, int z @@ -323,6 +337,7 @@ private void uploadTempModel( modelOverride, preOrientation, orientation, + modelBias, isSquashed, opaqueView, alphaView @@ -453,7 +468,7 @@ public void drawDynamic( final int tileExY = (z >> Perspective.LOCAL_COORD_BITS) + ctx.sceneContext.sceneOffset; final int modelBias; - if(plugin.configTileItemBiasing && r instanceof TileItem) { + if(plugin.configTileBiasing && r instanceof TileItem) { Tile tile = scene.getExtendedTiles()[tileObject.getPlane()][tileExX][tileExY]; modelBias = tile != null && tile.getGroundObject() != null ? 125 : 0; } else {