【问题标题】:Can you use raw WebGL Textures with three.js您可以将原始 WebGL 纹理与 three.js 一起使用吗
【发布时间】:2015-06-02 06:28:48
【问题描述】:

我有一个相当复杂的架构,我的大部分工作都是在 Three.JS 中完成的,但我也有一个特殊的渲染器,可以直接渲染到原始 WebGL 纹理。是否可以在 three.js“纹理”中使用此 WebGL 纹理?看起来 Three.JS 纹理类只是图像、视频或画布的容器,并且在 three.js 的内部深处的某个地方,它将上传到真正的 webgl 纹理。如何让 Three.js 将我的 WebGL 纹理渲染到网格上?

【问题讨论】:

标签: three.js webgl


【解决方案1】:

@Brendan 的回答不再有效。

不知道什么时候改变了,懒得去查了,但是从 r102 开始

const texture = new THREE.Texture();
renderer.setTexture2D(texture, 0);  // force three.js to init the texture
const texProps = renderer.properties.get(texture);
texProps.__webglTexture = glTex;

从 r103 开始​​,setTexture2D 不再存在。你可以改用这个

  const forceTextureInitialization = function() {
    const material = new THREE.MeshBasicMaterial();
    const geometry = new THREE.PlaneBufferGeometry();
    const scene = new THREE.Scene();
    scene.add(new THREE.Mesh(geometry, material));
    const camera = new THREE.Camera();

    return function forceTextureInitialization(texture) {
      material.map = texture;
      renderer.render(scene, camera);
    };
  }();

  const texture = new THREE.Texture();
  forceTextureInitialization(texture);  // force three.js to init the texture
  const texProps = renderer.properties.get(texture);
  texProps.__webglTexture = glTex;

'use strict';

/* global THREE */

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({
    canvas: canvas
  });
  
  const fov = 75;
  const aspect = 2; // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();

  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
  
  const forceTextureInitialization = function() {
    const material = new THREE.MeshBasicMaterial();
    const geometry = new THREE.PlaneBufferGeometry();
    const scene = new THREE.Scene();
    scene.add(new THREE.Mesh(geometry, material));
    const camera = new THREE.Camera();

    return function forceTextureInitialization(texture) {
      material.map = texture;
      renderer.render(scene, camera);
    };
  }();

  const cubes = []; // just an array we can use to rotate the cubes

  {
    const gl = renderer.getContext();
    const glTex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, glTex);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0,
        gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([
          255, 0, 0, 255,
          0, 255, 0, 255,
          0, 0, 255, 255,
          255, 255, 0, 255,
        ]));
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  
    const texture = new THREE.Texture();
    forceTextureInitialization(texture);
    const texProps = renderer.properties.get(texture);
    texProps.__webglTexture = glTex;
    
    const material = new THREE.MeshBasicMaterial({
      map: texture,
    });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    cubes.push(cube); // add to our list of cubes to rotate
  }

  function render(time) {
    time *= 0.001;

    cubes.forEach((cube, ndx) => {
      const speed = .2 + ndx * .1;
      const rot = time * speed;
      cube.rotation.x = rot;
      cube.rotation.y = rot;
    });

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();
<canvas id="c"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script>

注意:three.js 中没有“不支持的行为”之类的东西。 Three.js 不保证你今天所做的任何事情明天都会奏效。 Three.js breaks whatever it wants to whenever it wants to

【讨论】:

    【解决方案2】:

    这是完全不受支持的行为,但您可以模仿 WebGLRenderer 并直接在纹理上设置 __webglTexture 属性。例如

    var texure = new THREE.Texture();
    var rawTexture = gl.createTexture();
    texture.__webglTexture = rawTexture;
    texture.__webglInit = true;
    // ... use texture as a normal three.js texture ...
    

    同样,这是完全不受支持和未定义的行为,可能会在未来版本的 three.js 中中断,但如果您追求速度,可能会暂时有效。

    如果可以的话,我建议您查看WebGLRenderTarget,或者提交功能请求以正确启用该功能。

    【讨论】:

    • 在这种情况下您将如何使用 WebGLRenderTarget?其他渲染代码对three.js一无所知
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 2022-06-15
    相关资源
    最近更新 更多