The latest addition on my journey to OSL is a WindowBox (sometimes also called Interior Mapping or Parallax Mapping) shader.
I remember one of our teachers in university telling us about how they rendered all the interiors of the buildings in Spiderman with just a simple plane with a shader attached to it that simulates the room interior with proper parallax. Since then this has always stuck in my mind and I saw it being used in some studios I worked at whenever there was a big city to be rendered. I finally found the time (.. too much time :) ) to do this sort of shader myself in OSL!
It’s been a really exciting but also quite tough journey for a not very math-savy person like me to do this project but I have been able to mash something together that works! This shader is useful for giving the illusion of room interiors on just a single plane. It therefore safes you from modeling room interiors for mid-/background-buildings. It’s solely texture based – it takes a single input texture which should be laid out in a specific way to make sure the different sections of the room are where they are supposed to be:
Apart from all the walls of the room you also have a midground layer (which could be furniture for example) and a curtains layer to give additional complexity and depth.
The textures can be created in your favorite 2D program, but if you have access to Nuke and you are familiar with it I also added an example Nuke script to the package for creating and laying out your own window boxes. With it you get a few convenience features so you won’t have to worry about making sure everything is placed in the correct spot.
When you create your own textures there are a couple of things to keep in mind:
- Make sure you only have an alpha in the midground and curtains area.
All walls, the ceiling and the floor should have a black alpha.
- For use with RenderMan and Arnold, make sure to convert your textures to mipmapped texture files using maketx (Arnold) or txmake (RenderMan).
This is mainly for performance reasons but is a requirement for RenderMan.
- If you are exporting your texture in an initial format that keeps bounding boxes (like OpenEXR), make sure that the bounding box matches your format exactly.
Most renderers will take the bounds of the data window over the actual display window (this is also the case when converting to .tex files).
If your bounds are bigger or smaller than your output format it will mess up the alignment in the shader.
- The midground and curtains layer should be unpremultiplied.
Premultiplication is happening in the shader, so if your input midground/curtains area is already premultiplied you will most likely get dark edges.
The shader itself has a bunch of basic controls for placing your room interior:
It’s a bit hard to really show what it can do with still images so here’s a quick demo which shows it a bit more in-depth:
If you want to give it a go you can download it from HERE (updated link for github)
The package contains the source and compiled .osl and .oso files for Blender, Arnold and RenderMan, but it should work in any other renderer with OSL support.
For use with Arnold just put the compiled .oso into a folder that you append to your $ARNOLD_PLUGIN_PATH and for RenderMan either load the .oso via a PxrOSL node or do it the nice way.
I haven’t tested it in production yet, so use with caution and modify as needed :) Some bits could be more efficient here and there… to be continued… maybe.
If this post has helped you in any way you can express your gratefulness by using the Donate Button below to buy me a coffee! :)
//UPDATE 10.10.2017 – Initial VRay version
I had quite a few people requesting a VRay version for this one as well. VRay does things a little bit different but I think I hacked together a working version and updated the download link above.
As a word of warning, I found OSL in VRay to not be that stable (might very likely be inefficiency on my side, too ;) ). Also I could not get live IPR updates working when changing parameters in the shader, but once you made all your tweaks it should render normally.
You can load in the .oso file in a VRayTexOSL node. Instead of specifying a file directly within the shader, you have to load it separately (in the case of Maya a File node seems to work nicely) and then plug it into the Vray Input Tex.
//UPDATE 11.10.2017 – Usability in Applications that have Z as the Up-Axis
The links have been updated again specifically for those requesting support for DCC apps which have Z as their Up-Axis (e.g. 3ds Max). There’s a new switch called zUpAxis for the VRay, Arnold and RenderMan versions now. OFF (which is the default) uses Y as the up-Axis, ON uses Z as the up-Axis.
Make sure you load the compiled .oso file, not the .osl file. I got compiler issues with when trying to use it directly, but the compiled .oso seems to work in Max.
Hopefully that will do the trick.. :)
As of 03.04.2017 Zap was gracious enough to add it to the Max OSL Repo on github as well!
//UPDATE 15.10.2017 – VRay fix to use multiple Textures
I was made aware that with the VRay version trying to have multiple shaders with different textures does not quite work as it’s only rendering one of the textures. At the time of writing, the current release of VRay 3.6 in both Max and Maya has a bug that prevents the use of multiple textures. Chaosgroup is aware of the issue and will port it into the next hotfix release. If you can’t wait to try it out, there’s a way around it…
Luckily VRay does provide arbitrary user data options just like Arnold and PRMan and that actually seems to be working nicely.
To get it working set up the material like before and assign it to all objects. In your texture node instead of having an absolute path to your texture file (e.g. /path/to/file.exr) use a user data string encapsulated in <> (e.g. /path/to/<tex>).
For Max you will probably have to use a VRayHDRI node instead of a Bitmap node (I didn’t find a way to edit the filepath to something custom in the Bitmap node – D’oh..)
Next you have to add the part of the filename to replace <tex> with as an attribute on your geometry.
In Maya you can add it to the Shape node in the Attribute Editor under Attributes – VRay – User attributes. You then have to set your user data (in this example <tex>) to your filename (tex=file.exr)
The downside of using this method is that you cannot have individual setups for all the other shader parameters like roomdepth, etc. as they are not mappable.
From what I heard Chaosgroup is pretty quick at handing out fixes for small things like this. They have been aware of the issue for a little while now, so hopefully a hotfix will be released soon :) FWIW I heard it’s working with earlier VRay releases, too.
//UPDATE 14.07.2018 – Octane / LightWave version
A while ago I received an EMail by James Dean who kindly made slight modifications to the shader code to make it usable in Lightwave and Octane. I updated the zip above to contain his version which hopefully does the trick for those of you that are using either of the 2.
Unfortunately I don’t have access to Lightwave or Octane but I’d be happy to hear if these updates are working for everyone using those applications :)
//UPDATE 02.05.2021 – Now on github
It took way too much time, but I’m finally on github! All links are updated!