I’m attempting to transfer an array of float values to ShaderLab by packing them into a texture with each byte taking up one color channel. Four channels giving me exactly 32 bits, enough to store a single precision float.
Here’s my implementation of a float to color converter in C#;
float num;
Byte[] b = System.BitConverter.GetBytes(num);
Color32 c = new Color(b[0], b[1], b[2], b[3]);
The only problem is I have no idea how to repack this data in Shaderlab. Most methods I’ve found in other languages require some form of iteration, I know that’s just not feasible in this language. So assuming I can use any Texture Sampler and I already have the correct UV coordinates available, is there any method available to cast this data back into a float?
It’s a very good idea to download the built-in shader source and look through the files you’ve probably been including. Although it’s not very thoroughly documented, a lot of the functions have very clear purposes.
Can anyone explain why the fourth float in this line (and any other line where it appears) has a ZERO as its third digit?
float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 160581375.0);
255255255 should be 16581375, shouldn’t it?
See attached project (Unity 4.6.1 Free Edition). Not optimized but works as intended.
Maximum 96 lights (directional, point) for each game object with tag “Dynamic”. See script “Custom Shader” attached to “Main Camera”. You can combine meshes (not that it makes any performance difference) into one with “Do Combine Meshes”. Do Refresh Data Texture" refreshes the data texture and assigns a new material each frame. A simple “CustomShaderEditor” is included to enable display changes in editor. Click “Refresh” button or check “Refresh active” to enable constant update while changing game objects in editor.
I optimized encoding and decoding floating points. Ranging from -500.00 to 500.00. Precision loss over performance gain. It is much faster then the original encoding by IEEE 754 standard.
I noticed an unexpected fps slowdown when I move camera close to an object. It depends on how much of the camera viewport is filled with rendered objects. See attached images. Unity shader (like BumpedSpecular) does not have the same problem. Why does this happen? Can anyone explain?
Added support for lightmaps and specular highlights when using backed lighting. View CustomShader.jpg for preview.
You can do more lights by using a larger texture (but why would you want to). If all lights are being rendered the performance drops to about 80fps on my AMD Radeon HD 6800. This can be improved by including only the lights that are “needed” around the main camera. “Light occlusion”.
Do not resize game objects. Use only 1:1:1 as this causes dynamic resizing and decreases framerate.
No dynamic shadows or light cookies. Baked lighting only.
No mirror reflections. Only CubeMaps are possible (simple to add them) but they look a bit strange so I don’t use them.
Shader uses to many instructions. I was targeting 2.0 but it is not possible without the help of UnityPro features or shader engine.
probably more things but you get the basic idea … can be beneficial if used as intended.
Why performance drops (must be some editor events slowing it down):
2 times slower When “Inspector” window is focused and visible. Compared to when “Lightmapping” window is focused and visible.
The problem with performance slow down (camera close to game object) is due to active dynamic light calculations being made in the background by Unity. When light rendering is disabled, the framerate remains at expected values (under 0.2ms).
The solution is to use baked lightmaps or to disable the lights (to stop them from “rendering” in the background):
Render Mode = Not Important
Culling Mask = Nothing
Lightmapping = Baked only
They will still be rendered dynamically by the custom shader.
I do not mind. Please do post your improvements here. I will look into soft shadows as they are not (really) enabled in Unity free (at least they do not work in my project). Should be able to soften them up a bit :).