Wednesday, January 27, 2016

Ray Tracing in One Weekend

The books are now available in unprotected pdf for PAY WHAT YOU WISH, with 50% going to not for profit programming education organizations.   Here are the files.


Ray tracing was invented by Turner Whitted around 1980.   His classic paper is really amazing; it had bounding volume hierarchies, adaptive sampling, and it's future work suggested randomized reflection.   Since then it has branched into a ton of variations and is used in most movies for the indirect "bounce" lighting.

I've was assigned a 2D ray tracer in a physics class in 1984 and I was hooked.   Since then I have written a bunch of ray tracers in Pascal, Fortran, Scheme, C, C++, Java, and most recently Swift (which is awesome for writing ray tracers).   I've also taught classes with ray tracing about a dozen times, most recently at Westminster College in 2015.   My approach over the years has evolved to do what I think are the most fun parts of ray tracing that are still in the direction of writing a production-quality ray tracer.

Ray Tracing in One Weekend is a kindle book that goes through all of the details to generate a rudimentary ray tracer.   It's $2.99 on amazon.   It uses C plus classes plus operator overloading.   I have heard this referred to as "C plus" which I now call it.    Most production renderers are written in C++ so I opted for that as the driving language.    I put the most primal set of these assignments so that it's very doable in a weekend, the fundamental unit of coding self-improvement :)   Here is the book:




The resulting program generates this image:



Here's my MacOS code for the book.   Should be semi-portable but drand48() will need to be written on some systems and the fileio may be too.    I also have a little post on the tools I used to write the book for those interested in doing a little book of their own.   Please let me know if you do!


Links for further reading and exploration related to the book:


Chapter 0: Overview

Here is a list of basic graphics texts that cover the vector background the book assumes:

Fundamentals of Computer Graphics, Fourth Edition

Computer Graphics: Principles and Practice (3rd Edition)

The Graphics Codex

Real-Time Rendering, Third Edition



Chapter 1: Output an image

For output of most LDR and HDR images I love stb_image.

For more info on HDR images and tone mapping the I like the book  High Dynamic Range Imaging, Second Edition: Acquisition, Display, and Image-Based Lighting 


Chapter 2: The vec3 class

I advocate using the same class for points, displacements, colors, etc.   Some people like more structure and type checking (so for example multiplying two locations would be rejected by the compiler).   An example article where points and vectors are different is here.   Jim Arvo and Brian Smits experimented with not only distinguishing points and vectors, but using the compiler to do dimensional analysis (so velocity, length, and time would be different types for example).   They found this to be too cumbersome in 1990s C++ but I'd love to hear about anybody's experience.   Researchers at Dartmouth have taken a really serious effort at this and their code and paper are available at github.


Chapter 3:  Rays, a simple camera, and background

The first thing you might add to your background function is an environment map.   Paul Debevec has a terrific history of environment mapping.   The easiest mapping for this uses a single image for the entire sphere of directions.   Paul also provides some good images to use for your environment map.


Chapter 4:  Adding a sphere

There are a bunch of other object types you can add.   Triangles are usually first and I am a fan of barycentric methods.    After triangles, many people quit adding primitives because graphics has such a big infrastructure for triangles.    Ellipses are an easy thing to add but instancing is usually a more "ray tracey" approach (let the software do the heavy lifting).   Composite objects via CSG are surprisingly straightforward.


Chapter 5:  Surface normals and  multiple objects.

If you want your code to be more efficient for large numbers of objects, use a BVH-- they are as good as any other in efficiency and are the most robust and easiest to implement.


Chapter 6:  Antialiasing

Box filtering as done in the book suffices for most situations.   However, Guassian-like filters can have advantages and are pretty easy.   You can either uniformly sample the whole screen and weight the samples, or use non-uniform samples.   All approaches work.


Chapter 7:   Diffuse Materials

"Ideal" diffuse materials, also called "Lambertian" are used 99% of the time in graphics.     The wikipedia article on this approximation is good.   Real diffuse surfaces do not behave exactly as Lambertian (for example they get specular at grazing angle) but especially with interreflection in the mix the appearance differences are minor.   So this is probably not where you should push your renderer until many many other features are addressed.

Chapter 8:  Metal

The first improvement you might make is to have the color of the metal go to white at grazing angle.   The Schlick approximation (used in Chapter 9 for glass where grazing behavior matters more) works for that.    Full-bore Fresnel equations will describe color variation with angle, but in my experience getting normal incident color is good enough.


Chapter 9:  Dielectrics

The first thing you might add is filtering of light within the dielectric (like the subtle "greenness" of much glass).   This is a classic exponential decay and is covered well in the Beer's Law section of this nice page.


Chapter 10:  Positionable camera
Camera parameter setting is just plain ugly.  The system used in the book is relatively common and is in my opinion the prettiest.   I avoid the matrix formulation wherever possible because I never understand my code when I am done.   But it is very elegant and works.

Chapter 11:  Defocus blur

If you ever need to match a real camera, there is a nice survey of models used in graphics.   And here is a very good presentation on real lenses written for a technical audience.


Chapter 12:  Where next?

You should have the core of a very serious ray tracer now.    I would now take it in one of three directions.   They are not mutually exclusive but explicitly deciding your goals will simplify architectural decisions.
  1. Make it physically accurate.   This will imply using spectra instead of RGB (I like just using a big array of wavelengths) and get something where you know the reflectances.   Popular is to get a X-Rite MSCCC ColorChecker Classic whose data is available online.
  2. Make it good for generating animations.    Lots of movies use a ray traced system, and Disney, Pixar, and the Solid Angle teams have both disclosed a remarkable amount about their code.   Work on features and then efficiency.   I think you will be amazed how soon you can produce amazing images.
  3. Make it fast.   Here you can roll your own, or start using a commercial API.   To see exactly where that community is now, go to the 2016 HPG conference.   Or backtrack in their previous papers.   They are a very open community and the papers go into much detail relative to many sub-fields in computer graphics.
Please send me your questions, comments, and pictures.   Have fun with ray tracing!





 

