• Mindscape ๐Ÿ”ฅ
    • Playlist ๐ŸŽง
    • Vim ์‚ฌ์šฉ ๋งค๋‰ด์–ผ
  • ๐Ÿง  Algorithm

    • Python ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ํŒ
    • 1966๋ฒˆ: ํ”„๋ฆฐํ„ฐ ํ
    • 1018๋ฒˆ: ์ฒด์ŠคํŒ ๋‹ค์‹œ ์น ํ•˜๊ธฐ
  • ๐Ÿ’ฐ Finance

    • ๋น„ํŠธ์ฝ”์ธ(Bitcoin)
  • ๐Ÿ›๏ธ Humanities

    • Nordvik, Russia
    • North Sentinel Island
    • ๋กฑ๊ณ ๋กฑ๊ณ (Rongorongo)
  • ๐Ÿ‹๏ธ Wellness

    • ๐Ÿซ’ ์—‘์ŠคํŠธ๋ผ ๋ฒ„์ง„ ์˜ฌ๋ฆฌ๋ธŒ์œ  (Extra Virgin Olive Oil)
    • ์ฐจ์ „์žํ”ผ(Psyllium Husk)
  • ๐Ÿ–ฅ๏ธ Computer Graphics

    • 8 - Lighting
    • 9 - Orientation & Rotation
    • 10 - Character Animation
    • 11 - Curves
    • 12 - More Lighting, Texture
  • ๐Ÿ—‚๏ธ Operating System

    • 7. Deadlocks
    • 8. Memory Management(1)
    • 9. Memory Management(2)
    • 10. Virtual Memory(1)
    • 11. Virtual Memory(2)
    • 12. File System
    • 13. Mass Storage Management
    • 14. I/O Systems
  • ๐Ÿ”ฃ Programming Language Theory

    • 13. FPL(1)

12 - More Lighting, Texture

Revised Class Schedule

  • ์ด์ „์— ๊ณต์œ ๋œ ๊ฐ•์˜ ์ผ์ • ๋ฐ ๊ธฐ๋ง ์‹œํ—˜ ๋ฒ”์œ„์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์ž์„ธํ•œ ๋‚ด์šฉ์€ LMS ๊ฒŒ์‹œ๊ธ€ ์ฐธ์กฐ:
    https://learning.hanyang.ac.kr/courses/178704/discussion_topics/418144
  • ์ˆ˜์ •๋œ ์ผ์ •:
    • Lecture 12: 6์›” 5์ผ
    • Lecture 13 (๋งˆ์ง€๋ง‰ ์ˆ˜์—…): 6์›” 12์ผ (Lab ์—†์Œ)

Final Exam Announcement

  • ์ผ์‹œ: 6์›” 18์ผ (์ˆ˜), ์˜คํ›„ 6:30โ€“7:30

  • ์žฅ์†Œ: IT/BT Room 911

  • ๋ฒ”์œ„: Lecture 8โ€“12, Lab 8โ€“12

  • ์‹œํ—˜ ์‹œ์ž‘ ํ›„ 30๋ถ„ ์ „์—๋Š” ํ‡ด์‹คํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (์‹œํ—˜์„ ์ผ์ฐ ๋๋‚ด๋”๋ผ๋„)

  • ์ฆ‰, ์‹œํ—˜ ์‹œ์ž‘ ํ›„ 30๋ถ„ ์ดํ›„์—๋Š” ์ž…์žฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (์ง€๊ฐ ์ ˆ๋Œ€ ๊ธˆ์ง€!)

  • ํ•™์ƒ์ฆ์„ ๋ฐ˜๋“œ์‹œ ์ง€์ฐธํ•  ๊ฒƒ

Outline

  • More Lighting

    • BRDF
    • Local & Global Illumination
  • Texture Mapping

    • ๊ฐœ๋…
    • UV Mapping
    • Texture Mapping ๊ณผ์ •
    • Texture ์ขŒํ‘œ ํ•จ์ˆ˜ ์ •์˜
    • Texture๊ฐ€ ์ ์šฉ๋œ ๊ฐ์ฒด ๋ Œ๋”๋ง
    • Diffuse, Specular, Normal Map
    • Texture Map์˜ ๋‹ค์–‘ํ•œ ํ™œ์šฉ

More Lighting

Recall: Reflection of General Materials

  • ๋งŽ์€ ์žฌ์งˆ์˜ ํ‘œ๋ฉด์€ diffuse reflection๊ณผ specular reflection์„ ๋ชจ๋‘ ๊ฐ€์ง
  • ํ‘œ๋ฉด์˜ ๋ฐ˜์‚ฌ ํŠน์„ฑ์€ ๋ถ„ํฌ ํ•จ์ˆ˜(distribution function)๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅ
  • โ†’ BRDF

Bidirectional Reflectance Distribution Function (BRDF)

  • ๋ถˆํˆฌ๋ช… ํ‘œ๋ฉด์—์„œ ๋น›์ด ์–ด๋–ป๊ฒŒ ๋ฐ˜์‚ฌ๋˜๋Š”์ง€ ์ •์˜

    • ฮธi,ฯ•i\theta_i, \phi_iฮธiโ€‹,ฯ•iโ€‹: ์ž…์‚ฌ๊ด‘ ๋ฐฉํ–ฅ
    • ฮธo,ฯ•o\theta_o, \phi_oฮธoโ€‹,ฯ•oโ€‹: ๋ฐ˜์‚ฌ๊ด‘ ๋ฐฉํ–ฅ
    • frf_rfrโ€‹: ์ถœ์‚ฌ ๋ฐฉํ–ฅ์— ๋”ฐ๋ฅธ ๋ฐ˜์‚ฌ ๋ณต์‚ฌ๋„ ๋น„์œจ์„ ๋ฐ˜ํ™˜
  • ์ˆ˜์‹ ํ‘œํ˜„:

fr(ฮธi,ฯ•i;ฮธo,ฯ•o)โ‰ฅ0f_r(\theta_i, \phi_i; \theta_o, \phi_o) \ge 0 frโ€‹(ฮธiโ€‹,ฯ•iโ€‹;ฮธoโ€‹,ฯ•oโ€‹)โ‰ฅ0

Examples of BRDF

(theoretical approximation, not from measurement)

  • ์ž๋™์ฐจ ๋ฐฑ๋ฏธ๋Ÿฌ์˜ ๊ฐ•ํ•œ ๋ฐ˜์‚ฌ
  • ๋ถ„ํ•„ ํ‘œ๋ฉด์ฒ˜๋Ÿผ ๋งค์šฐ diffuseํ•œ ์žฌ์งˆ
  • ๋Œ€๋ฆฌ์„ ๋ฐ”๋‹ฅ๊ณผ ๊ฐ™์ด ๊ด‘ํƒ์ด ์žˆ๋Š” ํ‘œ๋ฉด
  • ์‚ฌ๊ณผ์ฒ˜๋Ÿผ ๋ณตํ•ฉ ๋ฐ˜์‚ฌ๋ฅผ ๊ฐ€์ง„ ์žฌ์งˆ

