Mantengo un sombreador de vértices encapsulado en una clase de material personalizada (heredada de ShaderMaterial pero ahora de MeshStandardMaterial ) que convierte las coordenadas 3D en NDC como de costumbre:
vec4 ndcPos = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); ndcPos /= ndcPos.w; //...other transformations to ndcPos luego se aplica un conjunto de transformaciones a ndcPos . Como puede ver, se aplican en el espacio NDC. Necesito llevar la coordenada resultante al espacio de la cámara (ojo), así que supongo que debemos invertir los pasos, algo como esto:
vec4 mvPos = ndcPos * ndcPos.w; mvPos *= inverse of projectionMatrix; Resultado esperado: mvPos solo tiene aplicada la transformación modelView.
Preguntas:
projectionMatrix ? Sería fácil y económico pasar camera.projectionMatrixInverse como uniforme al sombreador de vértices, pero no encontré la manera de hacerlo en three.js: ni las clases de material ancestral ni onBeforeCompile pueden acceder a la cámara.La operación inversa para calcular la posición del espacio de vista es
vec4 p = inverse(projectionMatrix) * ndc; vec4 mvPos = p / pw;y la operación inversa para calcular la posición del objeto es
vec4 p = inverse(projectionMatrix * modelViewMatrix) * ndc; vec4 pos = p / pw; (Tenga en cuenta que en el código anterior, pos corresponde a la position del atributo y mvPos corresponde a la position * modelViewMatrix ).
Nota: si transforma una coordenada cartesiana con una matriz de proyección de perspectiva (o matriz de proyección de perspectiva inversa), el resultado es una coordenada homogénea . Para convertir una coordenada homogénea en una coordenada cartesiana, debe realizar una división de perspectiva (después de la división de perspectiva, el componente w es 1).
Cabe mencionar que la función inverse existe solo desde GLSL ES 3.00 (WebGL 2.0) y no está disponible en GLSL ES 1.00 (WebGL 1.0). Por lo que puede ser necesario calcular la matriz inversa en Javascript y pasarla como variable uniforme al shader.