ã¡ã€ã³ã³ãŒã¹ã®å
容
ã³ãŒãæ¹å
å
¬åŒã®ç¿»èš³ïŒå°ã磚ãäžãããã®ïŒã¯ãã¡ãããå
¥æã§ããŸãã
楜ãã¿ã®æéã§ãããŸãã
çŸåšã®ã³ãŒãã®ãµã€ãºãèŠãŠã¿ãŸãããã
- geometry.cpp + .h- 218è¡
- model.cpp + .h- 139è¡
- our_gl.cpp + .h- 102è¡
- main.cpp- 66è¡
åèš
525è¡ ã ã³ãŒã¹ã®æåã«çŽæãããšããã§ãã our_glãšmainã§ã®ã¬ã³ããªã³ã°ã®ã¿ã«é¢äžããŠããããšã«æ³šæããŠãã ãããããã¯ãã£ã168è¡ã§ããããµãŒãããŒãã£ã©ã€ãã©ãªãåŒã³åºããšããã¯ãããŸããããã¹ãŠã®ã¬ã³ããªã³ã°ã¯ãŒãããè¡ãããŸããã
ç§ã®ã³ãŒãã¯ãäœæ¥äžã®ã³ãŒããšã®æçµçãªæ¯èŒã«ã®ã¿å¿
èŠã§ããããšãæãåºããŠãã ããïŒ ãã®äžé£ã®èšäºã«åŸãå Žåã¯ãè¯ãæ¹æ³ã§ãã¹ãŠããŒãããæžãå¿
èŠããããŸãã æãã¯ã¬ã€ãžãŒãªã·ã§ãŒããŒãå®è¡ããã³ã¡ã³ãã«åçãæçš¿ããŠãã ããïŒ
è§ã®é»ãäžè§åœ¢ã¯ããæãããã¢ãã«ã§ããèé»äººã®é ã«ããããããŸãããããããä¿®æ£ããããããŸããã
OpenGLãã¬ãŒã ã¯ãŒã¯ã«äŒŒãããã«ã³ãŒãããªãã¡ã¯ã¿ãªã³ã°ãã
ãããã£ãŠãmain.cppãå°ã倧ãããªãå§ããã®ã§ã2ã€ã®éšåã«åããŸãããã
- our_gl.cpp + .hã¯ããããŸãã«èšã£ãŠããã€ããªã©ã€ãã©ãªãã¡ã€ã«ãããã°ã©ã ã§ããªãéšåã§ãã
- main.cpp-ããã§ãå¿
èŠãªãã®ãããã°ã©ã ã§ããŸãã
our_glã§
åºåããå
容ã詳ããèŠãŠã¿ãŸãããã æåœ±ãããªãã¯ã¹ãã¿ã€ããããã³ã¹ã¯ãªãŒã³åº§æšãžã®é·ç§»ãæ§ç¯ããæ©èœãããã³ãããªãã¯ã¹èªäœã¯ãåã«ã°ããŒãã«å€æ°ã§ãã ããŠãäžè§åœ¢é¢æ°ã©ã¹ã¿ã©ã€ã¶ã ããã ãã§ãïŒ
our_gl.hãã¡ã€ã«ã®å
容ã¯
次ã®ãšããã§ãïŒå°ãåŸã®IShaderã®ç®çã«ã€ããŠïŒã
#include "tgaimage.h" #include "geometry.h" extern Matrix ModelView; extern Matrix Viewport; extern Matrix Projection; void viewport(int x, int y, int w, int h); void projection(float coeff=0.f);
main.cppãã¡ã€ã«ã«ã¯66è¡ããæ®ã£ãŠããªãã®ã§ããã®å
šäœãæäŸããŸãïŒã·ãŒãã«ã€ããŠã¯ç³ãèš³ãããŸãããããã®ãã¡ã€ã«ã奜ããªã®ã§ãã¹ãã€ã©ãŒã®äžã«é ããŸããïŒã
#include <vector> #include <iostream> #include "tgaimage.h" #include "model.h" #include "geometry.h" #include "our_gl.h" Model *model = NULL; const int width = 800; const int height = 800; Vec3f light_dir(1,1,1); Vec3f eye(1,1,3); Vec3f center(0,0,0); Vec3f up(0,1,0); struct GouraudShader : public IShader { Vec3f varying_intensity; // written by vertex shader, read by fragment shader virtual Vec4f vertex(int iface, int nthvert) { varying_intensity[nthvert] = std::max(0.f, model->normal(iface, nthvert)*light_dir); // get diffuse lighting intensity Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert)); // read the vertex from .obj file return Viewport*Projection*ModelView*gl_Vertex; // transform it to screen coordinates } virtual bool fragment(Vec3f bar, TGAColor &color) { float intensity = varying_intensity*bar; // interpolate intensity for the current pixel color = TGAColor(255, 255, 255)*intensity; // well duh return false; // no, we do not discard this pixel } }; int main(int argc, char** argv) { if (2==argc) { model = new Model(argv[1]); } else { model = new Model("obj/african_head.obj"); } lookat(eye, center, up); viewport(width/8, height/8, width*3/4, height*3/4); projection(-1.f/(eye-center).norm()); light_dir.normalize(); TGAImage image (width, height, TGAImage::RGB); TGAImage zbuffer(width, height, TGAImage::GRAYSCALE); GouraudShader shader; for (int i=0; i<model->nfaces(); i++) { Vec4f screen_coords[3]; for (int j=0; j<3; j++) { screen_coords[j] = shader.vertex(i, j); } triangle(screen_coords, shader, image, zbuffer); } image. flip_vertically(); // to place the origin in the bottom left corner of the image zbuffer.flip_vertically(); image. write_tga_file("output.tga"); zbuffer.write_tga_file("zbuffer.tga"); delete model; return 0; }
詳现ã«åæããŸãããã ããããŒãã¹ãããããŠãããã°ããŒãã«å®æ°ïŒç»é¢ãµã€ãºãã«ã¡ã©ã®èšçœ®å Žæãªã©ïŒã«é²ã¿ãŸãã
æ¬¡ã®æ®µèœã§GouraudShaderã®æ§é ãåæããã¹ãããããŸãã ããããçŽæ¥mainïŒïŒã«ãªããŸãïŒ
- .objãã¡ã€ã«ããã¢ãã«ãèªã¿åã
- ModelViewãProjectionãããã³Viewportãããªãã¯ã¹ã®åæåïŒå€æ°èªäœã¯our_glã¢ãžã¥ãŒã«ã«ä¿åãããããšãæãåºããŠãã ããïŒ
- ã¢ãã«ããŠã©ãŒã¯ã¹ã«ãŒããŠæç»ããŸã
æåŸã®æ®µèœã§ã¯ã楜ãã¿ãå§ãŸããŸãã å€åŽã®ãµã€ã¯ã«ã¯ãã¹ãŠã®äžè§åœ¢ãééããŸãã
å
åŽã®ã«ãŒãã¯äžè§åœ¢ã®ãã¹ãŠã®é ç¹ãééãããããã®ããããã«å¯ŸããŠé ç¹ã·ã§ãŒããŒãåŒã³åºããŸãã
é ç¹ã·ã§ãŒããŒã®äž»ãªç®çã¯ã倿ãããé ç¹ã®åº§æšãèšç®ããããšã§ãã 2çªç®ã¯ããã©ã°ã¡ã³ãã·ã§ãŒããŒã®ããŒã¿ãæºåããããšã§ããäžè§åœ¢ã®ãã¹ãŠã®é ç¹ã«å¯ŸããŠé ç¹ã·ã§ãŒããŒãåŒã³åºããåŸã¯ã©ããªããŸããïŒ äžè§åœ¢ã®ã©ã¹ã¿ã©ã€ã¶ãŒãåŒã³åºãããšãã§ããŸãã å
éšã§äœãèµ·ãã£ãŠããã®ãããããŸããïŒãã¡ãããèªåã§æžããããã§ã¯ãããŸããïŒã 1ã€ã®è峿·±ãããšãé€ããŠã äžè§åœ¢ã©ã¹ã¿ã©ã€ã¶ãŒã¯é¢æ°ãåŒã³åºããããããã©ã°ã¡ã³ãã·ã§ãŒããŒã«æž¡ããŸãã ã€ãŸããäžè§åœ¢å
ã®åãã¯ã»ã«ã«å¯ŸããŠãã©ã¹ã¿ã©ã€ã¶ãŒã¯ãã©ã°ã¡ã³ãã·ã§ãŒããŒãåŒã³åºããŸãã
ãã©ã°ã¡ã³ãã·ã§ãŒããŒã®äž»ãªç®çã¯ãçŸåšã®ãã¯ã»ã«ã®è²ã決å®ããããšã§ãã ã»ã«ã³ããª-trueãè¿ãããšã«ããããã®ãã¯ã»ã«ã®æç»ãæåŠããããšãã§ããŸããOpenGL 2ãããã©ã€ã³ã¯æ¬¡ã®ããã«ãªããŸãã

