
å
šæ¹åã·ã£ããŠããã
åã®ã¬ãã¹ã³ã§ã¯ãåçãªæåœ±ã·ã£ããŠãäœæããæ¹æ³ãèŠã€ããŸããã ãã®ææ³ã¯ããŸãæ©èœããŸãããæ®å¿µãªããšã«ãã·ã£ããŠãããã¯å
æºã®æ¹åã«äžèŽãã1ã€ã®æ¹åã§äœæããããããæåæ§å
æºã«ã®ã¿é©ããŠããŸãã ããããæ·±åºŠãããïŒã·ã£ããŠãããïŒãå
æºã®æ¹åã«æ£ç¢ºã«æ²¿ã£ãŠäœæãããããããã®ææ³ãæ¹åã·ã£ããŠããããšãåŒã°ããçç±ã§ãã
ãã®ã¬ãã¹ã³ã¯ãããããæ¹åã«æåœ±ããåçãªåœ±ãäœæããããšã«å°å¿µããŸãã ãã®ã¢ãããŒãã¯ãã¹ãããã©ã€ããäžåºŠã«ãã¹ãŠã®æ¹åã«æåœ±ããå¿
èŠããããããã¹ãããã©ã€ãã§ã®äœæ¥ã«æé©ã§ãã ãããã£ãŠããã®ææ³ã¯
å
šæ¹åã·ã£ããŠããããšåŒã°ã
ãŸã ã
ãã®ã¬ãã¹ã³ã¯ã åã®ã¬ãã¹ã³ã®è³æã«å€§ããäŸåããŠãããããéåžžã®ã·ã£ããŠãããã䜿çšããŠããªãå Žåã¯ããã®èšäºã®åŠç¿ãç¶ããåã«ãããè¡ãå¿
èŠããããŸãã
äžè¬ã«ãæäœã¢ã«ãŽãªãºã ã¯æå圱ã®å Žåãšã»ãŒåãã§ããå
æºã®èŠç¹ããæ·±åºŠããããäœæããåãã©ã°ã¡ã³ãã«ã€ããŠæ·±åºŠã®å€ãæ¯èŒããæ·±åºŠãããããèªã¿åããŸãã 䜿çšãããæ·±åºŠãããã®ã¿ã€ãã«ãããæåæ§ã¢ãããŒããšå
šæ¹åæ§ã¢ãããŒãã®äž»ãªéãã
å¿
èŠãªã·ã£ããŠãããã«ã¯ãå
æºã®åšå²ã®ãã¹ãŠã®æ¹åã«ã·ãŒã³ãã¬ã³ããªã³ã°ããå¿
èŠããããéåžžã®2Dãã¯ã¹ãã£ã¯ããã§ã¯è¯ããããŸããã ã ããå€å
ç«æ¹ãããã䜿çšã
ãŸããïŒ ç«æ¹äœãããã¯6ã€ã®é¢ã ãã§ç°å¢ããŒã¿ãä¿åã§ããããããããã®åé¢ã«ã·ãŒã³å
šäœãæç»ããç«æ¹äœãããããæ·±åºŠãéžæã§ããŸãã
äœæããããã¥ãŒããã¯ã·ã£ããŠãããã¯ãæçµçã«ãã©ã°ã¡ã³ãã·ã§ãŒããŒã§çµäºããæ¹åãã¯ãã«ã䜿çšããŠãµã³ããªã³ã°ãããŠãïŒãœãŒã¹ã®èŠç¹ããïŒãã©ã°ã¡ã³ã深床å€ãååŸããŸãã åã®ã¬ãã¹ã³ã§æè¡çã«è€éãªè©³çްã®ã»ãšãã©ãæ¢ã«èª¬æããã®ã§ã1ã€ã®åŸ®åŠãªç¹ãæ®ã£ãŠããŸã-3次ãããã䜿çšããŸãã
ç«æ¹äœããããäœæãã
å
æºã®æ·±åºŠãæ ŒçŽããç«æ¹äœããããäœæããã«ã¯ããããã®åé¢ã«1åãã€ãã·ãŒã³ã6åã¬ã³ããªã³ã°ããå¿
èŠããããŸãã ãããè¡ãïŒæãããªïŒæ¹æ³ã®1ã€ã¯ã6ã€ã®ç°ãªããã¥ãŒãããªãã¯ã¹ã䜿çšããŠã·ãŒã³ã6ååçŽã«æç»ããåãã¹ã§ãã¥ãŒããã¯ãããã®åå¥ã®é¢ããã¬ãŒã ãããã¡ãŒãªããžã§ã¯ãã®è²ã«æ¥ç¶ããããšã§ãã
for(unsigned int i = 0; i < 6; i++) { GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, face, depthCubemap, 0); BindViewMatrix(lightViewMatrices[i]); RenderScene(); }
ãã®ã¢ãããŒãã¯ãåäžã®ã·ã£ããŠããããäœæããããã«å€ãã®æç»åŒã³åºããè¡ããããããããã©ãŒãã³ã¹ãéåžžã«é«ããªããŸãã ã¬ãã¹ã³ã§ã¯ã幟äœåŠçã·ã§ãŒããŒã®äœ¿çšã«é¢é£ããå°ããªããªãã¯ã䜿çšããŠãããæé©ãªã¢ãããŒããå®è£
ããããšããŸãã ããã«ããã1åã®ãã¹ã§ãã¥ãŒããã¯æ·±åºŠããããäœæãããŸãã
æåã«ããã¥ãŒããã¯ããããäœæããŸãã
unsigned int depthCubemap; glGenTextures(1, &depthCubemap);
ãããŠãåé¢ãæ·±ãã®å€ãä¿åãã2Dãã¯ã¹ãã£ãšããŠèšå®ããŸãã
const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap); for (unsigned int i = 0; i < 6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
ãŸããé©åãªãã¯ã¹ãã£ãã©ã¡ãŒã¿ãèšå®ããããšãå¿ããªãã§ãã ããã
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
éåžžã®ã¢ãããŒãã§ã¯ããã¥ãŒããã¯ãããã®åé¢ããã¬ãŒã ãããã¡ãŒã«æ¥ç¶ããåãã¹ã§ã·ãŒã³ã6åã¬ã³ããªã³ã°ãããã¬ãŒã ãããã¡ãŒã®æ·±åºŠã¢ã¿ããã¡ã³ãã«æ¥ç¶ããããã¥ãŒããã¯ãããã®é¢ã眮ãæããŸãã ãã ãããžãªã¡ããªã·ã§ãŒããŒã䜿çšãããšã1åã®ãã¹ã§äžåºŠã«ãã¹ãŠã®åŽé¢ã«ã·ãŒã³ãæã¡èŸŒãããšãã§ãããããç«æ¹äœããããæ·±åºŠã¢ã¿ããã¡ã³ãã«çŽæ¥æ¥ç¶ããŸãã
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubemap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0);
ç¹°ãè¿ãã«ãªããŸããã
glDrawBufferãš
glReadBufferã®åŒã³åºãã«æ³šæããŠãã ãããæ·±åºŠã®å€ã®ã¿ãéèŠã§ãããããOpenGLã«ã«ã©ãŒãããã¡ãŒã«æžã蟌ãããšãã§ããªãããšãæç€ºçã«äŒããŸãã
æçµçã«ã2ã€ã®ãã¹ãããã«é©çšãããŸããæåã«ã·ã£ããŠããããæºåãããæ¬¡ã«ã·ãŒã³ãæç»ããããããã䜿çšããŠã·ã§ãŒãã£ã³ã°ãäœæãããŸãã ãã¬ãŒã ãããã¡ãŒãšãã¥ãŒããã¯ãããã䜿çšãããšãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
æåã®è¿äŒŒã§ã¯ãããã»ã¹ã¯æ¹åã·ã£ããŠãããã䜿çšããå Žåãšåãã§ãã å¯äžã®éãã¯ãéåžžã®2Dãã¯ã¹ãã£ã§ã¯ãªããç«æ¹æ·±åºŠãããã«ã¬ã³ããªã³ã°ããããšã§ãã
ãœãŒã¹ãåºæºãšããæ¹åããã·ãŒã³ã®çŽæ¥ã¬ã³ããªã³ã°ãéå§ããåã«ãé©åãªå€æãããªãã¯ã¹ãæºåããå¿
èŠããããŸãã
å
æºåº§æšç³»ã«å€æ
æºåããããã¬ãŒã ãããã¡ãªããžã§ã¯ããšãã¥ãŒããã¯ãããã䜿çšããŠããã¹ãŠã®ã·ãŒã³ãªããžã§ã¯ããå
æºããã®6ã€ã®æ¹åãã¹ãŠã«å¯Ÿå¿ãã座æšç©ºéã«å€æããåé¡ã«ç§»ããŸãã
åã®ã¬ãã¹ã³ãšåãæ¹æ³ã§å€æè¡åãäœæããŸãããä»åã¯åé¢ã«åå¥ã®è¡åãå¿
èŠã§ãã
ãœãŒã¹ç©ºéãžã®åæçµå€æã«ã¯ãå°åœ±è¡åãšçš®è¡åã®äž¡æ¹ãå«ãŸããŸãã å°åœ±è¡åã®å ŽåãéèŠæåœ±è¡åã䜿çšããŸãããœãŒã¹ã¯ç©ºéå
ã®ãã€ã³ããªã®ã§ãéèŠæåœ±ã¯ããã§æé©ã§ãã ãã®ãããªãã¯ã¹ã¯ããã¹ãŠã®æçµçãªå€æã§åãã«ãªããŸãã
float aspect = (float)SHADOW_WIDTH/(float)SHADOW_HEIGHT; float near = 1.0f; float far = 25.0f; glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), aspect, near, far);
éèŠãªç¹ã«æ³šæããŠãã ããïŒãããªãã¯ã¹åœ¢æäžã®èŠéè§ã®ãã©ã¡ãŒã¿ãŒã¯90°ã«èšå®ãããŸãã ãã®èŠè§ã®å€ã«ãããç«æ¹äœãããã®é¢ãæ£ç¢ºã«å¡ãã€ã¶ããŠã®ã£ãããªãã§åæã§ããããã«ããæåœ±æ³ãæäŸãããŸãã
å°åœ±è¡åã¯äžå®ã®ãŸãŸãªã®ã§ãåãè¡åãåå©çšããŠãæçµçãªå€æã®6ã€ã®è¡åãã¹ãŠãäœæã§ããŸãã ãã ããçš®ãããªãã¯ã¹ã¯ãåãã¡ã»ããã«åºæã®ãã®ãå¿
èŠã§ãã
glm :: lookAtã䜿çšããŠã次ã®é åºã§6ã€ã®æ¹åã衚ã6ã€ã®è¡åãäœæããŸãïŒå³ãå·Šãäžãäžãé¡ã«è¿ããé ãåŽïŒ
std::vector<glm::mat4> shadowTransforms; shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 1.0, 0.0, 0.0), glm::vec3(0.0,-1.0, 0.0)); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0,-1.0, 0.0)); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0,-1.0, 0.0), glm::vec3(0.0, 0.0,-1.0)); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0, 0.0, 1.0), glm::vec3(0.0,-1.0, 0.0)); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0, 0.0,-1.0), glm::vec3(0.0,-1.0, 0.0));
äžèšã®ã³ãŒãã§ã¯ãäœæããã6ã€ã®ãã¥ãŒãããªãã¯ã¹ã«æåœ±ãããªãã¯ã¹ãä¹ç®ããŠãå
æºã®ç©ºéã«å€æãã6ã€ã®äžæã®ãããªãã¯ã¹ãæå®ããŠããŸãã
glm :: lookAtã®åŒã³åºãã®
ã¿ãŒã²ãããã©ã¡ãŒã¿ãŒã¯ããã¥ãŒããã¯ãããã®åé¢ãèŠãæ¹åã衚ããŸãã
ããã«ããã®è¡åã®ãªã¹ãã¯ããã¥ãŒããã¯æ·±åºŠããããã¬ã³ããªã³ã°ãããšãã«ã·ã§ãŒããŒã«æž¡ãããŸãã
ããã¹ã·ã§ãŒããŒ
ç«æ¹äœãããã«æ·±åºŠãæžã蟌ãã«ã¯ãé ç¹ããã©ã°ã¡ã³ããããã³ãããã®ã¹ããŒãžéã§å®è¡ããã远å ã®ãžãªã¡ããªã®3ã€ã®ã·ã§ãŒããŒã䜿çšããŸãã
ã¯ãŒã«ã空éã®ãã¹ãŠã®é ç¹ãå
æºã®6ã€ã®åå¥ã®ç©ºéã«å€æããã®ã¯ããžãªã¡ããªã·ã§ãŒããŒã§ãã ãããã£ãŠãé ç¹ã·ã§ãŒããŒã¯ç°¡åã§ã幟äœåŠçã·ã§ãŒããŒã«éãããã¯ãŒã«ã空éã®é ç¹ã®åº§æšãåçŽã«æäŸããŸãã
#version 330 core layout (location = 0) in vec3 aPos; uniform mat4 model; void main() { gl_Position = model * vec4(aPos, 1.0); }
ãžãªã¡ããªã·ã§ãŒããŒã¯ãå
¥åã§äžè§åœ¢ã®3ã€ã®é ç¹ãšãå
æºã®ç©ºéãžã®å€æè¡åã®é
åãæã€ãŠããã©ãŒã ãåãåããŸãã ããã«è峿·±ãç¹ããããŸããã¯ãŒã«ã座æšãããœãŒã¹ç©ºéãžã®é ç¹ã®å€æãåŠçããã®ã¯å¹ŸäœåŠçã·ã§ãŒããŒã§ãã
ãžãªã¡ããªã·ã§ãŒããŒã®å Žåãçµã¿èŸŒã¿å€æ°
gl_Layerã䜿çšã§ããŸã ãããã¯ãã·ã§ãŒããŒãããªããã£ãã圢æãããã¥ãŒããã¯ãããã®é¢çªå·ãèšå®ããŸãã éåžžã®ç¶æ³ã§ã¯ãã·ã§ãŒããŒã¯ã¢ã¯ã·ã§ã³ãªãã§ãã€ãã©ã€ã³ã«ãã¹ãŠã®ããªããã£ããéä¿¡ããŸãã ãããããã®å€æ°ã®å€ã倿Žããããšã«ãããåŠçãããåããªããã£ãã3次ãããã®ã©ã®é¢ã«ã¬ã³ããªã³ã°ããããå¶åŸ¡ã§ããŸãã ãã¡ãããããã¯ãã¥ãŒããã¯ã«ãŒãããã¬ãŒã ãããã¡ã«æ¥ç¶ãããŠããå Žåã«ã®ã¿æ©èœããŸãã
#version 330 core layout (triangles) in; layout (triangle_strip, max_vertices=18) out; uniform mat4 shadowMatrices[6];
衚瀺ãããã³ãŒãã¯éåžžã«ç°¡åã§ãã ã·ã§ãŒããŒã¯ãå
¥åã§äžè§åœ¢ã¿ã€ãã®ããªããã£ããåãåããçµæãšããŠ6ã€ã®äžè§åœ¢ïŒ6 * 3 = 18é ç¹ïŒãçæããŸãã ã¡ã€ã³é¢æ°ã§ã¯ããã¥ãŒããã¯ãããã®6ã€ã®é¢ãã¹ãŠãã«ãŒãããçŸåšã®ã€ã³ããã¯ã¹ãã
gl_Layer倿°ã®å¯Ÿå¿ãããšã³ããªãæã€ãã¥ãŒããã¯ãããã®ã¢ã¯ãã£ããªé¢ã®çªå·ãšããŠèšå®ããŸãã ãŸããåå
¥åé ç¹ãã¯ãŒã«ã座æšç³»ããç«æ¹äœã¢ãŒãã®çŸåšã®é¢ã«å¯Ÿå¿ããå
æºã®ç©ºéã«å€æããŸãã ãããè¡ãã«ã¯ãFragPosã«shadowMatrices
åäžé
åããã®é©åãªå€æè¡åãä¹ç®ããŸãã
FragPoså€
ã¯ãã©ã°ã¡ã³ãã·ã§ãŒããŒã«ãæž¡ããããã©ã°ã¡ã³ãã®æ·±ããèšç®ãããããšã«æ³šæããŠãã ããã
ååã®ã¬ãã¹ã³ã§ã¯ã空ã®ãã©ã°ã¡ã³ãã·ã§ãŒããŒã䜿çšããOpenGLèªäœã¯ã·ã£ããŠãããã®æ·±åºŠã®èšç®ã«å¿ããã£ãã ä»åã¯ããã©ã°ã¡ã³ãã®äœçœ®ãšå
æºã®éã®è·é¢ãåºæºãšããŠãç·åœ¢æ·±åºŠå€ãæåã§äœæããŸãã æ·±åºŠå€ã®ãã®ãããªèšç®ã«ãããåŸç¶ã®ã·ã§ãŒãã£ã³ã°èšç®ãããå°ãçŽæçã«ãªããŸãã
#version 330 core in vec4 FragPos; uniform vec3 lightPos; uniform float far_plane; void main() {
ãžãªã¡ããªã·ã§ãŒããŒã®
FragPos倿°ããœãŒã¹äœçœ®ãã¯ãã«ãããã³å
æºã®æåœ±ã®ãã©ãããã®ãã¡ãŒã¯ãªããã³ã°ãã¬ãŒã³ãŸã§ã®è·é¢ã¯ããã©ã°ã¡ã³ãã·ã§ãŒããŒã®å
¥åã«
å°éããŸãã ãã®ã³ãŒãã§ã¯ããã©ã°ã¡ã³ããšãœãŒã¹éã®è·é¢ãèšç®ããå€ã®ç¯å²[0.ã1.]ã«ç§»åããŠãã·ã§ãŒããŒã®çµæãšããŠæžã蟌ã¿ãŸãã
ãããã®ã·ã§ãŒããŒãšãã¬ãŒã ãããã¡ãŒãªããžã§ã¯ãã«æ¥ç¶ããããã¥ãŒããã¯ããããæã€ã·ãŒã³ã¬ã³ãã©ãŒã¯ã次ã®ã¬ã³ããŒãã¹ã§äœ¿çšããããã«å®å
šã«æºåãããã·ã£ããŠããããçæããå¿
èŠããããŸãã
å
šæ¹åã·ã£ããŠããã
ãã¹ãŠãæºåã§ããããå
šæ¹åã·ã£ããŠã®çŽæ¥ã¬ã³ããªã³ã°ã«é²ãããšãã§ããŸãã æé ã¯ãæ¹åæ§ã·ã£ããŠã®åã®ã¬ãã¹ã³ã§ç€ºããæé ãšäŒŒãŠããŸãããä»åã¯æ·±åºŠããããšããŠ2次å
ãã¯ã¹ãã£ã®ä»£ããã«ç«æ¹äœãã¯ã¹ãã£ã䜿çšããå
æºã®æåœ±ãã©ãããã®é æ¹é¢ã®å€ãæã€ãŠããã©ãŒã ãã·ã§ãŒããŒã«è»¢éããŸãã
glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader.use();
ãã®äŸã§ã¯ãrenderScene颿°ã¯å€§ããªç«æ¹äœã®éšå±ã«ããããã€ãã®ç«æ¹äœã衚瀺ããã·ãŒã³ã®äžå€®ã«ããå
æºãã圱ãèœãšããŸãã
é ç¹ã·ã§ãŒããŒãšãã©ã°ã¡ã³ãã·ã§ãŒããŒã¯ãæ¹åæ§ã·ã£ããŠã®ã¬ãã¹ã³ã§èª¬æãããã®ãšã»ãšãã©åãã§ãã ãã©ã°ã¡ã³ãã·ã§ãŒããŒã§ã¯ãã·ã£ããŠãããããã®éžæãæ¹åãã¯ãã«ã䜿çšããŠè¡ãããããã«ãªã£ããããå
æºã®ç©ºéã«ããããã©ã°ã¡ã³ãã®äœçœ®ã®å
¥åãã©ã¡ãŒã¿ãŒã¯äžèŠã«ãªããŸããã
é ç¹ã·ã§ãŒããŒã¯ãããããäœçœ®ãã¯ãã«ãå
æºã®ç©ºéã«å€æããå¿
èŠããªãããã
FragPosLightSpace倿°ãæšãŠãããšã
ã§ããŸãã
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal; layout (location = 2) in vec2 aTexCoords; out vec2 TexCoords; out VS_OUT { vec3 FragPos; vec3 Normal; vec2 TexCoords; } vs_out; uniform mat4 projection; uniform mat4 view; uniform mat4 model; void main() { vs_out.FragPos = vec3(model * vec4(aPos, 1.0)); vs_out.Normal = transpose(inverse(mat3(model))) * aNormal; vs_out.TexCoords = aTexCoords; gl_Position = projection * view * model * vec4(aPos, 1.0); }
ãã©ã°ã¡ã³ãã·ã§ãŒããŒã®Blinn-Fongã©ã€ãã£ã³ã°ã¢ãã«ã³ãŒãã¯å€æŽããããæåŸã«ã·ã§ãŒãã£ã³ã°ä¿æ°ã«ããä¹ç®ãæ®ããŸãã
#version 330 core out vec4 FragColor; in VS_OUT { vec3 FragPos; vec3 Normal; vec2 TexCoords; } fs_in; uniform sampler2D diffuseTexture; uniform samplerCube depthMap; uniform vec3 lightPos; uniform vec3 viewPos; uniform float far_plane; float ShadowCalculation(vec3 fragPos) { [...] } void main() { vec3 color = texture(diffuseTexture, fs_in.TexCoords).rgb; vec3 normal = normalize(fs_in.Normal); vec3 lightColor = vec3(0.3);
ãŸããããã€ãã®åŸ®åŠãªéãã«ã泚æããŠãã ãããç
§æã¢ãã«ã®ã³ãŒãã¯å®éã«ã¯å€æŽãããŠããŸãããã
samplerCubemapã¿ã€ãã
䜿çšãã ã
ShadowCalculation颿°ã¯å
æºã®ã¹ããŒã¹ã§ã¯ãªãã¯ãŒã«ã座æšã§ãã©ã°ã¡ã³ãã®åº§æšã
ååŸããŸãã ãŸãããããªãèšç®ã§
far_planeå
æºæåœ±ãã©ããããã©ã¡ãŒã¿ãŒã䜿çšããŸãã ã·ã§ãŒããŒã®æåŸã§ãã·ã§ãŒãã£ã³ã°ãã¡ã¯ã¿ãŒãèšç®ããŸããããã¯ããã©ã°ã¡ã³ããã·ã£ããŠå
ã«ããå Žåã¯1ã§ãã ãŸãã¯ããã©ã°ã¡ã³ããã·ã£ããŠã®å€åŽã«ããå Žåã¯0ã ãã®ä¿æ°ã¯ãç
§æã®æ¡æ£ããã³ãã©ãŒã³ã³ããŒãã³ãã®æºåå€ã«åœ±é¿ãäžããããã«äœ¿çšãããŸãã
æå€§ã®å€æŽç¹ã¯ã
ShadowCalculation颿°ã®æ¬äœã«
é¢ä¿ããŸããããã§ã¯ã深床å€ã2Dãã¯ã¹ãã£ã§ã¯ãªããã¥ãŒããã¯ãããããéžæãããããã«ãªããŸããã ãã®é¢æ°ã®ã³ãŒããé çªã«åæããŠã¿ãŸãããã
æåã®ã¹ãããã¯ããã¥ãŒããã¯ãããããçŽæ¥ã®æ·±åºŠå€ãååŸããããšã§ãã èŠããŠããããã«ããã¥ãŒããã¯ãããã®æºåã§ã¯ããã®æ·±ããæžãçããŸãããããã¯ããã©ã°ã¡ã³ããšå
æºã®éã®è·é¢ãšããŠè¡šãããŸãã åãã¢ãããŒããããã§äœ¿çšãããŸãïŒ
float ShadowCalculation(vec3 fragPos) { vec3 fragToLight = fragPos - lightPos; float closestDepth = texture(depthMap, fragToLight).r; }
ãã©ã°ã¡ã³ãã®äœçœ®ãšå
æºã®éã®å·®ãã¯ãã«ãèšç®ããããã¥ãŒããã¯ãããããã®ãµã³ããªã³ã°ã®æ¹åãã¯ãã«ãšããŠäœ¿çšãããŸãã æãåºãããã«ããã¥ãŒããã¯ãããããã®ãµã³ãã«ãã¯ãã«ã¯åäœé·ããæã€å¿
èŠã¯ãªãããããæ£èŠåããå¿
èŠã¯ãããŸããã çµæãšããŠæãè¿ã
DepthDepthå€ã¯ãå
æºã«å¯ŸããŠæãè¿ãå¯èŠãã©ã°ã¡ã³ãã®æ£èŠåãããæ·±åºŠå€ã§ãã
nearestDepthã®å€ã¯åºé[0.ã1.]ã«ãããããæåã«åºé[0.ã
far_plane ]ãžã®é倿ãå®è¡ããå¿
èŠããããŸãã
closestDepth *= far_plane;
次ã«ãå
æºã«å¯ŸããçŸåšã®ãã©ã°ã¡ã³ãã®æ·±åºŠå€ãååŸããŸãã éžæããã¢ãããŒãã®å Žåãããã¯éåžžã«ç°¡åã§ãããã§ã«æºåãããŠãã
fragToLightãã¯ãã«ã®é·ããèšç®ããã ãã§ãã
float currentDepth = length(fragToLight);
ãããã£ãŠãæã
ã¯ã
closethDepthãšåãïŒãããŠãããããããã倧ããªïŒééã«ããæ·±åºŠå€ãååŸããŸãã
ããã§ãçŸåšã®ãã©ã°ã¡ã³ããã·ã£ããŠå
ã«ãããã©ããã調ã¹ãããã«ãäž¡æ¹ã®æ·±åºŠãæ¯èŒããããšãã§ããŸãã ãŸãã
åã®ã¬ãã¹ã³ã§èª¬æãããã·ã£ããŠãªããã«ãåé¡ãçºçããªãããã«ãæ¯èŒã«ãªãã»ããå€ãããã«å«ããŸãã
float bias = 0.05; float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
å®å
šãª
ShadowCalculationã³ãŒãïŒ
float ShadowCalculation(vec3 fragPos) {
æå®ãããã·ã§ãŒããŒã䜿çšãããšãã¢ããªã±ãŒã·ã§ã³ã¯ãã§ã«ããªã蚱容ã§ããã·ã£ããŠã衚瀺ããä»åã¯ãœãŒã¹ãããã¹ãŠã®æ¹åã«æåœ±ãããŸãã ãœãŒã¹ãäžå€®ã«ããã·ãŒã³ã®å Žåãç»åã¯æ¬¡ã®ããã«è¡šç€ºãããŸãã
å®å
šãªãœãŒã¹ã³ãŒãã¯
ãã¡ãã§ãã
æ·±ãã®3次ãããã®å¯èŠå
ããªããç§ãšãããã䌌ãŠãããªããç§ã¯ãããªããæåã¯ãã¹ãŠãæ£ããè¡ãããšãã§ããªãã ãããšæãã®ã§ãã¢ããªã±ãŒã·ã§ã³ããããã°ããããã€ãã®ææ®µã¯éåžžã«æçšã§ãããã æãæçœãªãªãã·ã§ã³ãšããŠã深床ãããã®æºåã®æ£ç¢ºæ§ãæ€èšŒã§ãããšäŸ¿å©ã§ãã çŸåšã¯2次å
ã®ãã¯ã¹ãã£ã§ã¯ãªãç«æ¹äœã®ãããã䜿çšããŠãããããèŠèŠåã®åé¡ã«ã¯ããå°ãè€éãªã¢ãããŒããå¿
èŠã§ãã
ç°¡åãªæ¹æ³ã¯ã
ShadowCalculation颿°ã®æ¬äœããæ£èŠåããã
nearestDepthå€ãååŸãããã©ã°ã¡ã³ãã·ã§ãŒããŒã®çµæãšããŠåºåããããšã§ãã
FragColor = vec4(vec3(closestDepth / far_plane), 1.0);
çµæã¯ã°ã¬ãŒã¹ã±ãŒã«ã®ã·ãŒã³ã«ãªããè²ã®åŒ·åºŠã¯ãã®ã·ãŒã³ã®ç·åœ¢æ·±åºŠå€ã«å¯Ÿå¿ããŸãã
éšå±ã®å£ã®é°åœ±é åã衚瀺ãããŸãã èŠèŠåã®çµæãäžãããããã®ãšé¡äŒŒããŠããå Žåãã·ã£ããŠããããæ£ããæºåãããŠããããšã確èªã§ããŸãã ããããªããšããšã©ãŒãã©ããã«å¿ã³èŸŒãã§ããŸããŸãããããšãã°ãå€
nearestDepthã¯éé[0.ã
far_plane ]ãã
ååŸãããŸããã
è¿ãããŒã»ã³ããŒãžã®ãã£ã«ã¿ãªã³ã°
å
šæ¹åæ§ã·ã£ããŠã¯ãæ¹åæ§ã·ã£ããŠãšåãåçã«åºã¥ããŠæ§ç¯ãããŠããããããã¯ã¹ãã£è§£å床ã®ç²ŸåºŠãšæéæ§ã«é¢é£ãããã¹ãŠã®ã¢ãŒãã£ãã¡ã¯ããç¶æ¿ããŸããã 圱ä»ãã®é åã®å¢çã«è¿ã¥ããšãã®ã¶ã®ã¶ã®ãšããžãèŠãããŸãã ãšã€ãªã¢ã·ã³ã°ã¢ãŒãã£ãã¡ã¯ãã
Percentage-closer filtering ïŒ
PCF ïŒ
ãã£ã«ã¿ãªã³ã°ã䜿çšãããšãçŸåšã®ãã©ã°ã¡ã³ãã®åšå²ã®è€æ°ã®æ·±åºŠãµã³ãã«ããã£ã«ã¿ãªã³ã°ããæ·±åºŠæ¯èŒçµæãå¹³ååããããšã«ããããšã€ãªã¢ã·ã³ã°ãã¬ãŒã¹ãã¹ã ãŒãºã«ã§ããŸãã
åã®ã¬ãã¹ã³ã®PCFã³ãŒããååŸãã3çªç®ã®æ¬¡å
ã远å ããŸãïŒ3次ãããã®ãµã³ãã«ã«ã¯æ¹åãã¯ãã«ãå¿
èŠã§ãïŒã
float shadow = 0.0; float bias = 0.05; float samples = 4.0; float offset = 0.1; for(float x = -offset; x < offset; x += offset / (samples * 0.5)) { for(float y = -offset; y < offset; y += offset / (samples * 0.5)) { for(float z = -offset; z < offset; z += offset / (samples * 0.5)) { float closestDepth = texture(depthMap, fragToLight + vec3(x, y, z)).r; closestDepth *= far_plane;
éãã¯ã»ãšãã©ãããŸããã å軞ã§äœæãããµã³ãã«ã®æ°ã«åºã¥ããŠããã¯ã¹ãã£åº§æšã®å€äœãåçã«èšç®ãããã¥ãŒãåããããµã³ãã«ã®æ°ã§å²ã£ãŠçµæãå¹³åããŸãã
ããã§ãã·ã£ããŠã¯ããæ¬ç©ã«èŠãããšããžã¯éåžžã«æ»ããã«ãªããŸããã
ãã ãããµã³ãã«ã®æ°ãsample
= 4ã«èšå®ãããšãå®éã«ã¯åãã©ã°ã¡ã³ãã«64åãã®ãµã³ãã«ãè²»ããããšã«ãªããããã¯éåžžã«å€ããªããŸãã
ãŸããã»ãšãã©ã®å Žåããããã®ãµã³ãã«ã¯å
ã®ãã¯ãã«ã«éåžžã«è¿ããããåé·ã«ãªããŸãã ããããããµã³ãã«ã®å
ã®ãã¯ãã«ã«åçŽãªæ¹åã«ãµã³ãã«ãäœæããæ¹ã䟿å©ã§ãããã æ®å¿µãªãããçæããã远å ã®æ¹åã®ã©ããåé·ã«ãªãããèŠã€ããããã®ç°¡åãªæ¹æ³ã¯ååšããŸããã 1ã€ã®ææ³ã䜿çšããŠããã€ã¢ã¹æ¹åã®é
åãèªåããããšãã§ããŸãããã€ã¢ã¹æ¹åã¯ãã¹ãŠãã»ãŒå®å
šã«åé¢å¯èœãªãã¯ãã«ã§ãã ãããããå®å
šã«ç°ãªãæ¹åãæããŸãã ããã«ãããäºãã«è¿ããããã€ã¢ã¹æ¹åã®æ°ãæžå°ããŸãã 以äžã¯ã20ã®ç¹å¥ã«éžæãããå€äœæ¹åãæã€åæ§ã®é
åã§ãã
vec3 sampleOffsetDirections[20] = vec3[] ( vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1), vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1), vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0), vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1), vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1) );
ããã«ãPCFã¢ã«ãŽãªãºã ã倿ŽããŠããã¥ãŒããã¯ãããããååŸããããã»ã¹ã§sampleOffsetDirectionsãªã©ã®åºå®ãµã€ãºã®é
åã䜿çšã§ããŸãããã®ã¢ãããŒãã®äž»ãªå©ç¹ã¯ãæåã®ã¢ãããŒããšèŠèŠçã«ã¯äŒŒãŠããŸãããå¿
èŠãªè¿œå ãµã³ãã«ã®æ°ã倧å¹
ã«å°ãªãçµæãäœæã§ããããšã§ãã float shadow = 0.0; float bias = 0.15; int samples = 20; float viewDistance = length(viewPos - fragPos); float diskRadius = 0.05; for(int i = 0; i < samples; ++i) { float closestDepth = texture(depthMap, fragToLight + sampleOffsetDirections[i] * diskRadius).r; closestDepth *= far_plane;
äžèšã®ã³ãŒãã§ã¯ãå€äœãã¯ãã«ã«diskRadiuså€ãä¹ç®ãããŠããŸããããã¯ãå
ã®fragToLightãµã³ãã«ãã¯ãã«ã®åšå²ã«æ§ç¯ããã远å ã®ãµã³ãã«ãäœæããããã£ã¹ã¯ã®ååŸã衚ããŸããããã«é²ãã§æ¬¡ã®ããªãã¯ãå®è¡ã§ããŸãããã©ã°ã¡ã³ãããã®ãªãã¶ãŒããŒã®è·é¢ã«å¿ããŠdiskRadiuså€ã倿ŽããŠã¿ãŠãã ããããã®ãããå€äœã®ååŸã倧ããããé ãã®ç Žçã§ã¯åœ±ãæããããã芳å¯è
ã«è¿ãç Žçã§ã¯ããã·ã£ãŒãã«ããããšãã§ããŸãã float diskRadius = (1.0 + (viewDistance / far_plane)) / 25.0;
ãã®ãããªPCFã¢ã«ãŽãªãºã ã®çµæã¯ãå
ã®ã¢ãããŒããããå£ããªããœããã·ã£ããŠãçæããŸãããã¡ãããåãã©ã°ã¡ã³ãã«è¿œå ããããã€ã¢ã¹å€ã¯ãã·ãŒã³ã®ã³ã³ããã¹ããšã³ã³ãã³ãã«å€§ããäŸåããŠãããããåžžã«è¿œå ã®å®éšèšå®ãå¿
èŠã«ãªããŸããææ¡ãããã¢ã«ãŽãªãºã ã®ãã©ã¡ãŒã¿ãŒã詊ããŠãæçµçãªç»åãžã®åœ±é¿ã確èªããŸãããã®äŸã®ãœãŒã¹ã³ãŒãã¯ãã¡ãã«ãããŸãããŸãã幟äœåŠçã·ã§ãŒããŒã䜿çšããŠç«æ¹äœã®æ·±åºŠããããäœæããããšã¯ãåé¢ã®ã·ãŒã³ã6åã«ã¬ã³ããªã³ã°ãããããå¿
ãããé«éã§ã¯ãªãããšã«æ³šæããŠãã ããããã®ã¢ãããŒãã䜿çšãããšãããã©ãŒãã³ã¹ã«ãã€ãã¹ã®åœ±é¿ããããŸããäžè¬ã«ãããã©ãŒãã³ã¹ãžã®ãã€ãã¹ã®å¯äžãããžãªã¡ããªã·ã§ãŒããŒãš1åã®æç»åŒã³åºãã䜿çšãããã¹ãŠã®å©ç¹ãäžåãå¯èœæ§ããããŸãããããŠããã¡ãããããã¯ããªããã©ã®ç°å¢ã§åããŠããããã©ã®ãããªã«ãŒããšã©ã®ãã©ã€ããããªãã«å©çšå¯èœãããããŠä»ã®å€ãã®ãã®ã«äŸåããŸãããããã£ãŠãããã©ãŒãã³ã¹ãæ¬åœã«éèŠãªå Žåãæ€èšäžã®ãã¹ãŠã®éžæè¢ããããã¡ã€ã«ããã¢ããªã±ãŒã·ã§ã³ã®ã·ãŒã³ã§æã广çã§ããããšã倿ããéžæè¢ãéžæããããšã¯åžžã«äŸ¡å€ããããŸããå人çã«ã¯ãã·ã£ããŠããããäœæããã¿ã¹ã¯ã§ã®ãžãªã¡ããªã·ã§ãŒããŒã®äœ¿çšãåºå®ããŠããŸããããã¯ãã·ã£ããŠã·ã§ãŒããŒã®äœ¿çšãããçŽæçã ããã§ãã远å è³æïŒ
PS ïŒè»¢éã調æŽããããã®
é»å ±confããããŸãã 翻蚳ãæäŒããããšããçå£ãªé¡æãããã°ã倧æè¿ã§ãïŒ