Phong Illumination Model & BRDF

  • Phong ๋ชจ๋ธ์€ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€๋ฅผ ๊ฐ€์ง„ BRDF๋ฅผ ๋ชจ๋ธ๋งํ•จ:
    • ๋ฐ˜๊ตฌ(hemisphere): diffuse ์„ฑ๋ถ„ ํ‘œํ˜„
    • lobe(๋กœ๋ธŒ): specular ์„ฑ๋ถ„์„ cosโฟ(ฮฑ) ํ˜•ํƒœ๋กœ ํ‘œํ˜„

Measuring BRDF

  • ํŠน์ • ์žฌ์งˆ์˜ BRDF๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ๋น„๋กœ ์ธก์ • ๊ฐ€๋Šฅ:
    • ๊ธฐ๋ณธ ๊ฐœ๋…: ํšŒ์ „ํ•˜๋Š” ๊ด‘์›๊ณผ ํšŒ์ „ํ•˜๋Š” ์„ผ์„œ ์‚ฌ์šฉ

Using Measured BRDF for Rendering

  • ์ธก์ •๋œ BRDF๋Š” ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ
Measured BRDFNickelPink fabricGray plasticNylon
Rendered object๋ Œ๋”๋ง๋œ ์˜ค๋ธŒ์ ํŠธ
Real object example์‹ค์ œ ๋ฌผ์ฒด ์˜ˆ์‹œ

Local vs. Global Illumination

  • Local (๋˜๋Š” direct, non-global) illumination
    • ๊ด‘์›์—์„œ ์ง์ ‘ ์˜ค๋Š” ๋น›๋งŒ์„ ๋ชจ๋ธ๋ง
    • ๋น ๋ฅด๊ฒŒ ๋ Œ๋”๋ง ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์‚ฌ์‹ค์„ฑ์ด ๋–จ์–ด์ง
    • ์˜ˆ: Phong illumination ๋ชจ๋ธ

(๊ทธ๋ฆผ: Direct illumination ์˜ˆ์‹œ)

  • Global illumination
    • ์ง์ ‘ ์กฐ๋ช… +
    • ๋‹ค๋ฅธ ๋ฌผ์ฒด์—์„œ ๋ฐ˜์‚ฌ๋œ ๊ฐ„์ ‘ ์กฐ๋ช… (inter-object reflections) ํฌํ•จ
    • ํ›จ์”ฌ ๋” ์‚ฌ์‹ค์ 
    • ์˜ˆ: Ray tracing, Path tracing, Radiosity

(๊ทธ๋ฆผ: ์ง์ ‘ ์กฐ๋ช… + ๊ฐ„์ ‘ ์กฐ๋ช… = ์ „์—ญ ์กฐ๋ช…)

Phong Illumination Model & Local, Global Illumination

  • Phong ์กฐ๋ช… ๋ชจ๋ธ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ local illumination model
  • ๊ฐ„์ ‘ ์กฐ๋ช…์€ ์ฃผ๋ณ€๊ด‘(ambient component)์œผ๋กœ๋งŒ ๋Œ€๋žต์ ์œผ๋กœ ๊ทผ์‚ฌ๋จ

(๊ทธ๋ฆผ: Phong direct vs. ambient ๊ทผ์‚ฌ ๋น„๊ต)

Texture Mapping

  • ํ‘œ๋ฉด์ƒ์˜ ์œ„์น˜์— ๋”ฐ๋ผ ํ‘œ๋ฉด ์†์„ฑ์„ ์ •์˜ํ•˜๋Š” ๊ธฐ๋ฒ•

  • ๋ณดํ†ต 2D texture ์ด๋ฏธ์ง€(= texture map)๋ฅผ 3D ๊ฐ์ฒด ํ‘œ๋ฉด์— ์ ์šฉ

  • ์ฃผ์š” ๋ชฉ์ : ํ‘œ๋ฉด ๋””ํ…Œ์ผ ์ถ”๊ฐ€

    • ๊ณ ํด๋ฆฌ๊ณค ๋ชจ๋ธ๋ณด๋‹ค
    • ๋” ์ ์€ ํด๋ฆฌ๊ณค์œผ๋กœ ๋†’์€ ๋””ํ…Œ์ผ ํ‘œํ˜„ ๊ฐ€๋Šฅ
    • ๋ Œ๋”๋ง ์†๋„ ๋Œ€ํญ ํ–ฅ์ƒ
    • texture map์˜ ๋ณต์žก๋„๋Š” ์ฒ˜๋ฆฌ ๋ณต์žก๋„์— ์˜ํ–ฅ ์—†์Œ

(๊ทธ๋ฆผ: ๊ณ ์ •๋ฐ€ vs. ํ…์Šค์ฒ˜ ์ ์šฉ ๋ชจ๋ธ)

UV Mapping

  • Texture mapping์€ ๋ณดํ†ต UV mapping์„ ํ†ตํ•ด ์ •์˜๋จ

  • UV mapping: 2D ํ…์Šค์ฒ˜ ์ขŒํ‘œ (u, v)๋ฅผ 3D ๋ชจ๋ธ์˜ ๊ฐ ์ •์ ์— ๋งคํ•‘

    • ๊ฐ ์ •์ ์ด 2D ์ด๋ฏธ์ง€์—์„œ ์–ด๋–ค ์œ„์น˜์— ๋Œ€์‘๋˜๋Š”์ง€ ์„ค๋ช…
  • UV mapping ํ•จ์ˆ˜๋Š” texture coordinate function์œผ๋กœ๋„ ๋ถˆ๋ฆผ

(๊ทธ๋ฆผ: UV ์ขŒํ‘œ ๋ฐ ๋งคํ•‘ ์˜ˆ์‹œ)

Texture Mapping Process

  1. ํ‘œ๋ฉด์˜ ์ ์„ UV ๊ณต๊ฐ„(UV map)์—์„œ์˜ ์ ์— ๋งคํ•‘ (UV mapping)
  2. ํ•ด๋‹น UV ์ขŒํ‘œ๋ฅผ ํ…์Šค์ฒ˜ ์ƒ์˜ ์ ์œผ๋กœ ๋งคํ•‘
  • Step 2๋Š” ๋‹จ์ˆœ ์Šค์ผ€์ผ๋ง์ด๋ฉฐ ์‹œ์Šคํ…œ์ด ์ž๋™ ์ˆ˜ํ–‰
  • Step 1์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ์ •์˜ํ•ด์•ผ ํ•  texture coordinate function

