Ray Tracing-final version

Source: Internet
Author: User

Today, I spent another day on ray tracing, but obviously, I have gained a lot.

First, it took half an hour to push the form of Sphere reflection and refraction, and then changed the position of the light source. The first figure shown below is as follows:

I was completely shocked. Why did it suddenly become so good? (We can compare the figure of yesterday)

Whack reminded me that I pulled the light source down, so the above walls experienced a halo, increasing the sense of reality. Thus, I added a halo, and the brightness of the Halo decreased linearly with the distance:

Ohno, this halo is really ugly, so I changed it to the cosine function:

Well, it's pretty good!

Next, I constantly modify the parameters:

Well, the Sawtooth is very serious .. ~~~

You can look for details. One of the two pictures above is that I allow the reflection to have a recursive depth of 4, and the other is 6.

It took two hours to adjust the parameters. Then, when the code was reached, the texture task was completed!

It's hard to see how image files are read .. I only won't read the output. I asked the lrj teacher, checked the Wiki, and finally turned to the FHQ code. Finally, I realized how to read the BMP file.

The first picture posted! Thrilling! (Hey, isn't that a violation of the Authority ?)

This figure clearly shows the refraction, And the inverted solid phase shown in the glass ball on the right.

The first texture is successful, so, Me ------

Added a background, but the picture is too peacekeeping =!

Finally, I made the most satisfactory HD wallpaper! 1440*900! (Oh no, compressed! It looks like a gray layer ..)

Finally, post lengthy code

#include <cmath>#include <cstdio>#include <algorithm>#include <vector>#define maxdepth 6#define e 1e-8using namespace std;struct P{double x,y,z;};P operator +(P a,P b) {return (P){a.x+b.x,a.y+b.y,a.z+b.z};}P operator -(P a,P b) {return (P){a.x-b.x,a.y-b.y,a.z-b.z};}P operator *(P a,double b) {return (P){a.x*b,a.y*b,a.z*b};}P operator /(P a,double b) {return a*(1/b);}P operator *(P a,P b) {return (P){a.y*b.z-a.z*b.y,a.z*b.x-b.z*a.x,a.x*b.y-a.y*b.x};}double operator /(P a,P b) {return a.x*b.x+a.y*b.y+a.z*b.z;}double mo(P a) {return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);}int C(double a) {return (a<-e)?-1:a>e;}double sqr(double x) {return x*x;}struct SJ{P p[4],X,Y,Z,o,color;int kind;double R,refl,refr,indx;};struct RAY{P a,b;};P change(P a,SJ b) {return (P){a/b.X,a/b.Y,a/b.Z};}double ttt,gr;struct BMP {#define a(i,j,k) data[((i)*((W*3+3)&~3))+(j)*3+(k)]  int W,H;  unsigned char* data;  int readLong(FILE *fin){    int b0,b1,b2,b3;    b0=fgetc(fin);b1=fgetc(fin);b2=fgetc(fin);b3=fgetc(fin);    return b0 | (b1<<8) | (b2<<16) | (b3<<24);  }  void build(char *Fname) {    FILE *fin=fopen(Fname,"rb");    if (!fin){fprintf(stderr,"error\n");return;}    fseek(fin,0x12,0);    W=readLong(fin);    H=readLong(fin);    fseek(fin,0x36,0);    data=new unsigned char[((W*3+3)&~3)*H];    fread(data,1,((W*3+3)&~3)*H,fin);    for (int i=0;H-1-i>=i;i++){      for (int j=0;j<W;j++){        swap(a(i,j,0),a(H-1-i,j,2));        swap(a(i,j,1),a(H-1-i,j,1));        swap(a(i,j,2),a(H-1-i,j,0));      };    };    fclose(fin);  }  P BMPcolor(double x,double y) {    int i=(int)(x*H),j=(int)(y*W);    if (i<0) i=0;    if (j<0) j=0;    if (i>=H) i=H-1;    if (j>=W) j=W-1;    return (P){a(i,j,0)/255.,a(i,j,1)/255.,a(i,j,2)/255.};  }};vector<BMP> pic(0);RAY get_f(SJ s,RAY r) {  RAY ans;  ans.a=(P){1e50,1e50};  if (s.indx>1e3) return ans;  if (!s.kind) {    r.b=r.b/(mo(r.b));    double dt=(r.b/s.o)-(r.b/r.a);    P md=r.a+(r.b*dt);    double dis=mo(md-s.o);    if (C(dis-s.R)>=0) return ans;    double kd=sqrt(s.R*s.R-dis*dis);    if (C(dt+kd)<=0) return ans;    if (C(dt-kd)>0) ans.a=md-(r.b*kd);               else ans.a=md+(r.b*kd);    P f=ans.a-s.o;    f=f/(mo(f));    dt=r.b/f;    ans.b=r.b-(f*(dt*2));    return ans;  };  P a=change(r.a,s);  P b=change(r.b,s);  if (!C(b.z)) return ans;  double dt=(s.p[0].z-a.z)/b.z;  if (C(dt)<=0) return ans;  a=a+(b*dt);  for (int i=0;i<(3+!!(s.kind<0));i++) {    P tt=(s.p[(i+1)&3]-s.p[i])*(a-s.p[i]);    if (C(tt.z)<0) return ans;  };  b.z=-b.z;  P dx=(P){1,0,0};  P dy=(P){0,1,0};  P dz=(P){0,0,1};  dx=change(dx,s);  dy=change(dy,s);  dz=change(dz,s);  dx=dx/(mo(dx));  dy=dy/(mo(dy));  dz=dz/(mo(dz));  ans.a=(P){a/dx,a/dy,a/dz};  ans.b=(P){b/dx,b/dy,b/dz};  return ans;}RAY get_z(SJ s,RAY r,double zr) {  RAY ans;  ans.a=(P){1e50,1e50};  if (!s.kind) {    r.b=r.b/(mo(r.b));    double dt=(r.b/s.o)-(r.b/r.a);    P md=r.a+(r.b*dt);    double dis=mo(md-s.o);    if (C(dis-s.R)>=0) return ans;    double kd=sqrt(s.R*s.R-dis*dis);    if (C(dt+kd)<=0) return ans;    if (C(dt-kd)>0) ans.a=md-(r.b*kd);               else ans.a=md+(r.b*kd);    P f=s.o-ans.a;    f=f/(mo(f));    dt=r.b/f;    double gm;    if (C(zr-s.indx)) gm=mo(r.b)*s.indx;                 else gm=mo(r.b)/s.indx;    gm=gm*gm-(sqr(mo(r.b))-dt*dt);    if (C(gm)<=0) {ans.a=(P){1e50,1e50};return ans;}    gm=sqrt(gm);    if (dt<0) gm=-gm;    ans.b=r.b+(f*(gm-dt));    return ans;  };  P a=change(r.a,s);  P b=change(r.b,s);  if (!C(b.z)) return ans;  double dt=(s.p[0].z-a.z)/b.z;  if (C(dt)<=0) return ans;    double gm;  if (C(zr-s.indx)) gm=mo(b)*s.indx;               else gm=mo(b)/s.indx;  a=a+(b*dt);  for (int i=0;i<(3+!!(s.kind<0));i++) {    P tt=(s.p[(i+1)&3]-s.p[i])*(a-s.p[i]);    if (C(tt.z)<0) return ans;  };  P dx=(P){1,0,0};  P dy=(P){0,1,0};  P dz=(P){0,0,1};  dx=change(dx,s);  dy=change(dy,s);  dz=change(dz,s);  dx=dx/(mo(dx));  dy=dy/(mo(dy));  dz=dz/(mo(dz));  gm=gm*gm-b.x*b.x-b.y*b.y;  if (C(gm)<=0) return ans;  gm=sqrt(gm);  if (b.z>0) b.z=gm; else b.z=-gm;  ans.a=(P){a/dx,a/dy,a/dz};  ans.b=(P){b/dx,b/dy,b/dz};  return ans;}vector<SJ> s(0);SJ getclose(RAY a,double &light,double md) {  SJ b;  b.indx=1e9;  P c,d=(P){1e30,1e30};  for (int i=0;i<(int)s.size();i++) {    c=get_f(s[i],a).a;    double idd=mo(c-a.a);    if (C(idd-md)<0) light*=s[i].refr;    if (idd<mo(d-a.a)) b=s[i],d=c;  };  return b;}SJ makeSJ(P a,P b,P c) {  SJ h;  h.kind=1;  h.p[0]=h.p[3]=a;  h.p[1]=b, h.p[2]=c;  h.Z=(b-a)*(c-a);  h.X=(b-a)*h.Z;  h.Y=h.Z*h.X;  h.X=h.X/(mo(h.X));  h.Y=h.Y/(mo(h.Y));  h.Z=h.Z/(mo(h.Z));  for (int i=0;i<4;i++) h.p[i]=change(h.p[i],h);  return h;}P sun,sunl;double amb;P get_point_color(SJ a,P b) {  RAY r=(RAY){b,sun-b};  r.b=r.b/(mo(r.b));  double l=1,sundis=mo(sun-b);  get_f(getclose(r,l,sundis),r).a;  P f=a.Z;  if (!a.kind) {    f=b-a.o;    f=f/(mo(f));  } else  if (a.kind<0) {    P nj=(P){b/a.X,b/a.Y,b/a.Z};    P fx=a.p[1]-a.p[0];    P fy=a.p[3]-a.p[0];    double mx=mo(fx),my=mo(fy);    fx=fx/mx,fy=fy/my;    nj=nj-a.p[0];    double dx=(nj.x*fy.y-nj.y*fy.x)/(fx.x*fy.y-fx.y*fy.x)/mx;    double dy=(nj.x*fx.y-nj.y*fx.x)/(fx.y*fy.x-fx.x*fy.y)/my;    a.color=pic[-1-a.kind].BMPcolor(dx,dy);  };  l*=pow(abs(f/r.b),3);  l=amb+(1-amb)*l;  a.color.x*=sunl.x;  a.color.y*=sunl.y;  a.color.z*=sunl.z;  return a.color*l;}P trace_ray(int depth, RAY r,double zr) {  P point_color=(P){0,0,0},reflect_color=(P){0,0,0},refract_color=(P){0,0,0};  if (mo(r.a)>1e20) return point_color;  SJ i=getclose(r,ttt,ttt);  P x;  if(i.indx<1e3) {    double refl=i.refl;    double refr=i.refr;    x=get_f(i,r).a;    point_color=get_point_color(i,x) * (1-refl-refr);    if(depth<maxdepth && C(refl)>0)      reflect_color=trace_ray(depth+1, get_f(i,r),zr) * refl;    if(depth<maxdepth && C(refr)>0)      refract_color=trace_ray(depth+1, get_z(i,r,zr),(!C(zr-1))?i.indx:1) * refr;  } else x=(P){1e30,1e30};  P ncl=point_color+reflect_color+refract_color;  r.b=r.b/(mo(r.b));  double sr=(r.b/r.a),dt=(r.b/sun)-sr;  P jd=r.a+(r.b*dt);  double rd=mo(jd-sun);  if (rd<gr && dt>e && (mo(x)>1e30 || dt<((r.b/x)-sr))) {    double l=cos(rd/gr*M_PI)/2+0.5;    ncl=(ncl*(1-l))+(sunl*l);  };  return ncl;}P shot(P s,P t) {  RAY r=(RAY){s,t};  return trace_ray(0,r,1);}int main() {  freopen("N_input_0.txt","r",stdin);  freopen("image.txt","w",stdout);  s.clear();  int n;  scanf("%d",&n);  while (n--) {    int np;    vector<P> p(0);    scanf("%d",&np);    for (int i=1;i<=np;i++) {      P h;      scanf("%lf%lf%lf",&h.x,&h.y,&h.z);      p.push_back(h);    };    int mp;    scanf("%d",&mp);    if (np==1) {      SJ h;      h.kind=0;      h.o=p[0];      scanf("%lf",&h.R);      s.push_back(h);    } else    if (np==4 && mp==1) {      BMP picture;      char Fname[100];      scanf("%s",Fname);      picture.build(Fname);      pic.push_back(picture);      SJ h=makeSJ(p[0],p[1],(p[2]+p[1])-p[0]);      h.p[3]=change(p[2],h);      h.kind=-((int)pic.size());      s.push_back(h);    } else    for (int i=1;i<=mp;i++) {      int a,b,c;      scanf("%d%d%d",&a,&b,&c);      s.push_back(makeSJ(p[a],p[b],p[c]));    };    P color;    scanf("%lf%lf%lf",&color.x,&color.y,&color.z);    double refl,refr,idx;    scanf("%lf%lf%lf",&refl,&refr,&idx);    for (int i=1;i<=mp;i++) {      s[s.size()-i].color=color;      s[s.size()-i].refl=refl;      s[s.size()-i].refr=refr;      s[s.size()-i].indx=idx;    };  };  scanf("%lf%lf%lf",&sun.x,&sun.y,&sun.z);  scanf("%lf%lf",&gr,&amb);  scanf("%lf%lf%lf",&sunl.x,&sunl.y,&sunl.z);  int np;  scanf("%d",&np);  while (np--) {    P cs,ct,cu;    scanf("%lf%lf%lf",&cs.x,&cs.y,&cs.z);    scanf("%lf%lf%lf",&ct.x,&ct.y,&ct.z);    scanf("%lf%lf%lf",&cu.x,&cu.y,&cu.z);    ct=ct-cs;    P cl=ct*cu;    cu=cu/mo(cu);    cl=cl/mo(cl);    ct=ct/mo(ct);    double fov;    int w,d;    scanf("%lf",&fov);    scanf("%d%d",&w,&d);    printf("%d %d\n",w,d);    double ld=tan(fov/180*M_PI/2)/(w*.5);    P rs=cl*ld,ds=cu*(-ld);    P ss=ct-(rs*(w*.5))-(ds*(d*.5));    for (int i=1;i<=d;i++) {      for (int j=1;j<=w;j++) {        if (!((i*w+j)%500))fprintf(stderr,"loading....   %.2lf%%\n",((i-1.)*w+j)/(d*w)*100);        P ns=ss+(rs*(j-.5))+(ds*(i-.5));        P cl=shot(cs,ns);        if (0) {          cl=cl+shot(cs,ns+(rs*.4));          cl=cl+shot(cs,ns-(rs*.4));          cl=cl+shot(cs,ns+(ds*.4));          cl=cl+shot(cs,ns-(ds*.4));          cl=cl/5;        };        printf("%02x%02x%02x ",(int)(cl.x*255),(int)(cl.y*255),(int)(cl.z*255));      };      printf("\n");    };  };  return 0;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.