From 6928b8ddf65f41130e210e751145255f95bc4772 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 10 Mar 2026 22:26:56 -0700 Subject: [PATCH] feat: desaturate quest markers for trivial (gray) quests Trivial/low-level quests now show gray '!' / '?' markers instead of yellow, matching the in-game distinction between available and trivial quests. Add grayscale parameter to QuestMarkerRenderer::setMarker and the push-constant block; application sets grayscale=1.0 for trivial markers and 0.0 for all others. --- assets/shaders/quest_marker.frag.glsl | 5 ++++- assets/shaders/quest_marker.frag.spv | Bin 1396 -> 1844 bytes include/rendering/quest_marker_renderer.hpp | 5 ++++- src/rendering/quest_marker_renderer.cpp | 13 ++++++++----- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/assets/shaders/quest_marker.frag.glsl b/assets/shaders/quest_marker.frag.glsl index 020b625d..0e209d8f 100644 --- a/assets/shaders/quest_marker.frag.glsl +++ b/assets/shaders/quest_marker.frag.glsl @@ -5,6 +5,7 @@ layout(set = 1, binding = 0) uniform sampler2D markerTexture; layout(push_constant) uniform Push { mat4 model; float alpha; + float grayscale; // 0 = full colour, 1 = fully desaturated (trivial quests) } push; layout(location = 0) in vec2 TexCoord; @@ -14,5 +15,7 @@ layout(location = 0) out vec4 outColor; void main() { vec4 texColor = texture(markerTexture, TexCoord); if (texColor.a < 0.1) discard; - outColor = vec4(texColor.rgb, texColor.a * push.alpha); + float lum = dot(texColor.rgb, vec3(0.299, 0.587, 0.114)); + vec3 rgb = mix(texColor.rgb, vec3(lum), push.grayscale); + outColor = vec4(rgb, texColor.a * push.alpha); } diff --git a/assets/shaders/quest_marker.frag.spv b/assets/shaders/quest_marker.frag.spv index e947d04c250e061fc5974110b6961604f7963add..90814c3072bc24151b35ce84c10df0fb079f4bbe 100644 GIT binary patch literal 1844 zcmYk5+fGwK6ovz{wtVb*SWtdLw|@A_KWQ{Wg%+QR>J+n8t%l{6Hes&G2%1MaO_*8P;lUf(Npn~BezSgvE-eP1 zbyO|;fp*97CdHt3Sd6%Iq@(YHuy|T86@ympq`5DyX5&!{?^SI!&g;%8Cv{H=#B~0o zY!*K6JP~=u?AjV}Q^Ibn#_4m-|GJq;e@sUXbQ>{_y5Y8koZf?;;mA$BF882V_{nI> zEloytTAU}0NKZa|=H=(&7}?)O*`+^Y3?FBbXwv=fiI z(9f5G~^=Y*X#9Jv8^__OkV zU~cq`&vyq$&kwYFLYqJ>_zwm5W{a}Xx_FOe(-(CR51;SA^~(JG5RPGH5XyDhBk@#?%Iw$^!0LNU3 zL0_W+{1<7M;kf0P?N7zHs-5*)dd{v0aP)%xN8Mt>5tBM51@i2vOHcch00&rY0&nwC zIjP~MfM!OZZr%aT#k(y#9&b)Q9ALS4uBUl%#MoDKPx~DK&Vlz}wo3xv12cDbmo4w^ zK9UdT&|`aA5l3FWIqD$?TI!$G&N(qX?W+Quo5NGt^b?;$RzAF|ZCy6C@jbcPHe|!U zx9_$Yof!lF!g9}KlaJ-NE!l9?>$q*pF^7Fkjk)az+(*wj@#%+eoU^}*up;~en8bUv delta 619 zcmYL_$w~u35QeK~a|z=`+%98l+@r=N2SpTvhXgzr4+=;DOdW`uZvMIzHuol8tiBuF+hM*|037^SPeic;nx8S|MsN_OMi*fiGGKveO z#DnU1_cZJhG;Akwj1C-aSvhmqVGH6|?Cf&3mA@c|cd8KXJqQmj74E=yAMMz#G7jR{ eo-z*B!jJLK_95P9KF`_U1ix=#dG?E^96*259V;yW diff --git a/include/rendering/quest_marker_renderer.hpp b/include/rendering/quest_marker_renderer.hpp index 2d6a73d3..a0d18776 100644 --- a/include/rendering/quest_marker_renderer.hpp +++ b/include/rendering/quest_marker_renderer.hpp @@ -35,8 +35,10 @@ public: * @param position World position (NPC base position) * @param markerType 0=available(!), 1=turnin(?), 2=incomplete(?) * @param boundingHeight NPC bounding height (optional, default 2.0f) + * @param grayscale 0 = full colour, 1 = desaturated grey (trivial/low-level quests) */ - void setMarker(uint64_t guid, const glm::vec3& position, int markerType, float boundingHeight = 2.0f); + void setMarker(uint64_t guid, const glm::vec3& position, int markerType, + float boundingHeight = 2.0f, float grayscale = 0.0f); /** * Remove a quest marker @@ -61,6 +63,7 @@ private: glm::vec3 position; int type; // 0=available, 1=turnin, 2=incomplete float boundingHeight = 2.0f; + float grayscale = 0.0f; // 0 = colour, 1 = desaturated (trivial quests) }; std::unordered_map markers_; diff --git a/src/rendering/quest_marker_renderer.cpp b/src/rendering/quest_marker_renderer.cpp index bc481d5a..d9aa3886 100644 --- a/src/rendering/quest_marker_renderer.cpp +++ b/src/rendering/quest_marker_renderer.cpp @@ -17,8 +17,9 @@ namespace wowee { namespace rendering { // Push constant layout matching quest_marker.vert.glsl / quest_marker.frag.glsl struct QuestMarkerPushConstants { - glm::mat4 model; // 64 bytes, used by vertex shader - float alpha; // 4 bytes, used by fragment shader + glm::mat4 model; // 64 bytes, used by vertex shader + float alpha; // 4 bytes, used by fragment shader + float grayscale; // 4 bytes: 0=colour, 1=desaturated (trivial quests) }; QuestMarkerRenderer::QuestMarkerRenderer() { @@ -340,8 +341,9 @@ void QuestMarkerRenderer::loadTextures(pipeline::AssetManager* assetManager) { } } -void QuestMarkerRenderer::setMarker(uint64_t guid, const glm::vec3& position, int markerType, float boundingHeight) { - markers_[guid] = {position, markerType, boundingHeight}; +void QuestMarkerRenderer::setMarker(uint64_t guid, const glm::vec3& position, int markerType, + float boundingHeight, float grayscale) { + markers_[guid] = {position, markerType, boundingHeight, grayscale}; } void QuestMarkerRenderer::removeMarker(uint64_t guid) { @@ -436,10 +438,11 @@ void QuestMarkerRenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSe vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 1, 1, &texDescSets_[marker.type], 0, nullptr); - // Push constants: model matrix + alpha + // Push constants: model matrix + alpha + grayscale tint QuestMarkerPushConstants push{}; push.model = model; push.alpha = fadeAlpha; + push.grayscale = marker.grayscale; vkCmdPushConstants(cmd, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,