(๊ทธ๋ฆผ: ์ง€๊ตฌ ํ‘œ๋ฉด UV๋กœ ํŽด๊ธฐ)

Defining Texture Coordinate Function:

  1. Creating "UV map"
  • ๋ฌผ์ฒด ํ‘œ๋ฉด์„ "ํŽผ์น˜๊ธฐ(Unwrap)"
    • Blender ๋“ฑ 3D ๋ชจ๋ธ๋ง ํˆด์—์„œ ์ž๋™ ์ˆ˜ํ–‰๋จ
  • ํ•„์š” ์‹œ, ์•„ํ‹ฐ์ŠคํŠธ๊ฐ€ ์ˆ˜์ž‘์—…์œผ๋กœ UV ์ขŒํ‘œ๋ฅผ ์ถ”๊ฐ€ ๋ณด์ •ํ•˜๊ธฐ๋„ ํ•จ

"Unwrapping"

  • ์ž๋™ "unwrapping" ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • ์ผ๋ถ€ ์ตœ์ ํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ 3D ๊ฐ์ฒด๋ฅผ ํŽผ์น  ๋•Œ ๊ฐ ์ •์ ์˜ (u, v)๋ฅผ ๋ถ€๋“œ๋Ÿฝ๊ณ  ์™œ๊ณก์ด ์ ์€ ๋ฐฉ์‹์œผ๋กœ ์„ ํƒ
    • Blender, Maya ๋“ฑ ๋‹ค์–‘ํ•œ 3D ๋ชจ๋ธ๋ง ํˆด์€ ๊ฐ๊ธฐ ๋‹ค๋ฅธ unwrapping ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉ

(๊ทธ๋ฆผ: ๋‹ค์–‘ํ•œ unwrap ์˜ˆ์‹œ)

UV Map Examples

(๊ทธ๋ฆผ: ๋‚˜๋ฌด ์ƒ์ž ๋ฐ ๋ฒ„์„ฏ ๋ชจ๋ธ์˜ UV ๋งคํ•‘ ์˜ˆ์‹œ)

(๊ทธ๋ฆผ: ์บ๋ฆญํ„ฐ, ์ž๋™์ฐจ ๋“ฑ ๋‹ค์–‘ํ•œ UV ๋งคํ•‘ ์˜ˆ์‹œ)

Defining Texture Coordinate Function:

  1. Projections to Parametric Surfaces
  • ์‚ฌ๊ฐํ˜•, ๊ตฌ, ์›๊ธฐ๋‘ฅ ๋“ฑ ํŒŒ๋ผ๋ฉ”ํŠธ๋ฆญ ํ‘œ๋ฉด(parametric surfaces)๊ณผ ์œ ์‚ฌํ•œ ๊ฐ์ฒด๋Š”
  • ํ•ด๋‹น ํŒŒ๋ผ๋ฉ”ํŠธ๋ฆญ ํ‘œ๋ฉด์— ์ •์ ์„ ํˆฌ์‚ฌํ•˜์—ฌ ํ…์Šค์ฒ˜ ์ขŒํ‘œ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Œ

Examples of coordinate functions

Planar projection

(๊ทธ๋ฆผ: ํ‰๋ฉด ํˆฌ์˜์— ์˜ํ•œ UV ๋ถ„ํฌ) Spherical projection

(๊ทธ๋ฆผ: ๊ตฌ๋ฉด ํˆฌ์˜์— ์˜ํ•œ ์ง€๊ตฌ ํ…์Šค์ฒ˜ ์ ์šฉ)

Cylindrical projection

(๊ทธ๋ฆผ: ์‹ค๋ฆฐ๋” ํ˜•ํƒœ๋กœ ํˆฌ์˜๋œ ํ…์Šค์ฒ˜)

Rendering Texture-Mapped Objects

for each pixel:
(u, v) = texture coordinates at pixel
color = texture.get_color(u, v)
pixel.color = color
  • ๊ทธ๋Ÿฌ๋‚˜ ํ…์Šค์ฒ˜ ์ขŒํ‘œ ํ•จ์ˆ˜๋Š” ๊ฐ ์ •์ (vertex)์— ๋Œ€ํ•ด ์ •์˜๋จ
  • ๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ ํ”ฝ์…€๋งˆ๋‹ค์˜ ํ…์Šค์ฒ˜ ์ขŒํ‘œ๋Š” ์–ด๋–ป๊ฒŒ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์„๊นŒ?
  • ํ…์Šค์ฒ˜ ์ขŒํ‘œ๋Š” ๋‹ค๊ฐํ˜• ๋‚ด๋ถ€์—์„œ barycentric interpolation์œผ๋กœ ๊ณ„์‚ฐ๋จ
  • ๋‹ค๊ฐํ˜• ๋‚ด๋ถ€์˜ ๊ฐ ํ”ฝ์…€์— ๋Œ€ํ•ด, ํ”ฝ์…€์ด ํฌํ•จ๋œ ์‚ผ๊ฐํ˜•์˜ ์ •์  ์ขŒํ‘œ์— ๋”ฐ๋ผ (u, v)๊ฐ€ ๊ฒฐ์ •๋จ

(u,v)=ฮฑ1(u1,v1)+ฮฑ2(u2,v2)+ฮฑ3(u3,v3)(u, v) = \alpha_1 (u_1, v_1) + \alpha_2 (u_2, v_2) + \alpha_3 (u_3, v_3) (u,v)=ฮฑ1โ€‹(u1โ€‹,v1โ€‹)+ฮฑ2โ€‹(u2โ€‹,v2โ€‹)+ฮฑ3โ€‹(u3โ€‹,v3โ€‹)

ฮฑ1+ฮฑ2+ฮฑ3=1\alpha_1 + \alpha_2 + \alpha_3 = 1 ฮฑ1โ€‹+ฮฑ2โ€‹+ฮฑ3โ€‹=1

Diffuse, Specular, Normal Maps

  • ํ…์Šค์ฒ˜ ๋งต์„ ํ†ตํ•ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ํ‘œ๋ฉด ์†์„ฑ์€?
    • diffuse color, specular color
    • specular ์ง€์ˆ˜, ํˆฌ๋ช…๋„, ๋ฐ˜์‚ฌ์œจ ๊ณ„์ˆ˜
    • surface normal
    • ๊ทธ๋ฆผ์ž ๋˜๋Š” ๋ฐ˜์‚ฌ ์ •๋ณด
    • ๊ธฐํƒ€

Examples of Diffuse, Specular, Normal Map

(์™ผ์ชฝ๋ถ€ํ„ฐ)

  • diffuse map
  • specular map
  • normal map

(์˜ˆ์‹œ: Game of Thrones ์บ๋ฆญํ„ฐ ํ…์Šค์ฒ˜)

  • final ๋ Œ๋”๋ง
  • diffuse
  • specular
  • wireframe
  • normal
  • texture map

