significa resultados que parley mejor impares impar goles ganar futbol estrategia deportivas como apuestas three.js glsl shader physics

three.js - que - Resultados impares de los sombreadores utilizados para preprocesar la simulación física de primavera



resultados impares en el futbol (1)

Nunca descubrí el problema con el violín en mi pregunta anterior; sin embargo, eventualmente encontré la versión más nueva del script THREE.FBOUtils que estaba usando anteriormente - ahora se llama THREE.GPUComputationRenderer . ¡Después de implementarlo, mi script finalmente funcionó!

Para aquellos que se encuentran intentándolo para resolver un problema similar, aquí está el nuevo y mejorado violín que usa el GPUComputationRenderer en lugar de los antiguos FBOUtils.

Aquí, a partir de la documentación del script, se encuentra un caso de uso básico de GPUComputationRenderer:

//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 );

Estoy haciendo una simulación física de primavera usando muestreadores 2D para albergar y preprocesar algunos datos de posición en un sombreador de fragmentos, y obteniendo resultados muy extraños. Si comienzo con 16 resortes ubicados individualmente (un punto al final de un resorte invisible que se origina de un ancla invisible), la visualización termina con ocho pares, cada par colgando del mismo punto de anclaje de primavera. Sin embargo, si simplemente ejecuto la visualización para colocar los puntos usando solo los valores de tOffsets , toda la información para calcular cada uno de los puntos de anclaje está allí y se muestra correctamente (aunque no la física, por supuesto). Es una vez que vuelvo a agregar en la física de primavera que termino con pares nuevamente. Además, al observar la visualización, puedo decir que los valores de los puntos de anclaje de los pares no son ninguno de los 16 valores originales del punto de anclaje. ¿Alguna idea de lo que está pasando aquí? (Vea a continuación el violín y los comentarios en línea destacados a continuación).

(three.js v 80)

Vea el violín usando v79 aquí.

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

ACTUALIZACIÓN 1: ¿Podría ser el problema con la cantidad de valores (rgba, xzyw) que coinciden entre todas las piezas de mi programa? He especificado los valores de rgba donde puedo pensar, pero quizás me he perdido en alguna parte. Aquí hay un fragmento de mi javascript:

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;

ACTUALIZACIÓN 2:

Tal vez el problema tiene que ver con cómo se leen los téxeles de estas texturas. De alguna manera, puede estar leyendo entre dos téxeles, y así tener una posición promedio compartida por dos resortes. es posible? Si es así, ¿dónde buscaría solucionarlo?