我有一个简短的问题,想知道是否有人有任何想法或库可供我使用。我正在制作一个 java 游戏,需要使 2d 图像凹入。问题是,1:我不知道如何使图像凹入。2:我需要凹面效果有点像后期处理,想想 Oculus Rift。一切正常,但玩家的相机将正常的 2d 图像扭曲为 3d。我是一名大二学生,所以我不知道很复杂的数学来完成这个。
谢谢,-蓝
如果您不使用任何 3D 库或类似的东西,只需将其实现为简单的 2D 失真即可。只要看起来不错,它不必在数学上是 100% 正确的。您可以创建几个数组来存储位图的扭曲纹理坐标,这意味着您可以预先计算一次扭曲(这会很慢,但只会发生一次),然后使用预先计算的值进行多次渲染(这会更快)。
这是一个使用幂公式生成失真场的简单函数。它没有任何 3D 效果,它只是吸在图像的中心以呈现凹面外观:
int distortionU[][];
int distortionV[][];
public void computeDistortion(int width, int height)
{
// this will be really slow but you only have to call it once:
int halfWidth = width / 2;
int halfHeight = height / 2;
// work out the distance from the center in the corners:
double maxDistance = Math.sqrt((double)((halfWidth * halfWidth) + (halfHeight * halfHeight)));
// allocate arrays to store the distorted co-ordinates:
distortionU = new int[width][height];
distortionV = new int[width][height];
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
// work out the distortion at this pixel:
// find distance from the center:
int xDiff = x - halfWidth;
int yDiff = y - halfHeight;
double distance = Math.sqrt((double)((xDiff * xDiff) + (yDiff * yDiff)));
// distort the distance using a power function
double invDistance = 1.0 - (distance / maxDistance);
double distortedDistance = (1.0 - Math.pow(invDistance, 1.7)) * maxDistance;
distortedDistance *= 0.7; // zoom in a little bit to avoid gaps at the edges
// work out how much to multiply xDiff and yDiff by:
double distortionFactor = distortedDistance / distance;
xDiff = (int)((double)xDiff * distortionFactor);
yDiff = (int)((double)yDiff * distortionFactor);
// save the distorted co-ordinates
distortionU[x][y] = halfWidth + xDiff;
distortionV[x][y] = halfHeight + yDiff;
// clamp
if(distortionU[x][y] < 0)
distortionU[x][y] = 0;
if(distortionU[x][y] >= width)
distortionU[x][y] = width - 1;
if(distortionV[x][y] < 0)
distortionV[x][y] = 0;
if(distortionV[x][y] >= height)
distortionV[x][y] = height - 1;
}
}
}
一旦传递了要扭曲的位图大小,就调用它。您可以使用这些值或使用完全不同的公式来获得您想要的效果。为 pow() 函数使用小于 1 的指数应该使图像具有凸面外观。
然后,当您渲染位图或将其复制到另一个位图时,使用distortionU 和distortionV 中的值来扭曲您的位图,例如:
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
// int pixelColor = bitmap.getPixel(x, y); // gets undistorted value
int pixelColor = bitmap.getPixel(distortionU[x][y], distortionV[x][y]); // gets distorted value
canvas.drawPixel(x + offsetX, y + offsetY, pixelColor);
}
}
我不知道你在画布上绘制像素的实际函数是什么,上面只是伪代码。