WebGL
Shader
cover

將比例一起傳入 uniform

item.ts
// function
function getResolution(imageHeight: number, imageWidth: number) {
  const imageAspect = imageHeight / imageWidth;
  const width = Func.instance.sw();
  const height = Func.instance.sh();
  let a1, a2;
  if (height / width > imageAspect) {
    a1 = (width / height) * imageAspect;
    a2 = 1;
  } else {
    a1 = 1;
    a2 = height / width / imageAspect;
  }
 
  return { width, height, a1, a2 };
}
 
 
// height / width
const imageAspect = 900 / 1600;
const width = Func.instance.sw();
const height = Func.instance.sh();
let a1, a2;
if (height / width > imageAspect) {
  a1 = (width / height) * imageAspect;
  a2 = 1;
} else {
  a1 = 1;
  a2 = height / width / imageAspect;
}
 
// material
 
// for mouse and other element
const { width, height, a1, a2 } = getResolution(1, 1);
// for image
const cover = getResolution(853, 1280);
 
this._material = new THREE.ShaderMaterial({
  vertexShader: vertex,
  fragmentShader: fragment,
  uniforms: {
    u_texture: {
      value: TexLoader.instance.get("/img/image.png"),
    },
    u_resolution: {
      value: new THREE.Vector4(width, height, a1, a2),
    },
    u_cover: {
      cover.width,
      cover.height,
      cover.a1,
      cover.a2
    },
  },
});
 
 
// resize
protected _resize(): void {
    super._resize();
    this._mesh.scale.set(Func.instance.sw(), Func.instance.sh(), 1);
 
    const { width, height, a1, a2 } = getResolution(1, 1);
    const cover = getResolution(853, 1280);
    this._material.uniforms.u_resolution.value.set(width, height, a1, a2);
    this._material.uniforms.u_cover.value.set(
      cover.width,
      cover.height,
      cover.a1,
      cover.a2
    );
  }
frag.glsl
uniform vec4 u_resolution;
uniform vec2 u_mouse;
 
varying vec2 v_uv;
 
void main(void) {
  // for cover images
  // 受圖片比例影響
  vec2 coverUv = (v_uv - vec2(0.5)) * u_cover.zw + vec2(0.5);
  // mouse position也要調整(with height and width)
  // 不受圖片比例影響
  vec2 newUv = (v_uv - vec2(0.5)) * u_resolution.zw + vec2(0.5);
  vec2 mouse = (u_mouse - vec2(0.5)) * u_resolution.zw + vec2(0.5);
 
  // 如果mouse沒有一起調整的話,出來的會是橢圓
  float mouseDistance = length(newUv - mouse);
  float smoothMouse = smoothstep(0.2, 0.0, mouseDistance);
 
  // ...
}