2016-09-14 39 views
9

Bir parça gölgelendiricisindeki bazı konum verilerini barındırmak ve önceden işlemek için 2D örnekleyicileri kullanarak bir yay fiziği simülasyonu yapıyorum ve çok tuhaf sonuçlar elde ediyorum. Eğer 16 ayrı ayrı bulunan yaylarla (görünmez bir ankrajtan çıkan görünmez bir yayın ucundaki bir nokta) başlıyorumsa, görselleştirme sekiz çift ile biter, her bir çift aynı yay tutturma noktasından asılır. Ancak, sadece tOffsets değerlerini kullanarak noktaları yerleştirmek için görselleştirmeyi çalıştırırsam, bağlantı noktalarının her birini hesaplamak için gereken tüm bilgiler oradadır ve doğru şekilde görüntülenir (elbette hiçbir fizik olmasa da). Bir kez daha bahar fiziğine tekrar eklediğimde tekrar çiftlerle çıkarım. Ayrıca, görselleştirmeyi izlemekle, çiftlerin çapa puan değerlerinin orijinal 16 bağlantı noktası değerlerinin hiçbiri olmadığını söyleyebilirim. Burada neler olduğu hakkında bir fikrin var mı? (Keman ve aşağıda yıldız işaretli satır içi yorumları hem Bkz.)İlkbahar fiziği simülasyonunu işlemek için kullanılan gölgelendiricilerin tek sonuçları

(Three.js 80 v)

burada V79 kullanarak fiddle bakınız.

uniform sampler2D tPositions; 
uniform sampler2D tOffsets; 

varying vec2 vUv; 

