2

私は CS の学生です。最終試験では、レイ トレーシングを使用して複数の球体に反射を作成するように言われました。それは、完成したときの様子の写真を除いて、ほぼ文字通り私たちが指示のために得たものです. そのため、ライトからの適切なシェーディングでマッピングされた反射 (レイ トレーシングを使用) である球が必要です。

複数の球体があることと、ルーブリック用に彼がくれた写真のように見えないという事実を除いて、すべてが機能しています。

複数の球体についてはどうすればよいかよくわかりませんが、それらを 2D 配列に格納し、コードのいくつかのセクションを変更する必要があると思います。

私が考えたのは、sphere_intersect と find_reflect を変更して、どの球体が分析されているかを含めることでした。次に、find_reflect を変更して、新しいベクトル u が計算されるときにその開始点 (P0) も更新されるようにします。次に、光線が球体に当たった場合、光線が反射された回数をカウントする必要があります。ある時点で (おそらく 10 回後) 終了し、ピクセルを描画します。追加のタッチのために、私が信じている球の法線を見つけることを要求する球に単色を追加したいと思います。

とにかく、彼の写真、私の写真、そしてソースコードを添付します。うまくいけば、誰かがこれについて私を助けてくれます。

前もって感謝します!

教授の球

ここに画像の説明を入力

私の球

ここに画像の説明を入力

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#include <string>

#define screen_width 750
#define screen_height 750
#define true 1
#define false 0
#define perpendicular 0

int gridXsize = 20;
int gridZsize = 20;
float plane[] = {0.0, 1.0, 0.0, -50.0,};
float sphere[] = {250.0, 270.0, -100.0, 100.0};
float eye[] = {0.0, 400.0, 550.0};
float light[] = {250.0, 550.0, -200.0};

float dot(float *u, float *v)
{
   return u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
}

void norm(float *u)
{
   float norm = sqrt(abs(dot(u,u)));

   for (int i =0; i <3; i++)
   {
      u[i] = u[i]/norm;
   }

}

float plane_intersect(float *u, float *pO)
{
   float normt[3] = {plane[0], plane[1], plane[2]};

   float s;

   if (dot(u,normt) == 0)
   {
      s = -10;
   }

   else
   {
      s = (plane[3]-(dot(pO,normt)))/(dot(u,normt));
   }

   return s;
}

float sphere_intersect(float *u, float *pO)
{

   float deltaP[3] = {sphere[0]-pO[0],sphere[1]-pO[1],sphere[2]-pO[2]};
   float deltLen = sqrt(abs(dot(deltaP,deltaP)));
   float t=0;
   float answer;
   float det;

   if ((det =(abs(dot(u,deltaP)*dot(u,deltaP))- (deltLen*deltLen)+sphere[3]*sphere[3])) < 0)
   {
      answer = -10;
   }

   else
   {
      t =-1*dot(u,deltaP)- sqrt(det) ;

          if (t>0)
      {
         answer = t;
      }

      else
      {
         answer = -10;
      }
   }

   return answer;
}

void find_reflect(float *u, float s, float *pO)
{
   float n[3] = {pO[0]+s *u[0]-sphere[0],pO[1]+s *u[1]-sphere[1],pO[2]+s *u[2]- sphere[2]};
   float l[3] = {s *u[0],s *u[1],s *u[2]};
   u[0] =(2*dot(l,n)*n[0])-l[0];
   u[1] = (2*dot(l,n)*n[1])-l[1];
   u[2] = (2*dot(l,n)*n[2])-l[2];
}

float find_shade(float *u,float s, float *pO)
{
   float answer;
   float lightVec[3] = {light[0]-(pO[0]+s *u[0]), light[1]-(pO[1]+s *u[1]), light[2]-(pO[2]+s *u[2])};
   float n[3] = {pO[0]+s *u[0]-sphere[0],pO[1]+s *u[1]-sphere[1],pO[2]+s *u[2]-sphere[2]};
   answer = -1*dot(lightVec,n)/(sqrt(abs(dot(lightVec,lightVec)))*sqrt(abs(dot(n,n))));
   return answer;
}

void init()
{
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0,screen_width,0,screen_height);
}

void display()
{
   glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   for (int i=0; i < screen_width; i++)
   {
      for (int j=0; j < screen_height; j++)
      {
         float ray[3] = {1*(eye[0]-i),-1*(eye[1]-j),1*eye[2]};
         float point[3] = {i,j,0};
         norm(ray);
         int plotted = false;

         while (!plotted)
         {
            float s_plane = plane_intersect(ray, point);
            float s_sphere = sphere_intersect(ray, point);

            if (s_plane <= 0 && s_sphere <=0)
            {
               glColor3f(0,0,0);
               glBegin(GL_POINTS);
               glVertex3f(i,j,0);
               glEnd();
               plotted = true;
            }

            else if (s_sphere >= 0  && (s_plane <=0 || s_sphere <= s_plane))
            {
               find_reflect(ray, s_sphere, point);
            }

            else if (s_plane >=0 && (s_sphere <=0 ||s_plane <= s_sphere))
            {
               float shade = find_shade(ray, s_plane, point);
               float xx = s_plane*ray[0] + eye[0];
               float z = s_plane*ray[2] + eye[2];

               if (abs((int)xx/gridXsize)%2 == abs((int)z/gridZsize)%2)
               {
                  glColor3f(shade,0,0);
               }

               else
               {
                  glColor3f(shade,shade,shade);
               }

               glBegin(GL_POINTS);
               glVertex3f(i,j,0);
               glEnd();
               plotted = true;
            }
         }
      }
   }

   glFlush();
}

int main(int argc, char **argv)
{
   glutInit(&argc, argv);
   glutCreateWindow("Ray Trace with Sphere.");
   glutInitWindowSize(screen_width,screen_height);
   glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
   glutDisplayFunc(display);
   init();
   glutMainLoop();
   return 0;
}
4

1 に答える 1

3

このようなトピックはウェブ上で何千回も取り上げられているため、教授はあまり多くを語っていません。「Whitted Raytracing」をチェックしてください ;) これは宿題です。宿題をせずに手伝う

段階的に行います。画像を 1 つの段階で再現しようとしないでください。

  • 平面の緑色のピクセル、球体の赤色のピクセル、何もヒットしない場合、1 つの球体が機能します。交差点を正しく計算するだけで十分です。あなたの写真を見ると、そもそも交差点が正しくないように見えます
  • 前と同じで、いくつかの球体があります。1 つの球体と同じ : すべてのオブジェクトの交差をチェックし、視点から最も近い交差を維持します。
  • 前と同じですが、検出された交差点ごとに受信した光の量も計算し、球体には赤の陰影を、平面には緑の陰影を付けます。(ヒント:内積^^)
  • 平面のテクスチャ
  • 球の反射。ヒント: ミラーは光の 100% を反射するのではなく、ほんの一部です。
于 2011-12-12T03:37:52.923 に答える