본문 바로가기
도전

3D Computer Graphics (1)

by oncerun 2023. 4. 1.
반응형

멋진 3D 인터랙티브 홈페이지를 발견했다.  나도 한번 만들고 싶었다. 

https://zero.tech/

 

ZERO - Distribute the Future

 

zero.tech

 

이를 위해 무엇이 필요한지 정보를 수집하던 도중 여러 키워드가 나왔다. 

 

1. Three.js (+gsap)

2. HTML5, CSS, JS

3. Shader ( GLSL)

4. 3D Computer Graphics

5. 선형대수학, 기하학..

 

그래서 이번 시리즈는 하나씩 관련 정보를 찾고 이를 구현하는 과정이다. 

구현은 아마 회사 홈페이지에 적용할 수 있지 않을까 싶다.

 

Three.js는 사실 몇 가지 예제를 만들어 보았다. WebGL의 상당 부분이 쉬운 API로 제공되어 간단하고 빠르게 만들 수 있지만 실제로 목표로 잡은 홈페이지기반 모델의 텍스처와 색을 특정 부분부터 점진적으로 변경하고 싶은데 이 경우 FragmentShader와 VertextShader를 사용해야 구현이 가능하다. 

 

 

HTML5, CSS3, JS는 내 기초지식을 기반으로 한다. 필요한 찾고 구현한다.  특정 프런트 프레임워크를 사용하지 않고 나중에 번들러 정도만 공부해서 적용할 것이다.  JS는 es6 이상 문법을 사용할 것이고, 최대한 객체지향적으로 사용해보려고 한다. 

 

Shader는 가장 큰 문제인데, 우선 병렬 프로그래밍을 하는 기분이다. 매우 생소하고 쉽지 않다. 

현재는 FragmentShader만을 사용해 도형을 그리고 부분의 색을 칠하는 정도까지 가능하다. 

 

그리고 이 분야를 1주 정도 알아보았는데, 내가 생각하기엔 이 분야는 그 자체가 수학이다. 

특히 기하학과 선형대수학의 개념이 상당히 많다. 그래서 복습도 할 겸, 중간에 모르는 개념이 나오면 수학을 공부하고 있다. 

 

 

 

우선 3차원 컴퓨터 그래픽은 3차원 모델, 작업물을 이용하여 이차원으로 표현하는 작업이다. 

 

이차원 영상들을 frames이라고 하는데, 이러한 frame을 연속적으로 보여주면 물체의 움직임을 표현할 수 있다. 

 

가상현실과 증강현실, 게임이 이러한 실시간 그래픽의 예시이다.  한편 비 실시간 그래픽은 CG와 같은 영화의 특수효과 처리이다. 

 

실시간 그래픽(real-time graphics)은 보통 다음과 같은 단계를 거친다. 

 

 

1. Modeling

2. rigging

3. animation

4. rendering

5.post-processing

 

 

보통 모델링, 리깅, 애니메이션은 3D모델러, 그래픽 디자이너가 작업을 진행한다. 

 

이후 애니메이션, 렌더링, 후처리를 하는 것은 보통 개발자의 몫이다. 

 

 

Modeling

 

모델은 컴퓨터가 이해하고 처리할 수 있는 형태로 물체를 표현하는 것을 말한다. 

 

모델링 기법 중 대부분은 폴리곤 메시를 사용한다. 즉 다각형들을 이용하여 모델링을 한다. 

 

폴리곤 메시를 이용하여 특정한 형태를 잡았다면 텍스처를 이용해 material을 만들어준다. 

 

 

Texture

텍스처에 대해 알아보기 위해 Three.js 기반 텍스처를 어떻게 입히는지 확인해 보기로 했다.

 

GIS Developer Three,js 강의 중 이미지

 

텍스처는 3D 모델 표면 즉 Material에 적용하는 이미지라고 했다. 

 

텍스쳐가 입혀지는 방법은 uv 좌표를 기준으로 입혀진다고 하는데 three.js 같은 경우 이러한 예시가 있다.

 