230 comments:

  1. You should consider publishing in iBooks too because it's easier to push updates. I imagine the book could be perfect but most computer books seem to have a few mistakes. It's just the nature of the topic.

    ReplyDelete
    Replies
    1. Thanks-- I already pushed an update so no not perfect! I'll look into iBooks. I think currently I have enabled some amazon features related to loaning and kindle unlimited free reading. I'll do some due diligence on the ecosystem once I finish part 2. I've had requests for pdf as well and there are a bunch of options there I don't yet understand...

      Delete
  2. SafeGI is a good example of the usage of dimensional analysis in a rendering system.
    https://github.com/ouj/safegi

    ReplyDelete
    Replies
    1. Really interesting work. Thanks for the link. The github has the EGSR paper as well. I'll be very interested in the authors' thoughts on this in a couple of years as it is clearly a double-edged sword. I added your link above. Thanks!

      Delete
  3. In the chapter 8, where you add the Metal material, can you provide the changes to the sphere class? The modifications to main() call sphere() with an additional 'new lambertian()' parameter, but I can't figure out what needs to be done in the sphere class to make it work.

    Thanks!

    ReplyDelete
    Replies
    1. I'll take a close look at this part of the discussion. In the meantime, here is the final sphere class.

      #ifndef SPHEREH
      #define SPHEREH

      #include "hitable.h"

      class sphere: public hitable {
      public:
      sphere() {}
      sphere(vec3 cen, float r, material *m) : center(cen), radius(r), mat_ptr(m) {};
      virtual bool hit(const ray& r, float tmin, float tmax, hit_record& rec) const;
      vec3 center;
      float radius;
      material *mat_ptr;
      };

      bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const {
      vec3 oc = r.origin() - center;
      float a = dot(r.direction(), r.direction());
      float b = dot(oc, r.direction());
      float c = dot(oc, oc) - radius*radius;
      float discriminant = b*b - a*c;
      if (discriminant > 0) {
      float temp = (-b - sqrt(b*b-a*c))/a;
      if (temp < t_max && temp > t_min) {
      rec.t = temp;
      rec.p = r.point_at_parameter(rec.t);
      rec.normal = (rec.p - center) / radius;
      rec.mat_ptr = mat_ptr;
      return true;
      }
      temp = (-b + sqrt(b*b-a*c))/a;
      if (temp < t_max && temp > t_min) {
      rec.t = temp;
      rec.p = r.point_at_parameter(rec.t);
      rec.normal = (rec.p - center) / radius;
      rec.mat_ptr = mat_ptr;
      return true;
      }
      }
      return false;
      }


      #endif

      Delete
    2. This discriminant does not work for me. When you removed the 2.0 (the 4 in the numerator and the 2 of the denominator) factors, the results are not valid any more. Am I missing something? from a mathematical point of view, I don't think that is correct, as the 4 is inside the square root affecting only one of the terms. Also, you already calculated the discriminant, you don't need to write it again inside the sqrt.

      Delete
  4. There also appears to be a circular dependency between the mat_ptr field in the hit_record struct, and the material class. It's not clear how you resolved this.

    Thanks

    ReplyDelete
    Replies
    1. I think the hit_record only needs to know that mat_ptr is a pointer but doesn't need to know the size of what it points to, so "class material;" at the beginning of the file where hit_record is defined takes care of it. (I say "I think" because I never trust my own compiler's acceptance of something that it works under the actual language spec.)

      Delete
    2. I looked it over and this is not mentioned in the book at all! I have fixed this and sent a new copy to amazon. It will probably update sometime today. Thanks for telling me about this!

      Delete
  5. That worked, thanks! I can reproduce the images in chapter 8 now. On to chapter 9!

    ReplyDelete
    Replies
    1. Awesome. Thanks for your help-- a book has to be debugged too and the readers are the compiler :)

      Delete
  6. Some more comments. Not sure how to specify location, as my Kindle reader just uses 'Location' -- hopefully that is universal:

    Location 283:
    list[2] sphere color doesn't match color in the picture on next page (blue vs. red)

    Location 314:
    The formula for the 'discrimant' variable gives bad results for me. But when I change it to:
    float discrimant = 2.0 - ni_over_nt*ni_over_nt*(1-dt*dt);

    my results closer to yours.

    Location 316:
    attenuation = vec3(1.0, 1.0, 0.0);
    should be:
    attenuation = vec3(1.0, 1.0, 1.0);

    ReplyDelete
    Replies
    1. Thanks! It looks like they are either close to universal or close enough.

      On 283 I think list[2] is the big sphere and (0.8, 0.6, 0.2) is some yellowish color. The blue sky will shift toward blue so the greenish pale "ground sphere should be ok?

      Delete
    2. I think that the formula in the book is ok. Here is what rtn says (rtn was a very active list among ray tracing nerds in the dark ages) http://www.realtimerendering.com/resources/RTNews/html/rtnv10n1.html#art3

      Delete
  7. Hey Peter,

    I'm not sure if it's me or the code, but I couldn't get the refraction in the dielectric working right until I switched to passing unit vectors to the refract method. After that it matches the renders in the book perfectly.

    ReplyDelete
    Replies
    1. Which vector? I do this in the first line of refract: vec3 uv = unit_vector(v);

      Delete
    2. Yes, but the normal also seems to need to be 'normalised':


      bool refract(const vec3& v, const vec3& n, float ni_over_nt, vec3& refracted) {
      vec3 uv = v.unit_vector();
      vec3 un = n.unit_vector();

      float dt = dot(uv, un);
      float discriminant = 2.0 - ni_over_nt*ni_over_nt*(1.0 - dt*dt);
      if (discriminant > 0) {
      refracted = ni_over_nt*(uv - un*dt) - un*sqrt(discriminant);
      return true;
      } else {
      return false;
      }
      }

      Delete
    3. I also had problems, but the fix was that the line which reads:

      refracted = ni_over_nt*(v - n*dt) - n*sqrt(discriminant);

      should read:

      refracted = ni_over_nt*(uv - n*dt) - n*sqrt(discriminant);

      Note the use of "uv" instead of the non-normalized "v". After making that one-character change I had the same results as in the book. I didn't need to normalize the normal.

      Delete
  8. Using unit vectors for the refract method also worked for me -- thanks for the tip.

    ReplyDelete
  9. Not having too much time, it took me more than one weekend to complete the raytracer :) but I'm quite happy with it. I adapted the C++ code to JavaScript and it now runs inside a browser. It is a bit slow, but I think it serves its educational purpose very well.

    I am curious about the camera parameters you used to generate the final image from chapter 12 (lookfrom, lookat,... , aperture, focus_dist). After some experimentation my image was similar to yours, but not quite so. In particular the perspective looks a bit strange, the small balls to the left were distorted like ovals.

    ReplyDelete
    Replies
    1. Cool! Could you post a link?-- ray tracing in a browser is always fun.

      The camera I use could be wrong. Let me set up some unit tests.

      Also, spheres projected to an image from ovals. If you get close enough to your image so your eye has the same field of view as your virtual eye does, you will see those ovals in perspective so on your retina you will get approximately a disk. In my first ray tracer I chased this "bug" for weeks...

      Delete
    2. Yes, I will post a link, but I need to clean up the code first and this will require another weekend.

      Delete
    3. Here's a link to my JavaScript version:

      https://www.googledrive.com/host/0BwNzpRS7-ABHeDFuRXJ6NmV0TFE/raytracer-ch12.html

      This code will run in your browser, so beware that it is slow! I reduced the number of small spheres and the number of samples for antialiasing, but even so, it takes a few minutes to render the image on a relatively fast notebook.

      The same directory also has versions that generate the images in each chapter. For example, for chapter 8:

      https://www.googledrive.com/host/0BwNzpRS7-ABHeDFuRXJ6NmV0TFE/raytracer-ch08.html

      Chapter 9 has two images, "ch09-1" and "ch09-2".

      I think I can make this a bit faster by exploring some features of JS 6 (like typed arrays). But for now I'm just waiting for the scond book in the series :)

      Delete
    4. Would it be possible to elaborate more on the issue where spheres appear as ovals? I have also been chasing this issue for a few weeks!

      Delete
    5. dargouder, there's a good explanation of this in the book "Real-Time Rendering" 3rd Ed (M öller et. al.) p 449. They explain that it's not an error and relates to a discrepancy between the field of view of the image and the FOV of your eye viewing the image on a monitor, so if the two FOVs match, the warping goes away. There should be some guides on the internet stating how far away from your monitor you need to be, given its width, to get a specific FOV. (I know Lengyel's "Mathematics for 3D Game Programming & Computer Graphics" has a discussion on this, and I would be surprised if Möller's book didn't also have a discussion on how viewing distance to a monitor relates to perceived FOV.)

      Delete
  10. A few comments:

    In location 139 the formula:
    t*t*dot(B,B) + 2*t*dot(A-C) + dot(C,C) - R*R = 0
    seems to be wrong (dot(A-C) doesn't even make sense).
    By looking at the code I think it should be something like:
    t*t*dot(B,B) + 2*t*dot(A-C, B) + dot(A-C, A-C) - R*R = 0

    All the images I generate seem to have a fish eye effect unless I use a small angle in the camera (like 20 degrees). It also happens on most pictures of the book, where the sphere in centre looks fine but the ones on the sides look distorted. Is it common to use such a small angle in the camera or to do something to compensate?

    Could anyone else replicate the bubble effect with the sphere with negative radius inside the glass sphere in 327? I even tried copying the code line by line and still couldn't get it (it's as if the negative sphere is not there at all).

    ReplyDelete
    Replies
    1. What's your sphere intersection and normal code look like.

      And good eye on the formula. The correct formula (which you got) is with luck in the updated version on the kindle store.

      Delete
    2. Noticed the same problem with the formula -- got Kindle version on Feb 23, 2016 and still not fixed.

      Also, just prior to that one there is "dot((p - C),(p - C)) = (y-cy)*(y-cy) + (z-cz)*(z-cz)" -- missing (x-cx)*(x-cx).

      Delete
  11. I also needed to normalize the normal vector in the refraction function. After that I was able to reproduce all images in the book (including the sphere with negative radius). As for the circular dependency, I just added 'class Material;' in Hitable file. Just in case, I've uploaded it to my github as https://github.com/netolcc06/BabyRayTracer.

    ReplyDelete
    Replies
    1. You code doesn't quite compile for me. What is your platform? I like that you templated vec3 and it would be fun to race floats and double....

      I also like your drand48() substitute. Not needing to know how big rand()'s range is is clever. Mind if I steal your rand for the book?

      Delete
    2. You can steal everything you want. :)

      I'm coding on Visual C++. A friend of mine also had trouble to compile my code on Linux. After I finish everything I want to add to the ray tracer, I'll port the code.

      Besides, I've posted an image with many spheres to the main page of github. Check it out: https://github.com/netolcc06/BabyRayTracer


      I've added planes and boxes. After triangles, textures and meshes, I intend to play with lights. Any hints on how to proceed?

      Delete
  12. Prof Shirley,

    Hope you consider writing a similar book for Swift. I would definitely buy it!


    ReplyDelete
  13. In your second dielectric code example, the first calculation of cosine multiplies by the ref_idx but the second calculation of cosine does not. Is that a bug or intentional? If it's intentional why is there a difference?

    You also calculate scattered = Ray(rec.p, reflected); twice.

    ReplyDelete
    Replies
    1. Thanks! That first "scattered =" can go. The cosine is intentional and I should add some words on it in the book. The Fresnel reflectance is the same no matter which direction you are traveling in or out. The Schlick approximation to Fresnel reflectance is framed in terms of the refractive index = 1.0 cosine (the larger angle side) of the material. HOWEVER, it may be both intentional and a bug-- Snell's Law applies to sines. I will need to do some digging here. Great eye!

      Delete
    2. Yep it's a bug! Here is the fix:
      http://psgraphics.blogspot.com/2016/03/my-buggy-implimentation-of-schlick.html
      Once I clean it up a bit I will add it to the book.

      Delete
  14. Hi,thanks for writing this short book. I took a class in college and we did a ray tracing program so it was a bit of a refresher.

    I implemented mine in Python to brush up on my Python skills.

    Can you provide the camera parameters for the last image?

    Thanks

    ReplyDelete
    Replies
    1. Cool-- I will be interested to see how fast your python version is. The efficiency tools keep getting better.

      Here is my main with all the scene parameters:
      http://www.cs.utah.edu/~shirley/main.cc

      Delete
    2. I'll get some numbers. I modified it to do parallel processing to speed it up.

      Delete
    3. It's pretty slow. For comparison, the Python version took 10min and 20 seconds. The C++ version took 10.5 seconds. My picture was 200x100 with a sample of 5. Single CPU for each program.

      Maybe there is a bug in my Python code somewhere, but the pictures do come out the same.

      Delete
    4. Would it be possible to send me your python code? I am trying to create a small raytracing program for my school project. It's been quite difficult, mainly because most of the tutorials are for C++ or other languages (other than python). Would be great if you could send with explanations. Many thanks!

      Delete
  15. I found the discussion about diffuse material a little bit complicated. In addition, in this code

    vec3 target = rec.p + rec.normal + random_in_unit_sphere();
    return 0.5 * color(ray(rec.p, target - rec.p), world);

    why you add rec.p in target and after you subtract it in ray function?

    ReplyDelete
    Replies
    1. You are right! I found that less confusing for myself when I wrote it, but I think your way is much better. I probably will need to change the figure but I think this will be a rare "100% better on all dimensions" code change....

      Delete
  16. Hi! Awesome book for ray tracing and I enjoy my first tour very much! I am reading the refraction part, but I confront the problem that I cannot get rid of the black stuff(edge). Base on my standing, if the dielectric scatter fail it would return false to the calling color function, which will return vec3(0,0,0) and cause black edge. Any one with the issue?

    ReplyDelete
    Replies
    1. Sorry I missed this comment until just now. I have often had similar things come up and refraction I **never** get right the first time. I would start with known cases and step debug. Painful, but what I always have to do.

      Delete
  17. Has the new version of the book been published with the fixes for the comment above (regarding the missing mat_ptr)

    http://in1weekend.blogspot.com/2016/01/ray-tracing-in-one-weekend.html?showComment=1454599661068#c3278073328434186794

    I ran into this problem as well and am looking for corrections. Also, is there a reason the source code for the book isn't available as reference?

    ReplyDelete
    Replies
    1. This is a good point-- I was unaware when I started that kindle doesn't auto-update changes. I think I will make the code available as a partial fix. For now, here's my uncleaned version: http://www.cs.utah.edu/~shirley/rtbook1/

      Delete
    2. The reason BTW was my belief that looking and typing was best. I am now thinking that is not a **good** reason :)

      Delete
    3. Awesome, thanks so much. I agree, I think looking and typing is the best as well, but my main nit is, when the code is embedding in images (and the type is really small), it is kind of hard to read, even when reading the book in the Kindle Web Viewer. I would prefer that that code was in some text form the I could then use the native zoom feature of the browser to enlarge the fonts properly.

      Again, thanks for making this book. I look forward to working through the others in the series as well.

      Delete
  18. Finished the book in Go. Was able to make a very parallel version: https://twitter.com/cwalker/status/727357592926711808

    ReplyDelete
  19. I'd be curious to see your implementation in Swift. I'm nearly done revisiting the book, in Swift this time, to learn both the language and your material on ray tracking more deeply. Trying to get it nearly as performant as the C++ implementation is interesting. I write Swift for my day job, but sadly I don't get to spend much time getting things to run fast (or understanding why they run slow), so this has been quite eye opening. I've found good use cases for optionals (returning a hit record) and for tuples (returning scattering, attenuation, and scatter success), and I can make initializers a little more terse when necessary and when intent is obvious, so that's kind of nice.

    ReplyDelete
    Replies
    1. My implementation in swift was VERY basic. It didn't compile anymore last time I checked. I will dig it up and get it to compile again. Email me a reminder if I don't post it soon!

      Delete
  20. Whats the point of this line of code
    vec3 p = r.point_at_parameter(2.0);
    At the end of the surface normal chapter in main function?
    p is not used in the rest of the function.

    ReplyDelete
    Replies
    1. D'oh! It is dead code. Good eye. Just trying to make the compiler writers proud of that optimization.

      Delete
  21. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. looks like first lower_left_corner calculation at the end of chapter 10 is pointless too.

      P.S Great Book. Thanks

      Delete
  22. Hi Peter, thanks for this book, or really, thank you for book 3, because the material that book discusses is pretty hard to follow in the "reference tomes".

    I wrote the dielectric as it was in the book, then thought the ref_idx term for the cosine was really strange. So it seems someone else here thought so as well and you had adressed it.

    I am better with math than physics sadly, here's the code and my comments anyway if you wish to take a look.
    https://github.com/skurmedel/strahl0/blob/master/inc/dielectric.hpp

    I probably misunderstood everything, but I think the derivation for Snell's is correct :D

    ReplyDelete
  23. Would anybody attending SIGGRAPH 2016 be interested in a Birds of a Feather meeting? There's still time to propose one.

    ReplyDelete
    Replies
    1. Dr. Shirley, would you have any objection to a BOF session referring to "Ray-Tracing In One Weekend" in the title?

      Delete
    2. I'm really sorry I missed this until just now. Yes I have no objection. For future reference the answer to all such questions is go for it!

      Delete
  24. Hi!, starting with your series of book.

    It would be great if you write something on the lines of: Rasterization/game rendering in one weekend/month or so.

    I think it would be possible and even more demanded than this series.

    Cheers!

    ReplyDelete
    Replies
    1. I agree that book would have a market. I would buy it! I don't think I have the games background. But good idea.

      Delete
  25. Hello, I was wondering if there was any chance you could also have this available in amazon.ca as a Canadian who is really interested in this series.

    Cheers,

    Vishahan Thilagakumar

    ReplyDelete
  26. Hi, I decided to implement my version in Haskell. I'm pretty sure that means a harder time eliminating performance bottlenecks, but hey...

    I can use both Float or Double in the implementation, but haven't really noticed a performance difference either way. One thing I did notice though is artifacts caused by rounding errors when I use Float, so I'll stick to Double as a default for now: https://github.com/tvh/raytracinginoneweekend.

    ReplyDelete
    Replies
    1. Cool! I don't know Haskell but it's very readable.

      I usually use double for my ray tracers. Precision with float is usually doable but requires care. However, lots of people will complain if you use doubles. But once you are using anything but C you will get hassled anyway :)

      Delete
    2. Yeah, that gigantic sphere was maybe a bit silly anyway, but I didn't get around to implementing other primitives yet. I managed to optimize the code enough so that the difference Float/Double is about 10% over the whole process now. Before it was completely shadowed by packing/unpacking of boxed values.

      Delete
  27. Regarding doubles vs floats, I've been implementing this in Swift, and noticed some dramatic (and very visible) difference in brightness in the diffuse materials example (ch7). I dug and dug and finally isolated it to float/double rounding errors.

    The largest, and the one that caused the brightness difference, was in sphere::hit. In the assignments of temp, using sqrtf rather than sqrt has a dramatic difference on the output. This really surprised me, since I assumed the impact of that would be detectible in the output, but too subtle to see easily.

    So far, to get my Swift code to exactly match the C++ output, I've had to switch all sqrt() to sqrtf(), and also apply float casts here:

    float u = float(i + float(drand48())) / float(nx);
    float v = float(j + float(drand48())) / float(ny);

    and here:

    int ir = int(float(255.99)*col[0]);
    int ig = int(float(255.99)*col[1]);
    int ib = int(float(255.99)*col[2]);

    (I could also explicitly promote the floats to doubles in Swift and then truncate back to floats, but that's a lot uglier than the equivalent C++.)

    The float casts had a much smaller impact on the final results than those sqrt's in the discriminant.

    Anyway, my suspicion is that the C++ would be easier to exactly match in other languages if it used double, since then there would be fewer implicit promotions/demotions and double tends to be the more natural type (i.e the type of literals) in many languages.

    Thanks for the book; this has been a great weekend project over the holidays.

    ReplyDelete
  28. I, thank you for this awesome book, i have a little problem, i don't speak well english so i make a screenshot:
    http://i68.tinypic.com/2zyyk2x.png
    :y display is reversed, it is a problem ? i try many thing thing but im not able to make it like yours.
    Thank you for your help.

    ReplyDelete
  29. The link for the image http://imgur.com/a/hxQ8L

    ReplyDelete
    Replies
    1. Think i have resolved my issue, it was the library i use inverse the order of putting pixel in image

      Delete
    2. And that happened all before I got to this. Sometimes procrastination pays :) Good luck with the project!

      Delete
  30. This comment has been removed by the author.

    ReplyDelete
  31. Hey, Pete. I'm curious about something in the Lambertian material. You scatter rays by sampling within a unit sphere that just touches the surface at the point of intersection. That's a nice simple technique, and I like it. But I'm wondering if it is equivalent to sampling the hemisphere over the point of intersection (which I haven't implemented, but seems more complicated to do). If they are not equivalent, is one more physically correct than the other? I suppose that depends on the desired material characteristics?

    ReplyDelete
    Replies
    1. Lambertian but I was sure it was diffuse (fuzzy but not necessarily a cosine distribution). In the third book I do it "right" and get a slightly different answer. On my to-do list is to see how close it is.

      Delete
    2. This comment has been removed by the author.

      Delete
  32. This comment has been removed by the author.

    ReplyDelete
  33. Hello. Thanks for your great book series. All three books are simply fantastic. I hope this concept of self publishing gains momentum. And i really like the refreshing overall "straight to the point and keep it as simple as possible" approach while still conveying most of the fundamental concepts.

    I have ported the "Ray Tracing in One Weekend" final ray tracer to glsl and put it online on shadertoys. With a webgl capable browser and a fast graphics card it is realtime:

    https://www.shadertoy.com/view/lssBD7

    ReplyDelete
  34. Hi all dear guy!
    nice article great post comment information thanks for sharing.gclub casino
    goldenslot casino
    goldenslot

    ReplyDelete
  35. Hi! Thanks for the book, I am learning a lot and truly appreciate it. Question on the metal/reflect function: I tried what you had but got a black part of on the sides of the metal sphere that were not facing the inner sphere. I negated both terms and got something similar to what you had (albeit with something wrong on the reflection with the bottom sphere). What do you think I'm missing?

    ReplyDelete
    Replies
    1. Just to be clear, if I replace the original Lambertian sphere and put a metal material on it, it is pitch black (this is before the diffuse factor is brought in). How would I be able to debug this issue?

      Delete
    2. Hey, did you ever figure this problem out? I also notice the same thing after implementing the metal spheres. I've been messing around with the color function and I'm getting some better results but it still looks weird.

      Delete
  36. Hi! thanks again for the book. I'm using it to learn Rust along the way. I made it a spectral raytracer this time. Already looks cool when using a material with high dispersion like SF11. I'll have to implement some light sources and triangles next to play around with prisms.
    https://github.com/tvh/rayer-rs

    ReplyDelete
  37. Thank you for the book! I'm up to chapter 7 now and use JavaScript to render in a browser. You can see the output for a simple test case here https://rkibria.github.io/multiray.js/ and the github project is here https://github.com/rkibria/multiray.js

    The images take about 4 seconds each to render in Firefox on a 2.2GHz i7, and surprisingly 50% longer on Chrome.

    ReplyDelete
  38. The final random spheres demo image from the first book drawn live on a webpage: https://rkibria.github.io/multiray.js/randomscene.html

    ReplyDelete
  39. Hi - I'm liking the book so far but I don't get the maths at kindle location 137 where you say 'The rules of vector algebra are all that we would want here, and if we expand that equation and move all the terms to the left hand side we get:'

    I just don't get how you are going between the two equations involved... can you go in to any more detail or provide a link to a good, free reference on 'vector algebra' ?

    Thanks

    ReplyDelete
  40. I gotta favorite this website it seems very helpful .
    escrow blockchain

    ReplyDelete
  41. Amazing job, thanks a lot for sharing. I wonder whether there is a small typo in the PDF when building up the sphere class extending from hitable, as parameter t derivation should be obtained dividing by 2*a and not a. Maybe I own an old copy of the PDF and the typo is gone.
    Anyway, thanks a lot for sharing your knowledge!!

    ReplyDelete
    Replies
    1. Actually it'd better read:
      float temp = (-b - sqrt(discriminant)) / (2*a)
      float temp = (-b + sqrt(discriminant)) / (2*a)
      than
      float temp = (-b - sqrt(b*b-a*c)) / (2*a)
      float temp = (-b + sqrt(discriminant)) / (2*a)

      Delete
  42. Thank You For sharing such a nice information if Any one Searching for Wonderla Hyderabad Places information and Entry Ticket Booking Please visit <a href="https://www.bestbus.in/info/hyderabad-tourism”> Bestbus.in</a>

    ReplyDelete
  43. Thanks first of all for the useful info.
    the idea in this article is quite different and innovative please update more.
    vmware training in bangalore
    vmware courses in bangalore
    vmware Training in Anna Nagar
    vmware Training in Tnagar

    ReplyDelete
  44. can you tell me how should i look the image?? I am stuck on the very first problem, the code is there compiler is there but i dont understand how view the image?? what is the procedure?

    ReplyDelete
  45. Can you tell me in detail? Should i compile it first and then use gimp to open the file?

    ReplyDelete
  46. Thank for providing good information for site,Thanks for your sharing.
    CASINO iwin89 ONLINE

    ReplyDelete
  47. please tell me what should i do after writing the code

    ReplyDelete
  48. Truly, this article is really one of the very best in the history of articles. I am a antique ’Article’ collector and I sometimes read some new articles if I find them interesting. And I found this one pretty fascinating and it should go into my collection. Very good work!

    state employee cashless treatment scheme

    ReplyDelete
  49. Hello. I have a problem with the chapter 5, rendering the normals.

    I'm getting this image: https://imge.to/i/vy41kU

    It's an error obviously, but I don't know what to do to fix it.

    Can anybody help me, please?

    This is my code, so far

    #include
    #include "ray.h"

    bool hit_sphere(const vec3& center, float radius, const ray& r) {
    vec3 oc = r.origin() - center;
    float a = dot(r.direction(), r.direction());
    float b = 2.0 * dot(oc, r.direction());
    float c = dot(oc, oc) - radius * radius;
    float discriminant = b * b - 4 * a * c;
    if (discriminant < 0) {
    return -1.0;
    }
    else {
    return (-b - sqrt(discriminant)) / (2.0 * a);
    }
    }

    vec3 color(const ray& r)
    {
    float x = r.direction().x();
    float y = r.direction().y();
    float z = r.direction().z();
    if(x*x+y*y == 0)
    return vec3(1.0, 1.0, 1.0);
    else
    return 0.5*vec3((x/sqrt(x*x+y*y))+1, (y/sqrt(x*x+y*y))+1, -(x/sqrt(x*x+y*y))+1);
    }

    int main() {
    int nx = 200;
    int ny = 100;
    std::cout << "P3\n" << nx << " " << ny << "\n255\n";

    vec3 lower_left_corner(-4.0, -1.0, -1.0);
    vec3 horizontal(4.0, 0.0, 0.0);
    vec3 vertical(0.0, 2.0, 0.0);
    vec3 origin(0.0, 0.0, 0.0);

    for (int j = ny - 1; j >= 0; j--) {
    for (int i = 0; i < nx; i++) {
    float u = float(i) / float(nx);
    float v = float(j) / float(ny);
    ray r(origin, lower_left_corner + u * horizontal + v * vertical);
    vec3 col = color(r);
    int ir = int(255.99 * col[0]);
    int ig = int(255.99 * col[1]);
    int ib = int(255.99 * col[2]);
    std::cout << ir << " " << ig << " " << ib << "\n";
    }
    }
    }

    ReplyDelete
    Replies
    1. oops the color functions was a test... the code is
      vec3 color(const ray& r) {
      float t = hit_sphere(vec3(0,0,-1), 0.5, r);
      if (t > 0.0) {
      vec3 N = unit_vector(r.point_at_parameter(t) - vec3(0,0,-1));
      return 0.5*vec3(N.x()+1, N.y()+1, N.z()+1);
      }
      vec3 unit_direction = unit_vector(r.direction());
      t = 0.5*(unit_direction.y() + 1.0);
      return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0);
      }

      Delete
  50. Fixed! ... sorry my big mistake was left the hit_sphere function as bool and not as float...

    Althought I've changed the last line for this: return (-b - double(sqrt(discriminant))) / (2.0 * a);

    In VS 2019, is throwing a warning c26451

    ReplyDelete
  51. Thanks For Sharring such a beautiful information with us. I hope you will share Some more Information about steel hemisphere Please Keep Sharring.


    steel hemisphere

    ReplyDelete
  52. Hey Great Blog!!! Thank you for sharing information about steel hemisphere. Its really helpful for me, waiting for a more new post. Keep it Up!


    steel hemisphere

    ReplyDelete
  53. Thank you for sharing information about Computer Graphics. Its really helpful.

    And if you looking for the best game slot online please choose

    >> goldenslot
    >> สล็อตออนไลน์
    >> สล็อตคาสิโน
    >> โกเด้นสล็อต

    ReplyDelete
  54. The entrance to Gclub online casino gclub websites for real money Baccarat betting formula on mobile The most reliable at this time. Open for service online today. We will take to study. How to use the gclub

    ReplyDelete
  55. football and allowing Manchester เว็บไซต์ พนันบอล United to get 1 point to win the top four Prior to this game, Chelsea could only attack Bournemouth on Saturday, so both Manchester United and Everton are fully committed to winning the match. For the opportunity to push up and wrestle for the top four

    ReplyDelete
  56. This comment has been removed by the author.

    ReplyDelete
  57. This is very informative article thanks for sharing this information

    hindi sex stories || marathi sex stories || english sex stories || antarvasna

    ReplyDelete
  58. What do you think is the difference in your emotional state when you have money and when you do not have it? The advice is simple, try, as I did once on the site จีคลับ
    in order to free my mind from constant evil thoughts

    ReplyDelete
  59. If you want to sell more properties, improve marketing costs, and turn out to be THE real estate specialist in your market, your firm or brokerage company needs to be front side and center when and where individuals are searching for homes. Do it with the best real estate seo company

    ReplyDelete
  60. websites At that time, it was sbobeth.com บาคาร่าออนไลน์ which the appointed representatives were responsible

    ReplyDelete
  61. some really useful information. 918kiss --- An excellent online casino with high chances to win, variety and guaranteed payouts. don't be dumb

    ReplyDelete
  62. Great post. A few days ago a friend advised me a great site - จีคลับ. You have a great time. One of the obvious advantages over competitors is a wide selection of various kinds of card games, slots. Do not waste your time.

    ReplyDelete

  63. Wow. That is so elegant and logical and clearly explained. Brilliantly goes through what could be a complex process and makes it obvious.I want to refer about the best data science training videos

    ReplyDelete
  64. บาคาร่าออนไลน์ เกมพนันที่นักเสี่ยงดวงทุกคนควรจะทดลองเล่นสักหนึ่งครั้งในชีวิต
    บาคาร่าออนไลน์เป็นไพ่ประเภทหนึ่ง โดยกรรมวิธีการเล่นนั้นก็คล้ายกับการเล่นป็อก9 โดยเจ้ามือจะทำแจกไพ่ให้ผู้เล่นคนละ 2-3 ใบ เพื่อนับแต้มรวม แม้ผู้ใดกันมีแต้มคะแนนสูงขึ้นยิ่งกว่า ก็จะนับว่าชนะเกมนนี้ไป โดยเกมบาคาร่าเป็นเกมที่เว็บไซต์พนันทุกเว็บไซต์ควรจะมีให้สมาชิกได้เล่น เนื่องจากว่าเป็นเกมพนันที่นักเล่นการพนันนิยมเล่นสูงสุดเป็นชั้น 1 ด้วยเหตุดังกล่าวในวันนี้พวกเราก็เลยจะมาเขียนเสนอแนะจุดเด่นของการเล่นบาคาร่าออนไลน์ตามเว็บไซต์พนันต่างๆกันขา
    ผู้เล่นช่องทางชนะเกมมากมาย
    เกมบาคาร่า เป็นเกมที่คุณได้โอกาสที่จะชนะเจ้ามือเยอะแยะ โดยตามธรรมดาจังหวะที่คุณชนะนั้นมีความเป็นไปได้พอๆกับ 0.5 หรือ 50% ซึ่งจัดว่าเยอะๆเมื่อเทียบกับการเล่นเกมพนันออนไลน์จำพวกอื่นๆได้แก่ เกมกำถั่ว ที่มีโอการชนะเพียงแค่ 0.25 หรือ 25% เพียงเท่านั้น โดยเหตุนั้นคนคนจำนวนไม่น้อยที่อยากชนะเกมกล้วยๆก็เลยเลือกมาเล่นบาคาร่าออนไลน์แทน
    การเล่นบาคาร่าออนไลน์แพ้ก็ได้เงินคืน
    การเล่นบาคาร่าออนไลน์ถือหากว่าคุณแพ้เจ้ามือ คุณก็ยังได้โอกาสได้รับเงินของคุณที่วางเดิมพันคืนเต็มปริมาณ เพียงแต่คุณเสมอกับเจ้ามือแค่นั้น ถือได้ว่าเกมที่ได้โอกาสเสียตังค์น้อยมาก
    บาคาร่ามีวิธีการเล่นที่ง่าย
    เกมบาคาร่าออนไลน์ เกมเกมพนันจำพวกไพ่ที่มีวิธีการเล่นที่เข้าใจง่าย บางครั้งก็อาจจะง่ายดายกว่าเกมไพ่บางประเภทด้วย เพียงคุณได้ทดลองอ่านกรรมวิธีการเล่นอย่างเป็นจริงเป็นจังสักหนึ่งครั้ง คุณก็จะสามารถเล่นมันได้แน่ๆ โดยปะทุรอาจหาบทความอ่านเพิ่ม หรืออ่านในกฎข้อตกลงที่ดินเว็บไซต์ได้มีการบอกที่หน้าเว็บก็ได้
    เกมบาคาร่าออนไลน์มีสูตรลัดให้ท่านได้ใช้
    การเล่นบาคาร่าออนไลน์ ถ้าคุณคิดว่าเล่นไม่เป็น หรือดวงของคุณไม่ดีคุณยังมีแนวทางอื่นที่จะสามารถช่วยให้ท่านชนะเกมพนันได้ มันก็คือการใช้สูตรลัดสำหรับเล่นบาคาร่าเข้ามาใช้ตอนคุณวางเดิมพัน
    เกมบาทำลายออนไลน์มีโปรโมชั่นมาก
    การเล่นบาคาร่าออนไลน์นั้นมีการจัดโปรโมชั่นที่โคตรเย้ายวนใจผู้เล่นทั้งยัง การให้โบนัสแรกเข้า การมอบเงินเครดิตคืน รวมทั้งการให้ค่าคอมมิชชั่นเมื่อพวกเราชักชวนเพื่อนฝูงมาเล่นด้วย โดยเมื่อคุณลงทะเบียนสมัครสมาชิกทางเว็บไซต์จะให้เครดิตฟรี 100 – 300 บาท โดยในเว็บไซต์บาคาร่ายังมีเกมหลายประเภทอย่างเช่น บาคาร่า เกมรูเล็ต ป๊อกกระดอน สล็อต นอกเหนือจากนี้ทางเว็บไซต์ยังไม่มีการกำหนดอย่างต่ำสำหรับในการฝากเงิน
    บุคลากรในเว็บไซต์บาค่าร่าดูแลลูกค้าดี
    ด้านในเว็บไซต์บาคาร่าออนไลน์ยังมีบุคลากรรอให้บริการคุณอยู่ตลอด ไม่ว่าคุณมีคำถามอะไรคุณสามารถถามได้ หรือถ้าเกิดเกียจคร้านถาม ทางเว็บไซต์มีการทำปัญหา-คำตอบที่พบได้มากให้ท่านได้อ่านด้วย เว็บไซต์ดังกล่าวมาแล้วข้างต้นจะบริการคุณเปรียบได้กับคุณเป็นพระผู้เป็นเจ้า ไม่ว่าคุณจะฝากเงินเข้าเว็บไซต์หลักร้อย หรือฝากเงินเข้าเว็บไซต์หลักล้านทางเว็บไซต์บาคาร่าก็ยินดีบริการคุณ บุคลากรตรงนี้จัดว่าบริการลูกค้าทุกคนมีมาตรฐานดีอย่างยิ่งจริงๆ
    เกมบาคาร่าออนไลน์เปิดให้เล่น 1 วัน
    เกมบาคาร่ามีการเปิดให้นักเล่นการพนันทุกคนได้เข้าเล่นตลอด 1 วัน ไม่ว่าจะเป็นตอนที่มันคิดว่าง ตอนที่คุณรู้สึกร้อนเงิน หรือตอนที่คุณรู้สึกต้องการเล่นอะไรสนุกสนานๆคุณก็สามารถเข้ามาเล่นบาคาร่าในเว็บไซต์นี้ได้
    และก็ทั้งผองนี้เป็นจุดเด่นของเกมบาคาร่าออนไลน์แบบโดยประมาณเว้นแต่จุดเด่นที่บอกในเนื้อหานี้แล้ว ยังมีจุดเด่นอื่นๆที่คุณจึงควรไปสัมผัสเอง เล่นเอง ถึงจะทราบ

    บาคาร่า

    ReplyDelete
  65. Tan Binh Over 10 years of supplying water materials, our company is now a reliable partner for most water supply systems companies in Hanoi as well as nationwide. With products always available from famous brands like Jaky, Round Start, Uib, Jeoenu YD Valve are pleased to serve you.

    https://forums.vwvortex.com/member.php?3759327-vancongnghiephn
    https://www.darkreading.com/profile.asp?piddl_userid=396420


    https://www.designspiration.com/baogiavancongnghiep/saves/

    https://twinoid.com/user/9959449

    https://gold-forum.kitco.com/member.php?348377-vancongnghiephn

    ReplyDelete
  66. Hello everyone, Are you into trading or just wish to give it a try, please becareful on the platform you choose to invest on and the manager you choose to manage your account because that’s where failure starts from be wise. After reading so much comment i had to give trading tips a try, I have to come to the conclusion that binary options pays massively but the masses has refused to show us the right way to earn That’s why I have to give trading tips the accolades because they have been so helpful to traders . For a free masterclass strategy kindly contact (paytondyian699@gmail.com) for a free masterclass strategy. He'll give you a free tutors on how you can earn and recover your losses in trading for free..

    ReplyDelete
  67. https://www.patreon.com/user/creators?u=38609150
    https://www.lonelyplanet.com/profile/dixienullify807266
    https://www.periscope.tv/maytinhdeban

    ReplyDelete
  68. Wow. That is so elegant and logical and clearly explained.
    918kiss
    vscr888

    ReplyDelete
  69. https://maytinhdeban.livejournal.com/1570.html
    https://www.ohay.tv/view/500-k-co-mua-duoc-man-hinh-may-tinh-cu-khong/CHhTc54BRb
    https://maytinhdeban.hatenablog.com/entry/2020/08/03/155827?_ga=2.44370977.442879880.1596437912-534267799.1596437912
    https://medium.com/p/5cb7aa91a09c/edit?source=your_stories_page---------------------------


    ReplyDelete
  70. Good article! It was awesome to read, thanks for sharing this great content to my vision, keep sharing… Instant Approval DoFollow Travel Blog Commenting Sites

    ReplyDelete
  71. Very Helpful Article. Super bull It might help you. Super bull Thanks For Sharing
    Super bull Thank you very much.

    ReplyDelete
  72. This Is Really Useful And Nice Information. Super bull
    This are such great articles. Super bull This articles can help you to make some new ideas.
    https://ww88thai.net/2020/08/super-bull/ I appreciate for reading my blogs.

    ReplyDelete
  73. This are new articles style for you. https://ww88thai.net/2020/08/super-bull/ You can find some new idea on this. https://ww88thai.net/2020/08/super-bull/ It might help you to write or think some new idea.
    https://ww88thai.net/2020/08/super-bull/ Thanks for sharing such a wonderful post.
    https://ww88thai.net/2020/08/super-bull/ I am very glad for reading my articles.

    ReplyDelete
  74. Led bullb repairing fast and lowest prices visit us : JAINAND DIGITAL POINT

    ReplyDelete
  75. Hello everyone, Are you into trading or just wish to give it a try, please becareful on the platform you choose to invest on and the manager you choose to manage your account because that’s where failure starts from be wise. After reading so much comment i had to give trading tips a try, I have to come to the conclusion that binary options pays massively but the masses has refused to show us the right way to earn That’s why I have to give trading tips the accolades because they have been so helpful to traders . For a free masterclass strategy kindly contact (paytondyian699@gmail.com) for a free masterclass strategy. He'll give you a free tutors on how you can earn and recover your losses in trading for free..or Whatsapp +1 562 384 7738

    ReplyDelete
  76. no requirement to upload documents, papers, certificates or proof.

    Sexy Casino
    ALLBET Casino

    ReplyDelete
  77. Nice Blog!
    Facing error while using QuickBooks get instant solution with our QuickBooks experts.Dial +1-(855)533-6333 QuickBooks Payroll Support

    ReplyDelete
  78. I am very much pleased with the contents you have mentioned. I wanted to thank you for this great article.
    edward cullen peacoat

    ReplyDelete

  79. UFC 254: Khabib vs. Gaethje is an upcoming mixed martial arts event produced by the Ultimate Fighting Championship that will take place on October 24, 2020 UFC 254

    ReplyDelete
  80. This comment has been removed by the author.

    ReplyDelete
  81. Great work on your blog right here, really helpful. keep on posting discussion like this ^^. please visit my site too agen togel online

    ReplyDelete
  82. Excelente, gracias por sus esfuerzos y gracias por compartir buena información.
    เล่นจีคลับ

    ReplyDelete
  83. jack88 สมัคร jack88 สมัคร jack88 jack88
    jack88 เกมสล็อต jack88 เกมสล็อต sagame sagame
    สมัครking99 สมัครking99
    jack88 ดาวน์โหลด jack88 ดาวน์โหลด
    jack88 สล็อต jack88 สล็อต

    ReplyDelete
  84. ace333 ace333
    918kiss สมัคร918kiss สมัคร
    slotciti slotciti
    168lottothai168lottothai
    sagame sagame
    sexygame sexygame
    เว็บพนัน คาสิโนออนไลน์ jack88 เว็บพนัน คาสิโนออนไลน์ jack88

    ReplyDelete
  85. It uses C plus classes plus operator overloading.


    ALLBET Casino
    ALLBET

    ReplyDelete
  86. https://maylamgiatot.wordpress.com/2020/12/01/quan-dong-da-tim-mua-may-tinh-de-ban-o-dau/
    https://leuxonghoigiadinh.wordpress.com/2020/12/01/quan-dong-da-tim-mua-may-tinh-de-ban-o-dau-gia-tot/
    https://mayxoidatnongnghiep.wordpress.com/2020/12/01/quan-dong-da-tim-mua-may-tinh-de-ban-o-dau-gia-tot-ban-co-biet/
    https://maylamdattrongngo.wordpress.com/2020/12/01/he-lo-quan-dong-da-tim-mua-may-tinh-de-ban-o-dau/
    https://maynongnghiepdananggiare.wordpress.com/2020/12/01/nhac-ban-quan-dong-da-tim-mua-may-tinh-de-ban-o-dau/

    ReplyDelete
  87. VERY NICE PAGE

    SBOBETPUSAT - BANDAR BOLA | CASINO ONLINE | SLOT | SABUNG AYAM | SBOBET | MAXBET/IBCBET |BONUS NEW MEMBER 100%


    SBOBETPUSAT.COM Adalah Agen Taruhan Bola Online Dan Live Kasino Terbesar Di Asia Tenggara Yang Menyediakan Jasa Pembuatan ID Taruhan Online Yang Sudah Terjamin Keamanan Dan Kepercayaan Nya Dalam Bertransaksi.

    Proses Deposit Dan Withdrawl Juga Hanya Membutuhkan Waktu 1-2 Menit, SBOBETPUSAT.COM Juga Siap Membantu Anda Jika Anda Mengalami Kesulitan.

    Bagi Anda Yang Ingin Bergabung Dengan SBOBETPUSAT Kami Juga Memiliki Beberapa Bonus Menarik Bagi Anda :

    Bagi Anda Yang Baru Saja Bergabung Dengan SBOBETPUSAT Hanya Dengan Minimal Deposit Senilai Rp. 500.000,- Anda Berhak Mendapatkan Hadiah Langsung Seperti Kaos Jersey Tim Kesayangan Anda Atau Sepatu Futsal.

    Dan juga BONUS NEW MEMBER 100%
    Berikut syarat2 nya :
    Promo Bonus New Deposit 100%
    depo pertama min. 300 dapat bonus 50%
    maks. bonus 500
    depo kedua min. 300 dapat bonus 50%
    maks. bonus 500
    syarat WD : TO = 8 x saldo + bonus

    Bonus Sportsbook :
    - Bonus New Member 100%
    - Bonus Rollingan 0.25%
    - Bonus Cashback Up to 7%

    Bonus Live Kasino :
    - Bonus New Member 100%
    - Bonus Rollingan 1%
    - Bonus Cashback Up to 7%

    Bonus Sabung Ayam :
    - Bonus New member 10%
    - Bonus Cashback Up to 7%

    Untuk Pendaftaran Bisa Langsung Menghubungi Kami Melalui :
    - Livechat
    - Line : SBOBETPUSAT
    - Whatsapp : +855968003753
    - Telegram : +855968003753

    https://viralbolapusat.blogspot.com/2021/01/sbobetpusat-bandar-bola-casino-online.html

    ReplyDelete
  88. Wonder to see your information, thanks for sharing with us.
    open apk file

    ReplyDelete

  89. slotx สล็อตออนไลน์ slotx.jack88
    หนังออนไลน์ หนังออนไลน์
    หนัง ใหม่ หนัง ใหม่
    sexygame66 sexygame66
    BAOver BAOver
    ufa191 ufa191
    ทางเข้า gclub มือถือ ทางเข้า gclub มือถือ
    sclub sclub
    mega888 mega888

    ReplyDelete
  90. I appreciate your efforts to collect the wonderful information open vob file .

    ReplyDelete
  91. Your Blog is awesome to get info, please if you want some business leads so
    MCA Leads

    ReplyDelete
  92. With today's modern society, the demanding needs of people are increasing. Not only beauty, eating and playing, but choosing a child's bedroom also requires a lot of factors. Because the bedroom is a place to rest, relax, study and sometimes also play a place for your baby. More: Phòng ngủ trẻ em, Giường tầng bé traiNội thất trẻ em

    ReplyDelete
  93. Hung was formerly an official distributor of industrial lubricants of Shell in the North. Currently, in addition to oil trading, we also trade in transportation and equipment trading. After nearly 12 years of establishment and development, Yen Hung is now a prestigious partner of nearly 10,000 large and small domestic and international factories. Main products:
    giá dầu truyền nhiệt
    dầu bánh răng
    dầu tuần hoàn
    dầu dẫn nhiệt
    dầu thủy lực shell
    mỡ bò bôi trơn chịu nhiệt

    ReplyDelete
  94. 328CASH adalah situs taruhan terbesar dan terpercaya di Indonesia. Dimana kami adalah salah satu bandar judi bola online, casino online dan poker online terbaik yang mencakup seluruh bidang permainan game online. 328CASH kini hadir sebagai salah satu bandar bola indonesia yang didukung oleh customer service profesional online 24 jam dan anda bisa menghubungi kami via livechat , SMS maupun telepon , Dan pastinya kami akan memberikan kemudahan kepada anda sehingga anda bisa menikmati permainan ini jauh lebih nyaman.

    Lalu anda juga bisa nonton bola online sekarang juga di website kami, sambil menikmati permainan judi bola online. 328CASH juga menyediakan permainan segala jenis permainan Live Casino dan Poker Online terbaik. Anda hanya cukup mendaftarkan diri anda sekali saja untuk bisa memainkan semua permainan yang kami sediakan.

    328cash.com
    https://139.162.45.92/desktop/home

    ReplyDelete
  95. DAFTAR 328CASH ,
    SANGAT TERPERCAYA
    https://139.162.45.92/

    ReplyDelete
  96. Apa itu 328CASH?

    328CASH adalah situs taruhan terbesar dan terpercaya di Indonesia. Dimana kami adalah salah satu bandar judi bola online, casino online dan poker online terbaik yang mencakup seluruh bidang permainan game online. 328CASH kini hadir sebagai salah satu bandar bola indonesia yang didukung oleh customer service profesional online 24 jam dan anda bisa menghubungi kami via livechat , SMS maupun telepon , Dan pastinya kami akan memberikan kemudahan kepada anda sehingga anda bisa menikmati permainan ini jauh lebih nyaman.

    Lalu anda juga bisa nonton bola online sekarang juga di website kami, sambil menikmati permainan judi bola online. 328CASH juga menyediakan permainan segala jenis permainan Live Casino dan Poker Online terbaik. Anda hanya cukup mendaftarkan diri anda sekali saja untuk bisa memainkan semua permainan yang kami sediakan.

    328CASH juga menyediakan :

    Minimal Deposit Rp 20,000 (Dua Puluh Ribu Rupiah)
    Minimal Withdraw Rp 50,000 (Lima Puluh Ribu Rupiah)
    Waktu Deposit ± 2 Menit (Kurang lebih dua menit)
    Waktu Penarikan ± 5 Menit (Krang lebih lima menit)
    Metode Deposit Bank Transfer, Gopay, Dana, Ovo, Link aja, Pulsa XL, Pulsa Telkomsel
    Provider Slot Terbaik Pragmatic Play, Joker Slot, Slot88, OneTouch

    Permainan slot online

    Bandar Slot terbaik dan terpercaya

    ReplyDelete
  97. Apa itu 328CASH?
    1
    328CASH adalah situs taruhan terbesar dan terpercaya di Indonesia. Dimana kami adalah salah satu bandar judi bola online, casino online dan poker online terbaik yang mencakup seluruh bidang permainan game online. 328CASH kini hadir sebagai salah satu bandar bola indonesia yang didukung oleh customer service profesional online 24 jam dan anda bisa menghubungi kami via livechat , SMS maupun telepon , Dan pastinya kami akan memberikan kemudahan kepada anda sehingga anda bisa menikmati permainan ini jauh lebih nyaman.

    Lalu anda juga bisa nonton bola online sekarang juga di website kami, sambil menikmati permainan judi bola online. 328CASH juga menyediakan permainan segala jenis permainan Live Casino dan Poker Online terbaik. Anda hanya cukup mendaftarkan diri anda sekali saja untuk bisa memainkan semua permainan yang kami sediakan.

    328CASH juga menyediakan :

    Minimal Deposit Rp 20,000 (Dua Puluh Ribu Rupiah)
    Minimal Withdraw Rp 50,000 (Lima Puluh Ribu Rupiah)
    Waktu Deposit ± 2 Menit (Kurang lebih dua menit)
    Waktu Penarikan ± 5 Menit (Krang lebih lima menit)
    Metode Deposit Bank Transfer, Gopay, Dana, Ovo, Link aja, Pulsa XL, Pulsa Telkomsel
    Provider Slot Terbaik Pragmatic Play, Joker Slot, Slot88, OneTouch

    Permainan slot online

    Bandar Slot terbaik dan terpercaya

    ReplyDelete
  98. Apa itu 328CASH?

    328CASH adalah situs taruhan terbesar dan terpercaya di Indonesia. Dimana kami adalah salah satu bandar judi bola online, casino online dan poker online terbaik yang mencakup seluruh bidang permainan game online. 328CASH kini hadir sebagai salah satu bandar bola indonesia yang didukung oleh customer service profesional online 24 jam dan anda bisa menghubungi kami via livechat , SMS maupun telepon , Dan pastinya kami akan memberikan kemudahan kepada anda sehingga anda bisa menikmati permainan ini jauh lebih nyaman.

    Lalu anda juga bisa nonton bola online sekarang juga di website kami, sambil menikmati permainan judi bola online. 328CASH juga menyediakan permainan segala jenis permainan Live Casino dan Poker Online terbaik. Anda hanya cukup mendaftarkan diri anda sekali saja untuk bisa memainkan semua permainan yang kami sediakan.
    Permainan slot online
    Permainan slot online
    daftar : 328cash.com
    https://139.162.45.92/desktop/register-done

    ReplyDelete
  99. This blog was very nicely formatted; it maintained a flow from the first word to the last. Royal Enfield Jacket

    ReplyDelete
  100. Finden Sie das beste Online Casino in Deutschland durch unsere Expertenübersicht der deutschen Top Online Casinos.

    ReplyDelete
  101. This impressed me so much amazing. Keep working and providing information
    attribute patch

    ReplyDelete
  102. Thank goodness I found it on Bing. You’ve made my day! Thanks again!
    activator

    ReplyDelete
  103. I’m glad that you just shared this helpful info with us. Please keep us informed like this
    Sidifi Music Converter

    ReplyDelete
  104. Great article..I am looking so forward to your blog comment and I love your page on your post.. That is so pretty.
    table games

    ReplyDelete
  105. That's great. It made me learn. And have developed a lot more of myself. The content is very good. I understand and know well. Let's share my experience with you. make your post It's a consolation prize.
    สล็อตออนไลน์
    สมัครสล็อต
    เติมเงินสล็อต
    ดาวน์โหลดสล็อต
    โปรโมชั่นสล็อต

    ReplyDelete
  106. I understand it very well, so I would like to share my experience with you. make your post It's a consolation prize. You don't have to be stuck with anything anymore. Because I told you it was very good.

    ReplyDelete
  107. Share this experience. It's awesome. It makes us discover new things.

    slotxo
    918kiss
    joker123
    pg slot
    goldenslot

    ReplyDelete
  108. This is a really well written article. I’ll be sure to bookmark it and come back to read extra of your helpful info. Thank you for the post. I will certainly comeback.
    ឡូកឡាក់ Online

    ReplyDelete

  109. This is very interesting blog. A lot of article I read nowadays don't really offer anything that I'm enthusiastic about, but I'm most certainly hooked about this one.

    Nitlimiter crack

    ReplyDelete
  110. My mind was blown by this.Keep up the great work!
    houdini patch

    ReplyDelete