首页 > 解决方案 > 我正在尝试使用三个 js 在 glsl 着色器中制作棋盘纹理,但它变得混叠或像素化,如何使其平滑?

问题描述

我正在尝试使用三个 js 在 glsl 着色器中制作棋盘纹理,但它变得混叠或像素化,如何使其平滑?

我试图用 smoothstep 函数模糊边缘,但它也不起作用,棋盘的立方体也被拉伸了。

如何制作平滑无缝的棋盘纹理?

//vertex shader
const vShader = `
  varying vec2 v_uv;
  varying float v_size_factor;
  varying vec3 v_position;

  uniform float u_time;

  void main(){
    v_uv = uv;
    v_position = position;

    v_size_factor = 0.45;
    
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position * v_size_factor, 1.0);
  }
`;

//fragment shader

const fShader = `

varying vec2 v_uv;
uniform vec2 u_resolution;
uniform float u_time;

varying vec3 v_position;

float Rect(vec2 pt, vec2 size, vec2 offset, float blur)
{
  vec2 p = pt - offset;
  vec2 halfSize = size * 0.5;

  float a = smoothstep(-halfSize.x, -halfSize.x + blur, p.x)
            - smoothstep(halfSize.x, halfSize.x + blur, p.x);
  float b = smoothstep(-halfSize.y, -halfSize.y + blur, p.y)
            - smoothstep(halfSize.x, halfSize.y + blur, p.y);

  return a * b;
}

void main() {
  
  vec2 uv = v_uv * vec2(0.999999);
  uv = fract(uv * 40.0);

  float blur = 0.001;
  float shape = Rect(uv, vec2(1.0), vec2(0.0), blur) ;
  shape += Rect(uv, vec2(1.0), vec2(1.0), blur) ;
  
  vec3 color = vec3(1.0) * shape;
  
  gl_FragColor = vec4(color, 1.0);
}
`;

const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });

const clock = new THREE.Clock();

renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// const geometry = new THREE.PlaneGeometry(2, 2, 100, 100);
const geometry = new THREE.TorusKnotGeometry(0.4, 0.2, 200, 64);

const uniform = {
  u_color: { value: new THREE.Color(0x00ff00) },
  u_time: { value: 0.0 },
  u_mouse: { value: { x: 0.0, y: 0.0 } },
  u_resolution: { value: { x: 0.0, y: 0.0 } },
};

const material = new THREE.ShaderMaterial({
  vertexShader: vShader,
  fragmentShader: fShader,
  uniforms: uniform,
  opacity: true,
});
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);

camera.position.z = 1;

onWindowResize();
animate();

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  onWindowResize();

  plane.rotation.y += 0.01;
  uniform.u_time.value = clock.getElapsedTime();
}

//set mouse coordinates
function move(e) {
  uniform.u_mouse.value.x = e.touches ? e.touches[0].clientX : e.clientX;
  uniform.u_mouse.value.y = e.touches ? e.touches[0].clientY : e.clientY;
}

if ("ontouchStart" in window) {
  document.addEventListener("touchmove", move);
} else {
  document.addEventListener("resize", onWindowResize, false);
  document.addEventListener("mousemove", move);
}

function onWindowResize(event) {
  const aspectRatio = window.innerWidth / window.innerHeight;
  let width, height;
  if (aspectRatio >= 1) {
    width = 1;
    height = (window.innerHeight / window.innerWidth) * width;
  } else {
    width = aspectRatio;
    height = 1;
  }
  camera.left = -width;
  camera.right = width;
  camera.top = height;
  camera.bottom = -height;

  if (uniform.u_resolution !== undefined) {
    uniform.u_resolution.value.x = window.innerWidth;
    uniform.u_resolution.value.y = window.innerHeight;
  }

  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}
         * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            overflow: hidden;
        }

        canvas {
            position: absolute;
            width: 100%;
            height: 100vh;
            z-index: -1;
        }
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shader - webgl</title>
</head>

<body>
    <canvas id="canvas"></canvas>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js"></script>
    <script src="script.js"></script>
</body>

</html>

标签: javascriptthree.jsglslshaderwebgl

解决方案


推荐阅读