SimulateEnvironment

Hello,

What is the correct implementation if I would like to return a custom environment texture from the overridden SimulateEnvironment function (and not just color)?

I have tried different things but at the end an image is always saved to the hard drive. Either the plugin saves this image and stores the filename in SimulatedEnvironment.BackgroundImage.filename, or in case I do it via the SimulatedTexture function (with my own Rendertexture) I have to call it with argument RenderTexture.TextureGeneration.Allow - it creates the texture but also saves it to the hard drive.

Can I pass a texture to the SimulatedEnvironment.BackgroundImage which evaluates only inside the memory but not saved to the hard drive cache?

Thanks,
Márton

@andy, @nathanletwory - is this something you can help with?

The RDK will always create cached versions of any texture used - this happens when either previews are rendered of materials, environments or textures, and when a material or environment is drawn in the viewport or during a production render.

Is there a reason you don’t want that to happen?

Hello Nathan,

My only problem is that in case the user would like to test an environment parameter by adjusting it quickly and checking the preview, it is slow. Maybe it is because of other reasons but also writing it to a disk file can slow down the process. And when I was using simple Rhino 6 textures as environment images, I haven’t experienced the same slowness and also I haven’t found where it writes the preview texture (so I was thinking maybe it doesn’t write them to the disk).

My other problem is: when I try the solution where I use a TextureEvaluator Rhino automatically saves it to a file cache - which is according to the information from you is normal. But when I change an environment parameter Rhino calls SimulateEnvironment again -> plugin follows the same process again but Rhino doesn’t want to forget the texture cache and regenerate the texture, so the texture doesn’t change.

Márton

You should create a custom RenderTexture implementation for your texture. Whenever you change a parameter for your texture you should update the RenderHash for your render content (texture, environment, material). That will signal the RDK and Rhino that your custom render content has changed

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Render_RenderContent_CalculateRenderHash.htm

Addendum:

if you use Fields for your parameters the render hash should update automatically. If that does not work please share code that shows the problem. You can contact me directly at nathan@mcneel.com in case you need to share code privately.

Thanks Nathan, this renderHash thing helped. I don’t want to add Fields to my environment texture, now overwriting the hash value it really recalculates the environment at parameter change.

But now it generates a lot of images. When the user changes a parameter, it calculates new render hash and it adds a new png file to the cache. Should I just delete the old cache files?
And another thing is not clear. How can I modify (from code) the projection of this texture which is seen in Rhino render view mode? Independently what I set here the projection is always the same.

Márton

You could delete the old cache files sure. @andy, is there a way to have RDK throw away old cache files automatically?

How are you curently setting the projection?

Cache deletion:
Even if I delete the file Rhino still remembers my previous renderHashes and doesn’t try to recalculate if I use any previous cache value - so it stores the value - doesn’t it make the system slower after a lot of changes?

Projection:
a) I have tried to set the projection from inside SimulateEnvironment by changing projection values of the SimulatedEnvironment variable.
b) Also tried to set projection directly inside my RenderTexture like:
public MyTexture()
{
ModifyRenderContentStyles(RenderContentStyles.LocalTextureMapping, RenderContentStyles.TextureSummary | RenderContentStyles.ModalEditing | RenderContentStyles.GraphDisplay);

SetProjectionMode(TextureProjectionMode.EnvironmentMap, ChangeContexts.Ignore);
SetRepeat(new Rhino.Geometry.Vector3d(10.0, 10.0, 10.0), ChangeContexts.Ignore);
SetRotation(new Rhino.Geometry.Vector3d(0.0, 0.0, 0.0), ChangeContexts.Ignore);
}

I have set it with repeate 10, but it shows the texture with repeat 1.0

Márton

The persons who know more about the hash caching are @andy and @johnc. But I don’t think you should worry about that. If it were a bottleneck we’d have noticed already with Raytraced mode and Rendered mode.

I have to check how texture projection mode is supposed to work. I’ll come back to you on that. Thank you for the code snippet.

Thank you for checking it!

Márton

Hello Nathan,

I am a bit more confused about this environment thing now.

It seems the “standard” renderer of Rhino reads the environment texture from my custom environment with the help of SimulateEnvironment.

but the ray-tracing mode (Cycles) get the child render content “texture” from my environment, and it evaluates this texture itself.

Also the mapping seems to be different (under normal render looks like spherical, Cycles - screen mapping).

And another not clear thing about caching. What is the normal behavior when I change a parameter (+and the render hash value)? Should it save the image on a new file name, or rewrite the old cache filename? I was able to produce both results, but now it generates a new file at every parameter change.

Márton

It uses the evaluator itself yes, because Raytraced doesn’t access the file system directly (other than writing and reading of rendering kernels). Using the texture evaluator gives directly an in-memory representation.

A bit hard to say without seeing an environment to play with. I just now tested emap, spherical and lightprobe mappings, and they all agree between Rendered and Raytraced modes.

You set projection on the texture, but do you also set something in the environment itself?

I think it writes a new file on each change - so that when you change back you get the cached version right away, but lets ask the RDK experts in that area:

@andy, @johnc - what does the caching system do? Write a new file for each new parameter?

Yes - that’s what it does. The cached textures are in the texture cache which is %temp%/McNeel/Rhino/6/TextureCache

Hello Nathan,

You are right, I haven’t set the projection for my custom environment class. After I set it, the Cycles engine really follows it.

But on the normal Render view mode the situation is different. It is always spherical mapping. I have tried to change projection mode on every item where there is a projection parameter but it seems it doesn’t follow it.

(Andrew: thanks for the clarification)

Márton

@DavidEranen, can you please help @marton.parlagh with getting his custom environment to work in Rendered mode?

Thanks for all the help Nathan! Really Appreciated!

This could be a question on a different topic but related. Do you know how to set a custom RenderTexture as hdr capable? (I can see I can query the texture about hdr, but can not set it.

Márton

@marton.parlagh it looks like we have a bug in the SDK. That function isn’t marked virtual, so you can’t override it (like IsLinear()). There is no other way to set that at the moment.

I’ve logged a bug for that: https://mcneel.myjetbrains.com/youtrack/issue/RH-52530

Thanks!

Márton

May I ask one more?

What are these texture or RenderContent flags?

  • IsElevated
    and
  • IsBuiltIn
    ?