首页 > 解决方案 > 三.js。如何将自定义材质用于场景背景而不是颜色或纹理?

问题描述

说颜色或纹理的文档scene可用于scene.background. 我想将 aShaderMaterial与我自己的自定义着色器一起使用。我怎样才能做到这一点?

具体来说,我想在前景元素后面绘制一个色带。这是片段着色器:

uniform vec2 uXYPixel;
void main() {
    vec2 xy = vec2(gl_FragCoord.x/uXYPixel.x, gl_FragCoord.y/uXYPixel.y);
    gl_FragColor.rgb = vec3(xy.x, xy.y, 0);
    gl_FragColor.a = 1.0;
}

uXYPixel是一个uniform vec2window.innerWidthwindow.innerHeight

标签: three.jsglslshadermaterial

解决方案


您需要手动创建两个渲染通道。一个使用简单的 渲染背景平面,Camera第二个渲染场景的其余部分。您可以使用最基本的Camera 类,因为您不会使用转换或投影矩阵:

// Set renderer with no autoclear
var renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
document.body.append(renderer.domElement);
renderer.setSize(window.innerWidth, window.innerHeight);

// Set up background scene
var bgScene = new THREE.Scene();
var bgCam = new THREE.Camera();
var bgGeom = new THREE.PlaneBufferGeometry(2, 2);
var bgMat = new THREE.ShaderMaterial({
    // Add shader stuff in here
    // ..
    // Disable depth so it doesn't interfere with foreground scene
    depthTest: false,
    depthWrite: false
});
var bgMesh = new THREE.Mesh(bgGeom, bgMat);
bgScene.add(bgMesh);

// Set up regular scene
var scene = new THREE.Scene();
var cam = new THREE.PerspectiveCamera(45, w/h, 1, 100);

function update() {
    // Clear previous frame
    renderer.clear();

    // Background render pass
    renderer.render(bgScene, bgCam);

    // Foreground render pass
    renderer.render(scene, cam);

    requestAnimationFrame(update);
}

update();

在这里您可以看到一个工作示例

请注意,渲染器的autoClear = false属性确保它不会在每次render()调用之间清除缓冲区;您必须在每帧开始时手动清除它。


推荐阅读