이는 Three.js example 폴더 내부에서 제공해 주는 이미지다. 

 

좌측 하단이 0.0으로 시작하여 우측 하단이 1.1로 마무리되는 좌표평면이다. 

 

나는 디자인에 지식이 없기 때문에 우선 Three.js를 통해 텍스쳐를 이해해 보기로 했다. 우선 Texture에 적용하는 속성은 다음과 같다.

const texutreLoader = new THREE.TextureLoader();
const map = texutreLoader.load(
    'data/uv_grid_opengl.jpg',
    texture => {
        //texture를 로딩한 후 텍스처의 속성을 변경할 수 있다.
        texture.repeat.x = 1;
        texture.repeat.y = 1;

        //이미지 끝단 픽셀로 채우거나, 반전효과를 줄 수 있다.
        texture.wrapS = THREE.ClampToEdgeWrapping;
        texture.wrapT = THREE.ClampToEdgeWrapping;

        //offset 속성으로 uv 좌표계를 조절할 수 있다.
        texture.offset.x = 0;
        texture.offset.y = 0;

        //texture를 회전시켜 적용할 수 있다.
        texture.rotation = THREE.MathUtils.degToRad(45);
        //기준 좌표는 center 속성으로 조절가능
        texture.center.x = 0.5;
        texture.center.y = 0.5;

        //텍스처 이미지의 원래 크기보다 화면에 더 크게 확대되어 렌더링 될 때 사용할 필터는 magFilter로 지정
        //작게 렌더링 될때는 minFilter를 사용한다.
        
        //LinearFilter는 가장 가까운 4개의 픽셀 색상을 얻어와 선형 보간한 값을 사용
				//LinearFilter는 확대시 이미지가 뭉개진다.
        texture.magFilter = THREE.LinearFilter;

        //NearestFilter는 가장 가까운 픽셀값을 사용하기에 계단 현상이 발생
        texture.magFilter = THREE.NearestFilter;

        //렌더링할 맵핑 크기와 가장 크기가 가까운 mipMap 이미지 2개를 선택하고 mipMap 이미지로부터 가장 
        //가까운 픽셀 1개씩을 얻은 뒤에 이렇게 얻어진 2개의 픽셀의 가중치 평균 값을 사용
        texture.minFilter = THREE.NearestMipMapLinearFilter;
    }
);

이를 TextureLoader를 통해 3D에 텍스쳐를 적용 다음과 같다. 

 

그러면 이제 실제 텍스쳐의 종류를 하나씩 알아보자.

 

Map ( Color Map)

 

 

 

우선 속성을 넣는 코드를 이해하기 위해선 Three.js에서의 특정 객체에 대해 알아야 한다.

 

Three.js에는 Geometry라는 기하학적 도형을 의미하는 객체가 있는데,

이는 실제 화면에 표현할 도형을 의미한다. 

 

도형만 있다고 바로 렌더링할 수 없는데 우선 카메라, 빛을 제외하고 Material과 Mesh라는 객체가 있다. 

 

Material에 보통 우리가 텍스처를 로딩하여 생성한 이후 Mesh 객체에 Geometry와 Material를 주입하여 Mesh 객체를 렌더링 한다. 

GIS Developer Three,js 강의 중 이미지

Material에도 다양한 Type이 존재하는데 이들은 map이란 속성을 전부 공유한다. 

 

공식문서에서의 map 속성은 color map을 의미한다. 

 

color map은 개체 표면의 각 픽셀 색상을 정의하는 이미지이다. 색상, 패턴 또는 질감과 같은 표면 모양에 대한 세부 정보를 제공한다고 한다. 여기서 diffuse map과 매우 헷갈렸는데,

diffuse map은 음영이나 조명 효과 없이 표면의 기본 색상을 지정하는 color map이라고 한다. 

 

이 둘이 종종 같은 의미로 사용되지만 일반적으로 color map은 개체의 색상을 정의하는 텍스처 맵이고 diffuse map은 개체의 기본 색상으로 사용되는 텍스처 맵이라고 한다고 한다..

 

 

