diff --git a/src/main/java/rs117/hd/HdPlugin.java b/src/main/java/rs117/hd/HdPlugin.java index cb715fd25a..dec67b35c4 100644 --- a/src/main/java/rs117/hd/HdPlugin.java +++ b/src/main/java/rs117/hd/HdPlugin.java @@ -907,6 +907,7 @@ public ShaderIncludes getShaderIncludes() { var includes = new ShaderIncludes() .addIncludePath(SHADER_PATH) .addInclude("VERSION_HEADER", OSType.getOSType() == OSType.Linux ? LINUX_VERSION_HEADER : WINDOWS_VERSION_HEADER) + .define("DEVELOPMENT", Props.DEVELOPMENT) .define("UI_SCALING_MODE", config.uiScalingMode()) .define("COLOR_BLINDNESS", config.colorBlindness()) .define("APPLY_COLOR_FILTER", configColorFilter != ColorFilter.NONE) @@ -933,6 +934,7 @@ public ShaderIncludes getShaderIncludes() { .define("CHARACTER_DISPLACEMENT", configCharacterDisplacement) .define("MAX_CHARACTER_POSITION_COUNT", max(1, UBOCompute.MAX_CHARACTER_POSITION_COUNT)) .define("WIREFRAME", config.wireframe()) + .define("HIGHLIGHT", developerTools.isHighlightModelOverridesEnabled()) .define("WINDOWS_HDR_CORRECTION", config.windowsHdrCorrection()) .define("LEGACY_RENDERER", renderer instanceof LegacyRenderer) .define("ZONE_RENDERER", renderer instanceof ZoneRenderer) diff --git a/src/main/java/rs117/hd/opengl/uniforms/UniformBuffer.java b/src/main/java/rs117/hd/opengl/uniforms/UniformBuffer.java index 0d1ca3104f..c0496de0a5 100644 --- a/src/main/java/rs117/hd/opengl/uniforms/UniformBuffer.java +++ b/src/main/java/rs117/hd/opengl/uniforms/UniformBuffer.java @@ -84,6 +84,8 @@ public final void set(int... values) { owner.markWaterLine(position, type.size); } + public final void set(boolean val) { set(val ? 1 : 0); } + public final void set(int x) { if (isUninitialized()) return; diff --git a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java index a0b1b3ba06..1df9db9bbd 100644 --- a/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java +++ b/src/main/java/rs117/hd/renderer/zone/ModelStreamingManager.java @@ -395,6 +395,7 @@ public void uploadTempModel( final DynamicModelVAO.View shadowView = ctx.beginDraw(VAO_SHADOW, culledFaces.length); sceneUploader.uploadTempModel( culledFaces, + renderable, m, modelOverride, preOrientation, @@ -421,6 +422,7 @@ public void uploadTempModel( sceneUploader.uploadTempModel( visibleFaces, + renderable, m, modelOverride, preOrientation, diff --git a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java index 5bd076799b..30d2ba3890 100644 --- a/src/main/java/rs117/hd/renderer/zone/SceneUploader.java +++ b/src/main/java/rs117/hd/renderer/zone/SceneUploader.java @@ -2134,6 +2134,7 @@ public boolean preprocessTempModel( // temp draw public void uploadTempModel( PrimitiveCharArray faces, + Renderable renderable, Model model, ModelOverride modelOverride, int preOrientation, @@ -2184,6 +2185,7 @@ public void uploadTempModel( final byte modelTransparency = model.getTransparency(); final boolean isVanillaTextured = faceTextures != null; + final boolean isActor = renderable instanceof Actor; int orientSin = 0; int orientCos = 0; @@ -2223,7 +2225,7 @@ else if (color3 == -1) color3 = faceOverride.modifyColor(color3); } - final int materialData = material.packMaterialData(faceOverride, uvType, false); + final int materialData = material.packMaterialData(faceOverride, uvType, false, isActor); final int triangleA = indices1[face]; final int vertexOffsetA = triangleA * 3; diff --git a/src/main/java/rs117/hd/scene/materials/Material.java b/src/main/java/rs117/hd/scene/materials/Material.java index a09194b73e..02290d0992 100644 --- a/src/main/java/rs117/hd/scene/materials/Material.java +++ b/src/main/java/rs117/hd/scene/materials/Material.java @@ -176,7 +176,7 @@ public boolean replaces(String name, HDVariables vars) { return replacementCondition.test(vars); } - public final int packMaterialData(@Nonnull ModelOverride modelOverride, UvType uvType, boolean isOverlay) { + public final int packMaterialData(@Nonnull ModelOverride modelOverride, UvType uvType, boolean isOverlay, boolean isActor) { // This needs to return zero by default, since we often fall back to writing all zeroes to UVs assert isValid : String.format("Material %s used after invalidation", this); int materialIndex = uboIndex; @@ -186,7 +186,8 @@ public final int packMaterialData(@Nonnull ModelOverride modelOverride, UvType u | ((modelOverride.windDisplacementModifier + 3) & 0x7) << 12 | (modelOverride.windDisplacementMode.ordinal() & 0x7) << 9 | (modelOverride.invertDisplacementStrength ? 1 : 0) << 8 - | (modelOverride.terrainVertexSnap ? 1 : 0) << 6 + | (modelOverride.terrainVertexSnap ? 1 : 0) << 7 + | (modelOverride == ModelOverride.NONE && !isActor ? 1 : 0) << 6 | (!modelOverride.receiveShadows ? 1 : 0) << 5 | (modelOverride.upwardsNormals ? 1 : 0) << 4 | (modelOverride.flatNormals ? 1 : 0) << 3 @@ -195,6 +196,10 @@ public final int packMaterialData(@Nonnull ModelOverride modelOverride, UvType u | (isOverlay ? 1 : 0); } + public final int packMaterialData(@Nonnull ModelOverride modelOverride, UvType uvType, boolean isOverlay) { + return packMaterialData(modelOverride, uvType, isOverlay, false); + } + public void fillMaterialStruct( UBOMaterials.MaterialStruct struct, float vanillaScrollX, diff --git a/src/main/java/rs117/hd/utils/DeveloperTools.java b/src/main/java/rs117/hd/utils/DeveloperTools.java index 091d7e834f..e4fab89c2c 100644 --- a/src/main/java/rs117/hd/utils/DeveloperTools.java +++ b/src/main/java/rs117/hd/utils/DeveloperTools.java @@ -2,8 +2,10 @@ import java.awt.event.KeyEvent; import javax.inject.Inject; +import javax.inject.Singleton; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import net.runelite.api.*; import net.runelite.api.events.*; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.Keybind; @@ -22,9 +24,11 @@ import static java.awt.event.InputEvent.SHIFT_DOWN_MASK; @Slf4j +@Singleton public class DeveloperTools implements KeyListener { // This could be part of the config if we had developer mode config sections private static final Keybind KEY_TOGGLE_TILE_INFO = new Keybind(KeyEvent.VK_F3, CTRL_DOWN_MASK); + private static final Keybind KEY_TOGGLE_HIGHLIGHT = new Keybind(KeyEvent.VK_H, CTRL_DOWN_MASK | SHIFT_DOWN_MASK); private static final Keybind KEY_TOGGLE_FRAME_TIMINGS = new Keybind(KeyEvent.VK_F4, CTRL_DOWN_MASK); private static final Keybind KEY_RECORD_TIMINGS_SNAPSHOT = new Keybind(KeyEvent.VK_F4, CTRL_DOWN_MASK | SHIFT_DOWN_MASK); private static final Keybind KEY_TOGGLE_SHADOW_MAP_OVERLAY = new Keybind(KeyEvent.VK_F5, CTRL_DOWN_MASK); @@ -35,6 +39,9 @@ public class DeveloperTools implements KeyListener { private static final Keybind KEY_TOGGLE_HIDE_UI = new Keybind(KeyEvent.VK_H, CTRL_DOWN_MASK); private static final Keybind KEY_RELOAD_SCENE = new Keybind(KeyEvent.VK_R, CTRL_DOWN_MASK); + @Inject + private Client client; + @Inject private ClientThread clientThread; @@ -68,6 +75,8 @@ public class DeveloperTools implements KeyListener { private boolean keyBindingsEnabled; private boolean tileInfoOverlayEnabled; @Getter + private boolean highlightModelOverridesEnabled; + @Getter private boolean frameTimingsOverlayEnabled; private boolean shadowMapOverlayEnabled; private boolean lightGizmoOverlayEnabled; @@ -107,6 +116,17 @@ public void deactivate() { hideUiEnabled = false; } + private void toggleModelOverrideHighlighter() { + highlightModelOverridesEnabled = !highlightModelOverridesEnabled; + clientThread.invoke(() -> client.addChatMessage( + ChatMessageType.GAMEMESSAGE, + "117 HD", + "[117 HD] " + (highlightModelOverridesEnabled ? "Enabled" : "Disabled") + " Model Override Highlighter", + "117 HD" + )); + plugin.recompilePrograms(); + } + @Subscribe public void onCommandExecuted(CommandExecuted commandExecuted) { if (!commandExecuted.getCommand().equalsIgnoreCase("117hd")) @@ -121,6 +141,9 @@ public void onCommandExecuted(CommandExecuted commandExecuted) { case "tileinfo": tileInfoOverlay.setActive(tileInfoOverlayEnabled = !tileInfoOverlayEnabled); break; + case "highlight": + toggleModelOverrideHighlighter(); + break; case "timers": case "timings": frameTimerOverlay.setActive(frameTimingsOverlayEnabled = !frameTimingsOverlayEnabled); @@ -160,6 +183,8 @@ public void onCommandExecuted(CommandExecuted commandExecuted) { public void keyPressed(KeyEvent e) { if (KEY_TOGGLE_TILE_INFO.matches(e)) { tileInfoOverlay.setActive(tileInfoOverlayEnabled = !tileInfoOverlayEnabled); + } else if (KEY_TOGGLE_HIGHLIGHT.matches(e)) { + toggleModelOverrideHighlighter(); } else if (KEY_TOGGLE_FRAME_TIMINGS.matches(e)) { frameTimerOverlay.setActive(frameTimingsOverlayEnabled = !frameTimingsOverlayEnabled); } else if (KEY_RECORD_TIMINGS_SNAPSHOT.matches(e)) { diff --git a/src/main/resources/rs117/hd/scene_frag.glsl b/src/main/resources/rs117/hd/scene_frag.glsl index a4bacf0f40..c4a823522e 100644 --- a/src/main/resources/rs117/hd/scene_frag.glsl +++ b/src/main/resources/rs117/hd/scene_frag.glsl @@ -87,6 +87,7 @@ void main() { // View & light directions are from the fragment to the camera/light vec3 viewDir = normalize(cameraPos - IN.position); + int combinedMaterialData = fMaterialData[0] | fMaterialData[1] | fMaterialData[2]; Material material1 = getMaterial(fMaterialData[0] >> MATERIAL_INDEX_SHIFT & MATERIAL_INDEX_MASK); Material material2 = getMaterial(fMaterialData[1] >> MATERIAL_INDEX_SHIFT & MATERIAL_INDEX_MASK); Material material3 = getMaterial(fMaterialData[2] >> MATERIAL_INDEX_SHIFT & MATERIAL_INDEX_MASK); @@ -125,7 +126,7 @@ void main() { // Vanilla tree textures rely on UVs being clamped horizontally, which HD doesn't do at the texture level. // Instead we manually clamp vanilla textures with transparency here. Including the transparency check // allows texture wrapping to work correctly for the mirror shield. - if ((fMaterialData[0] >> MATERIAL_FLAG_VANILLA_UVS & 1) == 1 && getMaterialHasTransparency(material1)) + if ((combinedMaterialData >> MATERIAL_FLAG_VANILLA_UVS & 1) == 1 && getMaterialHasTransparency(material1)) blendedUv.x = clamp(blendedUv.x, 0, .984375); vec2 uv1 = blendedUv; @@ -315,7 +316,7 @@ void main() { // normals vec3 normals; - if ((fMaterialData[0] >> MATERIAL_FLAG_UPWARDS_NORMALS & 1) == 1) { + if ((combinedMaterialData >> MATERIAL_FLAG_UPWARDS_NORMALS & 1) == 1) { normals = vec3(0, -1, 0); } else { vec3 n1 = sampleNormalMap(material1, uv1, TBN); @@ -333,7 +334,7 @@ void main() { #endif float shadow = 0; - if ((fMaterialData[0] >> MATERIAL_FLAG_DISABLE_SHADOW_RECEIVING & 1) == 0) + if ((combinedMaterialData >> MATERIAL_FLAG_DISABLE_SHADOW_RECEIVING & 1) == 0) shadow = sampleShadowMap(fragPos, vec2(0), lightDotNormals); shadow = max(shadow, selfShadowing); float inverseShadow = 1 - shadow; @@ -453,7 +454,7 @@ void main() { getMaterialIsUnlit(material3) )); - #if VANILLA_COLOR_BANDING + #if VANILLA_adjustedWorldPosCOLOR_BANDING outputColor.rgb = linearToSrgb(outputColor.rgb); outputColor.rgb = srgbToHsv(outputColor.rgb); outputColor.b = floor(outputColor.b * 127) / 127; @@ -471,6 +472,15 @@ void main() { if (isUnderwater) { sampleUnderwater(outputColor.rgb, waterType, waterDepth, lightDotNormals); } + + #if HIGHLIGHT + if(!isTerrain && (combinedMaterialData >> MATERIAL_FLAG_HIGHLIGHT_MODELS_WITHOUT_OVERRIDE & 1) == 1) { + float mask = checkerboard(IN.position + vec3(elapsedTime * 50.0), 16.0); + float str = sin(((mod(elapsedTime, 2.5)) / 2.5) * PI) * 0.5; + + outputColor.rgb += mix(vec3(0.59, 0.58, 0.94), vec3(0.98, 0.78, 0.83), mask) * str; + } + #endif } #if LEGACY_RENDERER diff --git a/src/main/resources/rs117/hd/utils/constants.glsl b/src/main/resources/rs117/hd/utils/constants.glsl index 1ef390944e..ed33f9f6f5 100644 --- a/src/main/resources/rs117/hd/utils/constants.glsl +++ b/src/main/resources/rs117/hd/utils/constants.glsl @@ -10,6 +10,7 @@ #include SHADER_TYPE #include LEGACY_RENDERER #include ZONE_RENDERER +#include DEVELOPMENT // Any changes here may need to be reflected in OpenCL's constants.cl // They are kept separate to avoid accidentally breaking OpenCL compatibility @@ -19,8 +20,8 @@ #define MATERIAL_FLAG_WIND_MODIFIER 12 #define MATERIAL_FLAG_WIND_SWAYING 9 #define MATERIAL_FLAG_INVERT_DISPLACEMENT_STRENGTH 8 -#define MATERIAL_FLAG_UNDO_VANILLA_SHADING 7 -#define MATERIAL_FLAG_TERRAIN_VERTEX_SNAPPING 6 +#define MATERIAL_FLAG_TERRAIN_VERTEX_SNAPPING 7 +#define MATERIAL_FLAG_HIGHLIGHT_MODELS_WITHOUT_OVERRIDE 6 #define MATERIAL_FLAG_DISABLE_SHADOW_RECEIVING 5 #define MATERIAL_FLAG_UPWARDS_NORMALS 4 #define MATERIAL_FLAG_FLAT_NORMALS 3 @@ -62,6 +63,7 @@ #include FLAT_SHADING #include APPLY_COLOR_FILTER #include WIREFRAME +#include HIGHLIGHT #include WIND_DISPLACEMENT #include WIND_DISPLACEMENT_NOISE_RESOLUTION #include CHARACTER_DISPLACEMENT diff --git a/src/main/resources/rs117/hd/utils/misc.glsl b/src/main/resources/rs117/hd/utils/misc.glsl index 6e5406693b..91de076aa5 100644 --- a/src/main/resources/rs117/hd/utils/misc.glsl +++ b/src/main/resources/rs117/hd/utils/misc.glsl @@ -210,3 +210,8 @@ vec2 getPoissonDisk(int idx) { default: return vec2( 0.14383161, -0.14100790); } } + +float checkerboard(vec3 fragPos, float size) { + vec2 p = floor(fragPos.xz / size); + return mod(p.x + mod(p.y, 2.0), 2.0); +} \ No newline at end of file