Normal Mapping - Motivation

  • circle, sphere ๋น„๊ต

  • circle์€ ์‚ผ๊ฐํ˜• ๊ฐœ์ˆ˜๊ฐ€ ์ ์–ด ๋ Œ๋”๋ง์ด ๋” ๋น ๋ฆ„

  • normal vector๊ฐ€ ์ ์ ˆํ•˜๋ฉด circle๋„ sphere์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Œ

  • ์ธ๊ฐ„ ์‹œ๊ฐ์€ ์‹ค์ œ ํ˜•์ƒ์ด ์•„๋‹Œ ๋ฐ๊ธฐ ํŒจํ„ด์œผ๋กœ ํ˜•ํƒœ๋ฅผ ์ธ์‹

    • ์ฆ‰, ๋ฐ๊ณ  ์–ด๋‘์šด ์˜์—ญ์˜ ํŒจํ„ด์€ normal์— ์˜ํ•ด ๊ฒฐ์ •๋จ

Normal Mapping - Basic Idea

๋ชฉํ‘œ: ๊ณ ํด๋ฆฌ ๋ชจ๋ธ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ์ €ํด๋ฆฌ ๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ

  1. ๊ณ ํด๋ฆฌ ๋ชจ๋ธ์˜ normal์„ ํ…์Šค์ฒ˜ ์ด๋ฏธ์ง€์— somehow ์ธ์ฝ”๋”ฉ
  2. ๊ทธ ํ…์Šค์ฒ˜ ์ด๋ฏธ์ง€๋ฅผ ์ €ํด๋ฆฌ ๋ชจ๋ธ์— ์ ์šฉ

(๊ทธ๋ฆผ: normal ์ „ํŒŒ ์˜ˆ์‹œ)

Normal Mapping - Example

  • ์ขŒ: high-poly (814 triangles)
  • ์ค‘: simplified (900 triangles)
  • ์šฐ: ๋” ๊ฐ„๋‹จํ•œ ๋ชจ๋ธ (200 triangles)

Normal Mapping - Details

  • ๊ณ ํด๋ฆฌ(high-poly) ๋ชจ๋ธ์˜ normal vector๋ฅผ ๊ฐ ํ”ฝ์…€์˜ RGB ๊ฐ’์œผ๋กœ ์ธ์ฝ”๋”ฉ
  • tangent space normal map์—์„œ๋Š” ํ”ฝ์…€ RGB๊ฐ€ u, v, w ์ถ•์— ํ•ด๋‹นํ•˜๋Š” normal ์„ฑ๋ถ„์„ ๋‚˜ํƒ€๋ƒ„

ํ‘œ๊ธฐ:

  • R = Nแตค, G = Nแตฅ, B = Nสท

  • u: ํ…์Šค์ฒ˜ u์ถ•

  • v: ํ…์Šค์ฒ˜ v์ถ•

  • w: ํ‘œ๋ฉด์˜ ์‹ค์ œ normal ๋ฐฉํ–ฅ

  • R = Nแตค, G = Nแตฅ, B = Nสท

    • U: -1 to +1 โ†’ Red: 0 to 255
    • V: -1 to +1 โ†’ Green: 0 to 255
    • W: 0 to +1 โ†’ Blue: 128 to 255
  • tangent space normal map์ด ํ‘ธ๋ฅด์Šค๋ฆ„ํ•œ ์ด์œ :

    • ๋Œ€๋ถ€๋ถ„์˜ normal์€ tangent space ๊ธฐ์ค€ (128, 128, 255) ๊ทผ์ฒ˜์ด๊ธฐ ๋•Œ๋ฌธ

Bump Mapping

  • ๋ชฉ์ ์€ normal mapping๊ณผ ๋™์ผ

  • ํ•ต์‹ฌ ์•„์ด๋””์–ด:

    • normal vector๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๋Œ€์‹  ์ƒ๋Œ€์ ์ธ ๋†’์ด(relative heights)๋ฅผ ์ €์žฅ
      • ๊ฒ€์ •: ์ตœ์†Œ ๋†’์ด ๋ณ€ํ™”
      • ํฐ์ƒ‰: ์ตœ๋Œ€ ๋†’์ด ๋ณ€ํ™”
  • normal์€ ๋†’์ด๋งต์œผ๋กœ๋ถ€ํ„ฐ ๊ณ„์‚ฐํ•˜์—ฌ ์ ์šฉ

Bump Mapping Example

(๊ทธ๋ฆผ: ์›๋ณธ ์˜ค๋ธŒ์ ํŠธ + bump map = bump๊ฐ€ ์ ์šฉ๋œ ๊ฒฐ๊ณผ)

Displacement Mapping

  • height map์˜ ๋†’์ด ๋ณ€ํ™”๋Ÿ‰์„ ์ฐธ์กฐํ•˜์—ฌ ์‹ค์ œ๋กœ ์ •์ ์˜ ์œ„์น˜๋ฅผ ์ด๋™์‹œํ‚ด

    • bump/normal mapping๊ณผ ๋‹ฌ๋ฆฌ ์‹ค๋ฃจ์—ฃ ๋ฐ ์ž๊ธฐ ๊ทธ๋ฆผ์ž(self-shadowing)๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ‘œํ˜„๋จ
  • ๊ธฐ๋ณธ์ ์œผ๋กœ normal/bump์ฒ˜๋Ÿผ ์ •์  ๊ฐ„์˜ ์„ธ๋ถ€ ํ‘œํ˜„์„ ์ œ๊ณตํ•˜์ง€๋Š” ์•Š์Œ

    • ์„ธ๋ถ€ ํ‘œํ˜„์„ ๋†’์ด๋ ค๋ฉด ์ •์ ์„ ๋” ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์—ฐ์‚ฐ๋Ÿ‰ ์ฆ๊ฐ€

(๊ทธ๋ฆผ: subdivision ์ •๋„์— ๋”ฐ๋ฅธ displacement ์ฐจ์ด)

[Demo] Normal / Bump / Displacement Mapping

  • Normal mapping / Displacement mapping
    • https://threejs.org/examples/#webgl_materials_displacementmap
  • Bump mapping
    • https://threejs.org/examples/#webgl_materials_bumpmap

Light Map

  • light map์€ ์‚ฌ์ „ ๊ณ„์‚ฐ๋œ ์กฐ๋ช… ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋จ
ํ•ญ๋ชฉTexture MapsLight Maps
๋ฐ์ดํ„ฐRGB๋ฐ๊ธฐ(Intensity)
ํ•ด์ƒ๋„๋†’์Œ๋‚ฎ์Œ

(์ด๋ฏธ์ง€: ํ…์Šค์ฒ˜๋งŒ ์ ์šฉ๋œ ์žฅ๋ฉด vs. ๋ผ์ดํŠธ๋งต์ด ์ ์šฉ๋œ ์žฅ๋ฉด ๋น„๊ต)

