Tengo el siguiente proyecto a continuación creado con ThreeJS. Notarás que el objeto dorado crea una sombra detrás de él en una esfera en la que solo renderizo la parte trasera para que podamos ver los objetos en el interior. Estoy usando un punto de luz en el centro del modelo de ojos para crear la sombra uniformemente en todas las direcciones. Esta es la razón por la cual la sombra es curva.
Necesito saber cómo obtener las coordenadas 3D (x,y,z) de cada píxel de esta sombra que se creó. Como referencia, aquí está el código que crea la sombra con mucho eliminado para simplificar.
renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.BasicShadowMap//THREE.PCFSoftShadowMap; const light = new THREE.PointLight( 0xffffff, 20, 0 ); light.position.set( 0, 0, 0 ); light.castShadow = true; light.shadow.mapSize.width = 512; light.shadow.camera.near = 0.5; light.shadow.camera.far = 500; scene.add( light ); const sphereGeometry = new THREE.SphereGeometry( 25, 32, 32 ); const sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xffffff } ); sphereMaterial.side=THREE.BackSide; const sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); sphere.castShadow = false; sphere.receiveShadow = true; scene.add( sphere );Investigué un poco sobre esto y creo que puede estar almacenando la información de la sombra en la propiedad de matriz del modelo, pero esto no está claro con seguridad en ninguna documentación, por lo que no estoy seguro de dónde buscar para obtener esta información. ¡Cualquier ayuda es apreciada!
--- Información extra no importante ---
Además, en caso de que tenga curiosidad, la razón por la que necesito las coordenadas de la sombra es porque las usaré para proyectar rayos de nuevo en el ojo y crear un tipo diferente de sombra en un proyecto equidistante acimutal a la derecha (es complicado...), pero solo sé que si tengo las coordenadas 3D de los píxeles de sombra, puedo hacer esto :). Ya lo estoy haciendo para los músculos del ojo por ejemplo.
No puede extraer la sombra en una nueva geometría porque todo esto se calcula en los sombreadores de GPU durante el tiempo de procesamiento, por lo que JavaScript realmente no tiene acceso a las posiciones de shadowMap. Sin embargo, hay una solución.
Suponiendo que su punto de luz está en (0, 0, 0) y está en el centro de la esfera, podría iterar a través de los vértices del objeto dorado y proyectar estas posiciones en la esfera:
// Sphere radius const radius = 25; const vec3 = new THREE.Vector3(); // Get the vertex position array const vertices = goldObject.geometry.getAttribute("position").array; // Loop that iterates through all vertex positions for (let i3 = 0; i3 < vertices.length; i3 += 3) { // Set this vertex into our vec3 vec3.set( vertices[i3 + 0], // x vertices[i3 + 1], // y vertices[i3 + 2] // z ); // Set vector magnitude to 1 vec3.normalize(); // Set vector magnitude to radius of sphere vec3.multiplyScalar(sphereRadius); // Now you have the spherical projection of this vertex! console.log(vec3); } Como la fuente de luz es el centro exacto de la esfera, podrías tomar la posición de cada vértice del objeto dorado, normalizarlo y luego multiplicarlo por el radio de la esfera. Ahora que tiene el vec3 en cada iteración, puede agregarlo a su propia matriz para crear su propia TRES.Geometría de búfer que se empuja contra la esfera.
Por supuesto, si ha trasladado o rotado el objeto dorado, eso afectará las posiciones de los vértices, por lo que tendrá que deshacer esas traslaciones, rotaciones, etc. al recorrer todos los vértices.