© 2013 Khoa Nguyen

Last updated: 2013-07-30

Interpolating Textures

Specifications

Issues and Resolutions

This is a shader developed for Prisma that takes two or more textures and interpolate between them using another script.

 

 

The Shader Must:

- Take at least four textures

- Be able to set the current texture and determine a target texture

- Be able to interpolate between the two textures

- Be able to reset the current texture to stay updated

 

Other Considerations:

- Toony Lighting

- Rim Lighting based on Texture

- Allow for transparency in models and effects that need it

- Fog based on distance from the camera

 

Development of Filtered Objects Shader:

This shader turned out to be the standard for Prisma's assets.  The Interpolate Textures shader worked well for assets that would be there no matter the dimension, such as floors and some walls.  However, there were objects that only existed in one or two dimensions.  Of course, it would be possible to add on an additional variable to check if the object is a constant or filtered object and adjust the shader on that. 

 

There are two schools of thought regarding this.  On one hand, having one shader consolidates all of the information in one spot so the developers can easily switch between the two shader types; on the other hand, separating them allows for easier maintenance and troubleshooting.  I chose to separate them since in the long run I can consolidate them if there is a pressing need, and in the short run I can still tweak them will relatively little trouble.

 

Shader Variables Types

One of the first basic assumptions I made was the variable types allowed by Unity.  Since we were working in Javascript for the majority of Prisma and were using integers, floats, booleans, and enumerated values in the game scripts, I naturally thought that Unity's shader would take the same types.  As it turns out the shaders could not take booleans or enumerated values.

 

Once I discarded that assumption, the problem became relatively easier.  While I could not pass a boolean or enumerated value directly, I can still pass integers, and booleans at its core is a state that can be defined as 0 and 1 whereas enumerated values can be defined as an array, in this case of integers.  Once that is set up, I can freely pass the different states to the shader and have it determine how to interpolate.

 

Current and Target Textures

After setting up the state machine to determine which texture to use, there was still the issue of actually interpolating.  Though the target texture was properly set, and the textures interpolated, it kept doing so using the first texture that was inputed in the editor.  As it turns out, I needed to create a current texture variable and keep updating it so that it would know which texture to interpolate from and not always the default texture.

 

Optimization

Over the course of developing and maintaining the shader, several passes of optimization were made, some absolutely necessary, some while I was waiting for the next task list.  One of the passes checked if the object is actually seen by the camera at the current time.  If the object is somewhere else in the level that is not currently on camera, it would ignore the calculations for the interpolation.  This made a noticeable difference in the framerate considering that over a hundred draw-calls can be made depending on how many objects and particles inhabit one section of the screen.