es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Reconstruir worldposition.xyz a partir de la profundidad.

Quiero restaurar la posición del mundo (worldposition.xyz) desde cualquier píxel de una imagen renderizada para su posterior procesamiento. Con la ayuda del ejemplo de three.js, he reconstruido el valor de profundidad. Creo que estoy cerca de mi objetivo. ¿Alguien sabe cómo puedo reconstruir las posiciones del mundo a partir de la vUv y el valor de profundidad?

depthShader = {

uniforms: {

   'tDiffuse': { value: null }, 
   'tDepth': { value: null },
   'cameraNear': { value: 0 },
   'cameraFar': { value: 0 },            
},

vertexShader:`

   varying vec2 vUv;

   void main() {

      vUv = uv;

      vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
      gl_Position = projectionMatrix * modelViewPosition;

   }`,

fragmentShader:`
   #include <packing>

   uniform sampler2D tDiffuse;
   uniform sampler2D tDepth;
   uniform float cameraNear;
   uniform float cameraFar; 
   varying vec2 vUv;

   float readDepth( sampler2D depthSampler, vec2 coord ) {
      float fragCoordZ = texture2D( depthSampler, coord ).x;
      float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
      return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
   }


   void main() {

      float depth = readDepth(tDepth, vUv);
      vec4 color = texture2D(tDiffuse, vUv);

      gl_FragColor.rgb = 1.0 - vec3( depth );

   }`
};
Tags:  ,

Answer

  1. Avatar for davy.ai

    Para reconstruir las posiciones mundiales a partir de la vUv y el valor de profundidad, necesitas modificar el depthShader proporcionado. Actualmente, el shader solo está emitiendo el valor de profundidad como un valor en escala de grises, pero necesitamos calcular las posiciones mundiales.

    Para hacer esto, necesitarás acceso a la cámara, de modo que puedas recuperar la matriz de proyección de la cámara. Puedes usar esta matriz, junto con el valor de profundidad y la vUv, para calcular la posición en la pantalla en el espacio de la cámara. Luego, puedes usar la inversa de la matriz de proyección para transformar esta posición en la pantalla al espacio mundial.

    Aquí tienes un fragment shader actualizado que realiza este cálculo:

    #include <packing>
    
    uniform sampler2D tDiffuse;
    uniform sampler2D tDepth;
    uniform float cameraNear;
    uniform float cameraFar;    
    uniform mat4 projectionMatrix;
    
    varying vec2 vUv;
    
    float readDepth( sampler2D depthSampler, vec2 coord ) {
        float fragCoordZ = texture2D( depthSampler, coord ).x;
        float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
        return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
    }
    
    
    void main() {
    
        float depth = readDepth(tDepth, vUv);
    
        // calculate camera space position
        vec3 posCamera = vec3((vUv - 0.5) * 2.0, depth);
        posCamera = vec3(posCamera.xy, -1.0) * posCamera.z;
    
        // transform to world space
        vec4 posWorld = vec4(posCamera, 1.0);
        posWorld = projectionMatrixInverse * posWorld;
        posWorld.xyz /= posWorld.w;
    
        gl_FragColor.rgb = posWorld.xyz;
    
    }
    

    En este shader actualizado, calculamos la posición en el espacio de la cámara usando la vUv y el valor de profundidad, como antes. Luego, transformamos esta posición al espacio mundial usando la inversa de la matriz de proyección. Finalmente, emitimos la posición mundial como el color final.

    Para usar este shader, necesitarás pasar la matriz de proyección de la cámara como una uniforme, al igual que cameraNear y cameraFar. Puedes obtener la matriz de proyección accediendo a la propiedad projectionMatrix de la cámara:

    depthShader.uniforms.projectionMatrix.value = camera.projectionMatrix;
    

    Con esta modificación en el depthShader, ahora deberías poder reconstruir la posición mundial desde cualquier píxel en la imagen renderizada.

Comments are closed.