๐ป texture ๋?
texture
๋ ๋ณดํต geometry
์ ํ๋ฉด์ ๊ฐ์ ์ ์๋ ์ด๋ฏธ์ง๋ฅผ ์๋ฏธํ๋ฉฐ, ๋ณดํต ํฌํ ์ต๊ณผ ๊ฐ์ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ง๋ญ๋๋ค.
์ฌ๋ฌ ์ข
๋ฅ๊ฐ ์กด์ฌํ๋ฉฐ, ๊ฐ texture
๋ง๋ค geometry
์ ์ ์ฉ๋๋ ํจ๊ณผ๊ฐ ๋ค๋ฆ
๋๋ค.
๐ป texture ์ข ๋ฅ
๐จโ๐ป Albedo (Diffuse / Color)
Albedo
๋ ๊ฐ์ฅ ํํ texture
๋ก, ์์๊ณผ ํจํด์ ์ด์ฉํ์ฌ ๋ฌผ์ฒด์ ์ง๊ฐ์ด๋ ์์ ํํํฉ๋๋ค.
๐จโ๐ป Opacity (Transparency)
Opacity
๋ ํน์ ๋ถ๋ถ์ ํฌ๋ช
ํ๊ฒ ๋ง๋ค ์ ์๋ texture
์
๋๋ค.
ํ์์กฐ(gray scale)๋ฅผ ๋๋ฉฐ, ํฐ์๋ถ๋ถ์ ๋ณด์ด๋ ๋ถ๋ถ์, ๊ฒ์์ ๋ถ๋ถ์ ๋ณด์ด์ง ์๋ ๋ถ๋ถ์ ์๋ฏธํฉ๋๋ค. ํ์์ ๋๋ ๋ถ๋ถ์ ํฐ์๊ณผ ๊ฒ์์ ์ฌ์ด์ ๋ค์ํ ๊ฐ์ ํฌ๋ช
๋๋ฅผ ๋ํ๋
๋๋ค.
๐จโ๐ป Height (Displacement)
Height
๋ ๋๋ฎ์ด(๊ตด๊ณก)๋ฅผ ํํํ๊ธฐ ์ํ๋ texture
์
๋๋ค.
ํ์์กฐ(gray scale)์ ๋๋ฉฐ, ํด๋น texture
๊ฐ ์ ์ฉ๋๋ geometry
์ ๋ฉด๋ค์ ์๊ฒ๋๋์ด ํด๋น ์ ์ ๋ค์ ๋ณ๊ฒฝํ๋ ํน์ฑ์ด ์์ต๋๋ค. texture
์ ๊ฒ์์ ๋ถ๋ถ์ ์ ์ ์ ์๋๋ก ์ด๋์ํค๋ฉฐ, ํฐ์ ๋ถ๋ถ์ ์๋ก ์ด๋์ํต๋๋ค. ํ์์ ๋๋ ๋ถ๋ถ์ ๋์ ์ฌ์ด์ ์ง์ ์ ์๋ฏธํฉ๋๋ค.
Height
์ ์ฅ์ ์ ์ธ๋ถ์ ์ธ ํํ์ด ๊ฐ๋ฅํ ๊ฒ์ด์ง๋ง, ์ฑ๋ฅ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๐จโ๐ป Normal
Normal
์ geometry
์ ์ ์ ๋ค์ ๋ณ๊ฒฝํ์ง ์๊ณ , ๋ฒ์ ๋ฒกํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋น์ด ํ๋ฉด๊ณผ ์ํธ์์ฉํ๋ ๋ฐฉ์์ ๊ฐ์ง๋ก ๋ง๋ค์ด ํ๋ฉด์ ๋ํ
์ผ์ ํํํฉ๋๋ค. ๋ํ ์ฐํ ๋ณด๋ผ์์ ๋๊ณ ์์ผ๋ฉฐ, rgb
๊ฐ๋ค์ ๋๋ฎ์ด๋, ํ์ ๋ํ๋
๋๋ค.
๐จโ๐ป Ambient Occlusion
geometry
๊ฐ ๋น์ ์ผ๋ง๋ ๋
ธ์ถ๋๋์ง๋ฅผ ํํํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ texture
์
๋๋ค.
ํ์์กฐ๋ฅผ ๋๋ฉฐ, ๋ฐ์ ๋ถ๋ถ์ ๋น์ ํก์ํ๋ ๋ถ๋ถ์ด๊ณ ์ด๋์ด ๋ถ๋ถ์ ๋น์ ๋ ๋ฐ์ํ๋ ๋ถ๋ถ์ ๋ํ๋
๋๋ค.
๐จโ๐ป Metalness
๊ธ์์ฑ๊ณผ, ๊ธ์์ ๋ฐ์ฌ๋ฅผ ํํํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ texture
์
๋๋ค.
ํ์์กฐ์ ์ด๋ฏธ์ง์ด๋ฉฐ, ํฐ์ ๋ถ๋ถ์ ๊ธ์์ฑ์ ๋๋ ๋ถ๋ถ์, ๊ฒ์์ ๋ถ๋ถ์ ๊ธ์์ฑ์ ๋์ง ์๋ ๋ถ๋ถ์ ์๋ฏธํฉ๋๋ค.
๐จโ๐ป Roughness
๊ฑฐ์น ๊ธฐ๋ฅผ ๋ํ๋ด๊ธฐ ์ํด ์ฌ์ฉ๋๋ texture
์
๋๋ค.
ํ์์กฐ์ด๋ฉฐ, ํฐ์์ ์ต๋ ๊ฑฐ์น ๊ธฐ๋ฅผ, ๊ฒ์์์ ์ต์ ๊ฑฐ์น ๊ธฐ๋ฅผ ์๋ฏธํฉ๋๋ค.
๐ป texture ๋ถ๋ฌ์ค๊ธฐ
texture
๋ฅผ geometry
์ ์ ์ฉ์ํค๊ธฐ ์ํด์๋ texture
๋ฅผ ๋ถ๋ฌ์์ผ ํฉ๋๋ค. texture
๋ฅผ ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ์ ๋ค์ํ์ง๋ง ๋ํ์ ์ธ ๋ฐฉ๋ฒ ๋๊ฐ์ง๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๐จโ๐ป image.onload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ...์๋ต...
THREE.ColorManagement.enabled = false;
const image = new Image();
const texture = new THREE.Texture(image);
image.src("image-path");
image.onload = () => {
texture.needsUpdate = true;
};
// ...์๋ต...
const mesh = new THREE.Mesh(
geometry,
new THREE.BasicMeshMaterial({ map: texture })
);
// ...์๋ต...
์ ์์๋ Image
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ texture
๋ฅผ ๋ถ๋ฌ์ค๋ ์ฝ๋์
๋๋ค.
onload
๋ Image
๊ฐ์ฒด์ ์ด๋ฏธ์ง ๋ก๋ฉ์ด ์๋ฃ๋๋ฉด ์คํ๋๋ ํจ์๋ก, ํจ์ ๋ด๋ถ์ texture.needsUpdated = true
๊ฐ ์ ์ธ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์ด๋ ์ด๋ฏธ์ง ๋ก๋ฉ์ด ์๋ฃ๋์์ด๋ texture
๋ ์๋ฃ์ฌ๋ถ๋ฅผ ์์ง๋ชปํ๊ธฐ ๋๋ฌธ์ needsUpdate
๋ฅผ true
๋ก ์ค์ ํด texture
๋ฅผ ์
๋ฐ์ดํธ ํด์ฃผ๊ธฐ ์ํจ์
๋๋ค.
๐จโ๐ป TextureLoader
1
2
3
4
5
6
7
8
9
10
11
12
13
// ...์๋ต...
THREE.ColorManagement.enabled = false;
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("image-path");
// ...์๋ต...
const mesh = new THREE.Mesh(
geometry,
new THREE.BasicMeshMaterial({ map: texture })
);
// ...์๋ต...
์ ์์์ ๊ฐ์ด TextureLoader
๋ฅผ ์ฌ์ฉํด์ texture
๋ฅผ ๋ถ๋ฌ์ฌ ์ ์์ผ๋ฉฐ, onload
๋ฐฉ์์ผ๋ก ๋ถ๋ฌ์์๋๊ณผ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
๐ TextureLoader์ ์ฝ๋ฐฑํจ์
TextureLoader
์ load
ํจ์๋ ์ด๋ฏธ์ง url
์ธ์๋ onLoad
, onError
, onProgress
์ ๊ฐ์ ์ฝ๋ฐฑํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ต๋๋ค.
onLoad
๋ก๋ฉ์ด ์๋ฃ๋์์ ๋ ํธ์ถ๋๋ ํจ์๋ก, ๋ก๋ฉ๋texture
๋ฅผ ์ธ์๋ก ๊ฐ์ต๋๋ค.onError
๋ก๋ฉ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๊ฒฝ์ฐ ์คํ๋ฉ๋๋ค.onProgress
๋ก๋ฉ์ด ์งํ ์ค์ผ ๊ฒฝ์ฐ ์คํ๋๋ ์ฝ๋ฐฑ์ ๋๋ค. ํ์ฌ๋ ์ง์๋์ง ์์ต๋๋ค.
๐ป LoadingManager
texture
๋ค์ ๋ก๋ฉ ์ํ๋ฅผ ์ถ์ ํ๊ณ , ์ํ์ ๋ฐ๋ฅธ ์ธํฐ๋ ์
์ ์ฃผ๊ธฐ์ํด LoadingManager
๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// ...์๋ต...
const loadingManager = new THREE.LoadingManager();
const textureLoader = new THREE.TextureLoader(loadingManager);
const materials = [
new THREE.MeshBasicMaterial({
map: textureLoader.load("image-path-1"),
}),
new THREE.MeshBasicMaterial({
map: textureLoader.load("image-path-2"),
}),
new THREE.MeshBasicMaterial({
map: textureLoader.load("image-path-3"),
}),
new THREE.MeshBasicMaterial({
map: textureLoader.load("image-path-4"),
}),
new THREE.MeshBasicMaterial({
map: textureLoader.load("image-path-5"),
}),
new THREE.MeshBasicMaterial({
map: textureLoader.load("image-path-6"),
}),
];
// ...์๋ต...
์ ์์๋ 6๊ฐ์ ์ด๋ฏธ์ง๋ฅผ texture
๋ก ์ฌ์ฉํ๊ธฐ ์ํด ๋ถ๋ฌ์จ ํ, BoxGeometry
์ ํ ๋ฉด์ฉ ์ ์ฉ๋๋๋ก ๋ง๋๋ ์ฝ๋์ ์ผ๋ถ์
๋๋ค. LoadingManager
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด, TextureLoader
์์ฑ์ ์ธ์์ ์ ๋ฌํ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์ด์ LoadingManager
๊ฐ ์์ฑ์ผ๋ก ๊ฐ๋ ํจ์๋ค์ ์ด์ฉํด ์์ฐ์ค๋ฌ์ด UX ๋ฅผ ๊ฐ์ง ์ ์๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
๐จโ๐ป onLoad
texture
๋ค์ด ๋ชจ๋ ๋ก๋ฉ ๋์์ ๋, ์คํ๋๋ ํจ์์
๋๋ค.
1
2
3
4
5
6
// ...์๋ต...
loadingManager.onLoad = () => {
const mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);
};
// ...์๋ต...
์ ์ฝ๋๋ ๋ชจ๋ texture
๋ค์ ๋ก๋ฉ์ด ์๋ฃ ๋์์ ๋, mesh
๋ฅผ ์์ฑํ๋ ์ฝ๋๋ก ์ด๋ฏธ์ง๊ฐ ๋ก๋ฉ ์๋๊ฐ ๊ท ์ผํ์ง ์์ ์ํฉ์์ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐จโ๐ป onProgress
์ฌ๋ฌ๊ฐ์ ์๋ฃ๋ค์ค, ํ๊ฐ๊ฐ ์๋ฃ๋ ๋๋ง๋ค ์คํ๋๋ ํจ์๋ก url
, itemsLoaded
, itemsTotal
์ธ๊ฐ์ ์ธ์๋ฅผ ๋ฐ์ต๋๋ค.
url
์ ํ์ฌ ๋ก๋ฉ์ค์ธ ์๋ฃ์ url
์, itemsLoaded
๋ ํ์ฌ๊น์ง ๋ก๋ฉ์๋ฃ๋ ์๋ฃ์ ๊ฐฏ์, itemsTotal
์ ๋ก๋ฉํด์ผ ํ ์ ์ฒด ์๋ฃ์ ๊ฐฏ์๋ฅผ ์๋ฏธํฉ๋๋ค.
1
2
3
4
5
6
// ...์๋ต...
loadingManager.onProgress = (url, itemsLoaded, itemsTotal) => {
console.log(
`current url is ${url}, and this item is ${itemsLoaded}/${itemsTotal}`
);
};
onProgress
ํจ์๋ฅผ ์ด์ฉํด ํ๋ก๊ทธ๋์ค ๋ฐ๋ฅผ ๋ง๋ค ์๋ ์์ต๋๋ค.
์๋ ์ด๋ฏธ์ง๋ ์ ์ฝ๋๋ฅผ ์คํ์ํจ ๊ฒฐ๊ณผ์ ๋๋ค.
๐จโ๐ป onStart
์ฌ๋ฌ๊ฐ์ ์๋ฃ๋ค์ค, ํ๊ฐ๊ฐ ๋ก๋ฉ์ ์์ํ ๋ ์คํ๋๋ ํจ์๋ก onProgress
์ ๊ฐ์ ์ธ์๋ฅผ ๋ฐ์ต๋๋ค.
๐จโ๐ป onError
๋ก๋ฉ ๊ณผ์ ์ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์คํ๋๋ ํจ์ ์
๋๋ค.
url
์ ์ธ์๋ก ๋ฐ์ผ๋ฉฐ, ์ค๋ฅ๊ฐ ๋ฐ์ํ ์๋ฃ์ url
์ ์๋ฏธํฉ๋๋ค.
์ ์ฝ๋๋ค์ ์ถ๊ฐํ ํ ์คํด์ํค๋ฉด ์๋์ ๊ฐ์ mesh
๊ฐ ๋์ต๋๋ค,
๐ป UV Mapping
UV mapping
์ 2D ์ด๋ฏธ์ง๋ฅผ 3D ๋ฌผ์ฒด์ ํ๋ฉด์ผ๋ก ํฌ์ํ๋ ๊ณผ์ ์ผ๋ก, ํ๋ฉด์ธ texture
๋ฅผ 3D์ธ mesh
์ ์ ์ฉ์ํค๊ธฐ ์ํด ์ฌ์ฉํ๋ ํ๋ก์ธ์ค ์
๋๋ค. ๋ํ UV mapping
์ ์งํํ๊ธฐ ์ํด์๋ mesh
๋ฅผ ์ ๊ฐ๋์ ๋น์ทํ ํ๋ฉด์ผ๋ก ๋ณํ(UV Map
)์์ผ์ฃผ๋ ๊ณผ์ ์ด ํ์ํ๋ฐ ์ด ๊ณผ์ ์ UV unwrapping
์ด๋ผ๊ณ ํฉ๋๋ค.
๐จโ๐ป UV ์ขํ๊ณ
UV mapping
, UV unwrapping
์ ์ธ๊ธ๋ UV
๋ mesh
์ ์ ์ ๋ค(vertices)์ ์ ์ฅ๋ 2D texture
์ ์ขํ๋ฅผ ์๋ฏธํฉ๋๋ค.
๋ณดํต openGL
์์๋ U
๋ ๊ฐ๋ก์ถ, V
๋ ์ธ๋ก์ถ์ ์๋ฏธํ์ง๋ง ์ด๋ ์ฌ์ฉํ๋ ๋๊ตฌ์ ๋ฐ๋ผ ์์ดํฉ๋๋ค. ๋ํ ๊ฐ์ถ์ ์ต์๊ฐ์ 0
, ์ต๋๊ฐ์ 1
์
๋๋ค.
์ ๊ทธ๋ฆผ์ texture
์ UV
์ขํ๊ณ๋ฅผ ๋ํ๋ธ ๊ฒ์ด๋ฉฐ, ์๋๋ ํด๋น texture
๋ฅผ BoxGeometry
์ ํ ๋ฉด์ UV
์ขํ์ ๋ฐ๋ผ ์ ์ฉ์ํจ ์์์
๋๋ค.
BoxGeometry
์ ๊ฐ ์ ์ ๋ค์ ํ ๋น๋ UV
์ขํ์ ํด๋นํ๋ texture
๊ฐ ์ ์ฉ๋์์ต๋๋ค. ๋ํ UV
์ ์ขํ์ ์ต๋๊ฐ๋ณด๋ค ํฐ ์ขํ๊ฐ ํ ๋น ๋์์ ๊ฒฝ์ฐ, ๋น๊ณต๊ฐ์ ์ฑ์ฐ๊ธฐ์ํด ๋ฐ๋ณต๋์์์ ์ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด๋ ์ค์ ์๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
๐ป texture ๋ณํํ๊ธฐ
๐จโ๐ป repeat
UV
์ขํ๊ณ์ ์ถ ๋ฐฉํฅ์ผ๋ก texture
๋ฅผ ์ผ๋ง๋ ๋ฐ๋ณต์ํฌ ๊ฒ์ธ์ง ์ค์ ํ๋ ์ต์
์
๋๋ค.
Vector2
ํ์
์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, 1๋ณด๋ค ํฐ ๊ฐ์ ์ค์ ํ๊ฒ๋๋ฉด wrap
์์ฑ(wrapS
, wrapT
) ์ THREE.RepeatWrapping
์ด๋ THREE.MirroredRepeatWrapping
์ ์ถ๊ฐ๋ก ์ง์ ํด ์ฃผ์ด์ผ ํฉ๋๋ค.
1
2
3
4
5
6
7
8
// ...์๋ต...
const loadingManager = new THREE.LoadingManager();
const textureLoader = new THREE.TextureLoader(loadingManager);
const texture = textureLoader.load("image-path");
texture.repeat.x = 3;
// ...์๋ต...
์๋ ์ด๋ฏธ์ง๋ ์ ์ฝ๋๋ฅผ ์คํ์ํจ ๊ฒฐ๊ณผ ์ ๋๋ค.
U
(x
) ์ถ ๋ฐฉํฅ์ผ๋ก ๋์ด๋๊ธฐ๋ง ํ ๋ฟ, ๋ฐ๋ณต๋์ง ์์์์ ์ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ wrapS
์ THREE.RepeatWrapping
์์ฑ์ ์ง์ ํด์ผ ํฉ๋๋ค.
1
2
3
4
5
6
7
8
9
// ...์๋ต...
const loadingManager = new THREE.LoadingManager();
const textureLoader = new THREE.TextureLoader(loadingManager);
const texture = textureLoader.load("image-path");
texture.repeat.x = 3;
texture.wrapS = THREE.RepeatWRapping;
// ...์๋ต...
๋ง์ฝ wrap
ํ๋กํผํฐ์ THREE.MirroredRepeatWrapping
์ ์ค์ ํด์ฃผ๊ฒ ๋๋ฉด, ๋งค ๋ฐ๋ณต์ texture
๊ฐ ๋ฐ์ ๋ฉ๋๋ค.
๐จโ๐ป offset
UV
์ขํ๊ณ์ ์ถ ๋ฐฉํฅ์ผ๋ก mesh
์ ์ ์ฉ๋ texture
์ offset
์ ์ค์ ํด ์ค๋๋ค.
Vector2
ํ์
์ ๊ฐ์ง๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
// ...์๋ต...
const loadingManager = new THREE.LoadingManager();
const textureLoader = new THREE.TextureLoader(loadingManager);
const texture = textureLoader.load("image-path");
texture.repeat.x = 3;
texture.wrapS = THREE.RepeatWRapping;
texture.offset.x = 0.5;
// ...์๋ต...
์ ์ฝ๋๋ x
์ถ ๋ฐฉํฅ์ผ๋ก texture
๋ฅผ 3๋ฒ ๋ฐ๋ณตํ ํ, offset
์ 0.5๋ก ์ค์ ํ ์ฝ๋ ์ด๋ฉฐ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์ต๋๋ค.
๐จโ๐ป rotation
texture
๊ฐ ์ค์ ์ ์ค์ฌ์ผ๋ก ์ผ๋ง๋ ํ์ ํ ์ง๋ฅผ ๊ฒฐ์ ํ๋ ์์ฑ์
๋๋ค.
์ค์ ์ center
์์ฑ์ ํตํด ์ค์ ํด ์ค ์ ์์ผ๋ฉฐ, ๊ธฐ๋ณธ๊ฐ์ UV
์ขํ๋ก (0, 0)
์ฆ ์ผ์ชฝ ์๋๊ฐ ๋ฉ๋๋ค.
1
2
3
4
5
6
7
8
9
// ...์๋ต...
const loadingManager = new THREE.LoadingManager();
const textureLoader = new THREE.TextureLoader(loadingManager);
const texture = textureLoader.load("image-path");
texture.repeat.x = 3;
texture.wrapS = THREE.RepeatWrapping;
texture.rotation = Math.PI * 0.25;
์ ์์๋ texture
๋ฅผ ๐/4
๋งํผ ํ์ ์ํค๋ ์ฝ๋์ด๋ฉฐ, ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์ต๋๋ค.
UV
์ขํ๊ณ์์ (0, 0)
์ฆ ์ผ์ชฝ ์๋๋ฅผ ์ค์ฌ์ผ๋ก ํ์ ์ด ๋์๊ณ , ๊ทธ๋ก์ธํด ์๊ธด ๋น๊ณต๊ฐ์ ์ฑ์ฐ๊ธฐ์ํด texture
๊ฐ ๋์ด๋๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
1
2
3
4
// ...์๋ต...
texture.center.x = 0.5;
texture.center.y = 0.5;
// ...์๋ต...
์์ ๊ฐ์ด ์ค์ฌ์ ๋ฉด์ ํ ๊ฐ์ด๋ฐ๋ก ์ฎ๊ธฐ๊ฒ ๋๋ฉด, ํด๋น ์ขํ๋ฅผ ์ค์ฌ์ผ๋ก ํ์ ํ๊ฒ ๋ฉ๋๋ค.
๐ป Mips and Filtering
์ ์ด๋ฏธ์ง๋ PlaneGeometry
์ 16x16
ํฌ๊ธฐ์ texture
๋ฅผ ์ ์ฉํ ํ, camera
๋ฅผ mesh
์ ๊ฑฐ์ ํํํ๊ฒ ์์น์ํจ ๋ชจ์ต์
๋๋ค. Camera
์์ ๋ฉ๋ฆฌ ๋จ์ด์ง texture
์ผ์๋ก ํ๋ ค์ง๋ ํ์์ ๋ณผ ์ ์๋๋ฐ ์ด๋ filter
๊ณผ mip mapping
๋๋ฌธ์
๋๋ค.
๐จโ๐ป Mip mapping
Mip mapping
์ ๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํ ํ๊ธฐ ์ํด, ์๋ณธ texture
์ ํฌ๊ธฐ๋ฅผ ์ถ์์ํจ texture
๋ค์ ๋ณต์ฌ๋ณธ๋ค(mips
)์ ์งํฉ(mip map
)์ ์ฌ์ ์ ๋ง๋๋ ๊ณผ์ ์ ์๋ฏธํฉ๋๋ค.
์ ๊ทธ๋ฆผ์ 16 x 16
ํฌ๊ธฐ์ ์๋ณธ texture
๋ฅผ ์ถ์์ํจ mip map
์
๋๋ค.
16 x 16
โ 8 x 8
โ 4 x 4
โ 2 x 2
โ 1 x 1
์ ๊ฐ์ด ๋์ด์ ๋์ด๋ฅผ ์ ๋ฐ์ผ๋ก ์ค์ฌ๊ฐ๋ฉฐ ์ถ์์ํจ๊ฒ์ ์ ์ ์์ผ๋ฉฐ, 1 x 1
ํฌ๊ธฐ์ mip
์ ์ป์ ๋ ๊น์ง ์ถ์์ํจ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๐จโ๐ป Filtering
๋ ๋๋ง ํด์ผํ๋ texture
๊ฐ ์๋ณธ ํฌ๊ธฐ๋ณด๋ค ํฌ๊ฑฐ๋, ์์ ๊ฒฝ์ฐ ์๋ณธ ๊ทธ๋๋ก ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๋ ๋๋งํด์ผํ๋ ์ ์ ํ ํฝ์
๊ฐ์ ๊ฒฐ์ ํด์ผ ํ๋๋ฐ ์ด ๊ณผ์ ์ filtering
์ด๋ผ๊ณ ํฉ๋๋ค.
๐ Magnification Filter
texture
์ ํฌ๊ธฐ๊ฐ ์๋ณธ ๋ณด๋ค ์ปค์ ธ์ผ ํ๋ ๊ฒฝ์ฐ, ์ฆ ์๋ณธ texture
๊ฐ mesh
๋ณด๋ค ์์ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ filter
์
๋๋ค.
์ด ์ํฉ์๋ texel
(texture
์ 1px) ์ด ํ๋ ์ด์์ ํฝ์
์ ์ปค๋ฒํด์ผ ํฉ๋๋ค.
THREE.LinearFilter
๊ฐ์ฅ ๊ฐ๊น์ด 4๊ฐ์ ํฝ์ ์ ๊ณจ๋ผ, ๊ฐ ํฝ์ ์ ์ค์ ๊ฑฐ๋ฆฌ์ ๋ฐ๋ผ ์ ์ ํ ๋น์จ๋ก ์๋ ๋ฐฉ์์ ๋๋ค.
three.js
์์๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ ์ฉ๋์ด ์์ต๋๋ค.1 2 3 4
// ...์๋ต... const texture = textureLoader.load("small-image-path"); texture.magFilter = THREE.LinearFilter; // ...์๋ต...
์ ์ฝ๋๋ ์์ฃผ ์์ ์ด๋ฏธ์ง๋ฅผ
texture
๋ก ๋ถ๋ฌ์จ ํ,magnification filter
๋กLinearFilter
๋ฅผ ์ ์ฉํด์ค ์ฝ๋๋ก, ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์ต๋๋ค.THREE.NearestFilter
texture
์์ ๊ฐ์ฅ ๊ฐ๊น์ด ํฝ์ ์ ๊ณจ๋ผ ๋ ๋๋ง ํฉ๋๋ค. ํด์๋๊ฐ ๋ฎ์texture
์ ์ ์ฉํ ๊ฒฝ์ฐ ํฝ์ ํ ๋ฉ๋๋ค.1 2 3 4
// ...์๋ต... const texture = textureLoader.load("small-image-path"); texture.magFilter = THREE.NearestFilter; // ...์๋ต...
์ ์์๋
NearestFilter
๋ฅผ ์ ์ฉํ ์ฝ๋์ด๊ณ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์ต๋๋ค.texture
๊ฐ ํฝ์ ํ ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๐ Minification Filter
texture
๊ฐ ์๋ณธ๋ณด๋ค ์์์ ธ์ผ ํ ๊ฒฝ์ฐ, ์ฆ ์๋ณธ texture
๊ฐ mesh
๋ณด๋ค ํด ๊ฒฝ์ฐ ์ฌ์ฉํ๋ filter
์
๋๋ค.
์ด ๊ฒฝ์ฐ๋ texel
์ด ์ต๋ ํ๊ฐ์ ํฝ์
์ ์ปค๋ฒํ๊ฒ ๋ฉ๋๋ค.
THREE.NearestFilter
Magnification filter
์ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ฐ์ฅ ๊ฐ๊น์ด ํฝ์ ์ ๊ณจ๋ผ ๋ ๋๋ง ํฉ๋๋ค.THREE.LinearFilter
Magnification filter
์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฃผ๋ณ์ ๊ฐ๊น์ด ํฝ์ 4๊ฐ์ ๊ณจ๋ผ ์ ์ ํ ๋น์จ๋ก ์์ต๋๋ค.THREE.NearestMipmapNearestFilter
์ ์ ํmip
์ ๊ณ ๋ฅธ ํ,mip
์์ ํฝ์ ํ๋๋ฅผ ์ ํํฉ๋๋ค.THREE.NearestMipmapLinearFilter
๋ ๊ฐ์mip
์ ๊ณจ๋ผ ํฝ์ ์ ํ๋์ฉ ์ ํํ ํ, ๋ ๊ฐ์ ํฝ์ ์ ์ ์ ํ ๋น์จ๋ก ์์ต๋๋ค.THREE.LinearMipmapNearestFilter
์ ์ ํ ๋ฐ์ ๊ณ ๋ฅธ ๋ค ๋ค ๊ฐ์ ํฝ์ ์ ๊ณจ๋ผ ์์ต๋๋ค.THREE.LinearMipmapLinearFilter
๋ ๊ฐ์mip
์ ๊ณจ๋ผ ๊ฐ๊ฐ ํฝ์ ์ 4๊ฐ์ฉ ์ ํํ๊ณ , ์ ํํ 8๊ฐ์ ํฝ์ ์ ์์ต๋๋ค.
three.js
์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ๋์ด ์์ต๋๋ค.
์ ์ด๋ฏธ์ง๋ ์๋์ ๊ฐ์ด, mip
์ ๊ฐ ๋จ๊ณ๊ฐ ๋ค๋ฅธ texture
์ ์ฌ์ฏ๊ฐ์ minification filter
๋ฅผ ์ ์ฉํ ์์์
๋๋ค.
์์ ์์์์ NearestFilter
์ LinearFilter
๋ฅผ ์ดํด๋ณด๋ฉด, ํญ์ ์๋ณธ texture
๋ฅผ ๋ ๋๋งํ๋ ๊ฒ์ผ๋ก ๋ณด์ mipmap
์ ์ฌ์ฉํ์ง ์์์ ์ ์ ์์ต๋๋ค. GPU๊ฐ ์๋ณธ texture
๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ฆฌ ๋จ์ด์ง์๋ก ๊น๋นก๊ฑฐ๋ฆผ์ ๊ด์ฐฐํ ์ ์์ต๋๋ค.
๋๋จธ์ง 4๊ฐ์ filter
๋ ๋ชจ๋ mipmap
์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์์ ์ ๋ฐ๋ผ ๋ ๋๋ง ๋๋ texture
๊ฐ ๋ฌ๋ผ์ง๋๋ค. LinearMipmapLinearFilter
๊ฐ ๊ฐ์ฅ ์์ฐ์ค๋ฌ์ฐ๋, 2๊ฐ์ mip
์์ ๊ฐ๊ฐ 4๊ฐ์ ํฝ์
์ ๊ฐ์ ธ์ค๊ธฐ๋๋ฌธ์ ๊ณ์ฐ๋์ด ๋ง์์ง๋ค๋ ๋จ์ ์ด ์์ต๋๋ค.
NearestFilter
์ LinearFilter
๋ mipmap
์ ์ฌ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ด mipmap
์์ฑ์ ๋นํ์ฑํ ์ํค๋ฉด GPU์ ๋ถํ๋ฅผ ์กฐ๊ธ ์ค์ผ ์ ์์ต๋๋ค.
1
2
3
// ...์๋ต...
texture.generateMipmaps = false;
// ...์๋ต...
๐ ์ฐธ๊ณ ์๋ฃ
How to make photorealistic 3D graphics with different texture maps?
A Brief Introduction to Texture mapping for 3D Artists
Texture Maps: The Ultimate Guide For 3D Artists
UV Unwrapping
What is UV Mapping & Unwrapping? (full beginners guide)
[ํฌํ์ ์์ด๋ ์
๋ฌธ๊ฐ์ข] 03. ํ
์ค์ฒ๋งคํ Part 1
What is mipmap technique and whatโs the benefit of using it in rendering?