Shadow Map

  • light view์—์„œ์˜ depth map์„ ์ด์šฉํ•ด ์ƒ˜ํ”Œ ์ง€์ ์ด ๋ณด์ด๋Š”์ง€๋ฅผ ํŒ๋‹จ
    • ๋ˆˆ์—๋Š” ๋ณด์ด์ง€๋งŒ ๊ด‘์›์— ๊ฐ€๋ ค์ง„ ์ง€์ ์€ ๊ทธ๋ฆผ์ž๋กœ ํ‘œ์‹œ๋จ

(๊ทธ๋ฆผ: teapot์„ ๊ธฐ์ค€์œผ๋กœ ๊ด‘์› ๋ฐฉํ–ฅ์—์„œ ๊นŠ์ด ํ™•์ธ)

Environment Map

  • ๋ณต์žกํ•œ ๊ฑฐ์šธ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด ์‹œ๋ฎฌ๋ ˆ์ด์…˜
    • ๊ฐ์ฒด ์ฃผ๋ณ€ ํ™˜๊ฒฝ์„ ํ…์Šค์ฒ˜๋กœ ์บก์ฒ˜
    • ํ‘œ๋ฉด normal์„ ์ด์šฉํ•ด ํ…์Šค์ฒ˜ ์ขŒํ‘œ ๊ณ„์‚ฐ

(๊ทธ๋ฆผ: ๊ตฌ๋ฉด์— ์ ์šฉ๋œ environment map)

[Practice] Online Demos

  • Light mapping

    • https://threejs.org/examples/?q=light#webgl_lights_physical
  • Shadow mapping

    • https://threejs.org/examples/#webgl_shadowmap
  • Environment mapping

    • https://threejs.org/examples/#webgl_materials_cubemap_dynamic
    • https://threejs.org/examples/?q=refrac#webgl_materials_cubemap_refraction

12 - Lab - Texture Mapping

Outline

  • Pillow ์„ค์น˜
  • ํ…์Šค์ฒ˜๊ฐ€ ์ ์šฉ๋œ ๋‹จ์ผ ์‚ผ๊ฐํ˜•
  • ํ…์Šค์ฒ˜ ํ•„ํ„ฐ๋ง
  • ๋ฐ‰๋งต
  • ํ…์Šค์ฒ˜ ๋ž˜ํ•‘
  • ๋‹ค์ค‘ ํ…์Šค์ฒ˜

Install Pillow

  • Pillow: ๋Œ€์ค‘์ ์ธ ํŒŒ์ด์ฌ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • ์„ค์น˜:

$ workon cg-course
$ pip install pillow
  • ๋ฌธ์„œ:
    https://pillow.readthedocs.io/en/stable/index.html

[Code] 1-triangle-texture

  • "5-Lab-3DTransformations-VertProcess/1/3-lookat.py"์—์„œ ์‹œ์ž‘
  • ํ”„๋ ˆ์ž„์„ ๊ทธ๋ฆฌ๋Š” ์ฝ”๋“œ ์ œ๊ฑฐ
  • PIL(Pillow) ๋ชจ๋“ˆ import:
from PIL import Image
  • VAO
    • ์ด์ œ vertex ๋ฐ์ดํ„ฐ์—๋Š” ๊ผญ์ง“์  ์œ„์น˜์™€ ์ƒ‰์ƒ๋ฟ ์•„๋‹ˆ๋ผ ํ…์Šค์ฒ˜ ์ขŒํ‘œ๋„ ํฌํ•จ๋จ

vertex ๋ฐฐ์—ด ๊ตฌ์„ฑ ์˜ˆ์‹œ:

# positions      # colors         # texture coordinates
0.0,  0.5, 0.0,   1.0, 0.0, 0.0,   0.5, 1.0,
-0.5, -0.5, 0.0,  0.0, 1.0, 0.0,   0.0, 0.0,
0.5, -0.5, 0.0,   0.0, 0.0, 1.0,   1.0, 0.0
  • VAO ์ƒ์„ฑ ๋ฐ ํ™œ์„ฑํ™”
  • VBO ์ƒ์„ฑ ๋ฐ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ
def prepare_vao_triangle():
    # ๊ผญ์ง“์  ์œ„์น˜ ์†์„ฑ ์„ค์ •
    glVertexAttribPointer(index, size, type, normalized, stride, pointer)
    glEnableVertexAttribArray(index)

    # ๊ผญ์ง“์  ์ƒ‰์ƒ ์†์„ฑ ์„ค์ •
    glVertexAttribPointer(...)
    glEnableVertexAttribArray(...)

    # ํ…์Šค์ฒ˜ ์ขŒํ‘œ ์†์„ฑ ์„ค์ • - 2D ๋ฐ์ดํ„ฐ
    glVertexAttribPointer(...)
    glEnableVertexAttribArray(...)

    return VAO
  • ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜๊ณ  ํ…์Šค์ฒ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •

  • ํ…์Šค์ฒ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ”์ธ๋”ฉ: glGenTextures, glBindTexture

  • ์ด๋ฏธ์ง€ ๋กœ๋“œ: Pillow ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ (Image.open)

  • ๋กœ๋“œํ•œ ์ด๋ฏธ์ง€๋ฅผ ํ…์Šค์ฒ˜๋กœ ์„ค์ •: glTexImage2D

def main():
    # ํ…์Šค์ฒ˜ ๊ฐ์ฒด ์ƒ์„ฑ
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)

    # ํ…์Šค์ฒ˜ ํ•„ํ„ฐ๋ง ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ •
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    try:
        img = Image.open("./A02pysc-Solarsystemscope_texture_8k_earth_daymap.jpg")

        # ์ด๋ฏธ์ง€ ์ˆ˜์ง ๋’ค์ง‘๊ธฐ (OpenGL์˜ y์ถ• ๋ฐฉํ–ฅ ๋•Œ๋ฌธ)
        img = img.transpose(Image.FLIP_TOP_BOTTOM)

        # ํ…์Šค์ฒ˜ ์ด๋ฏธ์ง€๋กœ ์„ค์ •
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width, img.height, 0,
                     GL_RGB, GL_UNSIGNED_BYTE, img.tobytes())

        img.close()
    except:
        print("Failed to load texture")
  • glTexImage2D ํ•จ์ˆ˜ ์‚ฌ์šฉ ์˜ˆ์‹œ ๋ฐ ์„ค๋ช…
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width, img.height, 0,
             GL_RGB, GL_UNSIGNED_BYTE, img.tobytes())
  • glTexImage2D(target, level, internalformat, width, height, border, format, type, data)
    • target: ํ…์Šค์ฒ˜ ๋Œ€์ƒ. GL_TEXTURE_2D๋กœ ์„ค์ •
    • level: ๋””ํ…Œ์ผ ๋ ˆ๋ฒจ. ๋ณดํ†ต 0 (glGenerateMipmap ์‚ฌ์šฉ ์‹œ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ)
    • internalformat: ํ…์Šค์ฒ˜๋ฅผ ์ €์žฅํ•  ๋‚ด๋ถ€ ํฌ๋งท
    • width, height: ์ด๋ฏธ์ง€ ํฌ๊ธฐ
    • border: 0 (๋ ˆ๊ฑฐ์‹œ ๊ฐ’)
    • format, type: ์›๋ณธ ์ด๋ฏธ์ง€์˜ ํฌ๋งท๊ณผ ๋ฐ์ดํ„ฐ ํƒ€์ž…
    • data: ๋ฉ”๋ชจ๋ฆฌ ์ƒ์˜ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ
  • Vertex Shader ์ฝ”๋“œ
