Guest User

Untitled

a guest
Oct 2nd, 2013
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.29 KB | None | 0 0
  1. // diydsp's threaded version of
  2. // https://github.com/kid0m4n/gorays/blob/940c91f601ef840e6d75ddf272ab6cd3eb8d5531/ref/rays.cpp
  3. // compile with g++ rt02.cpp -o rt02 -O3 and run with ./rt02
  4. // set NUM_THREADS from 1-64, depending on your CPU
  5. /*
  6. As run on my AMD Dual-Core E300 CPU:
  7.  
  8. Compiled with -g
  9. 1 threads ~50 seconds
  10. 2 threads ~40 seconds
  11. 3 threads ~36 seconds
  12. 4 threads ~34 seconds
  13. 5 threads ~33 seconds
  14.  
  15. Compiled with -O
  16. 1 thread ~22 seconds
  17. 2 threads ~18 seconds
  18. 3 threads ~18 seconds
  19. 4 threads ~17 seconds
  20. 5 threads ~19 secodns
  21. 6 threads ~16 seconds
  22. 7 threads ~17 seconds
  23. 8 threads ~17 seconds
  24.  
  25. Compiled with -O3
  26. 1 thread ~17 seconds
  27. 2 threads ~12 seconds
  28. 3 threads ~12 seconds
  29. 4 threads ~11 seconds
  30. 5 threads ~12 seconds
  31. 6 threads ~12 seconds
  32. */
  33.  
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <pthread.h>
  37. #include <math.h>
  38. #include <list>
  39. #include <cstring>
  40.  
  41. #define NUM_THREADS 8
  42. typedef struct { int y_start,y_end,byte_index; } Params;
  43. Params params[NUM_THREADS];
  44.  
  45. //Define a vector class with constructor and operator: 'v'
  46. struct vector {
  47. float x,y,z; // Vector has three float attributes.
  48. vector operator+(vector r){return vector(x+r.x,y+r.y,z+r.z);} //Vector add
  49. vector operator*(float r){return vector(x*r,y*r,z*r);} //Vector scaling
  50. float operator%(vector r){return x*r.x+y*r.y+z*r.z;} //Vector dot product
  51. vector(){} //Empty constructor
  52. vector operator^(vector r){return vector(y*r.z-z*r.y,z*r.x-x*r.z,x*r.y-y*r.x);} //Cross-product
  53. vector(float a,float b,float c){x=a;y=b;z=c;} //Constructor
  54. vector operator!(){return *this*(1 /sqrt(*this%*this));} // Used later for normalizing the vector
  55. };
  56.  
  57. const char *art[] = {
  58. " ",
  59. " 1111 ",
  60. " 1 1 ",
  61. " 1 11 ",
  62. " 1 1 1 ",
  63. " 1 11 1 1 ",
  64. " 1 1 1 1 ",
  65. " 1 1 1 1 ",
  66. " 11111 11 "
  67. };
  68.  
  69. struct object {
  70. int k,j;
  71. object(int x,int y){k=x;j=y;}
  72. };
  73.  
  74. std::list<object> objects;
  75.  
  76. void F() {
  77. int nr = sizeof(art) / sizeof(char *),
  78. nc = strlen(art[0]);
  79. for (int k = nc - 1; k >= 0; k--) {
  80. for (int j = nr - 1; j >= 0; j--) {
  81. if(art[j][nc - 1 - k] != ' ') {
  82. objects.push_back(object(k, nr - 1 - j));
  83. }
  84. }
  85. }
  86. }
  87.  
  88. unsigned int seed = ~0;
  89.  
  90. float R() {
  91. seed += seed;
  92. seed ^= 1;
  93. if ((int)seed < 0)
  94. seed ^= 0x88888eef;
  95. return (float)(seed % 95) / (float)95;
  96. }
  97.  
  98. //The intersection test for line [o,v].
  99. // Return 2 if a hit was found (and also return distance t and bouncing ray n).
  100. // Return 0 if no hit was found but ray goes upward
  101. // Return 1 if no hit was found but ray goes downward
  102. int T(vector o,vector d,float& t,vector& n) {
  103. t=1e9;
  104. int m=0;
  105. float p=-o.z/d.z;
  106.  
  107. if(.01<p)
  108. t=p,n=vector(0,0,1),m=1;
  109.  
  110. std::list<object>::iterator it;
  111.  
  112. for (it = objects.begin(); it != objects.end(); ++it) {
  113. int k = it->k,
  114. j = it->j;
  115.  
  116. // There is a sphere but does the ray hits it ?
  117. vector p=o+vector(-k,3,-j-4);
  118. float b=p%d,c=p%p-1,q=b*b-c;
  119.  
  120. // Does the ray hit the sphere ?
  121. if(q>0) {
  122. //It does, compute the distance camera-sphere
  123. float s=-b-sqrt(q);
  124.  
  125. if(s<t && s>.01)
  126. // So far this is the minimum distance, save it. And also
  127. // compute the bouncing ray vector into 'n'
  128. t=s, n=!(p+d*t), m=2;
  129. }
  130. }
  131.  
  132. return m;
  133. }
  134.  
  135. // (S)ample the world and return the pixel color for
  136. // a ray passing by point o (Origin) and d (Direction)
  137. vector S(vector o,vector d) {
  138. float t;
  139. vector n, on;
  140.  
  141. //Search for an intersection ray Vs World.
  142. int m=T(o,d,t,n);
  143. on = n;
  144.  
  145. if(!m) { // m==0
  146. //No sphere found and the ray goes upward: Generate a sky color
  147. float p = 1-d.z;
  148. p = p*p;
  149. p = p*p;
  150. return vector(.7,.6,1)*p;
  151. }
  152.  
  153. //A sphere was maybe hit.
  154.  
  155. vector h=o+d*t, // h = intersection coordinate
  156. l=!(vector(9+R(),9+R(),16)+h*-1); // 'l' = direction to light (with random delta for soft-shadows).
  157.  
  158. //Calculated the lambertian factor
  159. float b=l%n;
  160.  
  161. //Calculate illumination factor (lambertian coefficient > 0 or in shadow)?
  162. if(b<0||T(h,l,t,n))
  163. b=0;
  164.  
  165. if(m&1) { //m == 1
  166. h=h*.2; //No sphere was hit and the ray was going downward: Generate a floor color
  167. return((int)(ceil(h.x)+ceil(h.y))&1?vector(3,1,1):vector(3,3,3))*(b*.2+.1);
  168. }
  169.  
  170. vector r=d+on*(on%d*-2); // r = The half-vector
  171.  
  172. // Calculate the color 'p' with diffuse and specular component
  173. float p=l%r*(b>0);
  174. float p33 = p*p;
  175. p33 = p33*p33;
  176. p33 = p33*p33;
  177. p33 = p33*p33;
  178. p33 = p33*p33;
  179. p33 = p33*p;
  180. p = p33*p33*p33;
  181.  
  182. //m == 2 A sphere was hit. Cast an ray bouncing from the sphere surface.
  183. return vector(p,p,p)+S(h,r)*.5; //Attenuate color by 50% since it is bouncing (* .5)
  184. }
  185.  
  186. int w = 512,
  187. h = 512;
  188.  
  189. // The '!' are for normalizing each vectors with ! operator.
  190. vector g=!vector(-5.5,-16,0), // Camera direction
  191. a=!(vector(0,0,1)^g)*.002, // Camera up vector...Seem Z is pointing up :/ WTF !
  192. b=!(g^a)*.002, // The right vector, obtained via traditional cross-product
  193. c=(a+b)*-256+g; // WTF ? See https://news.ycombinator.com/item?id=6425965 for more.
  194.  
  195. int s = 3*w*h;
  196. char *bytes = new char[s];
  197.  
  198. // The main function. It generates a PPM image to stdout.
  199. // Usage of the program is hence: ./card > erk.ppm
  200. int main(int argc, char **argv) {
  201. F();
  202.  
  203.  
  204. if (argc > 1) {
  205. w = atoi(argv[1]);
  206. }
  207. if (argc > 2) {
  208. h = atoi(argv[2]);
  209. }
  210.  
  211. printf("P6 %d %d 255 ", w, h); // The PPM Header is issued
  212.  
  213.  
  214.  
  215.  
  216. pthread_t thr[NUM_THREADS];
  217. // void *render_thread(void *);
  218. void *render_thread(void *);
  219.  
  220. for(int i=0;i<NUM_THREADS;i++)
  221. {
  222. params[i].y_start = (i+1) * w / NUM_THREADS - 1;
  223. params[i].y_end = i * w / NUM_THREADS ;
  224. params[i].byte_index = params[i].y_end * w * 3;
  225. pthread_create(&thr[i],NULL,render_thread,&params[i]);
  226. }
  227.  
  228. for(int i=0;i<NUM_THREADS;i++)
  229. {
  230. pthread_join(thr[i],NULL);
  231. }
  232.  
  233. fwrite(bytes, 1, s, stdout);
  234. delete [] bytes;
  235. }
  236.  
  237. void *render_thread(void *data)
  238. {
  239. Params *p = (Params *)data;
  240. int k = p->byte_index;
  241. volatile int y;
  242.  
  243. //printf("\ny_start : %d ",p->y_start);
  244. //printf("y_end : %d ", p->y_end);
  245. //printf("byte_index: %d\n", p->byte_index);
  246.  
  247. for(y = p->y_start ; y >= p->y_end; y--) //For each column
  248. {
  249.  
  250. //printf(".%d\n",y);
  251.  
  252. for(int x=w;x--;) //For each pixel in a line
  253. {
  254. printf("x");
  255. //Reuse the vector class to store not XYZ but a RGB pixel color
  256. vector p(13,13,13); // Default pixel color is almost pitch black
  257.  
  258. // Cast 64 rays per pixel (For blur (stochastic sampling) and soft-shadows.
  259. for(int r=64;r--;)
  260. {
  261. // The delta to apply to the origin of the view (For Depth of View blur).
  262. vector t=a*(R()-.5)*99+b*(R()-.5)*99; // A little bit of delta up/down and left/right
  263. // Set the camera focal point vector(17,16,8) and Cast the ray
  264. // Accumulate the color returned in the p variable
  265. p=S(vector(17,16,8)+t, //Ray Origin
  266. !(t*-1+(a*(R()+x)+b*(y+R())+c)*16) // Ray Direction with random deltas
  267. // for stochastic sampling
  268. )*3.5+p; // +p for color accumulation
  269. }
  270.  
  271. bytes[k++] = (char)p.x;
  272. bytes[k++] = (char)p.y;
  273. bytes[k++] = (char)p.z;
  274. }
  275. //printf(",%d\n",y);
  276.  
  277. }
  278. }
Advertisement
Add Comment
Please, Sign In to add comment