0

我有一个简短的问题,想知道是否有人有任何想法或库可供我使用。我正在制作一个 java 游戏,需要使 2d 图像凹入。问题是,1:我不知道如何使图像凹入。2:我需要凹面效果有点像后期处理,想想 Oculus Rift。一切正常,但玩家的相机将正常的 2d 图像扭曲为 3d。我是一名大二学生,所以我不知道很复杂的数学来完成这个。

谢谢,-蓝

4

1 回答 1

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);
    }
}

我不知道你在画布上绘制像素的实际函数是什么,上面只是伪代码。

于 2015-01-20T05:12:15.600 回答