#version 330 core
layout (location = 0) in vec3 vin_pos;
layout (location = 1) in vec3 vin_color;
layout (location = 2) in vec2 vin_uv;

out vec3 vout_color;
out vec2 vout_uv;

uniform mat4 MVP;

void main() {
    // ๋™์ฐจ ์ขŒํ‘œ๊ณ„์—์„œ์˜ 3D ์œ„์น˜ ๊ณ„์‚ฐ
    vec4 pos4 = vec4(vin_pos.xyz, 1.0);
    gl_Position = MVP * pos4;

    vout_color = vec4(vin_color, 1.0);
    vout_uv = vin_uv;
}
  • Fragment Shader ์ฝ”๋“œ
#version 330 core
in vec2 vout_uv;          // ๋ณด๊ฐ„๋œ ํ…์Šค์ฒ˜ ์ขŒํ‘œ
in vec3 vout_color;

out vec4 FragColor;

uniform sampler2D texture1;  // GLSL ๋‚ด์žฅ sampler ํƒ€์ž…

void main()
{
    // FragColor = vec4(vout_color, 1.0);  // ์ƒ‰์ƒ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

    // ํ…์Šค์ฒ˜ ์ขŒํ‘œ์— ๋”ฐ๋ผ ์ƒ‰์ƒ ์ƒ˜ํ”Œ๋ง
    FragColor = texture(texture1, vout_uv);
}
  • ์ตœ์ข… ๊ทธ๋ฆฌ๊ธฐ ๋ฃจํ”„
def main():
    ...
    while not glfwWindowShouldClose(window):
        # ํ˜„์žฌ ํ”„๋ ˆ์ž„ ๊ธฐ์ค€์œผ๋กœ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆผ
        glBindVertexArray(vao_triangle)
        glDrawArrays(GL_TRIANGLES, 0, 3)
    ...
  • ์•„์ง uniform ๋ณ€์ˆ˜ texture1์˜ ๊ฐ’์„ ์„ค์ •ํ•˜์ง€ ์•Š์Œ
  • GLSL์—์„œ๋Š” sampler uniform์ด ๊ธฐ๋ณธ๊ฐ’ 0์œผ๋กœ ์„ค์ •๋œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†์Œ
  • ๋Œ€๋ถ€๋ถ„ ๋“œ๋ผ์ด๋ฒ„์—์„œ ๊ธฐ๋ณธ๊ฐ’์ด 0(GL_TEXTURE0)์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ,
    ํ”Œ๋žซํผ์ด๋‚˜ GPU์— ๋”ฐ๋ผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•จ
  • ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ uniform ๋ฐ”์ธ๋”ฉ์„ ๋ช…ํ™•ํžˆ ์„ค์ •:
loc_texture1 = glGetUniformLocation(shader_program, "texture1");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(loc_texture1, 0);

(์ด๋ฏธ์ง€ ์„ค๋ช…: ์ขŒ์ธก ํ•˜๋‹จ ๊ทธ๋ฆผ์€ ์ง€๊ตฌ ํ…์Šค์ฒ˜๋ฅผ ์‚ผ๊ฐํ˜•์— ๋งคํ•‘ํ•œ ์˜ˆ์‹œ์ž„)

[Code] 2-triangle-texture-color

  • vertex ์ƒ‰์ƒ๊ณผ ํ…์Šค์ฒ˜๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • ์˜ˆ: ํ…์Šค์ฒ˜ ๊ฐ’์— ์ƒ‰์ƒ ๊ฐ’์„ ๊ณฑํ•ด ์‹œ๊ฐ์  ํšจ๊ณผ ์ถ”๊ฐ€
void main() {
    ...
    FragColor = texture(texture1, vout_uv) * vout_color;
}

(์ด๋ฏธ์ง€ ์„ค๋ช…: ์ƒ‰์ƒ์ด ์ ์šฉ๋œ ์ง€๊ตฌ ์ด๋ฏธ์ง€์˜ ํ…์Šค์ฒ˜ ์˜ˆ์‹œ)

[Code] 3-triangle-texture-filter

  • ๋” ํฐ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ ค๋ณด์ž
def main():
    while not glfwWindowShouldClose(window):
        ...
        # ๋ชจ๋ธ๋ง ํ–‰๋ ฌ
        M = glm.mat4()
        M = glm.scale(glm.vec3(3.5, 5.5, 1.0))
        ...

(์ด๋ฏธ์ง€ ์„ค๋ช…: ํ™•๋Œ€๋œ ์‚ผ๊ฐํ˜•์— ์ €ํ•ด์ƒ๋„ ํ…์Šค์ฒ˜๊ฐ€ ๋šœ๋ ทํ•˜๊ฒŒ ๋ณด์ž„)

  • ๋” ๋ถ€๋“œ๋Ÿฌ์šด ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด?

(์ด๋ฏธ์ง€ ์„ค๋ช…: ์™ผ์ชฝ์€ GL_NEAREST๋กœ ํ”ฝ์…€์ด ๋šœ๋ ทํ•จ, ์˜ค๋ฅธ์ชฝ์€ GL_LINEAR๋กœ ๋ณด๊ฐ„๋˜์–ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ํ‘œํ˜„๋จ)

  • ํ…์Šค์ฒ˜ ํ•„ํ„ฐ๋ง(Texture filtering)์€ ์ฃผ์–ด์ง„ (u, v)์— ๋Œ€ํ•œ ์ƒ‰์ƒ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ์‹ ์ง€์ •
  • ํ…์Šค์ฒ˜ ์ขŒํ‘œ๋Š” ์‹ค์ˆ˜์ด๋ฏ€๋กœ ์ •ํ™•ํžˆ ํ”ฝ์…€ ์ค‘์‹ฌ๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ
  • GL_NEAREST: ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ…์…€(texel)์˜ ์ƒ‰์ƒ์„ ์‚ฌ์šฉ (ํ”ฝ์…€ํ™”๋œ ๊ฒฐ๊ณผ)
  • GL_LINEAR: ์ฃผ๋ณ€ ํ…์…€์„ ๋ณด๊ฐ„ํ•˜์—ฌ ์ƒ‰์ƒ์„ ๊ณ„์‚ฐ (๋ถ€๋“œ๋Ÿฌ์šด ๊ฒฐ๊ณผ) (์ด๋ฏธ์ง€ ์„ค๋ช…: ์ขŒ์ธก์€ Nearest ํ•„ํ„ฐ, ์šฐ์ธก์€ Linear ํ•„ํ„ฐ์— ๋”ฐ๋ฅธ ํ”ฝ์…€ ์‹œ๊ฐํ™” ์˜ˆ์‹œ)
  • MIN ํ•„ํ„ฐ์™€ MAG ํ•„ํ„ฐ๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ์„ค์ • ๊ฐ€๋Šฅ
  • MIN ํ•„ํ„ฐ: ์ถ•์†Œ ์‹œ
  • MAG ํ•„ํ„ฐ: ํ™•๋Œ€ ์‹œ
