by AdamB » Mon Oct 31, 2011 9:14 pm
Because I evidently have waay too much time on my hands, I offer for your delectation... A pure Ruby raytracerIt 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. 
Please, register (free) to access all the attachments on the forums.
-

AdamB
- LightUp
-
- Posts: 746
- Joined: Wed Dec 12, 2007 10:49 am
- Location: Brighton, UK
- Name: AdamB
by Chris Fullmer » Mon Oct 31, 2011 9:57 pm
Sounds cool Adam, I've got a render cooking in the background as we speak! 
-

Chris Fullmer
- SketchUp Team
-
- Posts: 6688
- Joined: Wed Nov 21, 2007 3:21 am
- Location: Davis, CA
- Name: Chris Fullmer
- Operating system: Windows
- SketchUp version: 8
- License type: Pro
- SketchUp use: landscape architecture
- Level of SketchUp: Advanced
-
by Mike Lucey » Mon Oct 31, 2011 10:29 pm
Thanks Adam.
Chris, can you show the results and original and anything else we might learn from?
-

Mike Lucey
- Mayor
-
- Posts: 7238
- Joined: Mon Oct 22, 2007 1:22 pm
- Location: Co. Clare, Ireland
- Name: Mike Lucey
- Operating system: Mac
- SketchUp version: 8
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
by thomthom » Mon Oct 31, 2011 10:42 pm
God heavens! Ruby raytracer ...  do you also race snails on your spare time? 
Please, register (free) to access all the attachments on the forums.
-

thomthom
- Global Moderator
-
- Posts: 17595
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: thomthom
- Operating system: Windows
- SketchUp version: 8
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
-
by Marian » Mon Oct 31, 2011 10:56 pm
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.
-

Marian
-
- Posts: 1340
- Joined: Thu Jan 03, 2008 10:31 am
- Location: Suceava / Cuj-Napoca, Romania
- Name: Marian
by thomthom » Mon Oct 31, 2011 11:27 pm
Marian wrote: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.
-

thomthom
- Global Moderator
-
- Posts: 17595
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: thomthom
- Operating system: Windows
- SketchUp version: 8
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
-
by Marian » Tue Nov 01, 2011 1:29 am
I guess I won't have much use for it then 
-

Marian
-
- Posts: 1340
- Joined: Thu Jan 03, 2008 10:31 am
- Location: Suceava / Cuj-Napoca, Romania
- Name: Marian
by Aerilius » Tue Nov 01, 2011 1:49 am
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.
-
Aerilius
- Top SketchUcator
-
- Posts: 1123
- Joined: Tue Dec 23, 2008 11:00 pm
- Location: Kaiserslautern
by thomthom » Tue Nov 01, 2011 9:28 am
There is a reason this is posted in the Developers section, not the Plugins section. 
-

thomthom
- Global Moderator
-
- Posts: 17595
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: thomthom
- Operating system: Windows
- SketchUp version: 8
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
-
by AdamB » Tue Nov 01, 2011 10:47 am
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
-

AdamB
- LightUp
-
- Posts: 746
- Joined: Wed Dec 12, 2007 10:49 am
- Location: Brighton, UK
- Name: AdamB
by thomthom » Tue Nov 01, 2011 10:51 am
Thanks for the breakdown Adam. 
-

thomthom
- Global Moderator
-
- Posts: 17595
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: thomthom
- Operating system: Windows
- SketchUp version: 8
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
-
by tomasz » Wed Nov 02, 2011 10:18 am
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 wrote:Thea will be quaking in their boots. 
-
tomasz
- SU2TH & SU2KT Developer
-
- Posts: 769
- Joined: Fri Nov 16, 2007 8:46 pm
- Location: Poland
- Name: Tomasz
- Operating system: Windows
- SketchUp version: 8
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
-
by Aerilius » Thu Nov 03, 2011 10:24 pm
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) - Code: Select all
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
Please, register (free) to access all the attachments on the forums.
-
Aerilius
- Top SketchUcator
-
- Posts: 1123
- Joined: Tue Dec 23, 2008 11:00 pm
- Location: Kaiserslautern
by thomthom » Fri Nov 04, 2011 9:19 am
It renders the SketchUp scene?
-

thomthom
- Global Moderator
-
- Posts: 17595
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: thomthom
- Operating system: Windows
- SketchUp version: 8
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
-
by Aerilius » Fri Nov 04, 2011 1:35 pm
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 
-
Aerilius
- Top SketchUcator
-
- Posts: 1123
- Joined: Tue Dec 23, 2008 11:00 pm
- Location: Kaiserslautern
by AdamB » Fri Nov 04, 2011 8:09 pm
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
-

AdamB
- LightUp
-
- Posts: 746
- Joined: Wed Dec 12, 2007 10:49 am
- Location: Brighton, UK
- Name: AdamB
by notareal » Sun Nov 06, 2011 11:58 am
Tomasz wrote: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/GraphicsGe ... iv/minray/
-
notareal
- Thea Render
-
- Posts: 951
- Joined: Tue Nov 13, 2007 9:54 pm
- Location: Oulu, Finland
- Name: notareal
-
Return to Developers' Forum
|