Scaling a shader centered at the mouse point
Posted: Wed Feb 28, 2024 11:29 pm
I'm working with shaders in my project to get a more interesting background than flat colour. Ideally, these shaders will remain in a logical position and scale when I manipulate the camera (using StalkerX: https://github.com/a327ex/STALKER-X).
I'm new to GLSL and after following a YouTube tutorial I created this shader that uses perlin noise to make a cool, pixellated water effect for the background: https://pastebin.com/Z7bMRq67
I then put this in the project and draw it as a background. I send time using love.time.getTime() and the other two in my code.
When the player drags the mouse around, I move the offset variable using this code (self refers to the current game 'board'):
self.parent.camera refers to a camera that is just the size of the window and never changes. This code works well and the shader moves along with all the other contents drawn with the camera without going too fast or too slow. However, the issue lies in updating the zoom of the camera and thus the shader. For that I use this code:
I copied the code I'm using for the camera scaling to just update shader_zoom and shader_offset, but it doesn't work at all. This is resulting in the offset moving too far and becoming misaligned with the camera. I thought I'd be able to sort this out myself but I'm quite confused as to what's actually going on and why these effects are happening. Here's what it looks like in game: https://youtu.be/Sk2Y5r5v5qw
Some more points of knowledge that might be helpful is that the self.camera.scale starts at 0.5 and shader_zoom starts at 1. I don't see how this could have this effect though but it might have some impact I'm not noticing. Additionally the shader is updated in main.update(dt) each frame with these values and they're used as shown in the shader code.
Any help would be greatly appreciated!
I'm new to GLSL and after following a YouTube tutorial I created this shader that uses perlin noise to make a cool, pixellated water effect for the background: https://pastebin.com/Z7bMRq67
I then put this in the project and draw it as a background. I send time using love.time.getTime() and the other two in my code.
When the player drags the mouse around, I move the offset variable using this code (self refers to the current game 'board'):
Code: Select all
if input:down('mouse1') then
mouse_pos(self.parent.camera) -- https://pastebin.com/qmfLiG0N
local x, y = (self.camera_lock[1] - mouse.x), (self.camera_lock[2] - mouse.y)
shader_offset[1] = shader_offset[1] + x
shader_offset[2] = shader_offset[2] + y
self.camera.x = self.camera.x + x/self.camera.scale
self.camera.y = self.camera.y + y/self.camera.scale
self.camera_lock = {mouse.x, mouse.y}
end
Code: Select all
function Board:wheelmoved(dx, dy)
dy = math.sign(dy) * math.min(math.abs(dy), 2)
mouse_pos(self.camera)
local mx, my = mouse.x, mouse.y
local scale_limit = {out = 0.14, inn = 0.65}
if (self.camera.scale > scale_limit.out or dy > 0) and (self.camera.scale < scale_limit.inn or dy < 0) then
self.camera.scale = self.camera.scale + dy/50
self.camera.x = self.camera.x + (mx - self.camera.x) * dy/50 / self.camera.scale
self.camera.y = self.camera.y + (my - self.camera.y) * dy/50 / self.camera.scale
shader_zoom = shader_zoom + dy/50
shader_offset[1] = shader_offset[1] + (mx - shader_offset[1]) * dy/50 / shader_zoom
shader_offset[2] = shader_offset[2] + (my - shader_offset[2]) * dy/50 / shader_zoom
end
end
Some more points of knowledge that might be helpful is that the self.camera.scale starts at 0.5 and shader_zoom starts at 1. I don't see how this could have this effect though but it might have some impact I'm not noticing. Additionally the shader is updated in main.update(dt) each frame with these values and they're used as shown in the shader code.
Any help would be greatly appreciated!