I've created a shader that uses a texture (cursorTex
) to show a mouse cursor, and draws it onto a fullscreen texture (bgTex
). I'm moving the cursor texture so that the center of the image is positioned on my mouse cursor. I'm designing the cursor for a trackpad that can detect pressure, and am able to adjust the opacity based on the amount of pressure:
cursorColor.rgb *= clamp(.5 - pressure, 0.0,1.0);
Now, I'm trying to also change the scaling of the cursor based on the amount of pressure, so that it shrinks to 50% it's original size if the pressure is 1.0, and stays at its original size if the pressure is 0.0.
I'm having trouble figuring out how to only scale the cursor texture based on the pressure
uniform while also retaining its original aspect ratio, and also offsetting it to center on the mouse cursor (half it's original width and height). Below is my full shader code.
// Set the precision
precision highp float;
uniform float time; // Time uniform variable
uniform vec2 mouse; // Mouse position uniform variable
uniform sampler2D cursorTex; // Texture sampler for the cursor image
uniform sampler2D bgTex; // Texture sampler for the background image
uniform vec2 cursorSize; // Size of the cursor image
varying vec2 vTexCoord; // Interpolated texture coordinates
uniform float pressure; // Pressure applied to touchpad/ mouse
void main() {
vec2 uv = vTexCoord.st;
// Flip the texture coords
uv.y = 1.0 - uv.y;
vec2 texture1Size = vec2(500.0, 500.0);
vec2 texture2Size = vec2(1080.0, 1920.0);
// Calculate the cursor position based on the mouse position
vec2 cursorPosition = mouse;
// Offset to center on the cursor position
vec2 texture1Offset = cursorPosition / texture1Size;
// Color of the cursor image at the adjusted texture coordinates
vec4 cursorColor = texture2D(cursorTex, uv / (texture1Size / texture2Size) - texture1Offset);
// Modify cursor opacity based on mouse pressure
cursorColor.rgb *= clamp(.5 - pressure, 0.0,1.0);
// Color of the background image at the original texture coordinates
vec4 bgColor = texture2D(bgTex, uv);
vec4 finalColor = cursorColor + bgColor;
// Handle clipping if UV coordinates go beyond the texture bounds
if (uv.x >= 1.0 || uv.y >= 1.0) {
finalColor = bgColor;
}
gl_FragColor = finalColor; // Set the final fragment color
}
This would be done in the vertex shader, if you post the vertex shader I can help, but here is the basic idea. You scale the position attribute with vec2 pos = Pos * (1 - pressure * 0.5f)
, scale it by cursorSize
and then translate the object to the mouse position.
// example position attribute
layout (location = 0) in vec2 Pos;
uniform vec2 mouse; // Mouse position uniform variable
uniform vec2 cursorSize; // Size of the cursor image
uniform float pressure; // Pressure applied to touchpad/ mouse
void main() {
// scale it by pressure
vec2 pos = Pos * (1 - pressure * 0.5f);
// scale it by cursorSize (ordering of this and pressure scaling might be reversed)
pos *= cursorSize;
// move to cursor position
pos += mouse;
gl_Position = vec4(pos, 0.0, 1.0);
}