çãã°ã©ãã£ãã¯ã³ãŒã¹ããããããããã§ã¯ããã2ã€ã®ã·ã§ãŒããŒã«éå®ããŸãã OpenGLã®æ°ããããŒãžã§ã³ã§ã¯ããžãªã¡ããªããã®å Žã§äœæã§ããæ°ããã¿ã€ãã®ã·ã§ãŒããŒãç»å ŽããŸããã ãã®å³ã§ã¯ãéãã¹ããŒãžã¯ããã°ã©ã ã§ããªãã¹ããŒãžã§ãããèµ€ãã¹ããŒãžã¯ããã°ã©ã å¯èœã§ãã å®éãã¡ã€ã³ïŒïŒã¯ããªããã£ãåŠçã§ãã é ç¹ã·ã§ãŒããŒãåŒã³åºããŸãã ããªããã£ããã«ããŒã¯ãããŸããã æããªäžè§åœ¢ãçŽæ¥æç»ããŸãïŒããªããã£ãåŠçã§æ¥çããŸããïŒã triangleïŒïŒé¢æ°ã¯ã©ã¹ã¿ã©ã€ã¶ãŒã§ãããåãã€ã³ãã«å¯ŸããŠãã©ã°ã¡ã³ãã·ã§ãŒããŒãåŒã³åºããz-bufferãªã©ã§æ·±åºŠãã§ãã¯ãè¡ããŸãã
ããã ãã§ã ã·ã§ãŒããŒãäœã§ããããç¥ã£ãŠããŠããããã®ããã°ã©ãã³ã°ãéå§ã§ããŸãã
ã·ã§ãŒããŒã®ç§ã®å
·äœåãGuroçè²ã®äŸã§ã©ã®ããã«æ©èœããã
main.cppã³ãŒãã§æã£ãŠããã·ã§ãŒããŒãèŠãŠã¿ãŸãããã ãæ³åã®ãšãããæåã®ã·ã§ãŒããŒã¯Guroã®è²åãã§ãã
é ç¹ã·ã§ãŒããŒã¯ã.objãã¡ã€ã«ããé ç¹ãèªã¿åãã4次å
空éã«æµžãïŒåã®èšäºãåç
§ïŒããã®ç»é¢åº§æšãèŠã€ããŸãã 3Dã§æåœ±ããããã€ã³ããè¿ããŸããããã®åã«ãæå®ãããé ç¹ã®æ¡æ£ç
§æä¿æ°ãèæ
®ããŠãvariing_intensityãã¯ãã«ã®å¯Ÿå¿ããã³ã³ããŒãã³ãã«ä¿åããŸãã
ããäžåºŠã䟿å®äžã®ã³ãŒãïŒ
é衚瀺ã®ããã¹ã Vec3f varying_intensity; // written by vertex shader, read by fragment shader virtual Vec4f vertex(int iface, int nthvert) { varying_intensity[nthvert] = std::max(0.f, model->normal(iface, nthvert)*light_dir); // get diffuse lighting intensity Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert)); // read the vertex from .obj file return Viewport*Projection*ModelView*gl_Vertex; // transform it to screen coordinates }
GLSLã§ã¯ãvariingã¯äºçŽèªã§ãããããã®é¡äŒŒç¹ã匷調ããããã«ãvariing_intensityãååãšããŠäœ¿çšããŸããïŒGLSLã«ã€ããŠã¯ã7çªç®ã®èšäºã§èª¬æããŸãïŒã äžè§åœ¢ã®å
éšã§è£éãããããŒã¿ãããŸããŸãªæ§é ã«ä¿åãããã©ã°ã¡ã³ãã·ã§ãŒããŒãè£éãããããŒã¿ãåãåããŸãã
ãã©ã°ã¡ã³ãã·ã§ãŒããŒãåæããŠã¿ãŸããããããäžåºŠã䟿å®äžã³ãŒããèŠãŠã¿ãŸãããã
é衚瀺ã®ããã¹ã Vec3f varying_intensity; // written by vertex shader, read by fragment shader // [...] virtual bool fragment(Vec3f bar, TGAColor &color) { float intensity = varying_intensity*bar; // interpolate intensity for the current pixel color = TGAColor(255, 255, 255)*intensity; // well duh return false; // no, we do not discard this pixel }
äžè§åœ¢å
ã®åãã¯ã»ã«ã«å¯ŸããŠã©ã¹ã¿ã©ã€ã¶ãŒã«ãã£ãŠåŒã³åºãããŸãã
éå¿åº§æšã®å
¥åãåãåããvariing_ããŒã¿ãè£éããŸãã
ã€ãŸããè£é匷床ã¯ãvariing_intensity [0] * bar [0] + changing_intensity [1] * bar [1] + changing_intensity [2] * bar [2]ããŸãã¯åã«variing_intensity * barãã¯ãã«éã®ã¹ã«ã©ãŒç©ãšããŠèšç®ã§ããŸãã ãã¡ãããå®éã®GLSLã§ã¯ãã·ã§ãŒããŒã¯ãã®å€ãæºåããŸãã
ãã©ã°ã¡ã³ãã·ã§ãŒããŒã¯ããŒã«å€ãè¿ãããšã«æ³šæããŠãã ããã ã©ã¹ã¿ã©ã€ã¶ãŒã®
å
éš ïŒ
our_gl.cpp ãäžè§åœ¢ïŒïŒïŒãèŠããšããã®æå³ã¯ç°¡åã«çè§£ã§ããŸãã
é衚瀺ã®ããã¹ã TGAColor color; bool discard = shader.fragment(c, color); if (!discard) { zbuffer.set(Px, Py, TGAColor(Pz)); image.set(Px, Py, color); }
ã·ã§ãŒããŒã¯æå®ããããã¯ã»ã«ã®æç»ãæåŠããå Žåãããããã®åŸãã©ã¹ã¿ã©ã€ã¶ãŒã¯zãããã¡ãŒãæŽæ°ããã«z座æšãç¡èŠããŸãã ãã€ããªãã¹ã¯ãäœæãããå Žåããä»ã«æãã€ããããšãããå Žåã«äŸ¿å©ã§ãã
ãã¡ãããã©ã¹ã¿ã©ã€ã¶ã¯ããªãã®é ã«æµ®ãã¶ããšãèããããšããã§ããªãã®ã§ãäºåã«ã·ã§ãŒãã§ã³ã³ãã€ã«ããããšã¯ã§ããŸããã ããã§ã¯ãæœè±¡ã¯ã©ã¹IShaderã圹ç«ã¡ãŸãã Uffãç§ã¯ãã£ãã«æœè±¡ã¯ã©ã¹ã䜿çšããŸããããããããªããã°æœè±¡ã¯ã©ã¹ãæªãå ŽåããããŸãã 颿°ãžã®ãã€ã³ã¿ãŒããŸã£ããæž¡ããããããŸããïŒ
æåã®ä¿®æ£
é衚瀺ã®ããã¹ã virtual bool fragment(Vec3f bar, TGAColor &color) { float intensity = varying_intensity*bar; if (intensity>.85) intensity = 1; else if (intensity>.60) intensity = .80; else if (intensity>.45) intensity = .60; else if (intensity>.30) intensity = .45; else if (intensity>.15) intensity = .30; else intensity = 0; color = TGAColor(255, 155, 0)*intensity; return false; }
ç
§æåŒ·åºŠã®åºå®ã»ãããèš±å¯ããŸãã ããã圌ã®ä»äºã®çµæã§ãã
ã¢ãã«ã®ãã¯ã¹ãã£ãªã³ã°
Phongã®è²åããã¹ãããããã³ã¡ã³ãã§è©³çްã«èª¿ã¹ãŸããããã¯ã¹ãã£ã課ããŸãããã ãããè¡ãã«ã¯ãUV座æšãè£éããå¿
èŠããããŸãã äœãæ°ããããšã¯ãããŸããã2è¡ïŒuvïŒãš3åïŒ3ã€ã®é ç¹ã®ãã¯ã¹ãã£åº§æšïŒã«ãããªãã¯ã¹ã远å ããã ãã§ãã
é衚瀺ã®ããã¹ã struct Shader : public IShader { Vec3f varying_intensity; // written by vertex shader, read by fragment shader mat<2,3,float> varying_uv; // same as above virtual Vec4f vertex(int iface, int nthvert) { varying_uv.set_col(nthvert, model->uv(iface, nthvert)); varying_intensity[nthvert] = std::max(0.f, model->normal(iface, nthvert)*light_dir); // get diffuse lighting intensity Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert)); // read the vertex from .obj file return Viewport*Projection*ModelView*gl_Vertex; // transform it to screen coordinates } virtual bool fragment(Vec3f bar, TGAColor &color) { float intensity = varying_intensity*bar; // interpolate intensity for the current pixel Vec2f uv = varying_uv*bar; // interpolate uv for the current pixel color = model->diffuse(uv)*intensity; // well duh return false; // no, we do not discard this pixel } };
ããŒãã«ãããã³ã°
ããŠãããã§ãã¯ã¹ãã£åº§æšãã§ããŸããã ããããè²ã ãã§ãªããã¯ã¹ãã£ã«ãä¿åã§ããŸããRGBã¯xyzã衚ãã®ã«ååã§ãã
ç»åã®ãã¯ã»ã«ããšã«ïŒä»¥åã®ããã«é ç¹ã ãã§ãªãïŒïŒéåžžã®ãã¯ãã«ãäžãããããªãã¯ã¹ãã£ãããŒãããŸãããã
ã¡ãªã¿ã«ããã®ãããªåçãšæ¯èŒããŠãã ãããããã¯åãæ
å ±ã§ãããç°ãªããã¬ãŒã ã«ãããŸãã
ãããã®ç»åã®1ã€ã¯ãã°ããŒãã«åº§æšç³»ã®æ³ç·ãã¯ãã«ãæäŸãããã1ã€ã¯ããªããžã§ã¯ãã®åãã€ã³ãã«å¯ŸããŠæ±ºå®ãããæ¥ç·ã®ãã¯ãã«ãæäŸããŸãã ãã®ãã¯ã¹ãã£ã§ã¯ããã¯ãã«zã¯ãªããžã§ã¯ãã®æ³ç·ããã¯ãã«xã¯ãµãŒãã§ã¹ã®æ²çã®äž»æ¹åã®ãã¯ãã«ãyã¯ãããã®ãã¯ãã«ç©ã§ãã
æŒç¿1
ãããã®ãã¯ã¹ãã£ã®ã©ããã°ããŒãã«åº§æšã§äžããããã©ã®æ¥ç·ã§ãªããžã§ã¯ãã«æ¥ããŠããã®ãæããŠãã ããã
æŒç¿2
æ¥ç·ãŸãã¯ã°ããŒãã«ã®ã©ã¡ãã®ãã¯ã¹ãã£ãŒåœ¢åŒãæšå¥šãããŸããïŒ ãªãã§ïŒ
ã³ã¡ã³ãã§ãããã®è³ªåãžã®åçãæäŸããããã«ïŒã³ã¡ã³ããäºåã«èªãããšãªãïŒãæ°è»œã«ïŒé衚瀺ã®ããã¹ã struct Shader : public IShader { mat<2,3,float> varying_uv; // same as above mat<4,4,float> uniform_M; // Projection*ModelView mat<4,4,float> uniform_MIT; // (Projection*ModelView).invert_transpose() virtual Vec4f vertex(int iface, int nthvert) { varying_uv.set_col(nthvert, model->uv(iface, nthvert)); Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert)); // read the vertex from .obj file return Viewport*Projection*ModelView*gl_Vertex; // transform it to screen coordinates } virtual bool fragment(Vec3f bar, TGAColor &color) { Vec2f uv = varying_uv*bar; // interpolate uv for the current pixel Vec3f n = proj<3>(uniform_MIT*embed<4>(model->normal(uv))).normalize(); Vec3f l = proj<3>(uniform_M *embed<4>(light_dir )).normalize(); float intensity = std::max(0.f, n*l); color = model->diffuse(uv)*intensity; // well duh return false; // no, we do not discard this pixel } }; [...] Shader shader; shader.uniform_M = Projection*ModelView; shader.uniform_MIT = (Projection*ModelView).invert_transpose(); for (int i=0; i<model->nfaces(); i++) { Vec4f screen_coords[3]; for (int j=0; j<3; j++) { screen_coords[j] = shader.vertex(i, j); } triangle(screen_coords, shader, image, zbuffer); }
GLSLã®uniformããŒã¯ãŒãã䜿çšãããšãã·ã§ãŒããŒã«å®æ°ãæž¡ãããšãã§ããŸããããã§ã¯ãæ³ç·ãã¯ãã«ã倿ããããã«Projection * Modelviewãããªãã¯ã¹ãšãã®é転眮ãããªãã¯ã¹ãã·ã§ãŒããŒã«æž¡ããŸããïŒåã®èšäºãåç
§ïŒã
ã€ãŸãããã¹ãŠã以åãšåãã§ãæ³ç·ãã¯ãã«ãè£éããªãã ãã§ãããæºåããããã¯ã¹ãã£ãããããããå
ãšæ³ç·ãã¯ãã«ã®æ¹åãã¯ãã«ãå¿ããã«ååŸããŸãã
å
æ²¢ã®ãã衚é¢ãŸãã¯é¡é¢åå°ãããã³ã°
äŒè©±ãç¶ããŸãïŒ ïŒå®ãïŒã¢ã€ããªãã¯ã®å Žåãã¢ãã«ãç
§ãããã
ã«Phongè¿äŒŒã䜿çš
ããŸãã ãã®é åã®å
šäœã®ç
§æã¯ãã·ãŒã³å
šäœã®äžå®ã®ç
§æïŒã¢ã³ããšã³ãç
§æïŒããããŸã§æ€èšããŠããããããµãŒãã§ã¹ã®ç
§æïŒæ¡æ£ç
§æïŒãå
æ²¢ã®ãã衚é¢ã®ç
§æïŒé¡é¢ç
§æïŒã§æ§æãããŸãã

ããããµãŒãã§ã¹ã®èŒåºŠã¯ãæ³ç·ãã¯ãã«ãšã©ã€ããã¯ãã«ã®éã®è§åºŠã®äœåŒŠãšèŠãªãããŸããã ã€ãŸãã衚é¢ãã»ãŒãã¹ãŠã®æ¹åã«å
ãæ£ä¹±ãããšä»®å®ããŸããã å
æ²¢ã®ãã衚é¢ã¯ã©ããªããŸããïŒ æ¥µç«¯ãªå ŽåïŒé¡é¢ã®å ŽåïŒããã®ãã¯ã»ã«ããã®å
æºãèŠããšå
ããããŸãã
åçã¯æ¬¡ã®ãšããã§ãã

ãã®ç¹ã«ã€ããŠãããããµãŒãã§ã¹ã®ç
§æããã¯ãã«
nãš
lã®éã®è§åºŠã®ã³ãµã€ã³ãšèããå Žåããã¯ãã«
r ïŒåå°å
ïŒãš
v ïŒãã¥ãŒã®æ¹åïŒã®éã®è§åºŠã®ã³ãµã€ã³ã«é¢å¿ããããŸãã
æŒç¿3ïŒãã¯ãã«nãšlãæã€ãã¯ãã«rãèŠã€ãã
é衚瀺ã®ããã¹ãnãšlãæ£èŠåãããŠããå Žåã r = 2 n < n ã l > -l
ããããµãŒãã§ã¹ã®ã©ã€ããè§åºŠã®äœåŒŠãšèŠãªããããšãæãåºããŠãã ããã ããããå
æ²¢ã®ããå
æºã¯ãã¯ããã«çŠç¹ã®åã£ãããŒã ã§å
æºãåæ ããŸãïŒ åãããšãè¡ã£ãŠããã®ã³ãµã€ã³ã10ä¹ããå Žåã¯ã©ããªããŸããïŒ ãŠããã£æªæºã®æ°ã¯ãèªåã«æ¯ã¹ãŠ10åã®1ã«æžå°ããããšãæãåºããŠãã ããïŒ ã€ãŸãã10床ã§ã¯ç
§æã®ååŸã倧å¹
ã«å°ãããªããŸãã ãããŠã100åã®1ã¯ããã«å°ãããªããŸãã ãã®åºŠåãã¯ã衚é¢ã®ãã¹ãŠã®ãã€ã³ãã«å
æ²¢ãäžãããã¯ã¹ãã£ã«ä¿åãããŸãã
é衚瀺ã®ããã¹ã struct Shader : public IShader { mat<2,3,float> varying_uv; // same as above mat<4,4,float> uniform_M; // Projection*ModelView mat<4,4,float> uniform_MIT; // (Projection*ModelView).invert_transpose() virtual Vec4f vertex(int iface, int nthvert) { varying_uv.set_col(nthvert, model->uv(iface, nthvert)); Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert)); // read the vertex from .obj file return Viewport*Projection*ModelView*gl_Vertex; // transform it to screen coordinates } virtual bool fragment(Vec3f bar, TGAColor &color) { Vec2f uv = varying_uv*bar; Vec3f n = proj<3>(uniform_MIT*embed<4>(model->normal(uv))).normalize(); Vec3f l = proj<3>(uniform_M *embed<4>(light_dir )).normalize(); Vec3f r = (n*(n*l*2.f) - l).normalize(); // reflected light float spec = pow(std::max(rz, 0.0f), model->specular(uv)); float diff = std::max(0.f, n*l); TGAColor c = model->diffuse(uv); color = c; for (int i=0; i<3; i++) color[i] = std::min<float>(5 + c[i]*(diff + .6*spec), 255); return false; } };
å®éãä¿æ°ãé€ããŠãããã§èª¬æãããã®ã¯ãããŸããã 䞊ãã§
forïŒint i = 0; i <3; i ++ïŒcolor [i] = std :: min <float>ïŒ5 + c [i] *ïŒdiff + .6 * specïŒã255ïŒ;
ã¢ã³ããšã³ãã«5ããã£ãã¥ãŒãºã«1ãã¹ããã¥ã©ã«0.6ãåããŸããã ã©ã¡ããåããã¯ããªã次第ã§ãã ããã¯ãããŸããŸãªçŽ æã®å°è±¡ãäžããŸãã ã»ãšãã©ã®å Žåãã¢ãŒãã£ã¹ãããäžããããŸãããããã®å Žåã¯æã£ãŠããŸããã®ã§ããã«ããŒã¶ãŒããåãåºããŸããã
ãããã«
ä¿¡ããããªããããªã·ãŒã³ãã¬ã³ããªã³ã°ããæ¹æ³ãåŠã³ãŸããããç
§æã¯ãŸã çæ³ããã¯ã»ã©é ãã§ãã æ¬¡ã®èšäºã§ã¯ãã·ã£ããŠãããã³ã°ãšã¯äœãã«ã€ããŠèª¬æããŸãã çŽäº€ããèšäºã®1ã€ã§ãæ°ããã©ã¹ã¿ã©ã€ã¶ã®åäœã«ã€ããŠèª¬æããŸãïŒå€ãã©ã¹ã¿ã©ã€ã¶ã§åãã³ãŒããå®è¡ããããšã劚ãããã®ã¯äœããããŸããïŒïŒã