
å
æº
ãã®èšäºãŸã§ãç§ãã¡ã¯ç©ºéã®ããç¹ããã®ç
§æã«æºè¶³ããŠããŸããã ãããŠãçµæã¯æªããããŸããã§ããããå®éã«ã¯ãç°ãªããæ¯ãèãããæã€ç
§æã®å€ãã®ãœãŒã¹ããããŸãã ãã®ã¬ãã¹ã³ã§ã¯ããããã®å
æºã®ããã€ãã«ã€ããŠèª¬æããŸãã ããŸããŸãªå
æºã®ç¹æ§ãæš¡å£ããæ©èœã¯ãäœæãããã·ãŒã³ãè±ãã«ããå¥ã®ããŒã«ã§ãã
æåæ§å
æºããã¬ãã¹ã³ãéå§ããŠãããç¹å
æºã«é²ã¿ãŸããããã¯ãåè¿°ã®åçŽãªç
§ææ¹æ³ã®éçºã§ãã æåŸã«ãã¹ãããã©ã€ãïŒã¹ãããã©ã€ãïŒã®ããããã£ãã·ãã¥ã¬ãŒããããœãŒã¹ã®èšèšæ¹æ³ãæ€èšããŸãã
æåæ§å
æº
å
æºã芳å¯å¯Ÿè±¡ç©ããé ãé¢ããŠããå Žåãå
¥å°å
ç·ã¯äºãã«ã»ãŒå¹³è¡ã§ããã察象ç©ã芳å¯è
ã®äœçœ®ã«é¢ä¿ãªããåãæ¹åã«å
ãåããããŠãããããªå°è±¡ãäžããŸãã ã·ãã¥ã¬ãŒããããç¡éé ã®å
æºã¯ããã¹ãŠã®å
ç·ãåãæ¹åã«é²ããšèŠãªãããå
æºèªäœã®å Žæã«äŸåããªããããæåæ§ãšåŒã°ããŸãã
ãã®ã¿ã€ãã®ãœãŒã¹ã®è¯ãäŸã¯ãSunã§ãã ç§ãã¡ããç¡éé ã§ã¯ãããŸãããããã®è·é¢ã¯ç
§æèšç®ã§ç¡éé ãšèããã®ã«ååã§ãã ãŸãã倪éœå
ç·ãå¹³è¡ã§ãããšä»®å®ããŸãããããå³ã«ç€ºããŸãã
å
ç·ã¯å¹³è¡ã§ãããšèãããããç
§ãããããªããžã§ã¯ããšå
æºã®çžå¯Ÿçãªäœçœ®ã¯éèŠã§ã¯ãããŸãããå
ç·ã®æ¹åã¯ã·ãŒã³å
šäœã§åãã§ãã ãããã£ãŠãç
§æã®èšç®ã¯ãã¹ãŠã®ãªããžã§ã¯ãã§åãã§ããããã¯ãç
§æã®æ¹åã®ãã¯ãã«ãã·ãŒã³å
ã®ã©ã®ãªããžã§ã¯ãã§ãåãã ããã§ãã
æåæ§ãœãŒã¹ãã·ãã¥ã¬ãŒãããããã«ãç
§æã®æ¹åãã¯ãã«ãèšå®ã§ããŸããäœçœ®ãã¯ãã«ã¯äžèŠã«ãªããŸãã ã·ã§ãŒããŒã®èšç®ã¢ãã«ã¯ã»ãšãã©å€æŽãããŸããããœãŒã¹äœçœ®ãã¯ãã«ã䜿çšãã
lightDirãœãŒã¹æ¹åãã¯ãã«ã®èšç®ã¯ãæå®ãããæ¹åãã¯ãã«ã®çŽæ¥äœ¿çšã«çœ®ãæããããŸãã
struct Light { // vec3 position; // . vec3 direction; vec3 ambient; vec3 diffuse; vec3 specular; }; ... void main() { vec3 lightDir = normalize(-light.direction); ... }
light.directionãã¯ãã«ã®éã«æ³šæããŠãã ããã ãããŸã§ãèšç®ã¢ãã«ã¯å
æºã®æ¹åãã¯ãã«ããã©ã°ã¡ã³ããããœãŒã¹ãžã®æ¹åãšããŠåãå
¥ããŠããŸããããæåå
æºã®å Žåãéåžžãæ¹åãã¯ãã«ã¯å
æºããã®æ¹åãšããŠæå®ãã
ãŸã ã ãããã£ãŠãå転ãå®è¡ãããå€æ°ã«å
æºã«åãããããã¯ãã«ãä¿åãããŸãã ãŸããæ£èŠåãå¿ããªãã§ãã ãã-å
¥åããŒã¿ãæ£èŠåãããããšãæåŸ
ããªãæ¹ãè¯ãã§ãã
ãã®ãããæçµçã«ã
lightDir㯠ã以åãšåãããã«æ¡æ£ããã³ãã©ãŒã³ã³ããŒãã³ãã®èšç®ã«äœ¿çšãããŸãã
æåæ§ãœãŒã¹ãå€ãã®ãªããžã§ã¯ãã®ã€ã«ãããŒã·ã§ã³ã«çãã圱é¿ããããšãæ確ã«ç€ºãããã«ã
座æšã·ã¹ãã ã¬ãã¹ã³ã®æåŸã®ã³ã³ããã®çŸ€ãã§ããªãã¿ã®ã·ãŒã³ã³ãŒãã䜿çšããŸãã èŠéãã人ã®ããã«ïŒæå
ã«ãã³ã³ããã®
10ã®ç°ãªãäœçœ®ãèšå®ããããããã«ããŒã«ã«åº§æšç³»ããäžçãžã®å¯Ÿå¿ããå€æãæ ŒçŽããäžæã®ã¢ãã«ãããªãã¯ã¹ãå²ãåœãŠãŸããã
for(unsigned int i = 0; i < 10; i++) { glm::mat4 model(1.); model = glm::translate(model, cubePositions[i]); float angle = 20.0f * i; model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f)); lightingShader.setMat4("model", model); glDrawArrays(GL_TRIANGLES, 0, 36); }
ãŸããæ¹åæ§ãœãŒã¹ã®æ¹åãã·ã§ãŒããŒã«è»¢éããããšãå¿ããªãã§ãã ããïŒãœãŒã¹ããæ¹åãèšå®ããããšãæãåºããŠãã ããããã¯ãã«ã®ã¿ã€ãã«ãã£ãŠãæ¹åãäžåãã§ãããšå€æã§ããŸãïŒã
lightingShader.setVec3("light.direction", -0.2f, -1.0f, -0.3f);
ãããŸã§ãäœçœ®ãšæ¹åã3ã³ã³ããŒãã³ããã¯ãã«ïŒ vec3 ïŒãšããŠéä¿¡ããŸããããäžéšã®éçºè
ã¯ã4ã³ã³ããŒãã³ãïŒ vec4 ïŒãæã€ãã¯ãã«ã®åœ¢åŒã§è»¢éããããšã奜ã¿ãŸãã vec4ã䜿çšããŠäœçœ®ãèšå®ããå Žåã転éå€æãšæ圱å€æãæ£ããé©çšãããããã«ã wã³ã³ããŒãã³ãã1ã«èšå®ããããšãéåžžã«éèŠã§ãã åæã«ãvec4ã®åœ¢åŒã§æ¹åãæå®ããå Žåã転éãæ¹åã«åœ±é¿ããããšã¯æãŸãããããŸããïŒããã¯çµå±æ¹åãã¯ãã«ã§ããããŸãïŒããããã£ãŠã w = 0ãèšå®ããå¿
èŠããããŸã ã
ãããã£ãŠãæ¹åãã¯ãã«ã¯vec4ïŒ0.2fã1.0fã0.3fã0.0fïŒãšããŠè¡šãããŸãã ãã®ãããªã¬ã³ãŒãã¯ãå
æºã®ã¿ã€ããšç
§æèšç®ã¢ãã«ã®éžæã«é¢ããã¢ã¯ã»ã¹å¯èœãªãã§ãã¯ã«ã䜿çšã§ããŸããã³ã³ããŒãã³ãwã1ã®å Žåãããã¯æããã«å
æºã®äœçœ®ãã¯ãã«ã§ããwã0ã®å Žåãæ¹åãã¯ãã«ããããŸãã
if(lightVector.w == 0.0) // // else if(lightVector.w == 1.0) // // ( )
é¢çœãäºå®ïŒããã¯ãOpenGLãå
æºãæåæ§ãŸãã¯å®çŸ©æžã¿ãšããŠå®çŸ©ããåºå®æ©èœãã€ãã©ã€ã³äžã«èšç®ã¢ãã«ãå€æŽããæ¹æ³ã§ãã
ããã§ã¢ããªã±ãŒã·ã§ã³ãã¢ã»ã³ãã«ããŠããã¹ããŒãžã移åãããšããã¹ãŠã®ãªããžã§ã¯ãããã®åäœã®å€ªéœã«äŒŒãå
æºã«ãã£ãŠç
§ããããŠããããšãããããŸãã å
æºã空ã®ã©ããã«ãããã®ããã«ããªããžã§ã¯ãã®ç
§æã®æ¡æ£ããã³ãã©ãŒã³ã³ããŒãã³ããã©ã®ããã«å€åãããã確èªããŠãã ããã çµæã¯æ¬¡ã®ããã«ãªããŸãã
ãã®äŸã®ãœãŒã¹ã³ãŒãã¯
ãã¡ãã«ãããŸã ã
ãã€ã³ããœãŒã¹
æåæ§å
æºã¯ã·ãŒã³å
šäœãç
§ããã®ã«é©ããŠããŸãããéåžžã¯ã·ãŒã³ã®ç©ºéã«ããã«ããã€ãã®ç¹å
æºãé
眮ããå¿
èŠããããŸãã ç¹å
æºã¯ã空éå
ã®æå®ã®äœçœ®ãæã¡ããã¹ãŠã®æ¹åã«åäžã«æŸå°ããå
匷床ã¯è·é¢ãšãšãã«æžå°ããŸãã ç¹å
æºã®äŸãšããŠãåŸæ¥ã®çœç±ç¯ãŸãã¯ããŒããæããããšãã§ããŸãã
åã®ã¬ãã¹ã³ã§ã¯ãç¹å®ã®äœçœ®ã«ããç¹å
æºã®æãåçŽãªå®è£
ã䜿çšããŠããã¹ãŠã®æ¹åã«å
ãæ¡æ£ããŸããã ãããããã®å
æºã®å
ç·ã¯æ¶ãããå
æºã¯éåžžã«åŒ·åã«èŠããŸããã äœæãããã»ãšãã©ã®ã·ãŒã³ã§ã¯ãã·ãŒã³å
šäœã«äžåºŠã«ã§ã¯ãªããç°å¢ã«åœ±é¿ãäžãããœãŒã¹ãæã€ããšãæãŸããã§ãããã
åã®äŸã®ã·ãŒã³ã«10åã®ã³ã³ãããè¿œå ãããšãæãé ãã«ããã³ã³ããã§ãããœãŒã¹ã®çŽåã«ããã³ã³ãããšåã匷床ã§ç¹ç¯ããŠããããšãããããŸãã ããã¯äºæ³ãããŠããããšã§ã-ç
§æã®åŒ·åºŠãå¶åŸ¡ããè¡šçŸãèæ
®ããŸããã§ããã ãã ãããœãŒã¹ã«æãè¿ãã³ã³ãããšæ¯èŒããŠããªã¢ãŒãã³ã³ããããããã«åŒ·èª¿è¡šç€ºããã ãã§ãã
æžè¡°
è·é¢ã«ããå
匷床ã®æžè¡°ã¯ãæžè¡°ãšåŒã°ããŸãã æžè¡°ãèšç®ããæãç°¡åãªæ¹æ³ã¯ãç·åœ¢æ³åã䜿çšããããšã§ãã ãã®å Žåã匷床ã¯è·é¢ãšãšãã«çŽç·çã«æžå°ããé ãã®ãªããžã§ã¯ãã®ç
§æãå°ãªããªããŸãã ããããèŠèŠçã«ãã®ãããªã¢ãã«ã¯éçŸå®çãªçµæããããããŸãã äžè¬çãªå Žåãå®éã®å
æºã¯è¿ãã«åŒ·ãç
§æãäžããŸãããå°ããªååŸã§ã¯åŒ·åºŠãéåžžã«æ¥æ¿ã«äœäžããè·é¢ãšãšãã«æ®ãã®äŸçµŠããã£ãããšæžå°ããŸãã ãã®ãããªåäœãã·ãã¥ã¬ãŒãããã«ã¯ãããç·åœ¢ãªèšç®ãå¿
èŠã§ãã
幞ããªããšã«ãç©çåŠè
ã¯ç ã£ãŠããŸãããé ãããæžè¡°ä¿æ°ãèšç®ããããã®äžè¬åãããè¡šçŸãé·ãéæšè«ãããŠããŸããã åãã©ã°ã¡ã³ãã®å€ãèšç®ããç¹å®ã®ãœãŒã¹ã®åŒ·åºŠãã¯ãã«ãçµæã§ä¹ç®ããã ãã§ãã
ã©ãã§
-ãã©ã°ã¡ã³ããããœãŒã¹ãŸã§ã®è·é¢ã
-å®æ°ãç·åœ¢ããã³äºæ¬¡ä¿æ°ã
- éåžžãå®æ°ä¿æ°ã¯1.0ã§ãåæ¯ã1æªæºã®å€ã«æžå°ããã®ãé²ããŸããããã«ãããç¹å®ã®è·é¢ã§ç
§æã®åŒ·åºŠãå¢å ããŸãã ç§ãã¡ã«ãšã£ãŠããã®å¹æã¯æãŸãããããŸããã
- ç·åœ¢ä¿æ°ã¯ãè·é¢ã®å¢å ãšãšãã«å
匷床ãç·åœ¢ã«æžå°ãããé
ãå®çŸ©ããŸãã
- 2次ä¿æ°ã¯ã匷床ã®2次æžå°ãå®çŸ©ããé
ã決å®ããŸãã è·é¢ãçãå Žåã2次é
ã®å¯äžã¯ç·åœ¢ã®å¯äžã«ãã£ãŠãããã¯ãããŸãããè·é¢ã倧ãããªããšåŒã§ã¯æ¯é
çã«ãªããŸãã
ç·åœ¢äŸåãšäºæ¬¡äŸåã®çµã¿åããã«ããã匷床ãå
æºã®è¿ãã§ç·åœ¢ã«æžå°ããç¹å®ã®é€å»è·é¢ãã¯ããã«éãæžå°ãå§ãããšãã«å¹æãäœæã§ããŸãã ãã®çµæãå
æºã®æããã¯è¿ãã§å€§ãããè·é¢ãé·ããªãã«ã€ããŠããªãéãæžå°ããè·é¢ãé ãã»ã©é
ããªããŸãã 次ã®ã°ã©ãã¯ã100ã®è·é¢åäœã«ãããæžè¡°ä¿æ°ã®äŸã瀺ããŠããŸãã
ã芧ã®ããã«ã匷床ã¯çè·é¢ã§æ倧ã«ãªããŸãããæé·ãããšå€§å¹
ã«äœäžãã100åäœä»è¿ã§ãŒãã«ãªãåŸåããããŸãã
ãªããºéžæ
3ã€ã®ä¿æ°ãéžæãããšããçåãçããŸãã
ã é©åãªå€ã¯ãã·ãŒã³ã§éçºãããŠããç°å¢ãå¿
èŠãªç
§æè·é¢ãå
æºã®ã¿ã€ããããã³ãã®ä»ã®èŠå ã«åºã¥ããŠæ±ããããŸãã ã»ãšãã©ã®å Žåãããã¯çµéšã®åé¡ã«ãªããè©Šè¡é¯èª€ã«ããããçšåºŠã®èª¿æŽã«ãªããŸãã 以äžã®è¡šã«ã¯ãç¹å®ã®æå³ã§ãæå®ãããè·é¢ãã«ããŒããå
æºã®åäœãçŸå®çã«æäŸãããã©ã¡ãŒã¿ãŒã®ãªã¹ããå«ãŸããŠããŸãã æåã®åã¯ãèšå®ãããæ¯çã§ã®ã³ãŒãã£ã³ã°ã®è·é¢ã瀺ããŸãã ãã®è¡šã¯ãOgre3Dãšã³ãžã³ã®ãããžã§ã¯ã
wikiããŒãžããååŸãããã®ã§ãå¿
èŠãªå€ãéžæããããã®åªããåºçºç¹ã§ãã
ã芧ã®ãšãããå®æ°ä¿æ°ã¯ã©ãã§ããŠããã£ã«çãããªããŸãã 倧ããªè·é¢ãç
§ããå Žåãç·åœ¢ä¿æ°ã¯å°ããéžæãããäºæ¬¡ä¿æ°ã¯ããã«å°ãããªããŸãã ãããã®å€ãè©ŠããŠã¿ãŠãå®è£
ã®æ¡ä»¶äžã§ãããã®å€æŽãã©ã®ãããªåœ±é¿ãäžããããå人çã«ç¢ºèªããŠãã ããã æ€èšäžã®ã·ãŒã³ã§ã¯ãã³ãŒãã£ã³ã°è·é¢ã¯32ã100ãŠãããã§ãã çµæ§ã§ãã
å®è£
æžè¡°ãå®è£
ããã«ã¯ããã©ã°ã¡ã³ãã·ã§ãŒããŒã³ãŒãã«ãå®éã«ã¯å®æ°ãç·åœ¢ãããã³2次ä¿æ°ã®3ã€ã®è¿œå ãã©ã¡ãŒã¿ãŒãå¿
èŠã§ãã 以åã«äœ¿çšãã宣èšããã
Lightæ§é ã«ä¿åããã®ãæãè«ççã§ãã
lightDirãã¯ãã«ã®èšç®ã¯ãåã®ã¬ãã¹ã³ãšåæ§ã«å®è¡ãããæåæ§å
æºã®ã»ã¯ã·ã§ã³ã§èª¬æãããŠãããã¹ã§ã¯ãªãããšã«æ³šæããŠãã ããã
struct Light { vec3 position; vec3 ambient; vec3 diffuse; vec3 specular; float constant; float linear; float quadratic; };
次ã«ãã³ãŒãã«ç¹å®ã®ãã©ã¡ãŒã¿ãŒå€ãèšå®ããŸãã çŽ50ãŠãããã®ç
§æè·é¢ãå¿
èŠã§ãããã®ããã次ã®å€ãè¡šã«ç€ºãããŠããŸãã
lightingShader.setFloat("light.constant", 1.0f); lightingShader.setFloat("light.linear", 0.09f); lightingShader.setFloat("light.quadratic", 0.032f);
ãã©ã°ã¡ã³ãã·ã§ãŒããŒã®èšç®ã³ãŒãã¯æããã§ããæžè¡°ä¿æ°ãèšç®ããŠãããç
§æã®èæ¯ãæ¡æ£ãããã³ãã©ãŒã³ã³ããŒãã³ããä¹ç®ããŸãã
ãã ããèšç®ã«ã¯ããã©ã°ã¡ã³ãããå
æºãŸã§ã®è·é¢ã®å€ãå¿
èŠã§ãã ã©ããã£ãŠæã«å
¥ããŸããïŒ ç°¡åã§ãããã©ã°ã¡ã³ããšãœãŒã¹ã®äœçœ®ãã¯ãã«éã®å·®ãèšç®ããçµã¿èŸŒã¿ã®GLSL
lengthïŒïŒé¢æ°ã䜿çšããã ãã§ãã
float distance = length(light.position - FragPos); float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
çµæãšããŠãçµæã®ä¿æ°ã«ç
§æã¢ãã«ã®ãã¹ãŠã®ã³ã³ããŒãã³ããæããŸãã
èæ¯ã³ã³ããŒãã³ããæžè¡°ããã«æ®ãããšã¯å¯èœã§ãããè€æ°ã®ãœãŒã¹ãããã·ãŒã³ã§ã¯ããã®ã³ã³ããŒãã³ãã®å¯äžãå ç®ããå§ããããã¯éåžžæãŸãããããŸããã ãã®å Žåãããã¯ã°ã©ãŠã³ãã³ã³ããŒãã³ãã«æžè¡°ãå«ããå¿
èŠããããŸãã
ambient *= attenuation; diffuse *= attenuation; specular *= attenuation;
ãã¹ãã¢ããªã±ãŒã·ã§ã³ãå®è¡ãããšã次ã®ããã«ãªããŸãã
çŸåšãåé¢ã®ã³ã³ããã®ã¿ã匷調衚瀺ãããæãè¿ãã³ã³ãããæãæããããšãããããŸãã ã¹ããŒãžã®åŸãã«ããã³ã³ããã¯ãå
æºããé¢ããããŠããããããŸã£ããç¹ç¯ããŠããŸããã
å®å
šãªãµã³ãã«ã³ãŒãã¯
ãã¡ãã«ãããŸã ã èŠçŽãããšãç¹å
æºã¯ãäœçœ®ã®èª¿æŽãå¯èœãªå
æºã§ãããç
§æã®èšç®ã§åŒ·åºŠã®æžè¡°ãèæ
®ãããã®ãšèšããŸãã 貯éç®±ã®å¥ã®ããŒã«ïŒ
Floodlight
æåŸã«èæ
®ããããœãŒã¹ã¿ã€ãã¯ã¹ãããã©ã€ãã«ãªããŸãã ãã®ãããªç·æºã¯æå®ã®äœçœ®ãæã£ãŠããŸããããã¹ãŠã®æ¹åã§ã¯ãªããéžæãããæ¹åã«ã®ã¿æŸå°ããŸãã ããã«ããªããžã§ã¯ãã¯ç¹å®ã®æ¹åããã®å°ããªè¿åã§ã®ã¿ç
§æããããã®é åã®å€åŽã«ãããªããžã§ã¯ãã¯ç
§æãªãã®ãŸãŸã§ãã äŸãšããŠãè¡ç¯ãæäžé»ç¯ãæ³åããŠãã ããã
ãã®ã¢ãã«ã§ã¯ãã¹ãããã©ã€ãã¯ã¯ãŒã«ã座æšã®äœçœ®ãæ¹åãã¯ãã«ãããã³ã¹ãããã©ã€ãã®ããã¯ã©ã€ãã®ååŸã決å®ãã
ã«ãããªãè§åºŠã«ãã£ãŠè¡šãããŸãã ãã©ã°ã¡ã³ãã匷調衚瀺ãããŠãããã©ãããå€æããããã«ãåé圢ã®ãœãŒã¹ã¯ãªããã³ã°ãŸãŒã³ã®å
åŽãå€åŽããèšç®ããŸãã ãã®ã¹ããŒã ã¯ããã¹ãŠãã©ã®ããã«æ©èœããããç解ããã®ã«åœ¹ç«ã¡ãŸãã
ããã§ã
LightDirã¯ãã©ã°ã¡ã³ããããœãŒã¹ã«åãããããã¯ãã«ã
SpotDirã¯ã¹ãããã©ã€ãã®æ¹åãã¯ãã«ã
ïŒ
phi ïŒ-ããã¯ã©ã€ãã®ååŸãå®çŸ©ããã¯ãªããã³ã°è§åºŠïŒãã®è§åºŠã®å€åŽã«ãããã©ã°ã¡ã³ãã¯åŒ·èª¿è¡šç€ºãããŸããïŒã
ïŒ
theta ïŒ
-LightDirãã¯ãã«ãš
SpotDirãã¯ãã«ã®éã®è§åºŠïŒif
ããå°ãã
ããã©ã°ã¡ã³ãã¯ããã¯ã©ã€ãé åã«èœã¡ãŸãïŒã
ãããã£ãŠãè¡ãå¿
èŠãããã®ã¯ã
LightDirãã¯ãã«ãš
SpotDirãã¯ãã«ã®ã¹ã«ã©ãŒç©ãèšç®ããåŸãããå€ãç¹å®ã®ã¯ãªããã³ã°è§åºŠãšæ¯èŒããããšã§ãïŒã¹ã«ã©ãŒä¹ç®ã¯2ã€ã®æ£èŠåãã¯ãã«éã®è§åºŠã®ã³ãµã€ã³ãè¿ããããè§åºŠã®ã³ãµã€ã³ã䜿çšïŒã ããã§ãµãŒãã©ã€ãã®åºæ¬çãªç解ãã§ããã®ã§ãå®è£
ã«ç§»ããŸãã
å®è£
æäžé»ç¯ã®åœ¢ã§ã¢ãã«ã«åœãå¹ã蟌ã¿ãŸãã 芳枬è
ã®äœçœ®ã«åºå®ããã芳枬è
ã®èŠç¹ãããŸã£ããåæ¹ã«åããããå
æºã å®éãæäžé»ç¯ã¯ãµãŒãã©ã€ãã®ã¿ã€ãã®ãœãŒã¹ã§ãããäœçœ®ãšæ¹åã¯ãã¬ãŒã€ãŒã®äœçœ®ãšæ¹åã«å³å¯ã«é¢é£ä»ããããŠããŸãã
ã·ã§ãŒããŒãžã®éä¿¡ã«ã¯ãäœçœ®å€ïŒå
æºãžã®ãã¯ãã«ãèšç®ããããïŒãã¹ãããã©ã€ãã®æ¹åãã¯ãã«ãããã³ã«ãããªãè§åºŠãå¿
èŠã§ãã ããã¯ãã¹ãŠã
Lightæ§é ã«é
眮ã§ããŸãã
struct Light { vec3 position; vec3 direction; float cutOff; ... };
次ã«ãããã°ã©ã ã³ãŒãã§ã·ã§ãŒããŒã«ããŒã¿ã転éããŸãã
lightingShader.setVec3("light.position", camera.Position); lightingShader.setVec3("light.direction", camera.Front); lightingShader.setFloat("light.cutOff", glm::cos(glm::radians(12.5f)));
ã芧ã®ãšãããããã§ã¯ã«ãããªãè§åºŠã§ã¯ãªãã³ãµã€ã³ãéä¿¡ããŸããã·ã§ãŒããŒã§ã¯ãã¯ãã«éã®ã¹ã«ã©ãŒç©ãèšç®ãããã¯ãã«éã®è§åºŠã®ã³ãµã€ã³ãè¿ãããã§ãã é«äŸ¡ãªé¢æ°
acosïŒïŒã®åŒã³åºãã§ã³ãµã€ã³ã«ããè§åºŠã®èšç®ãåé¿ããããã«ãã«ãããªãè§åºŠã®ã³ãµã€ã³ã®çµäºå€ãã·ã§ãŒããŒã«æž¡ãããããã®å€ãçŽæ¥æ¯èŒããŠãå°ãã®èšç®ãªãœãŒã¹ãç¯çŽããŸãã
å®éã«ãã¹ãããã©ã€ãã®ã«ãã¬ããžãšãªã¢å
ã«ãããã©ãããèšç®ããŠå€æããŸãã
float theta = dot(lightDir, normalize(-light.direction)); if(theta > light.cutOff) { // } // , // else color = vec4(light.ambient * vec3(texture(material.diffuse, TexCoords)), 1.0);
ãŸãã
LightDirãã¯ãã«ãšå転
æ¹åãã¯ãã«ã®ã¹ã«ã©ãŒç©ãèšç®ããŸãïŒãã¯ãã«ããã§ã¯ãªãããœãŒã¹ã«åãããããã¯ãã«ãå¿
èŠãªããïŒã ãã¹ãŠã®äœ¿çšæžã¿ãã¯ãã«ãæ£èŠåããããšãå¿ããªãã§ãã ããïŒ
æ¡ä»¶æã§ã<ãã®ä»£ããã«æ¯èŒæåã>ãã䜿çšãããšé©ããããããŸããã ã·ãŒã¿ã¯ã«ãããªãå€ãããå°ããããã©ã°ã¡ã³ãããµãŒãã©ã€ãã®ã¢ã¯ã·ã§ã³ã³ãŒã³å
ã«ããããã«ããŸãã ãã®éãã§ãããããã§ã¯è§åºŠãæ¯èŒããã®ã§ã¯ãªãããããã®äœåŒŠãæ¯èŒããŠããŸãã 0°ã®ã³ãµã€ã³ã¯1ã90°ã¯0ã§ããã°ã©ããèŠãŠãã ããã
æããã«ãã³ãµã€ã³å€ã¯è§åºŠãå°ãããªããš1ã«ãªãåŸåããããããã·ãŒã¿ãã«ãããªãå€ããã倧ãããªããã°ãªããªãçç±ãããããŸãã ãã®äŸã§ã¯ãã¯ãªããã³ã°å€ã¯è§åºŠ12.5°ã®äœåŒŠã«çããã0.9978ã§ãã ãããã£ãŠã ã·ãŒã¿å€ã0.9978ãã1.0ã®ç¯å²ã«ããå Žåããã©ã°ã¡ã³ãã¯ããã¯ã©ã€ãã³ãŒã³ã«ãããŸãã
ãã¹ãã¢ããªã±ãŒã·ã§ã³ãå®è¡ãããšãã¹ãããã©ã€ãã®ã¢ã¯ã·ã§ã³ã³ãŒã³å
ã«ãããã©ã°ã¡ã³ãã®ã¿ã匷調衚瀺ãããããã«ãªããŸãã
å®å
šãªãµã³ãã«ã³ãŒãã¯
ãã¡ãã§ãã
ãã ããçµæã¯å°è±¡çã§ã¯ãããŸããã 匷調衚瀺ãããé åã®ããŒãã§éããšããžã¯ãç¹ã«éçŸå®çã«èŠããŸãã æãããèœãšãããšãªããã¹ãããã©ã€ãã·ã§ãŒãã®ã³ãŒã³ããå³åº§ã«èœã¡ããã©ã°ã¡ã³ãã ã¯ãªããã³ã°ãŸãŒã³ã®ããã¯ã©ã€ãã®èŒåºŠãã¹ã ãŒãºã«äžããã®ãããçŸå®çã§ãã
ã¹ã ãŒãºãªæžè¡°
ããã¯ã©ã€ããŸãŒã³ã®ãœãããšããžã§ãµãŒãã©ã€ããå®è£
ããã«ã¯ããã®ãŸãŒã³ã®å
åŽãšå€åŽã®ã³ãŒã³ãèšå®ããå¿
èŠããããŸãã å
åŽã®åéã¯ãåã®ã»ã¯ã·ã§ã³ã§èª¬æããããŒã¿ã«åºã¥ããŠæ±ºå®ã§ããŸãã ãã®å¢çããå€åŽã®åéã®å¢çãŸã§ã匷床ã¯æ»ããã«æžè¡°ããã¯ãã§ãã
å€åŽã®åéã¯ããã®åéã®è§£ã®è§åºŠã®äœåŒŠã䜿çšããŠæ±ºå®ãããŸãã ãã®çµæã2ã€ã®åéã®å¢çéã®ééã®ãã©ã°ã¡ã³ãã«ã€ããŠã0.0ã1.0ã®ééã®ç
§æ匷床ãèšç®ããå¿
èŠããããŸãã å
åŽã®åéã«ãããã©ã°ã¡ã³ãã¯åžžã«åŒ·åºŠ1.0ã§ç
§ããããå€åŽã®åéã®å€åŽã«ãããã©ã°ã¡ã³ãã¯ãŸã£ããç
§ããããŸããã
匷床ã®æ»ãããªäœäžã決å®ãããã©ã¡ãŒã¿ãŒã¯ã次ã®åŒã䜿çšããŠèšç®ã§ããŸãã
ã©ãã§
å
éšãå®çŸ©ããè§åºŠã®äœåŒŠã®éãã¯
ïŒããã³å€éšïŒ
ïŒã³ãŒã³
-ç¹å®ã®ãã©ã°ã¡ã³ãã®å
匷床ä¿æ°ã
ãã®åŒãã©ã®ããã«åäœããããæ³åããã®ã¯é£ããå Žåããããããããã€ãã®äŸãèããŠã¿ãŸãããã
ã芧ã®ãšãããããã¯å€ã«å¿ããŠãå€åŽãšå
åŽã®ã«ãããªãè§åºŠã®ã³ãµã€ã³éã®åçŽãªè£éæŒç®ã§ã
ã ä»ã§ãäœãèµ·ãã£ãŠããã®ãã¯ã£ããããŠããªãå Žåã¯ãå¿é
ããªãã§ãã ãã-çµéšè±å¯ã§è³¢æãªäººã1幎åŸã«åŒãåçŽã«åãæ»ãããšãã§ããŸãã
äžã€ã®åé¡ã¯äŸ¡å€ã§ã
ä»ã§ã¯ãå€åŽã®åéã®å€åŽã®é åã§ã¯ãŒãæªæºã§ãããå
åŽã®åéã®é åã§ã¯åäžã§ãããå¢çéã®äžéå€ãããããšãããããŸãã æ¡ä»¶æŒç®åã®å¿
èŠæ§ãåãé€ããèšç®ããã匷床å€ã§ç
§æã¢ãã«ã®ã³ã³ããŒãã³ããåçŽã«ä¹ç®ããã«ã¯ãå€ã®ç¯å²ãæ£ããå¶éããå¿
èŠããããŸãã
float theta = dot(lightDir, normalize(-light.direction)); float epsilon = light.cutOff - light.outerCutOff; float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); ... // we'll leave ambient unaffected so we always have a little light. diffuse *= intensity; specular *= intensity; ...
clampïŒïŒé¢æ°ã«æ³šæããŠãã ãããããã¯ãæåã®ãã©ã¡ãŒã¿ãŒã®å€ã®ç¯å²ã2çªç®ãš3çªç®ã®ãã©ã¡ãŒã¿ãŒã®å€ã«å¶éããŸãã ãã®å Žåã
匷床ã®å€ã¯åºé[0ã1]ã«ãããŸãã
outerCutOffãã©ã¡ãŒã¿ãŒã
Lightæ§é ã«è¿œå ããç¹å®ã®å€ã®ãŠããã©ãŒã ã·ã§ãŒããŒå€æ°ãžã®è»¢éãæ§æããããšãå¿ããªãã§ãã ããã ãã®ç»åã§ã¯ãå
è§ã¯12.5°ã«èšå®ãããå€è§ã¯17.5°ã«èšå®ãããŠããŸãã
ã¯ããã«è¯ãïŒ ããã§ãã¯ãªããã³ã°ãŸãŒã³ã®èšå®ãæäœããŠãã¿ã¹ã¯ã«æé©ãªã¹ãããã©ã€ããååŸã§ããŸãã ã¢ããªã±ãŒã·ã§ã³ã®ãœãŒã¹ã³ãŒãã¯
ãã¡ãã«ãããŸã ã
ãã®ã¿ã€ãã®æäžé»ç¯ãœãŒã¹ã¯ããã©ãŒã²ãŒã ã«æé©ã§ãããæåæ§ããã³ãã€ã³ããœãŒã¹ãšçµã¿åãããŠãäœæããã·ãŒã³ã¯åçã«å€åããŸãã
次ã®ã¬ãã¹ã³ã§ã¯ãçŸæç¹ã§èæ
®ãããŠãããã¹ãŠã®ã¿ã€ãã®ãœãŒã¹ãšã°ã©ãã£ãã¯æè¡ã䜿çšããããã«ããŸãã
ããã·ã§ã³
説æãããŠãããã¹ãŠã®ã¿ã€ãã®ãœãŒã¹ãšãã®ãã©ã°ã¡ã³ãã·ã§ãŒããŒãè©ŠããŠã¿ãŠãã ããã ããã€ãã®ãã¯ãã«ãå転ãããããæ¯èŒã®ç¬Šå·ãå€æŽãããããŸãã ãã®ãããªã¢ã¯ã·ã§ã³ã®çµæãèªåã§ç解ããŠãã ããã
ãªãªãžãã«èšäº ã