我们正在开发一种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 );
}