Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 缓慢的内存爬升,直到GPU崩溃_Three.js_Glsl_Webgl_Shader_Gpu - Fatal编程技术网

Three.js 缓慢的内存爬升,直到GPU崩溃

Three.js 缓慢的内存爬升,直到GPU崩溃,three.js,glsl,webgl,shader,gpu,Three.js,Glsl,Webgl,Shader,Gpu,我正在使用着色器显示粒子云的网格。每次用户点击一个云,该云就会消失,一个新的云就会取而代之。奇怪的是,每次新云取代旧云时,GPU的内存使用率都会上升——不管新云是大还是小(缓冲区大小总是保持不变——未使用的点只是在屏幕外显示,没有颜色)。在不到10次点击后,GPU将达到最大值并崩溃 这是更新新位置的物理着色器-我通过更新tOffsets纹理中的某些值来传递新云的新位置值。之后是我的两个(vert和frag)视觉效果着色器。你能看到我的效率问题吗?或者这可能是垃圾收集问题提前谢谢 物理着色器(仅限

我正在使用着色器显示粒子云的网格。每次用户点击一个云,该云就会消失,一个新的云就会取而代之。奇怪的是,每次新云取代旧云时,GPU的内存使用率都会上升——不管新云是大还是小(缓冲区大小总是保持不变——未使用的点只是在屏幕外显示,没有颜色)。在不到10次点击后,GPU将达到最大值并崩溃

这是更新新位置的物理着色器-我通过更新
tOffsets
纹理中的某些值来传递新云的新位置值。之后是我的两个(vert和frag)视觉效果着色器。你能看到我的效率问题吗?或者这可能是垃圾收集问题提前谢谢

物理着色器(仅限frag):

// Physics shader: This shader handles the calculations to move the various points. The position values are rendered out to at texture that is passed to the next pair of shaders that add the sprites and opacity.

// the tPositions sampler is added to this shader by Three.js's GPUCompute script
uniform sampler2D tOffsets; 
uniform sampler2D tGridPositionsAndSeeds;
uniform sampler2D tSelectionFactors;
uniform float uPerMotifBufferDimension;
uniform float uTime;
uniform float uXOffW;

...noise functions omitted for brevity...

void main() {

        vec2 uv = gl_FragCoord.xy / resolution.xy;

        vec4 offsets = texture2D( tOffsets, uv ).xyzw;
        float alphaMass = offsets.z;
        float cellIndex = offsets.w;


        if (cellIndex >= 0.0) { // this point will be rendered on screen

            float damping = 0.98;

            float texelSize = 1.0 / uPerMotifBufferDimension;
            vec2 perMotifUV = vec2( mod(cellIndex, uPerMotifBufferDimension)*texelSize, floor(cellIndex / uPerMotifBufferDimension)*texelSize );
            perMotifUV += vec2(0.5*texelSize);

            vec4 selectionFactors = texture2D( tSelectionFactors, perMotifUV ).xyzw;
            float swapState = selectionFactors.x;
            vec4 gridPosition = texture2D( tGridPositionsAndSeeds, perMotifUV ).xyzw;
            vec2 noiseSeed = gridPosition.zw;
            vec4 nowPos;
            vec2 velocity;

            nowPos = texture2D( tPositions, uv ).xyzw;
            velocity = vec2(nowPos.z, nowPos.w);

            if ( swapState == 0.0 ) { // if no new position values are ready to be swapped in for this point
                nowPos = texture2D( tPositions, uv ).xyzw;
                velocity = vec2(nowPos.z, nowPos.w);
            } else { // if swapState == 1, this means new position values are ready to be swapped in for this point
                nowPos = vec4( -(uTime) + offsets.x, offsets.y, 0.0, 0.0 );
                velocity = vec2(0.0, 0.0);
            }

            ...physics calculations omitted for brevity...

            vec2 newPosition = vec2(nowPos.x - velocity.x, nowPos.y - velocity.y);

            // Write new position out to a texture for processing in the visual effects shader
            gl_FragColor = vec4(newPosition.x, newPosition.y, velocity.x, velocity.y);

        } else { // this point will not be rendered on screen
            // Write new position out off screen (all -1 cellIndexes have off-screen offset values)
            gl_FragColor = vec4( offsets.x, offsets.y, 0.0, 0.0);
        }
uniform sampler2D tPositions; // passed in from the Physics Shader
uniform sampler2D tSelectionFactors;
uniform float uPerMotifBufferDimension;
uniform sampler2D uTextureSheet;
uniform float uPointSize;
uniform float uTextureCoordSizeX;
uniform float uTextureCoordSizeY;

attribute float aTextureIndex;
attribute float aAlpha;
attribute float aCellIndex;

varying float vCellIndex;
varying vec2 vTextureCoords;
varying vec2 vTextureSize;
varying float vAlpha;
varying vec3 vColor;

...omitted noise functions for brevity...

void main() {

        vec4 tmpPos = texture2D( tPositions, position.xy );
        vec2 pos = tmpPos.xy;
        vec2 vel = tmpPos.zw;

        vCellIndex = aCellIndex;

        if (vCellIndex >= 0.0) { // this point will be rendered onscreen

            float texelSize = 1.0 / uPerMotifBufferDimension;
            vec2 perMotifUV = vec2( mod(aCellIndex, uPerMotifBufferDimension)*texelSize, floor(aCellIndex / uPerMotifBufferDimension)*texelSize );
            perMotifUV += vec2(0.5*texelSize);

            vec4 selectionFactors = texture2D( tSelectionFactors, perMotifUV ).xyzw;
            float aSelectedMotif = selectionFactors.x;
            float aColor = selectionFactors.y;
            float fadeFactor = selectionFactors.z;

            vTextureCoords = vec2( aTextureIndex * uTextureCoordSizeX, 0 );
            vTextureSize = vec2( uTextureCoordSizeX, uTextureCoordSizeY );

            vAlpha = aAlpha * fadeFactor;

            vColor = vec3( 1.0, aColor, 1.0 );

            gl_PointSize = uPointSize;

        } else { // this point will not be rendered onscreen
            vAlpha = 0.0;
            vColor = vec3(0.0, 0.0, 0.0);
            gl_PointSize = 0.0;
        }
        gl_Position = projectionMatrix * modelViewMatrix * vec4( pos.x, pos.y, position.z, 1.0 );
    }
uniform sampler2D tPositions;
    uniform sampler2D uTextureSheet;

    varying float vCellIndex;
    varying vec2 vTextureCoords;
    varying vec2 vTextureSize;
    varying float vAlpha;
    varying vec3 vColor;

    void main() {
        gl_FragColor = vec4( vColor, vAlpha );

        if (vCellIndex >= 0.0) { // this point will be rendered onscreen, so add the texture
            vec2 realTexCoord = vTextureCoords + ( gl_PointCoord * vTextureSize );
            gl_FragColor = gl_FragColor * texture2D( uTextureSheet, realTexCoord );
        }
    }
从物理着色器中,渲染带有点的新移动的
t位置
纹理,并将其传递给视觉效果着色器:

视觉效果着色器(垂直):

// Physics shader: This shader handles the calculations to move the various points. The position values are rendered out to at texture that is passed to the next pair of shaders that add the sprites and opacity.

// the tPositions sampler is added to this shader by Three.js's GPUCompute script
uniform sampler2D tOffsets; 
uniform sampler2D tGridPositionsAndSeeds;
uniform sampler2D tSelectionFactors;
uniform float uPerMotifBufferDimension;
uniform float uTime;
uniform float uXOffW;

...noise functions omitted for brevity...

void main() {

        vec2 uv = gl_FragCoord.xy / resolution.xy;

        vec4 offsets = texture2D( tOffsets, uv ).xyzw;
        float alphaMass = offsets.z;
        float cellIndex = offsets.w;


        if (cellIndex >= 0.0) { // this point will be rendered on screen

            float damping = 0.98;

            float texelSize = 1.0 / uPerMotifBufferDimension;
            vec2 perMotifUV = vec2( mod(cellIndex, uPerMotifBufferDimension)*texelSize, floor(cellIndex / uPerMotifBufferDimension)*texelSize );
            perMotifUV += vec2(0.5*texelSize);

            vec4 selectionFactors = texture2D( tSelectionFactors, perMotifUV ).xyzw;
            float swapState = selectionFactors.x;
            vec4 gridPosition = texture2D( tGridPositionsAndSeeds, perMotifUV ).xyzw;
            vec2 noiseSeed = gridPosition.zw;
            vec4 nowPos;
            vec2 velocity;

            nowPos = texture2D( tPositions, uv ).xyzw;
            velocity = vec2(nowPos.z, nowPos.w);

            if ( swapState == 0.0 ) { // if no new position values are ready to be swapped in for this point
                nowPos = texture2D( tPositions, uv ).xyzw;
                velocity = vec2(nowPos.z, nowPos.w);
            } else { // if swapState == 1, this means new position values are ready to be swapped in for this point
                nowPos = vec4( -(uTime) + offsets.x, offsets.y, 0.0, 0.0 );
                velocity = vec2(0.0, 0.0);
            }

            ...physics calculations omitted for brevity...

            vec2 newPosition = vec2(nowPos.x - velocity.x, nowPos.y - velocity.y);

            // Write new position out to a texture for processing in the visual effects shader
            gl_FragColor = vec4(newPosition.x, newPosition.y, velocity.x, velocity.y);

        } else { // this point will not be rendered on screen
            // Write new position out off screen (all -1 cellIndexes have off-screen offset values)
            gl_FragColor = vec4( offsets.x, offsets.y, 0.0, 0.0);
        }
uniform sampler2D tPositions; // passed in from the Physics Shader
uniform sampler2D tSelectionFactors;
uniform float uPerMotifBufferDimension;
uniform sampler2D uTextureSheet;
uniform float uPointSize;
uniform float uTextureCoordSizeX;
uniform float uTextureCoordSizeY;

attribute float aTextureIndex;
attribute float aAlpha;
attribute float aCellIndex;

varying float vCellIndex;
varying vec2 vTextureCoords;
varying vec2 vTextureSize;
varying float vAlpha;
varying vec3 vColor;

...omitted noise functions for brevity...

void main() {

        vec4 tmpPos = texture2D( tPositions, position.xy );
        vec2 pos = tmpPos.xy;
        vec2 vel = tmpPos.zw;

        vCellIndex = aCellIndex;

        if (vCellIndex >= 0.0) { // this point will be rendered onscreen

            float texelSize = 1.0 / uPerMotifBufferDimension;
            vec2 perMotifUV = vec2( mod(aCellIndex, uPerMotifBufferDimension)*texelSize, floor(aCellIndex / uPerMotifBufferDimension)*texelSize );
            perMotifUV += vec2(0.5*texelSize);

            vec4 selectionFactors = texture2D( tSelectionFactors, perMotifUV ).xyzw;
            float aSelectedMotif = selectionFactors.x;
            float aColor = selectionFactors.y;
            float fadeFactor = selectionFactors.z;

            vTextureCoords = vec2( aTextureIndex * uTextureCoordSizeX, 0 );
            vTextureSize = vec2( uTextureCoordSizeX, uTextureCoordSizeY );

            vAlpha = aAlpha * fadeFactor;

            vColor = vec3( 1.0, aColor, 1.0 );

            gl_PointSize = uPointSize;

        } else { // this point will not be rendered onscreen
            vAlpha = 0.0;
            vColor = vec3(0.0, 0.0, 0.0);
            gl_PointSize = 0.0;
        }
        gl_Position = projectionMatrix * modelViewMatrix * vec4( pos.x, pos.y, position.z, 1.0 );
    }
uniform sampler2D tPositions;
    uniform sampler2D uTextureSheet;

    varying float vCellIndex;
    varying vec2 vTextureCoords;
    varying vec2 vTextureSize;
    varying float vAlpha;
    varying vec3 vColor;

    void main() {
        gl_FragColor = vec4( vColor, vAlpha );

        if (vCellIndex >= 0.0) { // this point will be rendered onscreen, so add the texture
            vec2 realTexCoord = vTextureCoords + ( gl_PointCoord * vTextureSize );
            gl_FragColor = gl_FragColor * texture2D( uTextureSheet, realTexCoord );
        }
    }
视觉效果着色器(frag):

// Physics shader: This shader handles the calculations to move the various points. The position values are rendered out to at texture that is passed to the next pair of shaders that add the sprites and opacity.

// the tPositions sampler is added to this shader by Three.js's GPUCompute script
uniform sampler2D tOffsets; 
uniform sampler2D tGridPositionsAndSeeds;
uniform sampler2D tSelectionFactors;
uniform float uPerMotifBufferDimension;
uniform float uTime;
uniform float uXOffW;

...noise functions omitted for brevity...

void main() {

        vec2 uv = gl_FragCoord.xy / resolution.xy;

        vec4 offsets = texture2D( tOffsets, uv ).xyzw;
        float alphaMass = offsets.z;
        float cellIndex = offsets.w;


        if (cellIndex >= 0.0) { // this point will be rendered on screen

            float damping = 0.98;

            float texelSize = 1.0 / uPerMotifBufferDimension;
            vec2 perMotifUV = vec2( mod(cellIndex, uPerMotifBufferDimension)*texelSize, floor(cellIndex / uPerMotifBufferDimension)*texelSize );
            perMotifUV += vec2(0.5*texelSize);

            vec4 selectionFactors = texture2D( tSelectionFactors, perMotifUV ).xyzw;
            float swapState = selectionFactors.x;
            vec4 gridPosition = texture2D( tGridPositionsAndSeeds, perMotifUV ).xyzw;
            vec2 noiseSeed = gridPosition.zw;
            vec4 nowPos;
            vec2 velocity;

            nowPos = texture2D( tPositions, uv ).xyzw;
            velocity = vec2(nowPos.z, nowPos.w);

            if ( swapState == 0.0 ) { // if no new position values are ready to be swapped in for this point
                nowPos = texture2D( tPositions, uv ).xyzw;
                velocity = vec2(nowPos.z, nowPos.w);
            } else { // if swapState == 1, this means new position values are ready to be swapped in for this point
                nowPos = vec4( -(uTime) + offsets.x, offsets.y, 0.0, 0.0 );
                velocity = vec2(0.0, 0.0);
            }

            ...physics calculations omitted for brevity...

            vec2 newPosition = vec2(nowPos.x - velocity.x, nowPos.y - velocity.y);

            // Write new position out to a texture for processing in the visual effects shader
            gl_FragColor = vec4(newPosition.x, newPosition.y, velocity.x, velocity.y);

        } else { // this point will not be rendered on screen
            // Write new position out off screen (all -1 cellIndexes have off-screen offset values)
            gl_FragColor = vec4( offsets.x, offsets.y, 0.0, 0.0);
        }
uniform sampler2D tPositions; // passed in from the Physics Shader
uniform sampler2D tSelectionFactors;
uniform float uPerMotifBufferDimension;
uniform sampler2D uTextureSheet;
uniform float uPointSize;
uniform float uTextureCoordSizeX;
uniform float uTextureCoordSizeY;

attribute float aTextureIndex;
attribute float aAlpha;
attribute float aCellIndex;

varying float vCellIndex;
varying vec2 vTextureCoords;
varying vec2 vTextureSize;
varying float vAlpha;
varying vec3 vColor;

...omitted noise functions for brevity...

void main() {

        vec4 tmpPos = texture2D( tPositions, position.xy );
        vec2 pos = tmpPos.xy;
        vec2 vel = tmpPos.zw;

        vCellIndex = aCellIndex;

        if (vCellIndex >= 0.0) { // this point will be rendered onscreen

            float texelSize = 1.0 / uPerMotifBufferDimension;
            vec2 perMotifUV = vec2( mod(aCellIndex, uPerMotifBufferDimension)*texelSize, floor(aCellIndex / uPerMotifBufferDimension)*texelSize );
            perMotifUV += vec2(0.5*texelSize);

            vec4 selectionFactors = texture2D( tSelectionFactors, perMotifUV ).xyzw;
            float aSelectedMotif = selectionFactors.x;
            float aColor = selectionFactors.y;
            float fadeFactor = selectionFactors.z;

            vTextureCoords = vec2( aTextureIndex * uTextureCoordSizeX, 0 );
            vTextureSize = vec2( uTextureCoordSizeX, uTextureCoordSizeY );

            vAlpha = aAlpha * fadeFactor;

            vColor = vec3( 1.0, aColor, 1.0 );

            gl_PointSize = uPointSize;

        } else { // this point will not be rendered onscreen
            vAlpha = 0.0;
            vColor = vec3(0.0, 0.0, 0.0);
            gl_PointSize = 0.0;
        }
        gl_Position = projectionMatrix * modelViewMatrix * vec4( pos.x, pos.y, position.z, 1.0 );
    }
uniform sampler2D tPositions;
    uniform sampler2D uTextureSheet;

    varying float vCellIndex;
    varying vec2 vTextureCoords;
    varying vec2 vTextureSize;
    varying float vAlpha;
    varying vec3 vColor;

    void main() {
        gl_FragColor = vec4( vColor, vAlpha );

        if (vCellIndex >= 0.0) { // this point will be rendered onscreen, so add the texture
            vec2 realTexCoord = vTextureCoords + ( gl_PointCoord * vTextureSize );
            gl_FragColor = gl_FragColor * texture2D( uTextureSheet, realTexCoord );
        }
    }

感谢@Blindman67上面的评论,我解决了这个问题。这与着色器无关。在Javascript(Three.js)中,我需要在添加更新的纹理之前向GPU发出删除旧纹理的信号

每次更新纹理(我的大部分是DataTextures)时,在创建和更新新纹理之前,我需要对现有纹理调用
dispose()
,如下所示:

var textureHandle; // holds a reference to the current texture uniform value

textureHandle.dispose(); // ** deallocates GPU memory **
textureHandle = new THREE.DataTexture( textureData, dimension, dimension, THREE.RGBAFormat, THREE.FloatType );
textureHandle.needsUpdate = true;
uniforms.textureHandle.value = textureHandle;

这与着色器无关,它们与着色器无关。您需要显示您的Javascript代码。但我猜你每次迭代都在创建新的纹理,而不是破坏旧的纹理<代码>gl.deleteTexture(textureHandle)或者它是在three.js中完成的(请参阅有关删除纹理的文档)@Blindman67-Ah,很有趣。谢谢,我来看看。@Blindman67-Ha!明亮的这正是问题所在。如果你把答案写下来,我就接受。触发建议的方法是调用
textureHandle.dispose()代码。工作完美。谢谢