Originalmente, estaba tratando de crear un sombreador de skybox para Unity que funcionara con imágenes de ojo de pez como entrada, pero no pude hacerlo funcionar, así que comencé a experimentar con JavaScript porque estoy más familiarizado con él. Casi conseguí que funcionara, pero terminé con algunos artefactos extraños en forma de lágrima en un área que no debería contener color. esta fue la imagen de origen y esta fue la imagen de resultado que muestra los artefactos en forma de lágrima.
aquí está mi código:
res = 1000; const c2 = document.createElement("canvas"); c2.height = res; c2.width = res; const height = 1000; const width = 2000; const c3 = document.createElement("canvas"); c3.height = height; c3.width = width; document.body.appendChild(c3); img = new Image(); img.src = "test.png" img.addEventListener("load",function() { const ctx2 = c2.getContext("2d"); ctx2.drawImage(img, 0, 0, res, res); const data = ctx2.getImageData(0, 0, res, res).data; const ctx3 = c3.getContext("2d"); for (let j = 0; j <= width; j++) { for (let i = 0; i <= height; i++) { y = -Math.cos(Math.PI * (i / height)); d = Math.sin(Math.PI * (i / height)); z = Math.cos(Math.PI + 2 * Math.PI * (j / width)) * d; x = Math.sin(Math.PI + 2 * Math.PI * (j / width)) * d; const r = coord2fisheye(x,y,z); rx = Math.floor(rx * res); ry = Math.floor(ry * res); ctx3.fillStyle = `rgb(${data[ry * res * 4 + rx * 4]},${data[ry * res * 4 + rx * 4 + 1]},${data[ry * res * 4 + rx * 4 + 2]})` ctx3.fillRect(j, i, 1, 1); } } }) class Vector { constructor(x,y,z) { this.x = x; this.y = y; this.z = z; } get normalize() { const m = this.magnitude; return new Vector( this.x / m, this.y / m, this.z / m); } get magnitude() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } } function coord2fisheye(x,y,z) { const vector = new Vector(x,y,z); const normalizedVector = vector.normalize; const a = Math.atan2(normalizedVector.y,normalizedVector.x); const b = (180/220) * (2 / Math.PI) * Math.atan2(Math.sqrt(normalizedVector.x ** 2 + normalizedVector.y ** 2),normalizedVector.z); const fy = Math.sin(a) * b; const fx = Math.cos(a) * b; return {"x":fx * 0.5 + 0.5,"y":fy * 0.5 + 0.5}; }el error parece estar en alguna parte de la función coord2fisheye pero no puedo entender qué es lo que está mal. Espero que alguien pueda ayudarme con mi problema.