2017-03-14 22 views
6

मेरे पास शेडर प्रोग्राम की एक जोड़ी है, जहां मेरे डेटाटेक्चर स्क्वायर (1: 1) हैं, लेकिन यदि कोई या दोनों 2: 1 (चौड़ाई: ऊंचाई) अनुपात व्यवहार गड़बड़ हो जाता है। मैं यह सुनिश्चित करने के लिए अप्रयुक्त filler के साथ प्रत्येक बफर का विस्तार कर सकता हूं कि वे हमेशा वर्ग होते हैं, लेकिन यह लंबे समय तक अनावश्यक रूप से महंगा (स्मृति-वार) लगता है, क्योंकि दो बफर आकारों में से एक शुरू करने के लिए काफी बड़ा है। क्या इस परिदृश्य में 2: 1 बफर को संभालने का कोई तरीका है?अजीब व्यवहार अगर डेटाटेक्चर स्क्वायर नहीं हैं (1: 1)

  1. पहले एक भी frag मेरे कार्यक्रम के लिए भौतिकी की गणना करने के लिए प्रयोग किया जाता शेडर है (यह एक बनावट tPositions बाहर लिखते के दूसरे सेट के द्वारा पढ़ा जा करने के लिए:

    मैं शेडर कार्यक्रमों की एक जोड़ी है shaders)। यह थ्री.जेएस की जीपीयू कॉम्प्यूट रेंडरर स्क्रिप्ट (मेरे सबसे बड़े बफर के आकार पर संकल्प सेट) द्वारा संचालित है।

  2. शेडर्स (ऊर्ध्वाधर और टुकड़ा) की दूसरी जोड़ी डेटा बनावट tPositions का उपयोग करती है ताकि पहले शेडर प्रोग्राम द्वारा उत्पादित किया जा सके। विज़ुअलाइजेशन (विंडो आकार पर संकल्प सेट)।

विज़ुअलाइजेशन विभिन्न आकार के कण बादलों का एक ग्रिड है। शेडर कार्यक्रमों में, दो अलग-अलग आकारों के बनावट होते हैं: छोटे आकार के बनावट में प्रत्येक कण बादलों (प्रति क्लाउड एक टेक्सल) के लिए जानकारी होती है, बड़े आकार के बनावट में सभी बादलों में प्रत्येक कण के लिए जानकारी होती है (प्रति एक टेक्सल)। दोनों 2.

टेक्सेल-प्रति-कण बनावट आकार की एक शक्ति के लिए उन्हें भरने के लिए अंत पर हमला बोला अप्रयुक्त भराव की एक निश्चित राशि है (बड़े):tPositions, tOffsets

टेक्सेल-प्रति -cloud आकार बनावट (छोटे):tGridPositionsAndSeeds, tSelectionFactors

जैसा कि मैंने पहले भी कहा है, समस्या यह है कि जब इन दोनों बफ़र आकार (बड़े और छोटे) एक 1 पर हैं: 1 (चौड़ाई: ऊंचाई) अनुपात, कार्यक्रम ठीक काम करते हैं; हालांकि, जब एक या दोनों 2: 1 (चौड़ाई: ऊंचाई) अनुपात पर होते हैं तो व्यवहार एक गड़बड़ है। इसके लिए क्या खाते हैं, और मैं इसे कैसे संबोधित कर सकता हूं? अग्रिम में धन्यवाद!

अद्यतन: समस्या मेरी आवास से संबंधित हो सकता है Texel coords दूसरा शेडर कार्यक्रम में शेडर के position विशेषता में tPosition बनावट को पढ़ने के लिए? यदि ऐसा है, तो position विशेषता में टेक्साल कॉर्ड के संबंध में शायद यह Github issue संबंधित हो सकता है, हालांकि मुझे SO पर कोई प्रश्न/उत्तर नहीं मिल रहा है।

अद्यतन 2: मैं भी इस एक unpack alignment issue हो सकता है कि क्या में देख रहा हूँ। विचार?

यहां तीन में सेट अप है।पहले शेडर कार्यक्रम के लिए js:

