प्री-प्रोसेस करने के लिए प्रयुक्त शेडर्स के अजीब परिणाम मैं घर के लिए 2 डी नमूने का उपयोग कर वसंत भौतिकी सिमुलेशन कर रहा हूं और एक टुकड़े टुकड़े में कुछ स्थिति डेटा को प्री-प्रोसेस कर रहा हूं, और बहुत ही अजीब परिणाम प्राप्त कर रहा हूं। अगर मैं 16 अलग-अलग स्थित स्प्रिंग्स (एक अदृश्य लंगर से उत्पन्न अदृश्य वसंत के अंत में एक बिंदु) से शुरू होता हूं, तो विज़ुअलाइजेशन आठ जोड़े के साथ समाप्त होता है, प्रत्येक जोड़ी उसी वसंत एंकर पॉइंट से लटकती है। हालांकि, अगर मैं केवल tOffsets
मानों का उपयोग करके अंक रखने के लिए विज़ुअलाइजेशन चलाता हूं, तो प्रत्येक एंकर पॉइंट की गणना करने के लिए सभी जानकारी वहां होती है और सही तरीके से प्रदर्शित होती है (हालांकि निश्चित रूप से कोई भौतिकी नहीं)। एक बार जब मैं बसंत भौतिकी में वापस जोड़ता हूं कि मैं फिर से जोड़ों के साथ समाप्त होता हूं। साथ ही, विज़ुअलाइजेशन देखने से, मैं बता सकता हूं कि जोड़े के एंकर पॉइंट मान मूल 16 एंकर पॉइंट मानों में से कोई नहीं हैं। कोई विचार क्या हो रहा है? (दोनों बेला और नीचे तारांकित इनलाइन टिप्पणी देखें।)वसंत भौतिकी सिमुलेशन
(Three.js v 80)
यहाँ V79 का उपयोग कर fiddle देखें।
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
अद्यतन 1: समस्या मानों की संख्या (RGBA, xzyw) मेरे कार्यक्रम के टुकड़े के सभी के बीच सहमति के साथ हो सकता है? मैंने आरजीबीए मूल्य निर्दिष्ट किए हैं जहां भी मैं सोच सकता हूं, लेकिन शायद मैं कहीं याद कर चुका हूं।
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;
अद्यतन 2: यहाँ मेरी जावास्क्रिप्ट से एक टुकड़ा है
शायद समस्या कैसे texels इन बनावट से पढ़ा जा रहा है के साथ क्या करना है? किसी भी तरह यह दो texels के बीच पढ़ा जा सकता है, और तो दो स्प्रिंग्स द्वारा साझा औसत स्थिति के साथ आ रहा है? क्या यह संभव है? यदि हां, तो मैं इसे ठीक करने के लिए कहां देखूँगा?