skip to Main Content

fragment code :

export const fragment = `varying vec2 vUv;
uniform vec2 viewport;
uniform vec2 uMouse;

float createCircle() {
    vec2 viewportUv = gl_FragCoord.xy / viewport;
    float viewportAspect = viewport.x / viewport.y;

    vec2 mousePoint = vec2(uMouse.x, 1.0 - uMouse.y);
    float circleRadius = max(0.0, 100.0 / viewport.x);

    vec2 shapeUv = viewportUv - mousePoint;
    shapeUv /= vec2(1.0, viewportAspect);
    shapeUv += mousePoint;

    // Debug: Output mouse position
    if (length(viewportUv - mousePoint) < 0.01) {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red for mouse position
    }

    // Debug: Output shape UV
    if (length(shapeUv - mousePoint) < 0.01) {
        gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); // Blue for shape UV
    }

    float dist = distance(shapeUv, mousePoint);
    dist = smoothstep(circleRadius, circleRadius + 0.001, dist);

    return dist;
}

void main() {
    float circle = createCircle();
    float dist = length(gl_PointCoord - vec2(0.5));
    float disc = smoothstep(0.5, 0.45, dist);

    gl_FragColor = vec4(disc * circle); // Final color based on circle distance

    if (disc < 0.01) discard;
}`;

my pc viewport (1920,932)and laptop (1280,593)now when i vec2 viewportUv = gl_FragCoord.xy / vec2(1920,932) use like that then it circle display perfect in my laptop but during resize again circle not display perfact even it work fine in pc when i resize size then also circle create around pointer;

i just want the circle created around mouse pointer perfectly even we chagne the screen size or other device screen

2

Answers


  1. Most likely, if you check your window.devicePixelRatio, you will end up with a different result on both devices.

    The "not matching" window size and canvas size indicates that, the size of "projection" (viewport) corresponds to canvas size multiplied by the pixel ratio. By now you might have guess the anomaly.

    When you resize your window and pass the new viewport size, it need to correspond to the size of the window multiplied by the pixelRatio, and not just the size of the window (kind of similar sample).

    Alternatively, you could set your Renderer pixelRatio to 1 but you will lose a lot of quality on high pixelRatio device (documentation).

    Login or Signup to reply.
  2. In render/update function use pixel ratio to resize your canvas.

    Something like this:

    private resizeCanvasToDisplaySize(): void {
    const canvas = this.renderer.domElement;
    
    // look up the size the canvas is being displayed
    const pixelRatio = window.devicePixelRatio;
    console.log(canvas.getBoundingClientRect().height, canvas.clientHeight, this.htmlElement.clientHeight);
    const width = (canvas.clientWidth * pixelRatio) | 0;
    const height = (this.htmlElement.clientHeight * pixelRatio) | 0;
    // adjust displayBuffer size to match
    if (canvas.width !== width || canvas.height !== height) {
      // you must pass false here or three.js sadly fights the browser
      this.renderer.setSize(width, height, false);
    
      this.camera.aspect = width / height;
      this.camera.updateProjectionMatrix();
    }
    this.renderer.setViewport(0, 0, width, height);
    

    }

    To get right position, u can use this function.

    private getCanvasRelativePosition(event: MouseEvent) {
      const canvas = event.target as HTMLCanvasElement;
      const rect = canvas.getBoundingClientRect();
      return {
        x: (event.clientX - rect.left) * canvas.width / rect.width,
        y: (event.clientY - rect.top) * canvas.height / rect.height,
      };
    

    }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search