为什么我的墙壁从背面看不见?

时间:2015-04-12 22:19:50

标签: java 3d

我目前正在开发一个Java项目,该项目涉及创建3D迷宫游戏,但我的墙壁存在问题。实际上,当我们绕墙走动时,它会消失;它就像从后面看不到墙。

以下是我的代码(主要来自YouTube用户" thecherno"):

public void renderWall(double xLeft, double xRight, double zDistanceLeft, double zDistanceRight, double yHeight) {
    double upCorrect = 0.0625;
    double rightCorrect = 0.0625;
    double forwardCorrect = 0.0625;
    double walkCorrect = -0.0625;

    /* que se passe t-il quand on bouge vers la gauche sur l'axe des x */
    double xcLeft = ((xLeft) - (right * rightCorrect)) * 2;
    /* sur la gauche sur l'axe des z */
    double zcLeft = ((zDistanceLeft) - (forward * forwardCorrect)) * 2;

    /* quand on fait une rotation vers la gauche sur l'axe des x */
    double rotLeftSideX = xcLeft * cosine - zcLeft * sine;
    /* le coin du mur haut gauche */
    double yCornerTL = ((-yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
    /* bas gauche */
    double yCornerBL = ((+0.5 - yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
    /* quand on fait une rotation vers la gauche sur l'axe des z */
    double rotLeftSideZ = zcLeft * cosine + xcLeft * sine;

    /* Pour la droite */
    double xcRight = ((xRight) - (right * rightCorrect)) * 2;
    double zcRight = ((zDistanceRight) - (forward * forwardCorrect)) * 2;

    double rotRightSideX = xcRight * cosine - zcRight * sine;
    double yCornerTR = ((-yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
    double yCornerBR = ((+0.5 - yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
    double rotRightSideZ = zcRight * cosine + xcRight * sine;

    double tex30 = 0;
    double tex40 = 8;
    double clip = 0.5;
    if (rotLeftSideZ < clip && rotRightSideZ < clip) {
        return;
    }
    if (rotLeftSideZ < clip) {
        double clip0 = (clip - rotLeftSideZ) / (rotRightSideZ - rotLeftSideZ);
        rotLeftSideZ = rotLeftSideZ + (rotRightSideZ - rotLeftSideZ) * clip0;
        rotLeftSideX = rotLeftSideX + (rotRightSideX - rotLeftSideX) * clip0;
        tex30 = tex30 + (tex40 - tex30) * clip0;
    }
    if (rotRightSideZ < clip) {
        double clip0 = (clip - rotLeftSideZ) / (rotRightSideZ - rotLeftSideZ);
        rotRightSideZ = rotLeftSideZ + (rotRightSideZ - rotLeftSideZ) * clip0;
        rotRightSideX = rotLeftSideX + (rotRightSideX - rotLeftSideX) * clip0;
        tex40 = tex30 + (tex40 - tex30) * clip0;
    }


    double xPixelLeft = (rotLeftSideX / rotLeftSideZ * height + width / 2);
    double xPixelRight = (rotRightSideX / rotRightSideZ * height + width / 2);

    /* si le coté gauche du mur passe au dela du coté droit */
    if (xPixelLeft >= xPixelRight) {
        return;
    }

    /*
     * On cast les double en entier car les pixels sont placé dans un
     * tableau d'entier
     */
    int xPixelLeftInt = (int) (xPixelLeft);
    int xPixelRightInt = (int) (xPixelRight);

    /* Si ca depasse, on rend rien */
    if (xPixelLeftInt < 0) {
        xPixelLeftInt = 0;
    }
    if (xPixelRightInt > width) {
        xPixelRightInt = width;
    }

    double yPixelLeftTop = (yCornerTL / rotLeftSideZ * height + height / 2.0);
    double yPixelLeftBottom = (yCornerBL / rotLeftSideZ * height + height / 2.0);
    double yPixelRightTop = (yCornerTR / rotRightSideZ * height + height / 2.0);
    double yPixelRightBottom = (yCornerBR / rotRightSideZ * height + height / 2.0);

    double tex1 = 1 / rotLeftSideZ;
    double tex2 = 1 / rotRightSideZ;
    double tex3 = 0 / rotLeftSideZ;
    double tex4 = 8 / rotRightSideZ - tex3;

    for (int x = xPixelLeftInt; x < xPixelRightInt; x++) {

        double pixelRotation = (x - xPixelLeft) / (xPixelRight - xPixelLeft);
        double zWall = (tex1 + (tex2 - tex1) * pixelRotation);

        if(zBufferWall[x] > zWall){
            continue;
        }

        zBufferWall[x] = zWall;
        int xTexture = (int) ((tex3 + tex4 * pixelRotation) / (tex1 + (tex2 - tex1) * pixelRotation));

        double yPixelTop = yPixelLeftTop + (yPixelRightTop - yPixelLeftTop) * pixelRotation;
        double yPixelBottom = yPixelLeftBottom + (yPixelRightBottom - yPixelLeftBottom) * pixelRotation;

        int yPixelTopInt = (int) (yPixelTop);
        int yPixelBottomInt = (int) (yPixelBottom);

        /* Si ca depasse, on rend rien */
        if (yPixelTopInt < 0) {
            yPixelTopInt = 0;
        }
        if (yPixelBottomInt > height) {
            yPixelBottomInt = height;
        }

        for (int y = yPixelTopInt; y < yPixelBottomInt; y++) {
            double pixelRotationY = (y - yPixelTop) / (yPixelBottom - yPixelTop);
            int yTexture = (int) (8 * pixelRotationY);
            // pixels[x + y * width] = xTexture * 100 + yTexture * 100 *
            // 256;
            pixels[x + y * width] = Texture.floor.pixels[(xTexture & 7) + 8 + (yTexture & 7) * 16];
            zBuffer[x + y * width] = 1 / (tex1 + (tex2 - tex1) * pixelRotation) * 8;
        }
    }
}

我认为问题来自于此:

if (xPixelLeft >= xPixelRight) {
    return;
}

为什么代码中包含导致墙壁消失的线条,以及如何从两侧看到墙壁?

2 个答案:

答案 0 :(得分:0)

这是back-face culling,这种技术可以去除(通常)不可见的表面,因为它们位于不透明物体的远端。 (想想一个立方体:你只能同时看到它的三个面。)这样可以让程序更快,因为它可以减少工作量。

我认为你有两个主要选择:

  • 删除您标识的线条:这将使所有曲面都成双面,这样无论它们面向哪个方向,它们都会被绘制。请注意,墙壁将非常薄,另一侧的纹理会反映出来。
  • 在另一侧(需要它们的地方)添加额外(单面)表面。这允许您在每一侧使用不同的纹理和照明,并且您可以分离表面以使墙壁具有厚度。

您还可以对这些使用变体,例如在某些地方添加额外的曲面并在其他地方标记其他曲面,或在绘制背面时切换到其他纹理。

顺便说一句,尝试在游戏中设置noclip mode并飞到您通常受限的地方:您可能会看到这些和相关技术正在使用中。例如,在某些游戏中,天空只能在窗户内或室外区域的“天花板”上绘制。

答案 1 :(得分:0)

Thanx you deltab。

我写下这段代码:

    if (xPixelLeft >= xPixelRight) {
          double e = xPixelLeft;
          xPixelLeft = xPixelRight;
          xPixelRight = e;
          e = rotLeftSideX;
          rotLeftSideX = rotRightSideX;
          rotRightSideX = e;
          e = yCornerTL;
          yCornerTL = yCornerTR;
          yCornerTR = e;
          e = yCornerBL;
          yCornerBL = yCornerBR;
          yCornerBR = e;

          e = yPixelLeftTop;
          yPixelLeftTop = yPixelRightTop;
          yPixelRightTop = e;
          e = yPixelLeftBottom;
          yPixelLeftBottom = yPixelRightBottom;
          yPixelRightBottom = e;
    }

它有效! 我现在将解决这个问题,这将是一个很重要的问题......