• Login
sketchucation logo sketchucation
  • Login
πŸ”Œ Quick Selection | Try Didier Bur's reworked classic extension that supercharges selections in SketchUp Download

[plugin] Ruby Raytracer

Scheduled Pinned Locked Moved Developers' Forum
17 Posts 8 Posters 4.4k Views 8 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    AdamB
    last edited by 31 Oct 2011, 20:14

    Because I evidently have waay too much time on my hands, I offer for your delectation...

    A pure Ruby raytracer

    It has Depth-of-field (using jittered samples), 3 fixed materials, (sky, checkerboard and chrome) and font rendering - of sorts!

    There are a couple of constants you can edit:

    REZ for image size
    SAMPLES for number of jittered samples per pixel

    (I started from a micro raytracer written in C and transmogrified it into our chosen language and twiddled it a bit.)

    Enjoy - Thea will be quaking in their boots. πŸ˜‰


    raytrace.rb

    Developer of LightUp Click for website

    1 Reply Last reply Reply Quote 0
    • C Offline
      Chris Fullmer
      last edited by 31 Oct 2011, 20:57

      Sounds cool Adam, I've got a render cooking in the background as we speak! πŸ˜„

      Lately you've been tan, suspicious for the winter.
      All my Plugins I've written

      1 Reply Last reply Reply Quote 0
      • M Offline
        Mike Lucey
        last edited by 31 Oct 2011, 21:29

        Thanks Adam.

        Chris, can you show the results and original and anything else we might learn from?

        Support us so we can support you! Upgrade to Premium Membership!

        1 Reply Last reply Reply Quote 0
        • T Offline
          thomthom
          last edited by 31 Oct 2011, 21:42

          God heavens! Ruby raytracer ... πŸ˜† do you also race snails on your spare time? πŸ˜„


          Lost track of how long this took to render. :D

          Thomas Thomassen β€” SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • M Offline
            Marian
            last edited by 31 Oct 2011, 21:56

            Does it need a lot of resources? It just hangs for me after I point out the output file, it just stays at line 0 out of 512.

            http://marian87.deviantart.com/

            1 Reply Last reply Reply Quote 0
            • T Offline
              thomthom
              last edited by 31 Oct 2011, 22:27

              @marian said:

              Does it need a lot of resources? It just hangs for me after I point out the output file, it just stays at line 0 out of 512.

              Yes, it's a raytrace render - taking a long time. I set the resolution down to 256 and it still took a long time. The SketchUp UI stops updating as well - like when you do a large Sandbox operation.

              Thomas Thomassen β€” SketchUp Monkey & Coding addict
              List of my plugins and link to the CookieWare fund

              1 Reply Last reply Reply Quote 0
              • M Offline
                Marian
                last edited by 1 Nov 2011, 00:29

                I guess I won't have much use for it then πŸ˜›

                http://marian87.deviantart.com/

                1 Reply Last reply Reply Quote 0
                • A Offline
                  Aerilius
                  last edited by 1 Nov 2011, 00:49

                  And it seems to render a "built-in" model, not actually my SketchUp model (that's probably why it is called a "micro raytracer"). When I change the numbers in G, the balls shift.

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    thomthom
                    last edited by 1 Nov 2011, 08:28

                    There is a reason this is posted in the Developers section, not the Plugins section. πŸ˜‰

                    Thomas Thomassen β€” SketchUp Monkey & Coding addict
                    List of my plugins and link to the CookieWare fund

                    1 Reply Last reply Reply Quote 0
                    • A Offline
                      AdamB
                      last edited by 1 Nov 2011, 09:47

                      Guys, guys

                      Its a 100 lines of Ruby that manages to do image file writing, blurry depth of field, a point light and multiple materials!
                      How on earth do you think it would be a full raytracer! 😲

                      However, if you're interested in raytracing, its very simple and you can play around with it to learn about this area of graphics.

                      The G[] array contains a Bitmap of 32x10 stored as 10 integers.

                      In function T(), I test the primary ray against an infinite plane and if hit return position+surface normal+materialID (Line 36).
                      I run through each bit of the bitmap and where this is '1' bits, I trace a reflective Sphere returning a surface position+normal+materiaID. (Line 54)

                      The Scene function S(), traces the primary ray into the scene (Line 70) and colors the pixels depending on material m, and a single pointlight (Line 77). Try changing the position of the light.

                      The color for the infinite plane is chosen based on a mod function of position. Line 83 controls the scale of chequers.

                      The main function "raytrace" starts at line 93 and takes care of generating primary rays, and writing out an PPM image file.

                      Adam

                      Developer of LightUp Click for website

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        thomthom
                        last edited by 1 Nov 2011, 09:51

                        Thanks for the breakdown Adam. πŸ‘

                        Thomas Thomassen β€” SketchUp Monkey & Coding addict
                        List of my plugins and link to the CookieWare fund

                        1 Reply Last reply Reply Quote 0
                        • T Offline
                          tomasz
                          last edited by 2 Nov 2011, 09:18

                          Thanks for the sample code and the explanation.
                          I wasn't aware that a Raytracer can be written in such a small piece of code!! 😲

                          @adamb said:

                          Thea will be quaking in their boots. πŸ˜‰
                          πŸ˜†

                          Author of [Thea Render for SketchUp](http://www.thearender.com/sketchup)

                          1 Reply Last reply Reply Quote 0
                          • A Offline
                            Aerilius
                            last edited by 3 Nov 2011, 21:24

                            I edited and reduced some lines. Hope nobody minds...
                            (it's just what I thought would work, I've not yet looked at other raytracing source codes)

                            
                            module RubyRaytracer
                            
                            class Geom;;Vector3d
                              def sc(s)
                                Geom;;Vector3d.new(x*s,y*s,z*s)
                              end
                              def sc!(s)
                                self.x *= s
                                self.y *= s
                                self.z *= s
                                self
                              end
                            end
                            
                            def self.v(x,y,z)
                              Geom;;Vector3d.new(x,y,z)
                            end
                            
                            # @lights; position, color, intensity, radius of light source
                            @lights = [ [[1000,1000,1000],[255,255,255],300,10], [[-20,23,15],[255,0,0],50,0], [[-5.5,8,15],[0,0,255],50,0] ]
                            @groundcolor = v(180,160,120)
                            @skycolor = v(180,200,255)
                            @skycolor2 = v(140,160,220)
                            @rez = 256
                            @samples = 8
                            
                            def self.cast_ray(o, d)
                              hit = @model.raytest([o,d],false)
                              return (d.z<0)? @groundcolor.sc(1+0.5*d.z) ; @skycolor.sc(1-2*d.z)+@skycolor2.sc(2*d.z) if hit == nil || (f = hit[1].last).class != Sketchup;;Face
                              p = hit[0]
                              n = f.normal
                              rd = (d - n.sc( 2*(d%n)/(n.length**2) )).normalize # reflected ray on face
                              m = (d%n<0)? f.material ; (f.back_material||f.material)
                              a = (m!=nil)? m.alpha ; 1 # opacity; I use this parameter for reflectivity
                              lc = v(0,0,0) # light color
                              @lights.each{|lt| # loop over all light sources
                                l = Geom;;Point3d.new(lt[0].collect{|x| x+lt[3]*rand()}) # light position +/- light radius for smooth shadows
                                ld = (p.vector_to(l)).normalize # vector to light source
                                s = ( x=@model.raytest([p,ld]); x!=nil && x[0].on_line?([p,l]) )? 0.5 ; 1 # occlusion test for shadows
                                i = lt[2]/(4*Math;;PI*ld.length)**2 # light intensity decreases with distance
                                h = 0.25+0.75*[(1 - 2*Math.acos( n%ld )/Math;;PI),0].max # shading
                                lc += v(*lt[1]).sc(i*s*h)
                              }
                              c = (m!=nil)? v( *((m.materialType>0)? m.texture.average_color ; m.color).to_a.slice(0,3) ) ; v(255,255,255) # color of face
                              new_color = (lc - v(255,255,255) + c).sc(a)
                              # new_color += self.cast_ray(p,d).sc(1-a) if a<1 # uncomment this for transparency
                              new_color += self.cast_ray(p,rd).sc(1-a) if a<1 # reflectivity
                              return new_color
                            end #def cast_ray
                            
                            # credits to AdamB, http://forums.sketchucation.com/viewtopic.php?f=180&t=40989#p363271
                            def self.raytrace(filename=nil, width=@rez, samples=@samples)
                              @model = Sketchup.active_model
                              @lights[0] = [ @model.shadow_info["SunDirection"].sc(1000000).to_a, [255,255,255], 300, 100000] # SketchUp sun
                            
                              filename = UI.savepanel("Save Raytrace Image", "","output.ppm") unless filename
                              File.open(filename, "wb") {|f|
                                vw = Sketchup.active_model.active_view
                                height = (width*vw.vpheight/vw.vpwidth).to_i
                                f.printf("P6 #{width} #{height} 255\n")
                            
                                fov = vw.field_of_view.degrees
                                e = vw.camera.eye
                                o = v(e.x, e.y, e.z)
                                t = vw.camera.target - e
                                g = v(t.x, t.y, t.z).normalize
                                
                                a = (v(0,0,1).cross(g)).normalize.sc(fov / height)
                                b = (g.cross(a)).normalize.sc(fov / height) 
                                c = a.sc(-width*0.5)+b.sc(-height*0.5)+g
                                
                                for y1 in 0...height
                                  y = height - 1 - y1
                                  Sketchup.set_status_text "raytrace; line #{y1} of #{height}"
                                  for x1 in 0...width
                                    x = width - 1 - x1
                                    p = v(0,0,0)
                                    for r in 1..samples
                                      p += self.cast_ray(Geom;;Point3d.new(o.to_a), (a.sc(x+rand())+b.sc(y+rand())+c))
                                    end
                                    p = p.sc(1/samples.to_f)
                                    p = p.to_a.collect{|x| if x>255;255;elsif x<0;0;else;x.to_i;end}
                                    f.printf("%c%c%c", *p)
                                  end
                                end
                                Sketchup.set_status_text "Finished #{filename}"
                              }
                            end
                            
                            end #module RubyRaytracer
                            
                            if( not file_loaded?(__FILE__) )
                              menu=UI.menu("Plugins")
                              menu.add_item("Raytrace the model!") { RubyRaytracer.raytrace }
                              file_loaded(__FILE__)
                            end
                            
                            
                            
                            #100
                            
                            

                            output.png

                            1 Reply Last reply Reply Quote 0
                            • T Offline
                              thomthom
                              last edited by 4 Nov 2011, 08:19

                              It renders the SketchUp scene?

                              Thomas Thomassen β€” SketchUp Monkey & Coding addict
                              List of my plugins and link to the CookieWare fund

                              1 Reply Last reply Reply Quote 0
                              • A Offline
                                Aerilius
                                last edited by 4 Nov 2011, 12:35

                                Well, instead of the hard-coded materials and G-Bitmap, it does a raytest() in the model and takes the material of the face that the ray hits (+ shading from normal etc). That is all, but when it's repeated for every pixel, the result is impressive.
                                Nevertheless, it's still slow πŸ˜‰

                                1 Reply Last reply Reply Quote 0
                                • A Offline
                                  AdamB
                                  last edited by 4 Nov 2011, 19:09

                                  Thats pretty cool. Its it it much slower?

                                  Just FYI, I test LightUp raytests in a mode that gives realtime raytracing of your scene as you look around!

                                  Adam

                                  Developer of LightUp Click for website

                                  1 Reply Last reply Reply Quote 0
                                  • N Offline
                                    notareal
                                    last edited by 6 Nov 2011, 10:58

                                    @unknownuser said:

                                    Thanks for the sample code and the explanation.
                                    I wasn't aware that a Raytracer can be written in such a small piece of code!! 😲
                                    πŸ˜†

                                    Quite tiny indeed... there are others too, like
                                    http://tog.acm.org/resources/GraphicsGems/gemsiv/minray/

                                    Welcome to try [Thea Render](http://www.thearender.com/), Thea support | [kerkythea.net](http://www.kerkythea.net/) -team member

                                    1 Reply Last reply Reply Quote 0
                                    • 1 / 1
                                    1 / 1
                                    • First post
                                      1/17
                                      Last post
                                    Buy SketchPlus
                                    Buy SUbD
                                    Buy WrapR
                                    Buy eBook
                                    Buy Modelur
                                    Buy Vertex Tools
                                    Buy SketchCuisine
                                    Buy FormFonts

                                    Advertisement