Ok, I have seriously got a bone to pick with the Unity team. I've been developing a shader generator quite a while now, and while Unity 5's new lighting and GI system kinda slowed me down, they were an improvement, fair enough. But they also decided to do a wonderful switch in regards to their shader compiler. Previously it compiled NVidia's CG shader language, which is pretty good. The new compiler uses HLSL, which looks about the same (It's just a bit more strict, for example previously I could put float3(0.2), and it would equal float3(0.2,0.2,0.2). Not anymore, but meh), however the compiler is genuinely broken. I'll give an example.
I was working on a coherent noise generator (Like perlin noise but blockier), that get's fed a coordinate and outputs a value. When working, the noise looks like this:
The way it works is pretty simple:
1. Receive coordinate (UV), and feed it into the function NoiseB2D(float2 P)
2. Find the cell that the coordinates are within, then calculate a random number for each bordering cell corner.
3. Interpolate between each cell point based on the relative position that the coordinate holds.
Here's the code:
float NoiseB2D(float2 P)
{
float SS = Unique2D(P);//Always returns the same number for the same point.
float SE = Unique2D(P+float2(1,0));
float ES = Unique2D(P+float2(0,1));
float EE = Unique2D(P+float2(1,1));
float xx = Lerp2D(frac(P),SS,SE,ES,EE);
return xx;
}
But for some reason, the noise was appearing strange, points would randomly cutoff and flicker as I moved the camera.
This is the kicker. I looked through the generated assembly code, and found that it referenced a number that was in another part of the code, 0.99999. It decided they were close enough, and managed to bundle them together in a few "mads". So instead of being +float2(1,0), it was +float2(0.99999,0), which thew the entire calculation out. I ended up having to change it to 1.0000001 just to fix this silly, destructive compiler bug. Looking through assembly code isn't fun.
EDIT; Just to clarify, the 0.9999 wasn't the entire problem, as you probably may have guessed it would just output different numbers. However, due to the precision of the floats on certain GPUs, it would cause the flickering as sometimes it would just add closer to 1, and other times not.
And this isn't the only case of the compiler doing destructive optimizations. In my perlin noise function, the frac function ((Returns x-floor(x)) or (In goes 16.45 , and out comes 0.45)) was being removed when the number going into it was a constant, fair enough. Except it didn't do the correct operation. I fed 1.9 into it and in the assembler it output 78.4! wtf!
This stuff is absolutely mind boggling, and also incredibly difficult to predict. The number of if statements I've had to add to Shader Sandwich has been enormous to try and predict these little compiler quirks.
Ok, that was cathartic, back to work XD.
Fixed the noise image.
I have no idea what are you talking about.
XDYep, Microsoft's products suck. That's why I use OpenGL and GLSL (although I'm looking for the day when they are replaced by Vulkan).
I wasn't implying that, I just focused on your blanket statement of Microsoft's products. Either way, this is off topic so I'll just fly on out of here.
@Zuurix
Same here XD.Not a bad blog. I'm into co-noise. ;P Last year I tried to create a game with only generated
assets for the spring competition, using diamond-square, perlin and some sample-maps. I also tried to make it tiny in exe size but I never finished. :/ How will you use this stuff?P.S. DX owned GL last decade and GLSL is just as bothersome if not more than HLSL. I hope Vulkan brings order.Thanks, and yeah, coherent noise is pretty cool :D. It's part of an editor asset for Unity I'm making, which helps make shaders in a visual editor (Sorry for the cheap plug XD).
For example, in this image all the raindrops and puddles are drawn using perlin noise.Or at the start of this video(Please mute it, it sucks XD) (Sorry, no image :( ) you can see a procedural wood texture I made :D.Of course you can do even more stuff, like procedural terrain, grass motion, texture splatting, etc, so it's pretty useful. I hadn't seen the diamond-square one till now, I might add it in a future version of SS. Normally I used perlin for procedural terrain, but it really is too slow to use for the number of octaves you normally need so diamond-square could be useful :D.