我有一个简单的问题,并想知道是否有人可以使用任何想法或库。我正在制作一个java游戏,需要将2d图像凹进去。问题是,1:我不知道如何使图像凹陷。 2:我认为凹面效果有点像后期过程,想想Oculus Rift。一切都很正常,但是玩家的相机会扭曲正常的2D图像看起来像3d。我是Sophmore,所以我不知道非常复杂的数学来完成这个。
谢谢, 蓝
答案 0 :(得分:1)
如果您没有使用任何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);
}
}
我不知道你在画布上绘制像素的实际功能是什么,上面只是伪代码。