// tPositions is handled by the GPUCompute script 
    uniform sampler2D tOffsets; 
    uniform sampler2D tGridPositionsAndSeeds; 
    uniform sampler2D tSelectionFactors; 
    uniform float uPerMotifBufferWidth; 
    uniform float uPerMotifBufferHeight; 
    uniform float uTime; 
    uniform float uXOffW; 

    [...skipping a noise function 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) { 

      float damping = 0.98; 

      float texelSizeX = 1.0/uPerMotifBufferWidth; 
      float texelSizeY = 1.0/uPerMotifBufferHeight; 
      vec2 perMotifUV = vec2(mod(cellIndex, uPerMotifBufferWidth)*texelSizeX, floor(cellIndex/uPerMotifBufferHeight)*texelSizeY); 
      perMotifUV += vec2(0.5*texelSizeX, 0.5*texelSizeY); 

      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) { 
       nowPos = texture2D(tPositions, uv).xyzw; 
       velocity = vec2(nowPos.z, nowPos.w); 
      } else { // if swapState == 1 
       //nowPos = vec4(-(uTime) + gridPosition.x + offsets.x, gridPosition.y + offsets.y, 0.0, 0.0); 
       nowPos = vec4(-(uTime) + offsets.x, offsets.y, 0.0, 0.0); 
       velocity = vec2(0.0, 0.0); 
      } 

      [...skipping the physics for brevity...] 

      vec2 newPosition = vec2(nowPos.x - velocity.x, nowPos.y - velocity.y); 
      // Write new position out 
      gl_FragColor = vec4(newPosition.x, newPosition.y, velocity.x, velocity.y); 
    } 

यहाँ दूसरा शेडर कार्यक्रम के लिए सेटअप है:

function initComputeRenderer() { 

    textureData = MotifGrid.getBufferData(); 

    gpuCompute = new GPUComputationRenderer(textureData.uPerParticleBufferWidth, textureData.uPerParticleBufferHeight, renderer); 

    dtPositions = gpuCompute.createTexture(); 
    dtPositions.image.data = textureData.tPositions; 

    offsetsTexture = new THREE.DataTexture(textureData.tOffsets, textureData.uPerParticleBufferWidth, textureData.uPerParticleBufferHeight, THREE.RGBAFormat, THREE.FloatType); 
    offsetsTexture.needsUpdate = true; 

    gridPositionsAndSeedsTexture = new THREE.DataTexture(textureData.tGridPositionsAndSeeds, textureData.uPerMotifBufferWidth, textureData.uPerMotifBufferHeight, THREE.RGBAFormat, THREE.FloatType); 
    gridPositionsAndSeedsTexture.needsUpdate = true; 

    selectionFactorsTexture = new THREE.DataTexture(textureData.tSelectionFactors, textureData.uPerMotifBufferWidth, textureData.uPerMotifBufferHeight, THREE.RGBAFormat, THREE.FloatType); 
    selectionFactorsTexture.needsUpdate = true; 

    positionVariable = gpuCompute.addVariable("tPositions", document.getElementById('position_fragment_shader').textContent, dtPositions); 
    positionVariable.wrapS = THREE.RepeatWrapping; // repeat wrapping for use only with bit powers: 8x8, 16x16, etc. 
    positionVariable.wrapT = THREE.RepeatWrapping; 

    gpuCompute.setVariableDependencies(positionVariable, [ positionVariable ]); 

    positionUniforms = positionVariable.material.uniforms; 
    positionUniforms.tOffsets = { type: "t", value: offsetsTexture }; 
    positionUniforms.tGridPositionsAndSeeds = { type: "t", value: gridPositionsAndSeedsTexture }; 
    positionUniforms.tSelectionFactors = { type: "t", value: selectionFactorsTexture }; 
    positionUniforms.uPerMotifBufferWidth = { type : "f", value : textureData.uPerMotifBufferWidth }; 
    positionUniforms.uPerMotifBufferHeight = { type : "f", value : textureData.uPerMotifBufferHeight }; 
    positionUniforms.uTime = { type: "f", value: 0.0 }; 
    positionUniforms.uXOffW = { type: "f", value: 0.5 }; 

} 

यहाँ पहले शेडर कार्यक्रम (केवल भौतिक विज्ञान की गणना के लिए एक frag) है: नोट: इस अनुभाग के लिए प्रस्तुतकर्ता विंडो आकार

