错误:GL错误:GL_INVALID_OPERATION:glTexImage2D

时间:2018-08-08 11:24:34

标签: three.js webgl textures shader

我们正在开发一种3D图形。我们将Angular与三全NPM(https://github.com/Itee/three-full)配合使用。我们将节点实现为粒子,并使用着色器对其进行绘制。

帖子的代码行*

在具有Linux环境的Web浏览器(Mozilla和Chromium)中,这很好用,但是当我们在具有Windows环境的Web浏览器中对其进行测试时,着色器崩溃,并且节点绘制未完成(显示该错误消息)。

Windows环境中的错误消息

Linux环境中的3D图形

Windows环境中的3D图形

我们搜索错误的含义,但没有澄清信息。关键是,如果我们使用LineMaterial而不是使用RawShadersMaterial着色器,则效果很好,但是会降低性能。 Windows系统中是否有任何技术问题可以实现?我们该如何解决?我们尝试评论有关纹理的所有内容,但会产生相同的错误。似乎该问题尤其与两个着色器的使用有关。

代码运行,例如:https://jsfiddle.net/dmartmilln/a48by2vr/

const particles = this.numNodesValue;

    if (particles > 0) {

      const particle_system_geometry = new THREE.BufferGeometry();

      // Buffers
      const positionBuffer = new Float32Array(new ArrayBuffer(particles * 12)); // For positioning
      const colorBuffer = new Uint8Array(new ArrayBuffer(particles * 3)); // For giving color to nodes
      const sizeBuffer = new Float32Array(new ArrayBuffer(particles * 4)); // For giving size to nodes
      const highlightBuffer = new Float32Array(new ArrayBuffer(particles * 4)); // For giving highlight
      const subjectsBuffer = new Float32Array(new ArrayBuffer(particles * 4)); // For subjects
      const selectedBuffer = new Float32Array(new ArrayBuffer(particles * 4)); // For selected

      this.radius = Math.min(1000, Math.max(100, Math.sqrt(particles * Math.PI * 20)));

      this.innerDistance = Math.sqrt(Math.pow(this.radius - this.camera.position.x, 2) +
        Math.pow(0 - this.camera.position.y, 2) + Math.pow(0 - this.camera.position.z, 2));

      const dispersion = this.radiusDispersion;

      for (let i = 0; i < particles; i++) {

        let particularDispersion = 0;

        if (dispersion > 0) {
          particularDispersion = (((Math.ceil(Math.random() * 11) - 1) / 10) * dispersion) + Math.random(); // [0..1] * dispersion
        }

        highlightBuffer[i] = 1.0;

        const angleX = (Math.random() - 0.5) * 2 * Math.PI;
        const angleY = (Math.random() - 0.5) * 2 * Math.PI;

        const posX = (this.radius + particularDispersion) * Math.sin(angleX) * Math.cos(angleY);
        const posY = (this.radius + particularDispersion) * Math.sin(angleX) * Math.sin(angleY);
        const posZ = (this.radius + particularDispersion) * Math.cos(angleX);

        positionBuffer[(i * 3)]     = posX;
        positionBuffer[(i * 3) + 1] = posY;
        positionBuffer[(i * 3) + 2] = posZ;

        colorBuffer[(i * 3)]     = (Math.random() * 255);
        colorBuffer[(i * 3) + 1] = (Math.random() * 255);
        colorBuffer[(i * 3) + 2] = (Math.random() * 255);

        subjectsBuffer[i] = Math.random() < 0.3 ? 1.0 : 0.0;
        selectedBuffer[i] = 0.0;

        if (particularDispersion !== 0) {
          sizeBuffer[i] = Math.floor((Math.pow(particularDispersion, 2) / Math.pow(dispersion, 2)) * this.sizeDiff);
        } else {
          sizeBuffer[i] = 0;
        }
      }

      const nodeBufferPosition  = new THREE.InterleavedBuffer(positionBuffer, 3);
      const nodeBufferColor     = new THREE.InterleavedBuffer(colorBuffer, 3);
      const nodeBufferSize      = new THREE.InterleavedBuffer(sizeBuffer, 1);
      const nodeBufferHighlight = new THREE.InterleavedBuffer(highlightBuffer, 1);
      const nodeBufferSubject   = new THREE.InterleavedBuffer(subjectsBuffer, 1);
      const nodeBufferSelected  = new THREE.InterleavedBuffer(selectedBuffer, 1);

      particle_system_geometry.addAttribute('position', new THREE.InterleavedBufferAttribute(nodeBufferPosition, 3, 0, false));
      particle_system_geometry.addAttribute('color', new THREE.InterleavedBufferAttribute(nodeBufferColor, 3, 0, true));
      particle_system_geometry.addAttribute('size', new THREE.InterleavedBufferAttribute(nodeBufferSize, 4, 0, true));
      particle_system_geometry.addAttribute('highlighted', new THREE.InterleavedBufferAttribute(nodeBufferHighlight, 4, 0, true));
      particle_system_geometry.addAttribute('subject', new THREE.InterleavedBufferAttribute(nodeBufferSubject, 4, 0, true));
      particle_system_geometry.addAttribute('selected', new THREE.InterleavedBufferAttribute(nodeBufferSelected, 4, 0, true));

      const vertexShader = [
        'precision highp float;',
        '',
        'uniform mat4 modelViewMatrix;',
        'uniform mat4 projectionMatrix;',
        '',
        'attribute vec3 position;',
        'attribute vec3 color;',
        'attribute float size;',
        'attribute float highlighted;',
        'attribute float subject;',
        'attribute float selected;',
        '',
        'varying vec3 vColor;',
        'varying float vHighlighted;',
        'varying float vSubject;',
        'varying float vSelected;',
        '',
        'void main() {',
        '',
        ' vColor = color;',
        ' vHighlighted = highlighted;',
        ' vSubject = subject;',
        ' vSelected = selected;',
        '   gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xyz , 1.0);',
        '',
        ' if (subject > 0.0) {',
        '',
        '     gl_PointSize = (10.0 + (size * 2.0)) * (300.0 / length(gl_Position.xyz));',
        '',
        ' } else {',
        '',
        '   gl_PointSize = (15.0 + (size * 2.0)) * (300.0 / length(gl_Position.xyz));',
        '',
        ' }',
        '',
        '}'
      ].join('\n');
      const fragmentShader = [
        'precision highp float;',
        '',
        'uniform sampler2D map;',
        'uniform sampler2D map2;',
        'uniform sampler2D mapSelected;',
        '',
        'varying vec3 vColor;',
        'varying float vHighlighted;',
        'varying float vSubject;',
        'varying float vSelected;',
        '',
        'void main() {',
        '',
        ' vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y);',
        '',
        ' if (vSelected > 0.0) {',
        '',
        '   vec4 textureColor = vec4(texture2D(mapSelected, uv));',
        '   gl_FragColor = vec4(textureColor * vec4(vColor, 1.0));',
        '',
        ' } else {',
        '   if (vSubject > 0.0) {',
        '',
        '     vec4 textureColor = vec4(texture2D(map2, uv));',
        '     gl_FragColor = vec4((vec3(1) - textureColor.rgb) * vColor, textureColor.a);',
        '',
        '   } else {',
        '',
        '       gl_FragColor = vec4(texture2D(map, uv) * vec4(vColor, 1.0));',
        '',
        '     if (vHighlighted == 0.0) {',
        '       gl_FragColor = vec4(0.3, 0.3, 0.3, gl_FragColor.a);',
        '     }',
        '',
        '     if (gl_FragColor.a > 0.6) gl_FragColor.a = 1.0;',
        '',
        '   }',
        ' }',
        '',
        ' if (gl_FragColor.a < 0.6) discard;',
        '',
        '}'
      ].join('\n');

      const uniforms = {
        map: { type: 't', value: new THREE.TextureLoader().load('../../assets/transparent_sphere.png')},
        map2: { type: 't', value: new THREE.TextureLoader().load('../../assets/reach.svg')},
        mapSelected: { type: 't', value: new THREE.TextureLoader().load('../../assets/Design1.png')},
      };

      const nodeMaterial = new THREE.RawShaderMaterial( {
        uniforms: uniforms,
        vertexShader: vertexShader,
        fragmentShader: fragmentShader,
        defines: {
          USE_MAP: true
        },
        transparent: true
      });

      particle_system_geometry.boundingBox = null;
      particle_system_geometry.computeBoundingSphere();

      this.mesh = new THREE.Points( particle_system_geometry, nodeMaterial );

      this.scene.add( this.mesh );
}

0 个答案:

没有答案