visual studio - Omni-directional light in raytracing program gives wrong render c++ -


i trying implement omni-directional light source (a.k.a., point light source) in raytracing program in c++. not getting expected results, can't figure out problem. maybe can see doing wrong. have included 2 functions responsible raytracing , light. closestintersection function finds closest intersection , triangle. used later in directlight function. appreciate help.

#include <iostream> #include <glm/glm.hpp> #include <sdl.h> #include "sdlauxiliary.h" #include "testmodel.h" #include "math.h"  using namespace std; using glm::vec3; using glm::mat3;  // ---------------------------------------------------------------------------- // global variables  const int screen_width = 500; const int screen_height = 500; sdl_surface* screen; int t; vector<triangle> triangles; float focallength = 900; vec3 camerapos(0, 0, -4.5);  vec3 lightpos(0.5, 0.5, 0); vec3 lightcolor = 14.f * vec3(1,1,1);  // translate camera float translation = 0.1;        // use set translation increment  // rotate camera float yaw; vec3 truecamerapos;  const float pi = 3.1415927;  // ---------------------------------------------------------------------------- // classes  class intersection;  // ---------------------------------------------------------------------------- // functions void update(); void draw(); bool closestintersection(vec3 start, vec3 dir, const vector<triangle>& triangles,     intersection& closestintersection); vec3 directlight(const intersection& i); // ---------------------------------------------------------------------------- // structures struct intersection {     vec3 position;     float distance;     int triangleindex; };  float m = std::numeric_limits<float>::max();  int main(int argc, char* argv[]) {     loadtestmodel(triangles);      screen = initializesdl(screen_width, screen_height);     t = sdl_getticks(); // set start value timer.      while (noquitmessagesdl())     {         update();         draw();     }      sdl_savebmp(screen, "screenshot.bmp");     return 0; }  void update() {     // compute frame time:     int t2 = sdl_getticks();     float dt = float(t2 - t);     t = t2;     cout << "render time: " << dt << " ms." << endl;     } }  void draw() {     if (sdl_mustlock(screen))         sdl_locksurface(screen);      (int y = 0; y<screen_height; ++y)     { (int x = 0; x < screen_width; ++x) {     vec3 start = camerapos;     vec3 dir(x - screen_width / 2, y - screen_height / 2, focallength);     intersection intersection;     if (closestintersection(start, dir, triangles, intersection))     {         //vec3 thecolor = triangles[intersection.triangleindex].color;         vec3 thecolor = directlight(intersection);         putpixelsdl(screen, x, y, thecolor);     }     else     {         vec3 color(0, 0, 0);         putpixelsdl(screen, x, y, color);     } }     }      if (sdl_mustlock(screen))         sdl_unlocksurface(screen);      sdl_updaterect(screen, 0, 0, 0, 0); }  bool closestintersection(vec3 s, vec3 d,     const vector<triangle>& triangles, intersection& closestintersection) {     closestintersection.distance = m;     (size_t = 0; < triangles.size(); i++)     {         vec3 v0 = triangles[i].v0;         vec3 v1 = triangles[i].v1;         vec3 v2 = triangles[i].v2;         vec3 u = v1 - v0;         vec3 v = v2 - v0;         vec3 b = s - v0;         vec3 x;          // determinant of = [-d u v]         float det = -d.x * ((u.y * v.z) - (v.y * u.z)) -             u.x * ((-d.y * v.z) - (v.y * -d.z)) +             v.x * ((-d.y * u.z) - (u.y * -d.z));          // cramer'r rule t = x.x         x.x = (b.x * ((u.y * v.z) - (v.y * u.z)) -             u.x * ((b.y * v.z) - (v.y * b.z)) +             v.x * ((b.y * u.z) - (u.y * b.z))) / det;          if (x.x >= 0)         {             // cramer'r rule u = x.y             x.y = (-d.x * ((b.y * v.z) - (v.y * b.z)) -                 b.x * ((-d.y * v.z) - (v.y * -d.z)) +                 v.x * ((-d.y * b.z) - (b.y * -d.z))) / det;              // cramer'r rule v = x.z             x.z = (-d.x * ((u.y * b.z) - (b.y * u.z)) -                 u.x * ((-d.y * b.z) - (b.y * -d.z)) +                 b.x * ((-d.y * u.z) - (u.y * -d.z))) / det;              if (x.y >= 0 && x.z >= 0 && x.y + x.z <= 1 && x.x < closestintersection.distance)             {                 closestintersection.position = x;                 closestintersection.distance = x.x;                 closestintersection.triangleindex = i;             }         }      }     //end of loop      if (closestintersection.distance != m)     {         return true;     }     else     {         return false;     }  }  vec3 directlight(const intersection& i) {     vec3 n = triangles[i.triangleindex].normal;     vec3 r = lightpos - i.position;     float r2 = r.x * r.x + r.y * r.y + r.z * r.z;     vec3 d = (lightcolor * fmaxf((glm::dot(glm::normalize(r), n)), 0)) / (4 * pi * r2);     return d; } 

if i'm understanding code in closestintersection correctly, here's it's doing each triangle:

  • let u,v vectors 1 vertex of triangle other 2 vertices. let d (the reverse of) direction of ray we're considering.
  • and let b vector vertex of triangle camera.
  • find p,q,r b = pd+qu+rv (p,q,r code calls x.x, x.y, x.z).
  • now ray meets triangle if p>0, q>=0, r>=0, q+r<=1 , distance intersection point p.

so, conditions on q,r make sense; idea b-qu-rv vector camera relevant point in triangle , it's in direction d. distances aren't distances, along single ray they're the same multiple of actual distance, means works fine determining triangle you've hit, , that's use them for. far, good.

but closestintersection.position = x; , surely that's wrong, because x isn't in same coordinate system camera location, triangle vertices, etc. it's in funny "how of d, how of u, how of v" coordinate system isn't same 1 triangle next. (which why getting discontinuities @ triangle boundaries within single face, think.)

try setting v0+x.y*(v1-v0)+x.z*(v2-v0) instead (i think right; it's meant actual point ray crosses triangle, in same coordinates other points) , see does.


Comments

Popular posts from this blog

Ansible - ERROR! the field 'hosts' is required but was not set -

customize file_field button ruby on rails -

SoapUI on windows 10 - high DPI/4K scaling issue -