About Me

Hi. I'm Josh Ols. Lead Graphics Developer for RUST LTD.


View Joshua Ols's profile on LinkedIn


Alloy 3 is up on the asset store!

After months and months of work it is finally here! See the Unity forum thread for details:

Alloy - Unity Asset Store


Parallax/POM + Detail Mapping Gotchas

So I'm going to make a bold assertion. We as an industry are doing texture transforms wrong! >:(

...I suppose you want context for that statement. Well then...



Let's start from the most common way to transform textures:

Texcoord = UV * Tiling + Offset;

This approach has a very serious problem in that Offset and Tiling are both implicitly coupled together. By that I mean that when the Tiling rate increases/descrease then the Offset's translation effect is decreased/increased. To compensate for this limitation, artists typically have to manually adjust the Offset value by dividing by the previous Tiling amount and then multiplying by the new amount. 

It would be far more preferable to have the two properties be decoupled, so that Offset always has a consistent translation effect. Thankfully it is pitifully easy to do this in code via:

Texcoord = (UV * Tiling) + (Offset * Tiling);

or just:

Texcoord = (UV + Offset) * Tiling;

Sadly we can't do much with this as the content creation tools do it the wrong way, so the engines also have to do it that way to be consistent. So what does knowing this really gain us?

I'll tell you...


Parallax Mapping

For those who don't know, Parallax Mapping of most varieties work by using a height map to generate a per-pixel texture coordinate offset to create the illusion of depth on flat surfaces. Now what you may not know is that this offset is implicitly multiplied by the Tiling amount of the texture coordinates used by said heightmap. So assuming your base texture uses the same texture coordinates, you can apply the parallax offset by doing the following:

Texcoord = UV * Tiling + ParallaxOffset;

Simple! Convenient! But...


Parallax + Detail Mapping

Detail mapping is a very common way to increase surface detail by combining a second set of textures into the base textures, usually at a much higher Tiling frequency. As you might imagine, combining parallax + detail mapping is a great way to make visually interesting surfaces. However, it comes with a nasty gotcha as the equation from above doesn't work for detail mapping!

The detail textures' Tiling rate will almost always be different from the base maps', meaning that the Parallax Offset will almost always translate the texture coordinates either too much or too little. This results in the rather unsightly effect of detail maps swimming across the surface as the camera changes position relative to it. So how do we fix this?

It turns out that the same fix applies as with any other offset. You just need to remove the base Tiling by dividing it out of the Parallax Offset. The resulting normalized offsets can be applied the correct way and benefit from the detail Tiling amount without any texture swimming. That looks something like this:

DetailTexcoord = (UV + (ParallaxOffset / BaseTiling)) * DetailTiling;

Any questions?


Unity Shader Gotcha #11 - World Normals

So it turns out that Unity's WorldNormalVector() and WorldReflectionVector() macros only return world-space vectors for the shader's generated forward base pass, and not its forward add pass. So say you wanted to try to do some sort of direct lighting trick that relies on world space normals, it would work for the directional light in the forward base pass, but then fail for lights in the forward add pass. 

As a result of this limitation, and the fact that Unity seems to have abandoned surface shaders for their new Standard shader, we at RUST LTD are officially abandoning surface shaders for Alloy development. Going forward, we will be using our own framework built on top of raw vertex, fragment, geometry, etc shaders. This is more complex to maintain and develop, but gives us maximum control to add and optimize new features. 


Unity Shader Gotcha #10 - Exclude PrePass

So with surface shaders, sometimes you need to make a forward-only shader for odd lighting models (skin, hair, eyes, etc) and blending modes (premultiplied alpha, additive, etc). In these cases you need to remember to use the attribute "exclude_path:prepass". If you forget, though it might look fine on the PC, it will have broken visuals on MacOSX when used in deferred mode. We've also found that it will get weird results when used with third-party frameworks like Candela SSRR in deferred mode.

Bottom line, for all custom forward-only shaders ALWAYS include the attribute "exclude_path:prepass" in your surface definition pragma!


Alloy 2.1 Released

Asset Store link

Version 2.1

- Added support for Parallax & Parallax Occlusion Mapping modes in "\Core" and "\Transparent\Cutout" shaders.
- Added a TeamColor detail mode to the standard shaders.
- Added archviz-friendly UV1AO2 shader variants.
- Dissolve 
* Added variants to all the standard shaders so it is easier to apply the effect to common materials.
* Changed the Cutoff parameter to use [0,1], rather than [0,1.01].
- Skin 
* Moved to "Skin" folder.
* Generalized to support other shader features (Decal, Detail, Rim, etc)
* Added custom material editor support.
- Modified “Self-Illumin/Glow” and “Self-Illumin/Glow Cutout” to use the custom editor.
- Added support for Skyshop 1.07 and up.
* Box projection is now accessed through skyshop's sky manager UI.
* Added support for sky blending.
* PLEASE NOTE: Alloy will no longer work with older versions of Skyshop due to changes in how they do their calculations.
- Changed the custom editor parameter names and order to improve readability.
- Fixed an issue where the misnamed Decal material map parameter prevented it from showing up in our custom editor.
- Fixed an issue where we weren’t gamma-correcting the transition glow intensity in the Transition shaders.
- Restored support for low-quality vertex lighting mode.

PackedTextures (ie. "_AlloyPM" and "_AlloyDM")
- Added support for setting the Wrap Mode on packed textures.
* Still defaults to "Repeat".
- Added support for setting packed textures to "Automatic TrueColor" format.
* Best to keep it on "Automatic Compressed" unless compression artifacts are harming visuals.
- Added support for setting max size on packed textures.
* Capped to not exceed texture's dimensions.
- Fixed issue where user could accidentally set the packed textures to an invalid format.

NOTE: It is also possible to set the Aniso level, in case you didn't know.

Substance Designer
- SD4.1 shader fix so it no longer manually gamma-corrects the environment map. 

Bug Fixes
- Fixed an issue where our custom material inspector's tab and texture name text was hard to read in Light Skin mode.
- Minor cleanup in our RSRM Generator and Material Map Packer to make them more readable using Light Skin.

The following shaders and paths are to be removed after this release:
"Assets/Alloy/Core/Skin Bumped"