[Info] Ambient Occlusion -> Simple Rays
-
@wacov said:
I guess I don't know what I'm talking about, but doesn't SU's raytest method extract more information than you need for your plugin? Maybe that's why it's so (comparatively) slow.
I thought exactly the same, as it returns "the first thing that the ray hits". I suppose it means "the closest thing". For my purpose it's enough to get first-on-the-list hit end exit.
That might do the trick. -
I quickly wrote this, but it worked MUCH slower than original method.
def raytest2 ray hit = false entities = self.entities entities.each { |face| if face.kind_of?(Sketchup;;Face) and face.classify_point(ray[0]) > 4 plane = [face.vertices[0].position, face.normal] intersection = Geom.intersect_line_plane(ray, plane) if intersection and face.classify_point(intersection) < 8 hit = true break end end } return hit end
This could be optimized by passing pre-sorted face array (based on results from previous tests) instead of browsing entities array, but I doubt it would speed it up much.
What do you think? -
@qpik said:
plane = [face.vertices[0].position, face.normal]
You can use
face.plane
instead@qpik said:
This could be optimized by passing pre-sorted face array (based on results from previous tests) instead of browsing entities array, but I doubt it would speed it up much.
What do you think?hmm... If you only iterate the entities collection once then it won't help to pre-process to filter out only faces. Infact, that would mean more iterations. But if you need to iterate the face multiple times, then you will save time on pre-filtering.
@qpik said:
I thought exactly the same, as it returns "the first thing that the ray hits". I suppose it means "the closest thing". For my purpose it's enough to get first-on-the-list hit end exit.
Isn't that the same thing?
@qpik said:
I quickly wrote this, but it worked MUCH slower than original method.
You're writing a ruby method to be faster than a C method - that C method must be doing a lot of extra processing in order to be able to out-perform it in Ruby.
-
@thomthom said:
You can use
face.plane
insteadSomehow I didn't notice that one in the API
@thomthom said:
hmm... If you only iterate the entities collection once then it won't help to pre-process to filter out only faces. Infact, that would mean more iterations. But if you need to iterate the face multiple times, then you will save time on pre-filtering.
I meant to sort the collection before proceeding to the next testing point. The faces that got hit before might as well be the first to get hit by rays cast from adjacent point.
@thomthom said:
@qpik said:
I thought exactly the same, as it returns "the first thing that the ray hits". I suppose it means "the closest thing". For my purpose it's enough to get first-on-the-list hit end exit.
Isn't that the same thing?
I suppose
model.raytest
doesn't break after first positive ray hit, but returns the closest one from an array of all.@thomthom said:
@qpik said:
I quickly wrote this, but it worked MUCH slower than original method.
You're writing a ruby method to be faster than a C method - that C method must be doing a lot of extra processing in order to be able to out-perform it in Ruby.
That is certainly true. That is why I managed to connect with a DLL using
Win32api.call
(BTW thanks to TBD for his SUDLL example).
Now I'm on my way to moving everything to C. I hope this will finally give a speed boost.I'm looking into Ruby-OpenGL as well for another approach.
Here is an example - http://forums.sketchucation.com/viewtopic.php?f=180&t=20893&p=209966#p209966 -
@qpik said:
I suppose model.raytest doesn't break after first positive ray hit, but returns the closest one from an array of all.
that would be very odd. if it did produce a full array before returning I think it should return the full array.
-
But then how would it find out the closest intersection?
ps. I write all this out of my head, I'm not familiar with 3d algorithms.
-
@qpik said:
I suppose
model.raytest
doesn't break after first positive ray hit, but returns the closest one from an array of all.I think it does break after first positive hit. Make sure you check if the object is not hidden or on a hidden layer, otherwise your rays will stop too early when hidden layer present in a model.
-
Yeah, but how would the method know if the first hit is the closest?
It could be for example some distant face that got hit first, because it was first in the collection. -
Did you ever find any improvements that could be made?
-
I planned writing new method in C and calling it via Win32api... but I never find time and enough determination to do it. I wish somebody else did it instead , someone who knows C, unlike me.
-
I'm also an C ignorant...
-
Any chance this ever might come out which works for round shapes?
Love to use this as subtile shadows over the textures, sort of lighting baking. -
how can i download the plug-in
-
It's attached to the first post of the topic. But it is not yet tested on SU version 9 - so it may not work for you (unless you made a typo when registering in which case, could you correct it, please?).
-
Hi Kuba,
Nice to see another Polish architect in action as a programmer.
I am getting more and more comfortable with C++, but I do not expect to be able to help you within next few months.
I won't forget you effort and if I will find time, I will see whether I can help you with the raytest issue. -
This "plugin" (using the term liberally,) has been NOMINATED for QUARANTINE.
-
NOTICE: Preliminary Overhaul of the SimpleRays plugin !
Developers' forum: [Plugin] Qpik::SimpleRays OVERHAUL
I did this overhaul so we can remove SimpleRays from the Quarantine List
Jakub, where are you ?
-
I'm back
-
-
Hello SketchUcators!
I have a lot of interest in this topic. While modeling in Sketchup can be bliss, creating impressive visual displays without a full blown renderer is very difficult. Being a game developer hobbyist, this limitation keeps me in Blender for most of my game related art.
Anyways, I was curious about raytest and what it's quirks were. As was stated earlier in this thread, limiting the raytest's scanning distance could be the solution to faster raycasting. Unfortunately, the ruby API doesn't offer this option; I suppose all rays are infinite (or my theory is the raytests are to the bounds of the scene.)
I decided to do a test: I made a ruby method > raytest_repeating(ray, repeatCount) and cast a ray along the y axis 10,000 times. With no obstructions, it completed it's process on average around 0.15 seconds. Introducing two cubes in separate groups to intersect with, the same method took about 0.68 seconds on average. Here's the interesting part. I placed 2000 groups along the y axis and ran the same method again. This process took ~938 seconds to complete! Keeping the same cubes in the scene and moving all but two of them out of the ray path dropped the calculation back down to the 0.68 average!
In conclusion, raytest must be spending time on all objects the ray interesects, even though it only returns the closest object. It's no wonder your occlusion process drops to a crawl in dense scenes, since I assume you're casting hemispherical rays into 'infinite space', colliding with EVERYTHING along the way! I believe a possible solution to your problem is to find the faces that are in the range of a raytest (IE, nearby faces that actually effect the shading) and to dynamically hide the rest of your scene as needed. Since the raytest can ignore hidden objects, it should speed up the overall process considerably. I ran one final test with the 2000 cubes, hiding all but 2 of them. While the process was slower, 10,000 rays came back in 5.2 seconds, which is far better than 938!
I hope my findings can assist you on this wonderful creation of yours!
-Thomas Pendergrass
Advertisement