You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js着色器列宽自定义调整问题求助

Three.js着色器列宽自定义调整问题求助

我现在遇到了Three.js着色器布局的难题,想请大家帮忙出出主意。按照设计要求,整个着色器区域要分成6列3行,整体尺寸是100vw×100vh:

  • 3行的高度需要平均分配
  • 6列的宽度要按指定比例设置,从左到右依次是17.65vw、16.25vw、16.32vw、16.32vw、16.25vw、17.15vw

但目前所有列的宽度都是一致的,我尝试了各种方法都没达到预期效果。

我之前完全没接触过Three.js,初始代码是设计师提供的,原本是React版本,我把它改成了原生JS,但原代码里的着色器片段都是等宽的正方形,没办法调整成不同尺寸的布局。我也查了不少Three.js的资料,反复研究现有代码,还是没找到解决办法。下面是我当前的实现代码:

JavaScript 代码

const canvas = document.getElementById('canvas');
const renderer = new THREE.WebGLRenderer({ canvas });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
const scene = new THREE.Scene();

const camera = new THREE.OrthographicCamera(
    window.innerWidth / -2, window.innerWidth / 2,
    window.innerHeight / 2, window.innerHeight / -2,
    0.1, 1000
);
camera.position.z = 1;

window.addEventListener('resize', () => {
    const width = window.innerWidth;
    const height = window.innerHeight;
    renderer.setSize(width, height);
    camera.left = width / -2;
    camera.right = width / 2;
    camera.top = height / 2;
    camera.bottom = height / -2;
    camera.updateProjectionMatrix();
    uniforms.resolution.value.set(width, height);
});

const vertexShader = `
    varying vec2 vUv;
    void main() {
        vUv = uv;
        vec4 modelPosition = modelMatrix * vec4(position, 1.0);
        vec4 viewPosition = viewMatrix * modelPosition;
        vec4 projectionPosition = projectionMatrix * viewPosition;
        gl_Position = projectionPosition;
    }
`;

const fragmentShader = `
    uniform float time;
    uniform vec2 resolution;
    uniform vec2 pointer;
    varying vec2 vUv;

    vec3 palette(float t) {
        vec3 a = vec3(0.5, 0.5, 0.5);
        vec3 b = vec3(0.5, 0.5, 0.5);
        vec3 c = vec3(1.0, 1.0, 1.0);
        vec3 d = vec3(0.263, 0.416, 0.557);
        return a + b * cos(6.28318 * (c * t + d));
    }

    void main() {
        vec2 uv = (gl_FragCoord.xy * 2.0 - resolution.xy) / resolution.y;
        vec2 uv0 = uv;
        vec3 finalColor = vec3(0.0);
        vec2 gridSize = vec2(6.0, 3.0);
        vec2 gridPos = floor(vUv * gridSize);
        vec2 localUv = fract(vUv * gridSize) - 0.5;
        uv = sin(localUv * 0.5) - pointer;
        float d = length(uv) * exp(-length(uv0));
        vec3 col = palette(length(uv0) + time * 0.4);
        d = sin(d * 8.0 + time) / 8.0;
        d = abs(d);
        d = pow(0.02 / d, 2.0);
        finalColor += col * d;
        gl_FragColor = vec4(finalColor, 1.0);
    }
`;

const uniforms = {
    time: { value: 0 },
    resolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) },
    pointer: { value: new THREE.Vector2(0, 0) }
};

const material = new THREE.ShaderMaterial({
    vertexShader,
    fragmentShader,
    uniforms
});

const geometry = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight);
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);

const clock = new THREE.Clock();
function animate() {
    uniforms.time.value += clock.getDelta();
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
}

animate();

CSS 代码

#canvas {
  display: block; 
  position: absolute; 
  top: 0; 
  left: 0; 
  width: 100vw; 
  height: 100vh;
}

HTML 代码

<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

有没有大佬能帮我解决这个问题,让着色器的每一列宽度可以单独调整,实现设计要求的不等宽比例布局呢?

备注:内容来源于stack exchange,提问作者Andrew Kargin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 03:20:31