Cub3d 학습일지 - 4 - 벽 영상 렌더링하기

대표 사진

 

Raycasting Basics with JavaScript

Learn the mathematics behind the ray casting technique used in the Wolfenstein 3D source code and implement a 3D projected scene using JavaScript

courses.pikuma.com

제 4강 Rendering Wall Projection 벽 영상 렌더링하기

4.1  Wall Projection 벽 영상
4.2 
Visualizing the Minimap 미니맵 가상화하기
4.3 
Coding the Wall Projection 벽 영상 구현하기
4.4 
Fixing the Fishbowl Distortion 어항 왜곡 수정하기
4.E 
Exercise: Wall Shading by Depth 깊이에 따른 벽 그림자 구현하기
4.5 
Coding Wall Shading by Depth 깊이에 따른 벽
4.6 
Bright /Dark Wall Sides 밝은/어두운 벽들

4.1  Wall Projection 벽 영상

우리가 벽을 볼 때, 밑 그림처럼 이해하면 좋습니다.

실제 벽의 크기가 다르게 보이는 것처럼 벽을 볼 때 wall projection이라는 것으로 비춰 본다고 생각해봅시다.

 

여기서 저희가 알아내야 하는 건 wall projection의 길이입니다. (projected wall height)

삼각형의 __ 현상을 이용할 것입니다.

$ (actual\,wall\,height) / (distance\,to\,wall) $

$ =\,(projected\,wall\,height) / (distance\,from\,player\,to\,projection\,plane) $

이를 해석하자면 다음과 같이 말 할 수도 있겠네요!

$ (TILE\_SIZE) / (ray\,distance) $

$ =\,($알고 싶은 값$) / ($크기에 따라 새로 계산 : $320$이면 $277) $

 

Javascript 코드로 나타내면 다음과 같습니다.

var distanceProjPlane = (WINDOW_WIDTH / 2) / Math.tan(FOV_ANGLE / 2);

var wallStripHeight = (TILE_SIZE / ray_distance) * distanceProjPlane;

4.2  Visualizing the Minimap 미니맵 가상화하기
4.3  
Coding the Wall Projection 벽 영상 구현하기

 

github.com/KKWANH/cub3d_kkim/tree/main/J6_3D_Wall_Projection

 

KKWANH/cub3d_kkim

Contribute to KKWANH/cub3d_kkim development by creating an account on GitHub.

github.com


4.4  Fixing the Fishbowl Distortion 어항 왜곡 수정하기

4.3 까지 진행된 후 실행시키면 다음과 같은 모습을 보실 수 있으실 겁니다.

 

뭔가 이상하지 않나요..? 벽이 너무 둥글어보이죠.

 

이 챕터에서는 이렇게 벽이 둥글게 보이는 Fishbowl Distortion 문제를 해결해 보려고 합니다.

Pic 2.

아래 사진에 이렇게 나오는 이유가 나와있습니다.

 

같은 벽임에도 A와 B까지의 거리가 달라 보이기 때문에 이런 문제가 벌어지는 겁니다.

 

 

그렇다면 이런 문제를 어떻게 해결해야할까요?

 

피쿠마 센세는 이렇게 해결하셨습니다.

 

맞는 길이를 찾기 위한 삼각형을 하나 더 만들어서요.

 

조금 다르게 말하면,

ray의 출발점이 플레이어가 아니라 벽으로부터 직선 거리가 되도록 하는 거라고 할 수도 있겠네요.

 

$ correct\,distance\,=\,distorted\,distance\,*\,cos(θ) $

var correctDisance = ray.distance * Math.cos(ray.rayAngle - player.rotationAngle);

 

function    render3DProjectedWalls()
{
    // loop every ray in the array of rays
    for (var i=0; i<NUM_RAYS; i++)
    {
        var correctWallDistance = rays[i].distance * Math.cos(rays[i].rayAngle - player.rotationAngle);

        // calculate the distance in the projection plane
        var distanceProjectionPlane = (WINDOW_WIDTH / 2) / Math.tan(FOV_ANGLE / 2);

        // projected wall height
        var wallStripHeight = (TILE_SIZE / correctWallDistance) * distanceProjectionPlane;

        fill("rgba(255, 255, 255, 1.0)");
        // noStroke();
        rect(
            i * WALL_STRIP_WIDTH,
            (WINDOW_HEIGHT / 2) - (wallStripHeight / 2),
            WALL_STRIP_WIDTH,
            wallStripHeight
        );
    }
}

 

해결했습니다.


Javascript는 여기까지 --

이후로 거리에 따른 밝기 등 여러가지를 배웠는데,

github에 다 올려 놓았습니다! 참고하세용!

github.com/KKWANH/cub3d_kkim

 

KKWANH/cub3d_kkim

Contribute to KKWANH/cub3d_kkim development by creating an account on GitHub.

github.com