def main():
    ...
    # ํ…์Šค์ฒ˜ ์ƒ์„ฑ
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)

    # GL_NEAREST ์„ค์ • ์˜ˆ์‹œ
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)

    # GL_LINEAR ์„ค์ • ์˜ˆ์‹œ
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    try:
        img = Image.open("./230px-Solarsystemscope_texture_8k_earth_daymap.jpg")

(์ด๋ฏธ์ง€ ์„ค๋ช…: Python ์ฝ”๋“œ์—์„œ MIN/MAG ํ•„ํ„ฐ๋ฅผ GL_LINEAR ๋˜๋Š” GL_NEAREST๋กœ ์„ค์ •ํ•˜๋Š” ์˜ˆ์‹œ)

[Code] 4-triangle-texture-mipmaps

  • ๊ณ ํ•ด์ƒ๋„ ํ…์Šค์ฒ˜๋ฅผ ๋ฉ€๋ฆฌ ์žˆ๋Š” ๋ฌผ์ฒด์— ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ํ•œ ํ”ฝ์…€์— ๋ชจ๋“  ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐ€ ๋น„ํšจ์œจ์ ์ž„
  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด mipmap ์‚ฌ์šฉ
    • mipmap์€ ๋™์ผ ํ…์Šค์ฒ˜์˜ ํ•ด์ƒ๋„๋ฅผ ์ ์  ๋‚ฎ์ถ˜ ์ด๋ฏธ์ง€ ์ง‘ํ•ฉ
    • ๊ฐ์ฒด์™€์˜ ๊ฑฐ๋ฆฌ ๋“ฑ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ํ•ด์ƒ๋„์˜ ๋ ˆ๋ฒจ์„ ์„ ํƒํ•ด ์‚ฌ์šฉ
    • OpenGL์€ ์ž๋™์œผ๋กœ ์ ์ ˆํ•œ mipmap ๋ ˆ๋ฒจ์„ ์„ ํƒ

(์ด๋ฏธ์ง€ ์„ค๋ช…: ๊ฐ ๋ ˆ๋ฒจ๋งˆ๋‹ค ํ…์Šค์ฒ˜ ํ•ด์ƒ๋„๊ฐ€ ์ ˆ๋ฐ˜์”ฉ ์ค„์–ด๋“ค๋ฉฐ, ํ”ฝ์…€ ์ˆ˜์ค€์˜ ์ƒ˜ํ”Œ๋ง์ด ์ด๋ฃจ์–ด์ง)

def main():
    ...
    # GL_TEXTURE_MIN_FILTER: ์ถ•์†Œ ์‹œ ํ•„ํ„ฐ๋ง ๋ฐฉ์‹
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)

    # GL_LINEAR_MIPMAP_LINEAR: ์ธ์ ‘ํ•œ ๋‘ mipmap ๋ ˆ๋ฒจ์—์„œ ๊ฐ๊ฐ ์„ ํ˜• ๋ณด๊ฐ„ ํ›„, ๋‹ค์‹œ ์„ ํ˜• ๋ณด๊ฐ„
    # GL_LINEAR_MIPMAP_NEAREST: ๊ฐ€๊นŒ์šด ๋‘ ๋ ˆ๋ฒจ ์ค‘ ํ•˜๋‚˜ ์„ ํƒ + ๋‚ด๋ถ€๋Š” ์„ ํ˜• ๋ณด๊ฐ„

    # GL_TEXTURE_MAG_FILTER: ํ™•๋Œ€ ์‹œ ํ•„ํ„ฐ๋ง ๋ฐฉ์‹
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width, img.height, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, img.tobytes())

    glGenerateMipmap(GL_TEXTURE_2D)

[Code] 5-triangle-texture-wrap

  • ํ…์Šค์ฒ˜ ์ขŒํ‘œ๊ฐ€ (0.0, 1.0) ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๊ฒฝ์šฐ OpenGL์€ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ๊นŒ?

  • ํ…์Šค์ฒ˜ ๋ž˜ํ•‘ ๋ฐฉ์‹ 4๊ฐ€์ง€:

    • GL_REPEAT: ๊ธฐ๋ณธ๊ฐ’, ํ…์Šค์ฒ˜ ๋ฐ˜๋ณต
    • GL_MIRRORED_REPEAT: ๋ฐ˜์ „ํ•˜๋ฉฐ ๋ฐ˜๋ณต
    • GL_CLAMP_TO_EDGE: ๊ฐ€์žฅ์ž๋ฆฌ๋ฅผ ๋Š˜๋ฆผ
    • GL_CLAMP_TO_BORDER: ํ…Œ๋‘๋ฆฌ ์ƒ‰์ƒ์œผ๋กœ ์ฑ„์›€

(์ด๋ฏธ์ง€ ์„ค๋ช…: ๊ฐ๊ฐ์˜ wrapping ๋ชจ๋“œ์— ๋”ฐ๋ฅธ ์‹œ๊ฐ์  ์ฐจ์ด ๋น„๊ต)

def prepare_vao_triangle():
    vertices = glm.array(glm.float32,
        # position        # color       # texture coordinates
         0.0, 0.0, 0.0,    1.0, 0.0, 0.0,   -0.5, -0.5,  # v0
         0.5, 0.0, 0.0,    0.0, 1.0, 0.0,    2.0, -0.5,  # v1
         0.0, 0.5, 0.0,    0.0, 0.0, 1.0,   -0.5, 2.0    # v2
    )

(ํ…์Šค์ฒ˜ ์ขŒํ‘œ๊ฐ€ 0~1์„ ๋ฒ—์–ด๋‚˜๋„๋ก ์ง€์ •ํ•ด wrap ๋ชจ๋“œ์— ๋”ฐ๋ฅธ ์ฐจ์ด๋ฅผ ์‹คํ—˜)