void main() { 

    float damping = 0.98; 

    vec4 nowPos = texture2D(tPositions, vUv).xyzw; 
    vec4 offsets = texture2D(tOffsets, vUv).xyzw; 
    vec2 velocity = vec2(nowPos.z, nowPos.w); 


    vec2 anchor = vec2(offsets.x, 130.0); 

    // Newton's law: F = M * A 
    float mass = 24.0; 
    vec2 acceleration = vec2(0.0, 0.0); 

    // 1. apply gravity's force: **this works fine 
    vec2 gravity = vec2(0.0, 2.0); 
    gravity /= mass; 
    acceleration += gravity; 

    // 2. apply the spring force ** something goes wrong once I add the spring physics - the springs display in pairs 
    float restLength = length(yAnchor - offsets.y); 
    float springConstant = 0.2; 

    // Vector pointing from anchor to point position 
    vec2 springForce = vec2(nowPos.x - anchor.x, nowPos.y - anchor.y); 
    // length of the vector 
    float distance = length(springForce); 
    // stretch is the difference between the current distance and restLength 
    float stretch = distance - restLength; 

    // Calculate springForce according to Hooke's Law 
    springForce = normalize(springForce); 
    springForce *= (1.0 * springConstant * stretch); 

    springForce /= mass; 
    acceleration += springForce; // ** If I comment out this line, all points display where expected, and fall according to gravity. If I add it it back in the springs work properly but display in 8 pairs as opposed to 16 independent locations 

    velocity += acceleration; 
    velocity *= damping; 

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

    // Write new position out to texture for the next shader 
    gl_FragColor = vec4(newPosition.x, newPosition.y, velocity.x, velocity.y); // **the pair problem shows up with this line active 

    // sanity checks with comments: 
    // gl_FragColor = vec4(newPosition.x, newPosition.y, 0.0, 0.0); // **the pair problem also shows up in this case 
    // gl_FragColor = vec4(offsets.x, offsets.y, velocity); // **all points display in the correct position, though no physics 
    // gl_FragColor = vec4(nowPos.x, nowPos.y, 0.0, 0.0); // **all points display in the correct position, though no physics 

GÜNCELLEME 1: sorun benim programın tüm parçaları arasında kabul değerlerin sayısı (RGBA, xzyw) ile olabilir mi? Düşünebildiğim her yerde rgba değerlerini belirledim, ama belki de bir yerlerde özledim.

if (! renderer.context.getExtension('OES_texture_float')) { 
     alert('OES_texture_float is not :('); 
} 

var width = 4, height = 4; 
particles = width * height; 

// Start creation of DataTexture 
var positions = new Float32Array(particles * 4); 
var offsets = new Float32Array(particles * 4); 

// hardcoded dummy values for the sake of debugging: 
var somePositions = [10.885510444641113, -6.274578094482422, 0, 0, -10.12020206451416, 0.8196354508399963, 0, 0, 35.518341064453125, -5.810637474060059, 0, 0, 3.7696402072906494, -3.118760347366333, 0, 0, 9.090447425842285, -7.851400375366211, 0, 0, -32.53229522705078, -26.4628849029541, 0, 0, 32.3623046875, 22.746187210083008, 0, 0, 7.844726085662842, -15.305091857910156, 0, 0, -32.65345001220703, 22.251712799072266, 0, 0, -25.811357498168945, 32.4153938293457, 0, 0, -28.263731002807617, -31.015430450439453, 0, 0, 2.0903847217559814, 1.7632032632827759, 0, 0, -4.471604347229004, 8.995194435119629, 0, 0, -12.317420959472656, 12.19576358795166, 0, 0, 36.77312469482422, -14.580523490905762, 0, 0, 36.447078704833984, -16.085195541381836, 0, 0]; 

for (var i = 0, i4 = 0; i < particles; i ++, i4 +=4) { 

    positions[ i4 + 0 ] = somePositions[ i4 + 0 ]; // x 
    positions[ i4 + 1 ] = somePositions[ i4 + 1 ]; // y 
    positions[ i4 + 2 ] = 0.0; // velocity 
    positions[ i4 + 3 ] = 0.0; // velocity 

    offsets[ i4 + 0 ] = positions[ i4 + 0 ];// - gridPositions[ i4 + 0 ]; // width offset 
    offsets[ i4 + 1 ] = positions[ i4 + 1 ];// - gridPositions[ i4 + 1 ]; // height offset 
    offsets[ i4 + 2 ] = 0; // not used 
    offsets[ i4 + 3 ] = 0; // not used 

} 

positionsTexture = new THREE.DataTexture(positions, width, height, THREE.RGBAFormat, THREE.FloatType); 
positionsTexture.minFilter = THREE.NearestFilter; 
positionsTexture.magFilter = THREE.NearestFilter; 
positionsTexture.needsUpdate = true; 

offsetsTexture = new THREE.DataTexture(offsets, width, height, THREE.RGBAFormat, THREE.FloatType); 
offsetsTexture.minFilter = THREE.NearestFilter; 
offsetsTexture.magFilter = THREE.NearestFilter; 
offsetsTexture.needsUpdate = true; 

rtTexturePos = new THREE.WebGLRenderTarget(width, height, { 
    wrapS:THREE.RepeatWrapping, 
    wrapT:THREE.RepeatWrapping, 
    minFilter: THREE.NearestFilter, 
    magFilter: THREE.NearestFilter, 
    format: THREE.RGBAFormat, 
    type:THREE.FloatType, 
    stencilBuffer: false 
}); 

rtTexturePos2 = rtTexturePos.clone(); 

simulationShader = new THREE.ShaderMaterial({ 
    uniforms: { 
     tPositions: { type: "t", value: positionsTexture }, 
     tOffsets: { type: "t", value: offsetsTexture }, 
    }, 
     vertexShader: document.getElementById('texture_vertex_simulation_shader').textContent, 
     fragmentShader: document.getElementById('texture_fragment_simulation_shader').textContent 
}); 

fboParticles = new THREE.FBOUtils(width, renderer, simulationShader); 
fboParticles.renderToTexture(rtTexturePos, rtTexturePos2); 

fboParticles.in = rtTexturePos; 
fboParticles.out = rtTexturePos2; 

GÜNCELLEME 2: İşte benim javascript snippet'idir Belki sorun teksel bu dokular okunan şekliyle ilgili ilgisi var

? Her nasılsa iki metin arasında okuma yapıyor olabilir ve bu yüzden iki yayın paylaştığı ortalama bir konumla mı geliyor? Mümkün mü? Eğer öyleyse, nerede tamir edebilirim?

cevap

0

Sorunu yukarıdaki sorudaki kemanla hiç bulamadım; Ancak, sonunda kullandığım THREE.FBOUtils komut dosyasının daha yeni sürümünü buldum - şimdi THREE.GPUComputationRenderer deniyor. Bunu uyguladıktan sonra senaryo yazdım! kendileri de benzer bir sorunu çözmeye böylece çalışırken çalışırken bulanlar için

, burada yeni ve eski FBOUtils yerine GPUComputationRenderer kullanılarak fiddle düzeldi.

//Initialization... 

// Create computation renderer 
var gpuCompute = new GPUComputationRenderer(1024, 1024, renderer); 

// Create initial state float textures 
var pos0 = gpuCompute.createTexture(); 
var vel0 = gpuCompute.createTexture(); 
// and fill in here the texture data... 

// Add texture variables 
var velVar = gpuCompute.addVariable("textureVelocity", fragmentShaderVel, pos0); 
var posVar = gpuCompute.addVariable("texturePosition", fragmentShaderPos, vel0); 

// Add variable dependencies 
gpuCompute.setVariableDependencies(velVar, [ velVar, posVar ]); 
gpuCompute.setVariableDependencies(posVar, [ velVar, posVar ]); 

// Add custom uniforms 
velVar.material.uniforms.time = { value: 0.0 }; 

// Check for completeness 
var error = gpuCompute.init(); 
if (error !== null) { 
    console.error(error); 
} 

// In each frame... 

// Compute! 
gpuCompute.compute(); 

// Update texture uniforms in your visualization materials with the gpu renderer output 
myMaterial.uniforms.myTexture.value = gpuCompute.getCurrentRenderTarget(posVar).texture; 

// Do your rendering 
renderer.render(myScene, myCamera); 
: Burada

, senaryo belgelerinden, GPUComputationRenderer temel kullanım durumu