function makePerParticleReferencePositions() { 

    var positions = new Float32Array(perParticleBufferSize * 3); 

    var texelSizeX = 1/perParticleBufferDimensions.width; 
    var texelSizeY = 1/perParticleBufferDimensions.height; 

    for (var j = 0, j3 = 0; j < perParticleBufferSize; j ++, j3 += 3) { 

     positions[ j3 + 0 ] = ((j % perParticleBufferDimensions.width)/perParticleBufferDimensions.width) + (0.5 * texelSizeX); 
     positions[ j3 + 1 ] = (Math.floor(j/perParticleBufferDimensions.height)/perParticleBufferDimensions.height) + (0.5 * texelSizeY); 
     positions[ j3 + 2 ] = j * 0.0001; // this is the real z value for the particle display 

    } 

    return positions; 
} 

var positions = makePerParticleReferencePositions(); 

... 

// Add attributes to the BufferGeometry: 
gridOfMotifs.geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3)); 
gridOfMotifs.geometry.addAttribute('aTextureIndex', new THREE.BufferAttribute(motifGridAttributes.aTextureIndex, 1)); 
gridOfMotifs.geometry.addAttribute('aAlpha', new THREE.BufferAttribute(motifGridAttributes.aAlpha, 1)); 
gridOfMotifs.geometry.addAttribute('aCellIndex', new THREE.BufferAttribute(
     motifGridAttributes.aCellIndex, 1)); 

uniformValues = {}; 
uniformValues.tSelectionFactors = motifGridAttributes.tSelectionFactors; 
uniformValues.uPerMotifBufferWidth = motifGridAttributes.uPerMotifBufferWidth; 
uniformValues.uPerMotifBufferHeight = motifGridAttributes.uPerMotifBufferHeight; 

gridOfMotifs.geometry.computeBoundingSphere(); 

... 

function makeCustomUniforms(uniformValues) { 

    selectionFactorsTexture = new THREE.DataTexture(uniformValues.tSelectionFactors, uniformValues.uPerMotifBufferWidth, uniformValues.uPerMotifBufferHeight, THREE.RGBAFormat, THREE.FloatType); 
    selectionFactorsTexture.needsUpdate = true; 

    var customUniforms = { 
     tPositions : { type : "t", value : null }, 
     tSelectionFactors : { type : "t", value : selectionFactorsTexture }, 
     uPerMotifBufferWidth : { type : "f", value : uniformValues.uPerMotifBufferWidth }, 
     uPerMotifBufferHeight : { type : "f", value : uniformValues.uPerMotifBufferHeight }, 
     uTextureSheet : { type : "t", value : texture }, // this is a sprite sheet of all 10 strokes 
     uPointSize : { type : "f", value : 18.0 }, // the radius of a point in WebGL units, e.g. 30.0 
     // Coords for the hatch textures: 
     uTextureCoordSizeX : { type : "f", value : 1.0/numTexturesInSheet }, 
     uTextureCoordSizeY : { type : "f", value : 1.0 }, // the size of a texture in the texture map (they're square, thus only one value) 
    }; 
    return customUniforms; 
} 
पर एक वेबग्लेंडरर है

वर्टेक्स शेडर:

uniform sampler2D tPositions; 
    uniform sampler2D tSelectionFactors; 
    uniform float uPerMotifBufferWidth; 
    uniform float uPerMotifBufferHeight; 
    uniform sampler2D uTextureSheet; 
    uniform float uPointSize; // the radius size of the point in WebGL units, e.g. "30.0" 
    uniform float uTextureCoordSizeX; // vertical dimension of each texture given the full side = 1 
    uniform float uTextureCoordSizeY; // horizontal dimension of each texture given the full side = 1 

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

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

    [...skipping noise function for brevity...] 

    void main() { 

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

     vCellIndex = aCellIndex; 

     if (aCellIndex >= 0.0) { // buffer filler cell indexes are -1 

      float texelSizeX = 1.0/uPerMotifBufferWidth; 
      float texelSizeY = 1.0/uPerMotifBufferHeight; 
      vec2 perMotifUV = vec2(mod(aCellIndex, uPerMotifBufferWidth)*texelSizeX, floor(aCellIndex/uPerMotifBufferHeight)*texelSizeY); 
      perMotifUV += vec2(0.5*texelSizeX, 0.5*texelSizeY); 

      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; 
      vDensity = vel.x + vel.y; 
      vAlpha *= abs(vDensity * 3.0); 

      vColor = vec3(1.0, aColor, 1.0); // set RGB color associated to vertex; use later in fragment shader. 

      gl_PointSize = uPointSize; 

     } else { // if this is a filler cell index (-1) 
      vAlpha = 0.0; 
      vDensity = 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); // position holds the real z value. The z value of "color" is a component of velocity 
    } 