def main():
    ...
    # ๊ธฐ๋ณธ๊ฐ’์€ GL_REPEAT

    # GL_TEXTURE_WRAP_S: ์ˆ˜ํ‰(u) ๋ฐฉํ–ฅ ์„ค์ •
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)

    # GL_TEXTURE_WRAP_T: ์ˆ˜์ง(v) ๋ฐฉํ–ฅ ์„ค์ •
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)

    # ๊ฒฝ๊ณ„์ƒ‰ ์„ค์ • (GL_CLAMP_TO_BORDER ์‹œ ์‚ฌ์šฉ๋จ)
    border_color = [1.0, 1.0, 1.0, 1.0]
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color)

    try:
        ...

[Code] 6-cube-multiple-textures

  • ๋‘ ๊ฐœ์˜ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜์—ฌ diffuse map๊ณผ specular map์œผ๋กœ ๊ฐ๊ฐ ์‚ฌ์šฉ
  • ๋‹ค์–‘ํ•œ ์กฐ๋ช… ํšจ๊ณผ ํ‘œํ˜„ ๊ฐ€๋Šฅ

(์ด๋ฏธ์ง€ ์„ค๋ช…: ์™ผ์ชฝ์€ diffuse map, ๊ฐ€์šด๋ฐ๋Š” specular map, ์˜ค๋ฅธ์ชฝ์€ ๊ฒฐ๊ณผ ํ๋ธŒ)

  • glUniform1i๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ sampler uniform์— texture unit์˜ ์œ„์น˜๋ฅผ ํ• ๋‹น ๊ฐ€๋Šฅ
  • ์ด๋ฅผ ํ†ตํ•ด fragment shader์—์„œ ์—ฌ๋Ÿฌ ํ…์Šค์ฒ˜๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • ๊ธฐ๋ณธ ๋ฐฉ์‹:
    • ๊ฐ sampler ๋ณ€์ˆ˜์— ๋Œ€ํ•ด glUniform1i๋กœ texture unit ์ธ๋ฑ์Šค ์ง€์ •
    • glActiveTexture(GL_TEXTUREi)๋กœ ํ™œ์„ฑํ™”
    • glBindTexture(GL_TEXTURE_2D, texture)๋กœ ๋ฐ”์ธ๋”ฉ

(์š”์•ฝ: diffuse map๊ณผ specular map์„ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ์กฐ)

  • 8-Lab-Lighting/4-all-components-phong-faceonvm.py์—์„œ ์‹œ์ž‘
  • Pillow import
  • VAO์˜ vertex data์— texture coordinate ์ถ”๊ฐ€
  • sampler uniform ๋ณ€์ˆ˜ texture_diffuse, texture_specular๋ฅผ ํ…์Šค์ฒ˜ ๊ฐ์ฒด์— ์—ฐ๊ฒฐ
  • shader ๋‚ด๋ถ€์—์„œ diffuse/ambient๋Š” texture_diffuse๋กœ๋ถ€ํ„ฐ,
    specular์€ texture_specular๋กœ๋ถ€ํ„ฐ ์ƒ˜ํ”Œ๋ง
def main():
    # diffuse texture
    texture_diffuse = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture_diffuse)
    try:
        img = Image.open("./230px-Solarsystemscope_texture_8k_earth_daymap.jpg")

    # specular texture
    texture_specular = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture_specular)
    try:
        img = Image.open("./plain-checkerboard.jpg")

    # ์œ ๋‹ˆํผ์— texture unit ์ธ๋ฑ์Šค ์ง€์ •
    glUniform1i(glGetUniformLocation(shader_program, "texture_diffuse"), 0)
    glActiveTexture(GL_TEXTURE0)
    glBindTexture(GL_TEXTURE_2D, texture_diffuse)

    glUniform1i(glGetUniformLocation(shader_program, "texture_specular"), 1)
    glActiveTexture(GL_TEXTURE1)
    glBindTexture(GL_TEXTURE_2D, texture_specular)
  • Vertex Shader
#version 330 core
layout (location = 0) in vec3 vin_pos;
layout (location = 1) in vec3 vin_normal;
layout (location = 2) in vec2 vin_uv;

out vec3 vout_surface_pos;
out vec3 vout_normal;
out vec2 vout_uv;

uniform mat4 MVP;
uniform mat4 M;

void main() {
    vec4 pos4 = vec4(vin_pos.xyz, 1.0);
    gl_Position = MVP * pos4;

    vout_surface_pos = vec3(M * pos4);
    vout_normal = normalize(mat3(transpose(inverse(M))) * vin_normal);
    vout_uv = vin_uv;
}
  • Fragment Shader
in vec2 vout_uv;

uniform sampler2D texture_diffuse;
uniform sampler2D texture_specular;

void main() {
    // ์žฌ์งˆ ์ƒ‰์ƒ ๊ณ„์‚ฐ ์˜ˆ์‹œ
    vec3 material_color = vec3(1.0, 0.0, 0.0); // ๊ธฐ๋ณธ๊ฐ’

    // ํ…์Šค์ฒ˜์—์„œ diffuse ์ƒ‰์ƒ ์ƒ˜ํ”Œ๋ง
    vec3 material_diffuse = vec3(texture(texture_diffuse, vout_uv));

    // ๋น„๊ธˆ์† ์žฌ์งˆ์—์„œ specular ์‚ฌ์šฉ ์˜ˆ์‹œ
    vec3 material_specular = vec3(texture(texture_specular, vout_uv));

    // ์ตœ์ข… ์ƒ‰์ƒ ์กฐํ•ฉ ์˜ˆ์‹œ
    FragColor = vec4(diffuse + specular, 1.0);
}
  • ํ๋ธŒ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” 12๊ฐœ์˜ ์‚ผ๊ฐํ˜•์— ๋Œ€ํ•ด vertex ๋ฐ์ดํ„ฐ ๊ตฌ์„ฑ
def prepare_vao_cube():
    vertices = glm.array(glm.float32,
        # pos        normal       texcoord
        -1, -1,  1,   0,  0,  1,   0, 0,  # v0
         1, -1,  1,   0,  0,  1,   1, 0,  # v1
         1,  1,  1,   0,  0,  1,   1, 1,  # v2
        -1, -1,  1,   0,  0,  1,   0, 0,  # v0
         1,  1,  1,   0,  0,  1,   1, 1,  # v2
        -1,  1,  1,   0,  0,  1,   0, 1,  # v3
        ...
    )
์ตœ๊ทผ ์ˆ˜์ •:: 25. 6. 19. ์˜คํ›„ 8:26
Contributors: kmbzn
Prev
11 - Curves

BUILT WITH

CloudflareNode.jsGitHubGitVue.jsJavaScriptVSCodenpm

All trademarks and logos are property of their respective owners.
ยฉ 2025 kmbzn ยท MIT License