ã€ã³ã¹ã¿ã³ã¹å
ãªããžã§ã¯ãã®èšå€§ãªæ°ã®ã¢ãã«ãå«ãã·ãŒã³ãæ³åããããã«ããããã®ã¢ãã«ã¯äž»ã«åãé ç¹ããŒã¿ãå«ã¿ãé©çšãããå€æãããªãã¯ã¹ã®ã¿ãç°ãªããšæ³åããŠãã ããã ããšãã°ãèå°ã®ããã·ãŒã³ã§ã¯ãèã®èã®ããããããæåéãäžè§åœ¢ã®ãã¢ã§æ§æãããå°ããªã¢ãã«ã§è¡šãããŸãã ãã¡ãããç®çã®å¹æãåŸãã«ã¯ããã®ã¢ãã«ã1åã§ã¯ãªãããã¬ãŒã ããšã«1äžåã1äžåã¬ã³ããªã³ã°ããå¿ èŠããããŸãã åèã«ã¯æåéãäžè§åœ¢ã®ãã¢ãå«ãŸããŠãããããã¬ã³ããªã³ã°ã¯ã»ãšãã©ç¬æã«è¡ãããŸãã ãã ããé¢æ°ãäžç·ã«ã¬ã³ããªã³ã°ããããã«äœååãç¹°ãè¿ãåŒã³åºããšãããã©ãŒãã³ã¹ãèããäœäžããŸãã
å
容
ããŒã1.ã¯ããã«
ããŒã2.åºæ¬çãªç §æ
ããŒã3. 3Dã¢ãã«ãããŠã³ããŒããã
ããŒã4.é«åºŠãªOpenGLæ©èœ
ããŒã5.é«åºŠãªç §æ
ããŒã6. PBR
- Opengl
- ãŠã£ã³ããŠäœæ
- ããã«ã¡ã¯ãŠã£ã³ããŠ
- ããã«ã¡ã¯ãã©ã€ã¢ã³ã°ã«
- ã·ã§ãŒããŒ
- ãã¯ã¹ãã£ãŒ
- å€æ
- 座æšç³»
- ã«ã¡ã©
ããŒã2.åºæ¬çãªç §æ
ããŒã3. 3Dã¢ãã«ãããŠã³ããŒããã
ããŒã4.é«åºŠãªOpenGLæ©èœ
- 深床ãã¹ã
- ã¹ãã³ã·ã«ãã¹ã
- è²æ··å
- é¡ã®ã¯ãªããã³ã°
- ãã¬ãŒã ãããã¡
- ãã¥ãŒããã¯ã«ãŒã
- é«åºŠãªããŒã¿åŠç
- é«åºŠãªGLSL
- 幟äœåŠã·ã§ãŒããŒ
- ã€ã³ã¹ã¿ã³ã¹å
- ã¹ã ãŒãžã³ã°
ããŒã5.é«åºŠãªç §æ
- é«åºŠãªç §æã Blinn-Fongã¢ãã«ã
- ã¬ã³ãè£æ£
- ã·ã£ããŠã«ãŒã
- å šæ¹åã·ã£ããŠããã
- æ³ç·ãããã³ã°
- èŠå·®ãããã³ã°
- HDR
- ãã«ãŒã
- é 延ã¬ã³ããªã³ã°
- SSAO
ããŒã6. PBR
説æããæ¹æ³ã§ã·ãŒã³ã«å€ãã®ãªããžã§ã¯ãã衚瀺ããããšãæ¬åœã«èšç»ããå Žåãã³ãŒãã§ã¯æ¬¡ã®ããã«ãªããŸãã
for (unsigned int ix = 0; ix < model_count; ++ix) { // VAO, , , ... DoSomePreparations(); glDrawArrays(GL_TRIANGLES, 0, vertex_count); }
åãã¢ãã«ã®è€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãã¬ã³ããªã³ã°ããå Žåãããã©ãŒãã³ã¹ã®ç¹ã§ããã«ããã¯ã«ããã«å°éããŸããããã¯ãããªããã£ãã¬ã³ããªã³ã°é¢æ°ã®å€ãã®åŒã³åºãã«ãªããŸãã çŽæ¥ã¬ã³ããªã³ã°ã«ãããââæéãšæ¯èŒããŠã glDrawArraysãglDrawElemenetsãªã©ã®é¢æ°ã䜿çšããŠäœããã¬ã³ããªã³ã°ããããšããããŒã¿ãGPUã«è»¢éãããšãããªãæéãããããŸãã ãã®æéã¯ãé ç¹ããŒã¿ãçŽæ¥åºåããåã«OpenGLãå¿ èŠãšããæºåã«è²»ããããŸããçŸåšã®ããŒã¿èªã¿åããããã¡ãŒãé ç¹å±æ§ããŒã¿ã®å Žæãšåœ¢åŒãªã©ã«é¢ããããŒã¿ãGPUã«è»¢éããŸãã ãããŠããã®ãã¹ãŠã®äº€æã¯ãCPUãšGPUãæ¥ç¶ããæ¯èŒçäœéã®ãã¹ã§å®è¡ãããŸãã é説çãªç¶æ³ããããŸããé ç¹ããŒã¿ã®ã¬ã³ããªã³ã°ã¯éåžžã«é«éã§ãããã¬ã³ããªã³ã°ã®ããã®ã³ãã³ãã®è»¢éã¯ããªãé ãã§ãã
å¿ èŠãªããŒã¿ããããªã«ãŒãã«1åéä¿¡ããŠãããOpenGLã«1åã®åŒã³åºãã§ãã®ããŒã¿ã䜿çšããŠå€ãã®ãªããžã§ã¯ããã¬ã³ããªã³ã°ããããã«äŸé Œã§ãããšäŸ¿å©ã§ãã ã€ã³ã¹ã¿ã³ã¹åã®äžçãžããããïŒ
ã€ã³ã¹ã¿ã³ã¹åãšã¯ãæç»é¢æ°ã®1åã®åŒã³åºãã§å€ãã®ãªããžã§ã¯ãã衚瀺ã§ããæè¡ã§ãã¬ã³ããªã³ã°äžã®äžå¿ èŠãªCPU-> GPU亀æããç§ãã¡ãæããŸãã ã€ã³ã¹ã¿ã³ã¹åã®äœ¿çšãéå§ããããã«å¿ èŠãªããšã¯ã glDrawArraysãšglDrawElemenetsã®åŒã³åºããããããglDrawArraysInstancedãšglDrawElementsInstancedã«å€æŽããããšã§ãã ã€ã³ã¹ã¿ã³ã¹åããµããŒãããããŒãžã§ã³ã¯ãéåžžã®ããŒãžã§ã³ã§ããç¥ãããŠããæ©èœã«å ããŠã1ã€ã®è¿œå ãã©ã¡ãŒã¿ãŒãåãå ¥ããŸãã ãã®ãã©ã¡ãŒã¿ãŒã¯ã€ã³ã¹ã¿ã³ã¹ã®æ°ãã€ãŸã ã¬ã³ããªã³ã°ããã¢ãã«ã®ã€ã³ã¹ã¿ã³ã¹ã®æ°ã ãããã£ãŠãäžåºŠã¬ã³ããªã³ã°ã«å¿ èŠãªãã¹ãŠã®ããŒã¿ãGPUã«äŸçµŠããç¹å¥ãªé¢æ°ã1ååŒã³åºãã ãã§ãç®çã®æ°ã®ãªããžã§ã¯ãã€ã³ã¹ã¿ã³ã¹ãã¬ã³ããªã³ã°ããæ¹æ³ãæå®ããŸãã ãŸãããããªã«ãŒãã¯ãCPUã«åžžã«ã¢ã¯ã»ã¹ããããšãªããå€ãã®ãªããžã§ã¯ãããã¹ãŠæç»ããŸãã
ãã®ãããªæ©äŒã¯ããèªäœã§ã¯ããŸã圹ã«ç«ã¡ãŸãããåãæ¹æ³ã§äœåãã®ãªããžã§ã¯ããåãäœçœ®ã«è¡šç€ºãããšã1ã€ã®ãªããžã§ã¯ãã®åãç»åã«ãªããŸãããã¹ãŠã®ã³ããŒãäºãã«éãåãããããŸãã ãã®åé¡ã解決ããããã«ãé ç¹ã·ã§ãŒããŒã§ã¯ãGLSL gl_InstanceIDçµã¿èŸŒã¿å€æ°ã䜿çšå¯èœã§ã ã
ã¬ã³ããªã³ã°ã®ã€ã³ã¹ã¿ã³ã¹åããµããŒãããé¢æ°ã䜿çšããå Žåããã®å€æ°ã®å€ã¯ã衚瀺ãããã€ã³ã¹ã¿ã³ã¹ããšã«1ãã€å¢å ãããŒãããå§ãŸããŸãã ãããã£ãŠããªããžã§ã¯ãã®43çªç®ã®ã€ã³ã¹ã¿ã³ã¹ãã¬ã³ããªã³ã°ãããšãé ç¹ã·ã§ãŒããŒã§gl_InstanceIDã42ã«ãªããŸããã€ã³ã¹ã¿ã³ã¹ã«å¯Ÿå¿ããäžæã®ã€ã³ããã¯ã¹ãããå Žåãããšãã°ãäœçœ®ãã¯ãã«ã®å€§ããªé åããéžæããŠã·ãŒã³ã®ç¹å®ã®å Žæã«åã€ã³ã¹ã¿ã³ã¹ãã¬ã³ããªã³ã°ã§ããŸãã
ã€ã³ã¹ã¿ã³ã¹åã®æ¬è³ªãããããç解ããããã«ã1åã®æç»åŒã³åºãã§ããã€ã¹ïŒNDCïŒã®æ£èŠåããã座æšã«100åã®åè§åœ¢ïŒåè§åœ¢ïŒãã¬ã³ããªã³ã°ããç°¡åãªäŸãèããŠã¿ãŸãããã ãªãã»ããã¯ããŠããã©ãŒã ïŒ100åã®ãªãã»ãããã¯ãã«ãå«ãé åïŒããã®éžæã䜿çšããŠæ±ºå®ãããŸãã çµæã¯ããŠã£ã³ããŠé åå šäœãåããé·æ¹åœ¢ã®ããŠããªã°ãªããã§ãã
åã¯ã¯ããã¯2ã€ã®äžè§åœ¢ã§æ§æããã6ã€ã®é ç¹ãæäŸããŸãã åé ç¹ã«ã¯ãNDCã®2ã³ã³ããŒãã³ãã®äœçœ®ãã¯ãã«ãšè²ãã¯ãã«ãå«ãŸããŠããŸãã äŸããã®é ç¹ããŒã¿ã以äžã«ç€ºããŸã-äžè§åœ¢ã®ãµã€ãºã¯ãç»é¢ã倧éã«æ£ããæºããã®ã«ååãªã»ã©å°ããéžæãããŸãã
float quadVertices[] = { // // -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, -0.05f, -0.05f, 0.0f, 0.0f, 1.0f, -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 0.05f, 0.05f, 0.0f, 1.0f, 1.0f };
ã¯ã¯ããã«ã©ãŒã¯ãã©ã°ã¡ã³ãã·ã§ãŒããŒã«ãã£ãŠæ±ºå®ãããŸãããã©ã°ã¡ã³ãã·ã§ãŒããŒã¯ãé ç¹ã·ã§ãŒããŒããååŸããè£éé ç¹ã«ã©ãŒãåºåå€æ°ã«çŽæ¥ãªãã€ã¬ã¯ãããŸãã
#version 330 core out vec4 FragColor; in vec3 fColor; void main() { FragColor = vec4(fColor, 1.0); }
ç§ãã¡ã«ãšã£ãŠæ°ãããã®ã¯ãããŸããã ããããé ç¹ã·ã§ãŒããŒã§ã¯ãç¶æ³ã¯ç°ãªããŸãïŒ
#version 330 core layout (location = 0) in vec2 aPos; layout (location = 1) in vec3 aColor; out vec3 fColor; uniform vec2 offsets[100]; void main() { vec2 offset = offsets[gl_InstanceID]; gl_Position = vec4(aPos + offset, 0.0, 1.0); fColor = aColor; }
ããã§ã¯ã100åã®ãªãã»ãããã¯ãã«ãå«ããªãã»ããåäžé åã宣èšããŸããã ã·ã§ãŒããŒã³ãŒãã§ã¯ã gl_InstanceIDå€æ°ã®å€ã«ãã£ãŠé åããååŸããããšã§ãªãã»ããå€ãååŸããŸãã ãã®çµæããã®ã·ã§ãŒããŒã䜿çšããŠãç»é¢äžã®ããŸããŸãªäœçœ®ã«ããæ°çŸã®ã¯ã¯ãããã¬ã³ããªã³ã°ã§ããŸãã
ãã ããè¿œå ã®äœæ¥ãå¿ èŠã«ãªããŸã-ãªãã»ããã®é åã ãã§ã¯ãã£ã±ãã«ãªããŸããã ã¡ã€ã³ã¬ã³ããªã³ã°ãµã€ã¯ã«ã«å ¥ãåã«ãã¢ããªã±ãŒã·ã§ã³ã«å ¥åããŸãã
glm::vec2 translations[100]; int index = 0; float offset = 0.1f; for(int y = -10; y < 10; y += 2) { for(int x = -10; x < 10; x += 2) { glm::vec2 translation; translation.x = (float)x / 10.0f + offset; translation.y = (float)y / 10.0f + offset; translations[index++] = translation; } }
ããã§ã¯ãåäžãª10x10ã°ãªãããå®çŸ©ãã100åã®è»¢éãã¯ãã«ãäœæãããŸãã
çæãããããŒã¿ãã·ã§ãŒããŒã®åäžãªé åã«è»¢éããããšãå¿ããªãã§ãã ããïŒ
shader.use(); for(unsigned int i = 0; i < 100; i++) { stringstream ss; string index; ss << i; index = ss.str(); shader.setVec2(("offsets[" + index + "]").c_str(), translations[i]); }
ãã®ã³ãŒãã§ã¯ãã«ãŒãå€æ°iãæåååã®å€æ°ã«å€æããŠããŠããã©ãŒã ã®ååã®æååãåçã«èšå®ãããã®ååã§ãŠããã©ãŒã ã®å ŽæãååŸã§ããããã«ããŸãã ãªãã»ããåäžé åã®åèŠçŽ ã«å¯ŸããŠã察å¿ããçæããããªãã»ãããã¯ãã«ãæž¡ããŸãã
C ++ 11以éã䜿çšå¯èœãªå Žåã¯ãstd :: to_stringïŒïŒã䜿çšããããšããå§ãããŸãã Note.perãæºåäœæ¥ãå®äºããã®ã§ãæçµçã«ã¬ã³ããªã³ã°ã«é²ãããšãã§ããŸãã ã€ã³ã¹ã¿ã³ãã¬ã³ãã©ãŒãåŒã³åºãã«ã¯ã glDrawArraysInstancedãŸãã¯glDrawElementsInstancedã䜿çšããå¿ èŠãããããšãæãåºãããŠãã ããã ãã®äŸã§ã¯ã€ã³ããã¯ã¹ãããã¡ã䜿çšããªãããã次ã®ã³ãŒãã䜿çšãããŸãã
glBindVertexArray(quadVAO); glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100);
ã¬ã³ããªã³ã°é¢æ°ã«æž¡ããããã©ã¡ãŒã¿ã¯ã glDrawArraysã«æž¡ããããã©ã¡ãŒã¿ãšåãã§ãããã ããæåŸã®ãã©ã¡ãŒã¿ã¯äŸå€ã§ãã¬ã³ããªã³ã°ããã€ã³ã¹ã¿ã³ã¹ã®åžææ°ãèšå®ããŸãã 10x10ã°ãªããã§100åã®ã¯ã¯ãããåºåãããã®ã§ã100ãæž¡ããŸããã³ãŒããå®è¡ãããšãæ°çŸã®ã«ã©ãã«ãªé·æ¹åœ¢ã§æ¢ã«éŠŽæã¿ã®ããç»åãåºåãããã¯ãã§ãã
ã€ã³ã¹ããŒã«ãããã¢ã¬ã€
åã®äŸã¯éåžžã«æ©èœããŠããããã®ã¿ã¹ã¯ã«å¯ŸåŠããŠããŸãã ããããåé¡ããããŸããé£æ¬²ãå¢ãã100ã³ããŒãã¯ããã«è¶ ããŠåŒãåºãããå Žåãã·ã§ãŒããŒã«éä¿¡ãããåäžããŒã¿ã®èš±å®¹éã®äžéã«ããã«å°éããŸãã ãŠããã©ãŒã ãä»ããŠããŒã¿ãæž¡ã代ããã«ã ã€ã³ã¹ã¿ã³ã¹åãããé åããããŸã ãããã¯é ç¹å±æ§ãšããŠèšå®ããããªããžã§ã¯ãã®ã¬ã³ããªã³ã°ãããã€ã³ã¹ã¿ã³ã¹ã®çŸåšã®ã€ã³ããã¯ã¹ãå€æŽããããšãã«ã®ã¿éžæãè¡ãããŸãã ãã®çµæãããã«ãããã¯ããã«å€§éã®ããŒã¿ããã䟿å©ãªæ¹æ³ã§è»¢éã§ããŸãã
éåžžã®é ç¹å±æ§ã®å ŽåãGLSLã¯é ç¹ã·ã§ãŒããŒã³ãŒãã®åŸç¶ã®å®è¡ããšã«æ°ããé ç¹ããŒã¿å€ããã§ããããŸãã ãã ããé ç¹å±æ§ãã€ã³ã¹ã¿ã³ã¹åãããé åãšããŠèšå®ãããšãGLSLã¯ããªããžã§ã¯ãã®æ¬¡ã®é ç¹ã§ã¯ãªãããªããžã§ã¯ãã®é£ç¶ããã€ã³ã¹ã¿ã³ã¹ããšã«æ°ããå±æ§å€ãéžæããŸãã ãã®çµæãåçŽã«è¡šç€ºãããããŒã¿ã«ã¯éåžžã®é ç¹å±æ§ã䜿çšãããªããžã§ã¯ãã€ã³ã¹ã¿ã³ã¹ã«åºæã®ããŒã¿ã«ã¯ã€ã³ã¹ã¿ã³ã¹åãããé åã䜿çšã§ããŸãã
ãããã©ã®ããã«æ©èœããããããããç解ããããã«ãåäžãªé åã®ä»£ããã«ã€ã³ã¹ã¿ã³ã¹åãããé åã䜿çšããããã«ãµã³ãã«ã³ãŒããå€æŽããŸãã æ°ããé ç¹å±æ§ãèšå®ããŠãã·ã§ãŒããŒã³ãŒããæŽæ°ããå¿ èŠããããŸãã
#version 330 core layout (location = 0) in vec2 aPos; layout (location = 1) in vec3 aColor; layout (location = 2) in vec2 aOffset; out vec3 fColor; void main() { gl_Position = vec4(aPos + aOffset, 0.0, 1.0); fColor = aColor; }
ããã§ã¯ã gl_InstanceIDå€æ°ã䜿çšãããé åããéžæããå¿ èŠãªãã offsetå±æ§ã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸãã
ã€ã³ã¹ã¿ã³ã¹åãããé åã®å®è£ ã¯ãåºæ¬çã«positionãcolorãªã©ã®é ç¹å±æ§ã«åºã¥ããŠãããããé ç¹ãããã¡ãŒãªããžã§ã¯ãã«ããŒã¿ãä¿åããé ç¹å±æ§ã®ãã€ã³ã¿ãŒãæ§æããå¿ èŠããããŸãã ãŸãã 翻蚳é åããŒã¿ãæ°ãããããã¡ãŒãªããžã§ã¯ãã«ä¿åããŸãã
unsigned int instanceVBO; glGenBuffers(1, &instanceVBO); glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 100, &translations[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0);
ãŸããé ç¹å±æ§ã®ãã€ã³ã¿ãŒãæ§æããå±æ§ãã¢ã¯ãã£ãã«ããŸãã
glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribDivisor(2, 1);
ãã®ã³ãŒãã¯ã glVertexAttribDivisorã®åŒã³åºãã®æåŸã®è¡ãé€ããŠããç¥ãããŠããŸã ã ãã®é¢æ°ã¯ãé ç¹å±æ§ããæ°ããèŠçŽ ãéžæããã¿ã€ãã³ã°ãOpenGLã«äŒããŸãã æåã®ãã©ã¡ãŒã¿ãŒã¯å¯Ÿè±¡ã®å±æ§ã®ã€ã³ããã¯ã¹ã§ã2çªç®ã¯å±æ§divisorã§ãã ããã©ã«ãã§ã¯ã0ã«èšå®ãããŸããããã¯ãé ç¹ã·ã§ãŒããŒã«ãã£ãŠåŠçãããæ°ããé ç¹ããšã«å±æ§ãæŽæ°ããããšã«å¯Ÿå¿ããŸãã ãã®ãã©ã¡ãŒã¿ãŒã1ã«èšå®ããããšã«ãããåŸç¶ã®åã€ã³ã¹ã¿ã³ã¹ãã¬ã³ããªã³ã°ãããšãã«å±æ§ãæŽæ°ããå¿ èŠãããããšãOpenGLã«éç¥ããŸãã åºåãæåã2ã«èšå®ããããšã«ããã2ã€ã®ã€ã³ã¹ã¿ã³ã¹ããšã«æŽæ°ãæäŸããŸãã å®éãã»ãã¬ãŒã¿ãŒã1ã«èšå®ãããšããã®ã»ãã¬ãŒã¿ãŒãæã€å±æ§ãã€ã³ã¹ã¿ã³ã¹åãããé åã«ãã£ãŠè¡šãããããšã瀺ããŸãã
glDrawArraysInstancedã䜿çšããŠã·ãŒã³ãæç»ãããšã次ã®å³ãåŸãããŸãã
ååãšãŸã£ããåãã§ãããã€ã³ã¹ã¿ã³ã¹åãããé åã䜿çšããŠå®è£ ãããŸããããã«ãããããå€ãã®ããŒã¿ãé ç¹ã·ã§ãŒããŒã«è»¢éããŠãã€ã³ã¹ã¿ã³ã¹åãããã¬ã³ããªã³ã°ãä¿èšŒã§ããŸãã
çŽç²ã«ãããããããå³äžé ããå·Šäžé ã®æ¹åã«åãã£ãŠãåã¯ã¯ãããåŸã ã«æžããããã«ããŸãã gl_InstanceIDå€æ°ãå床䜿çšããã®ã¯ããªãã§ããïŒ
void main() { vec2 pos = aPos * (gl_InstanceID / 100.0); gl_Position = vec4(pos + aOffset, 0.0, 1.0); fColor = aColor; }
ãã®çµæãæåã®ã³ããŒãå°ããã¬ã³ããªã³ã°ãããç»åãåŸãããŸãããã³ããŒæ°ã100ã«è¿ã¥ããšãåé·æ¹åœ¢ã®ãµã€ãºã¯å ã®ãµã€ãºã«è¿ã¥ããŸãã ã€ã³ã¹ã¿ã³ã¹åãããé åãšgl_InstanceIDã®ãã®å ±æã¯å®å šã«åãå ¥ããããŸãã
ã¬ã³ããªã³ã°ãããã¬ã³ããŒã®åäœåçãé©åã«ãã¹ã¿ãŒããŠããããšãçãå ŽåããŸãã¯ãµã³ãã«ã³ãŒãå šäœã®ããã€ã¹ã調ã¹ããå Žåã¯ããœãŒã¹ãããã«ãããŸã ã
ãã¡ãããããã¯ãã¹ãŠè¯ãããšã§ããããããã®äŸã¯ãã€ã³ã¹ã¿ã³ã¹åã®æ¬åœã®å©ç¹ã«ã€ããŠã¯ããããããŸããã ãã¡ãããæè¡çãªè©³çŽ°ã¯ããã«ç€ºãããŠããŸãããã€ã³ã¹ã¿ã³ã¹ã®æ¬è³ªã¯ã䌌ããããªãªããžã§ã¯ãã倧éã«ã¬ã³ããªã³ã°ããå Žåã«ã®ã¿æããã«ãªããŸããããã¯ãŸã å°éããŠããŸããã ãã®ããã次ã®ã»ã¯ã·ã§ã³ã§ã¯ãã€ã³ã¹ã¿ã³ã¹åã®çã®åãå人çã«ç¢ºèªããããã«ãå®å®ç©ºéã«ç§»åããå¿ èŠããããŸãã
å°ææãã£ãŒã«ã
巚倧ãªææãå°ææã®å·šå€§ãªãã«ãã«å²ãŸããŠããã·ãŒã³ãæ³åããŠãã ããã ãã®ãããªãã«ãã«ã¯ãæ°åãŸãã¯æ°äžã®å²©å±€ãå«ãŸããŠããå ŽåããããŸãã ãã®ãããªã·ãŒã³ã®çµè«ã¯ããããããããªã«ãŒãã§ã¯ã»ãšãã©äžå¯èœã«ãªããŸãã ãããããã®ã·ããªãªã§ã¯ããã«ãã®ãã¹ãŠã®å°ææãåäžã®ã¢ãã«ãšããŠè¡šçŸã§ãããããã€ã³ã¹ã¿ã³ã¹åã®äœ¿çšã瀺åãããŠããŸãã åå°ææã¯ããã®åºæã®å€æè¡åã«ãããé£æ¥ããå°ææãšãããã«ç°ãªããŸãã
ã€ã³ã¹ã¿ã³ã¹åã®ãã©ã¹ã®å¹æã瀺ãããã«ããŸããã®ã·ãŒã³ã䜿çšããã«åŒãåºãããšããŸãã ã·ãŒã³ã«ã¯å€§ããªææãå«ãŸãããã®ã¢ãã«ã¯ããããããŠã³ããŒãã§ããŸãããŸããææã®åšãã«ç¹å¥ã«é 眮ãããå°ææã®å€§ããªã»ãããå«ãŸããŸãã å°ææã¢ãã«ã¯ããããããŠã³ããŒãã§ããŸã ã
ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã§ã¯ãããŒããŒã䜿çšããŠã¢ãã«ã®ããŒã¿ãããŒãããŸããããã¯ã ã¢ããªã³ã°ã®ã¬ãã¹ã³ã§åæãããŸããã
ã·ãŒã³ã®å¿ èŠãªæ§æãå®çŸããããã«ãåå°ææã«åºæã®å€æãããªãã¯ã¹ãäœæããŸããããã¯ãåå°ææãã¬ã³ããªã³ã°ãããšãã«ã¢ãã«ãããªãã¯ã¹ãšããŠäœ¿çšãããŸãã ãããªãã¯ã¹ã¯ããã€ãã®æ®µéã§åœ¢æãããŸãã æåã«ã転éå€æãé©çšããŠãå°ææããªã³ã°å ã®ã©ããã«é 眮ããŸãã ãŸããå°ããªã©ã³ãã ãã€ã¢ã¹ãé©çšããŠãå°ææã®ååžã«ãªã¢ãªãºã ãè¿œå ããŸãã 次ã«ãã©ã³ãã ãªã¹ã±ãŒãªã³ã°ãšå転ãã¯ãã«ã®åšãã®å転ãè¿œå ãããŸãã ãã®çµæãåå°ææãææã®è¿ãã®ã©ããã«é 眮ããå€æè¡åãååŸããåæã«ãã®ãŠããŒã¯ãªå€èŠ³ãæäŸããŸãã ãããŠãå°ææ垯ã¯ãäºãã«ç°ãªãç³ã®å¡ã§æºããããŠããŸãã
unsigned int amount = 1000; glm::mat4 *modelMatrices; modelMatrices = new glm::mat4[amount]; srand(glfwGetTime()); // seed . float radius = 50.0; float offset = 2.5f; for(unsigned int i = 0; i < amount; i++) { glm::mat4 model(1.0f); // 1. : 'radius' // [-offset, offset] float angle = (float)i / (float)amount * 360.0f; float displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; float x = sin(angle) * radius + displacement; displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; // , XZ float y = displacement * 0.4f; displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; float z = cos(angle) * radius + displacement; model = glm::translate(model, glm::vec3(x, y, z)); // 2. : (0.05, 0.25f) float scale = (rand() % 20) / 100.0f + 0.05; model = glm::scale(model, glm::vec3(scale)); // 3. : float rotAngle = (rand() % 360); model = glm::rotate(model, rotAngle, glm::vec3(0.4f, 0.6f, 0.8f)); // 4. modelMatrices[i] = model; }
ãã®ã³ãŒãã®æçã¯æãããããã«èŠãããããããŸããããããã§ã¯ååŸradiusã§å®çŸ©ãããåã«æ²¿ã£ãŠåå°ææãXZå¹³é¢ã«é 眮ã ããã®åã«é¢ããŠïŒ -offset ã offset ïŒå ã«å°ããªã©ã³ãã ãªãã»ãããè¿œå ããŸãã Asterodianãªã³ã°ã«ãªã³ã°èªäœã®åœ¢ç¶ãäžããããã«ãY座æšãå°ãã ãå€æŽããŸãã ããã«ãã¹ã±ãŒãªã³ã°ãšå転ãé©çšãããçµæã¯ãéãšãšãã«ã modelMatricesãããªãã¯ã¹ã®é åã«æ ŒçŽãããŸãã ãã®äŸã§ã¯ãå°ææããšã«1ã€ã1000åã®ã¢ãã«è¡åãäœæãããŸãã
ææã¢ãã«ãšå°ææã¢ãã«ãããŒãããã·ã§ãŒããŒãã³ã³ãã€ã«ããåŸãã¬ã³ããªã³ã°ã³ãŒãã«é²ãããšãã§ããŸãã
// shader.use(); glm::mat4 model(1.0f); model = glm::translate(model, glm::vec3(0.0f, -3.0f, 0.0f)); model = glm::scale(model, glm::vec3(4.0f, 4.0f, 4.0f)); shader.setMat4("model", model); planet.Draw(shader); // for(unsigned int i = 0; i < amount; i++) { shader.setMat4("model", modelMatrices[i]); rock.Draw(shader); }
æåã«ãææã®ã¢ãã«ãæç»ããŸãããã®ã¢ãã«ã¯ãã·ãŒã³ã«åãŸãããã«ãããã«ã·ããããã³ã¹ã±ãŒãªã³ã°ããå¿ èŠããããŸãã 次ã«ãæºåãããå€æã®é åã®éã«çããéã®å°ææãã¬ã³ããªã³ã°ããŸãã åå°ææã®åºåã®åã«ã察å¿ããããŒã¿ãã¢ãã«è¡åãå«ããŠããã©ãŒã ã«è»¢éããå¿ èŠããããŸãã
å®å®ããã®åçã«äŒŒãåçã§ãå°ææ垯ã«å²ãŸããããªã説åŸåã®ããææããããŸãã
ãã®ã·ãŒã³ã¯ããã¬ãŒã ããšã«1001åã®ã¬ã³ããªã³ã°é¢æ°ã®åŒã³åºããå®è¡ãããã®ãã¡1000åã¯å°ææã¢ãã«ã«è©²åœããŸãã ãœãŒã¹ã¯ãã¡ãã§ãã
衚瀺ãããå°ææã®æ°ãå¢ããå§ãããšãã·ãŒã³ãã¹ã ãŒãºã«åæç»ãããªããªãã1ç§ãããã®ãã¬ãŒã æ°ãæ¥æ¿ã«äœäžããããšãããã«ããããŸãã 2000åã®å°ææãåãåºãããšãããšããã«ãã¬ã³ããªã³ã°ãéåžžã«åå¿ããªããªããåçŽã«ã·ãŒã³å ã移åããããšã¯ã»ãšãã©äžå¯èœã«ãªããŸãã
ã§ã¯ãåãããšãè©ŠããŠã¿ãŸãããããã ããã€ã³ã¹ã¿ã³ã¹åã䜿çšããŸãã ãŸããé ç¹ã·ã§ãŒããŒãå°ã調æŽããŸãã
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 2) in vec2 aTexCoords; layout (location = 3) in mat4 instanceMatrix; out vec2 TexCoords; uniform mat4 projection; uniform mat4 view; void main() { gl_Position = projection * view * instanceMatrix * vec4(aPos, 1.0); TexCoords = aTexCoords; }
ã¢ãã«ãããªãã¯ã¹ãå«ããŠããã©ãŒã ã¯äœ¿çšããªããªããŸããã 代ããã«ããããªãã¯ã¹ãæ ŒçŽããæ°ããé ç¹å±æ§ã宣èšããŸãããã®å±æ§ã«ãã€ã³ã¹ã¿ã³ã¹åãããå€æãããªãã¯ã¹ã®é åãé 眮ããŸãã vec4ãµã€ãºãè¶ ããã¿ã€ããµã€ãºã§é ç¹å±æ§ãæå®ããå Žåã1ã€ã®ç¹æ§ãèæ ®ããå¿ èŠãããããšã«æ³šæããŠãã ããã mat4ã¯åºæ¬çã«4ã€ã®æ¥ç¶ãããvec4sã§ããããããã®å±æ§ã§ã¯ãé ç¹å±æ§ã®äœçœ®ïŒ location ïŒã®ã€ã³ããã¯ã¹ãæ倧 4ã€äºçŽãããŸãã ããã§ãå±æ§ã«é 眮ã€ã³ããã¯ã¹3ãå²ãåœãŠãŸãããããã¯ããããªãã¯ã¹ã®åã3ã4ã5ãããã³6ã®é 眮ã€ã³ããã¯ã¹ãåãåãããšãæå³ããŸãã
ã¯ã©ã€ã¢ã³ãã³ãŒãã§ã¯ããããã®æé»çã«æå®ãããåäœçœ®ã€ã³ããã¯ã¹ã®é ç¹å±æ§ãžã®ãã€ã³ã¿ãŒãèšå®ããå¿ èŠããããŸãã ãããŠããããã®ãããããã€ã³ã¹ã¿ã³ã¹åãããé åãšããŠåæåããããšãå¿ããªãã§ãã ããïŒ
// VBO unsigned int buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &modelMatrices[0], GL_STATIC_DRAW); for(unsigned int i = 0; i < rock.meshes.size(); i++) { unsigned int VAO = rock.meshes[i].VAO; glBindVertexArray(VAO); // GLsizei vec4Size = sizeof(glm::vec4); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)0); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(vec4Size)); glEnableVertexAttribArray(5); glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(2 * vec4Size)); glEnableVertexAttribArray(6); glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(3 * vec4Size)); glVertexAttribDivisor(3, 1); glVertexAttribDivisor(4, 1); glVertexAttribDivisor(5, 1); glVertexAttribDivisor(6, 1); glBindVertexArray(0); }
ããã§ã VAOãMeshã¯ã©ã¹ã®ãã©ã€ããŒãå€æ°ã§ã¯ãªããããªãã¯ãšããŠå®£èšããããšã§ãå°ãããŸãããããšã«æ³šæããŠãã ãããããã«ãããé ç¹é åãªããžã§ã¯ããžã®ã¢ã¯ã»ã¹ãç°¡åã«ãªããŸããã ããã¯æããšã¬ã¬ã³ãã§ããããªãœãªã¥ãŒã·ã§ã³ã§ã¯ãªããããããŸããããç°¡åãªäŸã®ããŒãºã®ããã«ããã¯ããŸãã ãã®å°ããªããã¯ã«å ããŠãæ®ãã®ã³ãŒãã¯æ確ã«ããå¿ èŠããããŸãã ããã§ã¯ããããªãã¯ã¹ã§è¡šãããé ç¹å±æ§ã®åèŠçŽ ã«ã€ããŠãOpenGLããããã¡ãŒã®å 容ãã©ã®ããã«è§£éããããåã«ç€ºããŸãã ãŸãããããã®åå±æ§ãã€ã³ã¹ã¿ã³ã¹åãããé åã§ããããšã瀺ããŸãã
次ã«ã VAOã§æºåãããã¢ãã«ã«æ»ã ãã¬ã³ããªã³ã°ãåŒã³åºããŸãã
// draw meteorites instanceShader.use(); for(unsigned int i = 0; i < rock.meshes.size(); i++) { glBindVertexArray(rock.meshes[i].VAO); glDrawElementsInstanced( GL_TRIANGLES, rock.meshes[i].indices.size(), GL_UNSIGNED_INT, 0, amount ); }
ããã§ã¯ãåã®äŸãšåãæ°ã®å°ææã§ã¬ã³ããªã³ã°ãå®è¡ãããŸãããçŸåšã¯ã€ã³ã¹ã¿ã³ã¹åã䜿çšãããŠããŸãã èŠèŠçã«ã¯ãçµæã¯äŒŒãŠããŸããäž»ãªéãã¯ãå°ææã®æ°ã®å¢å ã«çŸããŸããã€ã³ã¹ã¿ã³ã¹åããã«ã1000ãã1500å°ææã®ç¯å²ã§ãããªã«ãŒãããæ»ãããªã¬ã³ããªã³ã°ãçµãããšãã§ããŸããã€ã³ã¹ã¿ã³ã¹ã䜿çšãããšãä¿¡ããããªãã»ã©ã®100,000åã®å°ææãŸã§å·éã«ã¬ãã«ãäžããããšãã§ããŸããããããã«576åã®é ç¹ãå«ãŸããŠãããããããã©ãŒãã³ã¹ãäœäžãããããšãªããçŽ5,700äžåã®åŠçæžã¿é ç¹ãååŸã§ããŸãã
ãã®ç»åã¯ãå€æ°radius = 150.0fããã³offset = 25.0fã®100,000åã®å°ææã®åºåã§ååŸãããŸããããœãŒã¹ã³ãŒãã¯ãã¡ãã§ãã
äœæ¥ãã·ã³ã®æ§æã¯ã ãããç°ãªãããã100,000ã®å¶éã¯å€å°æ¥œèŠ³çãããããŸããããã¬ãŒã ã¬ãŒãã蚱容ç¯å²å ã«åãŸãããã«ãç¹å®ã®æ°å€ã調æŽããŠã¿ãŠãã ãããã芧ã®ãšãããç¹å®ã®ã¿ã¹ã¯ã§ã¯ãã€ã³ã¹ã¿ã³ã¹åã«ããããã©ãŒãã³ã¹ãå€§å¹ ã«åäžããå ŽåããããŸãããã®ããããã®ææ³ã䜿çšããŠãèãæ€ç©ãããŒãã£ã¯ã«ã·ã¹ãã ãããã³ã¬ãã¹ã³ã§ç€ºãããã®ã«é¡äŒŒããä»ã®ã·ãŒã³ãã¬ã³ããªã³ã°ããŸãã
PS ïŒè»¢éã調æŽããããã®é»å ±confããããŸãã 翻蚳ãæäŒããããšããçå£ãªé¡æãããã°ã倧æè¿ã§ãïŒ