टुकड़ा शेडर:

uniform sampler2D tPositions; 
    uniform sampler2D uTextureSheet; 

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

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

     if (vCellIndex >= 0.0) { // only render out the texture if this point is not a buffer filler 
      vec2 realTexCoord = vTextureCoords + (gl_PointCoord * vTextureSize); 
      gl_FragColor = gl_FragColor * texture2D(uTextureSheet, realTexCoord); 
     } 
    } 

अपेक्षित व्यवहार: मैं इस लक्ष्य को हासिल कर सकते हैं

और यहाँ इसी शेडर कार्यक्रम (Vert & frag) है सभी DataTextures को 1: 1 पर मजबूर कर 210

अजीब व्यवहार: जब छोटे DataTextures 2: 1 प्रपत्र नीचे चित्र के ऊपरी दाएँ भाग में उन लोगों के लिए पूरी तरह से क्षैतिज बादल और भौतिक विज्ञान में गड़बड़ है। जब बड़े DataTextures 2: 1 होते हैं, तो ग्रिड खराब हो जाता है, और बादलों में गुम भाग दिखाई देते हैं (जैसा कि नीचे देखा गया है)। जब छोटे और बड़े दोनों बनावट 2: 1 होते हैं, तो दोनों अजीब व्यवहार होते हैं (यह नीचे दी गई छवि में है)। weird behavior - particle clouds incorrectly assembled and displayed in a skewed grid

उत्तर

0

मेरे संबंधित प्रश्न here के उत्तर के लिए धन्यवाद, अब मुझे पता है कि क्या गलत हो रहा था। समस्या यह थी कि मैं शेडर में डेटाटेक्चर 'टेक्क्सल्स तक पहुंचने के लिए इंडेक्स (1,2,3,4,5 ...) के सरणी का उपयोग कर रहा था।

इस समारोह (और बड़ा DataTextures के लिए एक) में ...

float texelSizeX = 1.0/uPerMotifBufferWidth; 
float texelSizeY = 1.0/uPerMotifBufferHeight; 
vec2 perMotifUV = vec2( 
    mod(aCellIndex, uPerMotifBufferWidth)*texelSizeX, 
    floor(aCellIndex/uPerMotifBufferHeight)*texelSizeY); 
perMotifUV += vec2(0.5*texelSizeX, 0.5*texelSizeY); 

... मैं मान लिया है कि आदेश अपने कस्टम यूवी, perMotifUV के लिए y मूल्य बनाने के लिए, मैं करने की आवश्यकता होगी बफर की ऊंचाई से aCellIndex को विभाजित करें, uPerMotifBufferHeight (यह "लंबवत" आयाम है)। हालांकि, जैसा कि एसओ क्यू & ए here में बताया गया है, निश्चित रूप से, बफर की चौड़ाई से विभाजित किया जाना चाहिए, जो आपको बताएगा कि आप कितनी पंक्तियां नीचे हैं!

इस प्रकार, समारोह संशोधित किया जाना चाहिए करने के लिए ...

float texelSizeX = 1.0/uPerMotifBufferWidth; 
float texelSizeY = 1.0/uPerMotifBufferHeight; 
vec2 perMotifUV = vec2( 
    mod(aCellIndex, uPerMotifBufferWidth)*texelSizeX, 
    floor(aCellIndex/uPerMotifBufferWidth)*texelSizeY); **Note the change to uPerMotifBufferWidth here 
perMotifUV += vec2(0.5*texelSizeX, 0.5*texelSizeY); 

कारण मेरा कार्यक्रम वर्ग DataTextures पर काम किया (1: 1) यह है कि ऐसे मामलों में ऊंचाई और चौड़ाई बराबर थे, इसलिए मेरे समारोह गहराई से चौड़ाई से प्रभावी ढंग से विभाजित कर रहा था क्योंकि ऊंचाई = चौड़ाई!

संबंधित मुद्दे