aopMap

 

 

aopMap은 텍스쳐에 미리 음영 효과를 그려 넣은 것이라고 한다. 

 

음영효과란 빛의 존재 또는 부재로 인해 미치는 물체 또는 표면의 강도, 색상의 변화를 나타낸고합니다. 

빛과 관련된 텍스쳐군요 .

 

aopmap을 지정하기 위해선 다음과 같이 추가 속성이 필요합니다.

  1. ambient light(모든 mesh의 전체 면에 대해서 균일하게 비추는 광원)가 필요합니다.

  2. geometry 속성에 uv2 데이터를 지정해주어야 합니다.
    geometry의 uv 속성은 각 정점에 대한 텍스처 좌표를 나타냅니다. 텍스쳐 좌표는 텍스처를 형상의 표면에 매핑하는 데 사용되며 각 좌표는 텍스처 이미지에서 형상의 특정 정점에 해당하는 위치를 지정합니다. 
aoMap : aoMap,
aoMapIntensity : 2

 

 

displacementMap

 

실제로 Mesh의 geometry 좌표를 변형시켜 입체감을 표현한다.

해당 Map의 픽셀값이 밝을수록 좌표의 변위가 커지게 됩니다.

 

단순히 적용하면 구성 면이 변위에 의해 분리되어 버린다. 따라서 scale과 bias 값을 적절히 할당해야 한다.

 

const boxMaterial = new THREE.MeshStandardMaterial({
            map : map,
            normalMap : normalMap,
            displacementMap : heightMap,
            displacementScale : 1.2,
            displacementBias : -0.9
        });

box인 경우 이 값을 조정하면 변위가 변경되지 않는데,

 

박스의 표면에 대한 구성 좌표를 제공해야 합니다.

 

따라서 각 표면에 대한 segment값을 제공해야 실제 변위가 변경됩니다.

 

다만 이를 위해 좌표를 더 많이 추가하는 것은 렌더링 속도 면에서 비효율적입니다.

 

 

matalnessMap

금속 재질에 대한 느낌을 부여하는 맵입니다.

 

metalnessMap : metallicMap,
metalness: 1

 

 

normalMap

 

법선벡터를 이미지화해 저장해둔 것으로 법선 벡터는 메시의 표면에 대한 수직 벡터로 광원에 대한 영향을 계산하는 데 사용됩니다.

 

alphaMap

 

투명도에 대한 맵 속성입니다.

픽셀 값이 밝을수록 불투명하게 되고 픽셀 값이 검은색일 때 완전히 투명하게 됩니다.

 

alphaMap : opacityMap,
transparent: true,
side : THREE.DoubleSide  //(뒷면 확인)

 

 

roughnessMap

맵 이미지의 픽셀 값이 밝을수록 거칠기가 강하게 됩니다.

roughnessMap : roughnessMap,
roughness: 0.5  //값이 낮을 수록 플라스틱 느낌이 난다.

 

 

lightMap

 

지정된 이미지의 색상으로 발광하는 느낌을 표현할 수 있다.

 

이를 알아본 이유는 단순하다. 

 

3D 모델을 사용하는 경우 특정 효과를 위해 텍스처를 변경해줄 일이 있을 때 어떤 텍스처를 입혀주면 좋을지 알아보기 위함이다. 

 

혹은 사용자의 특정 행위(이벤트)로 모델의 텍스처를 변경해줄때 이러한 텍스처에 대한 기본지식이 있으면 더

편하지 않을까해서 텍스처에 대해 알아보고 이를 Three.js에서 적용한 결과를 보았다. 

 

 

 

반응형

'도전' 카테고리의 다른 글

기억장치, PLD (1)  (0) 2023.04.02
3D Computer Graphics (2)  (0) 2023.04.01
레지스터와 카운터(2)  (0) 2023.03.26
레지스터와 카운터(1)  (0) 2023.03.26
순서논리회로 (3)  (0) 2023.03.20

댓글