javascript - 我正在尝试使用三个 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>
解决方案
推荐阅读
- kubernetes - Kubernetes 上的 Prometheus Presto-Exporter 配置
- c# - 为什么在 WPF 中使用页面时控件会变大?我该如何解决?
- vue.js - 使用 SVG 创建动态 Google 地图标记
- postgresql - 数组:找不到数据类型字符变化 [] 的数组类型
- python - 如何按某个值创建一列升序数字?
- android - Android Studio 上参数化类的原始使用
- python-3.x - Python Protobuf (IPv4/IPv6 地址) 到 Clickhouse FixedString(16)
- powershell - 使用 Powershell PNP 获取 Sharepoint 在线文档库中特定文件夹中的项目
- android - 如何知道何时调用了`navController.popBackStack()`?
- visual-studio - 如何将我的 VS 2019 引入虚幻引擎?