VrayInstancer over-logging

I’m currently working on a scattering plug-in for in-house use, based on the VrayInstancer code in the SDK samples (think poor man’s Forest Pack).

Everything is working surprisingly well. My only question is if there is some way to inhibit the logging of the following messages:

[2015/Apr/26|18:17:25] Creating render mesh for “Teapot001”: fixed dynamic mesh, node handle is 227
[2015/Apr/26|18:17:25] Bounding box for “Teapot001” is [1043.6,841.768,0.622777]-[1062.38,862.15,9.44243]

They are generated for every render instance, so if I have 500k render objects, my vraylog.txt file is hundreds of megabytes.
Of course it’s not the end of the world, I was just wondering if there is some flag I can set to disable it.

Also, if there are any tricks I can use to speed up instance generation. I noticed it doesn’t tolerate multithreading (crashes on FrameBegin when run in parallel).

Thanks!

Unfortunately there is no flag to prevent that message right now; I will see what can be done about it.

Actually I do have a version of the instancer that generates the instances using multithreading - I can post it here if you are interested.

Best regards,
Vlado

Interested would be an understatement. Thanks a lot!

So I added an experimental multithreaded option to the instancer in the latest builds; I had to make some modifications to V-Ray itself as well in order to get it working. I also took the opportunity to disable the logging of these messages for each instance.

If you don’t have access to the nightly builds, email me to vlado@chaosgroup.com and we’ll arrange that.

Best regards,
Vlado

email sent, thanks.

Thank you for that excellent, well-commented code.
I copied your multi-threading method, and so far it seems to be purring like a cat!

On a particular scene with 500k instances, setup time went from 34.4s to 5.3s.
This is on a machine with 6 cores + HT, so I’d say that it scales quite well.

You mention this method is experimental. Are there any edge cases you know of that I should be concerned about?

Regards,
Rotem

Well, I haven’t tested it will all possible geometry types - only with regular meshes and proxies. There might be some code in other geometry types (displacement, hair) that might not be thread-safe; I will have to go through them all and check.

Best regards,
Vlado

Yup, makes sense. So far displacement works fine for me, haven’t tested other types of objects.

I have a question regarding a related matter. Let’s suppose I would like my instanced objects to inherit UVW channel data from the surface they are scattered on.
I understand that since they all reference the same underlying ‘Object’ and therefore the same ‘Mesh’, I can not really modify the actual UVW channels.

So the remaining option is to attach custom data for each instance, and then write a custom map which can make use of this data, I think it’s similar to how it’s done in Forest Pack:
http://docs.itoosoft.com/display/FORESTPACK/Forest+Material

I was hoping to do this by inheriting from ‘VRenderInstanceData’, and putting the data on the ‘data’ field of ‘VRenderInstance’.

1) Am I wrong in any of my assumptions?
2) Is that what the ‘data’ field is meant for or is it already being used by Vray for something else?
3) This field is protected. Should I inherit from ‘VRenderInstance’ to use it?

Thanks a lot for your help on this.

Regards,
Rotem

In regard to multi-threading, it does seem to create issues when I enable random animation offset for the instances (sampling them at more than one time per frame). Without it, it seems to be working fine.

The data member is internal to the class and you shouldn’t change it. I very hacky way would be to store the UVW’s into the “name” member f.e. make name[0] to make sure it’s still a valid string and then add the UVWs as binary data right after that. Then you can read that from your shader.

For the random animation offset, jumping back and forth in time will be a problem. Maybe you can first generate your instance data (transformations, time moments) beforehand, sort by time value, and the do multithreading for each separate time value.

Best regards,
Vlado

That’s quite a hack, but it seems to work very well. I also had to add a magic header to the data so the texture map could determine if the VRenderInstance is loaded with my custom data or not.
I haven’t tried your suggestion regarding multithreading yet, I will update when I do.

Thanks for your suggestions.

Would it be possible to include ‘enum_particle_tms.h’ and ‘enum_particle_tms.cpp’ which are referenced by VrayInstancer in the nightlies SDK samples?
I want to add support for motion blur and I need to see how exactly to calculate the required TimeValues from the motion blur parameters.

Thank you very much.

I can email them to you - can you send me a reminder email?

Best regards,
Vlado

Sent, thank you.

I just sent you the two files.

Best regards,
Vlado

Thanks for those.

On the issue of multi-threading, there is a crash when using any source objects with deformation.
The first frame will render fine, but max will crash on the start of the 2nd frame, when calling renderBegin and frameBegin on the instances.
I’ve attached a short script which recreates the bug:

(
	delete objects
	t = teapot()
	addModifier t (noiseModifier animate:on strength:[1,1,1])
	(
		p = pf_source()
		ParticleFlow.BeginEdit()
		a1 = RenderParticles()
		p.AppendAction a1
		ev = Event()
		ev_a1 = Birth Emit_Start:0 Emit_Stop:0 Amount:10
		ev_a2 = Position_Icon()
		ev.appendAction ev_a1
		ev.appendAction ev_a2
		ParticleFlow.EndEdit()
		p.appendInitialActionList ev
	)

	i = vrayInstancer source_nodes:#(t) particles:#(p) multithreaded:on
        --render a sequence with at least 2 frames
)

Another very bizarre VrayInstancer bug is the following:

(
	delete objects
	c = cone pos:[50, 0, 0]
	addModifier c (noiseModifier animate:on strength:[1,1,1])
	addModifier c (turbosmooth())

	(
		p = pf_source Emitter_Length:150 Emitter_Width:150
		ParticleFlow.BeginEdit()
		a1 = RenderParticles()
		p.AppendAction a1
		ev = Event()
		ev_a1 = Birth Emit_Start:0 Emit_Stop:0 Amount:50
		ev_a2 = Position_Icon()
		ev.appendAction ev_a1
		ev.appendAction ev_a2
		ParticleFlow.EndEdit()
		p.appendInitialActionList ev
	)

	i = vrayInstancer source_nodes:#(c) particles:#(p) multithreaded:off
	--render a sequence with at least 2 frames
)

The first rendered frame will generate all 50 instances as expected. Subsequent frames will generate only about half that number, as shown below.

Note that multithreading is off in this example.
For some reason, recreating this in a simple scene requires that the object be a cone, and that the top modifier be turbosmooth, though I have encountered it on some pointcached characters as well. The middle modifier can be anything which generates deformation.

Any idea what is causing this or how this could be worked around?


The first issue will be fixed in the next nightly build tomorrow. The problem was a call in VRenderInstance::init() to a 3ds Max SDK function that is not really designed to work from multiple threads.

The second issue I can’t reproduce after fixing the first one. Which 3ds Max version are you using?

Best regards,
Vlado

Amazing, thank you so much!

I am using 2014. Neither issue appears in the latest nightly. Will this fix be included in the official 3.20 builds?

Yes, I think so.

Best regards,
Vlado