Monday, July 23, 2012

Unity GPU Noise 1.3 Released!

As you can tell from the title, I've been able to release several updates for GPU Noise since my last post.

I borrowed a MacBook from one of my friends and installed Unity on it.  That allowed me to quickly port all of the noise functions to GLSL and ensure they all worked on Mac.  However, I was still having issues with the noise functions on my Android devices.  Unity on Android is actually incredibly unhelpful in this regard.  It doesn't report any errors or anything. The shader simply fails and runs a fallback shader.

I decided to create a WebGL test page using the same GLSL code since WebGL uses OpenGL ES 2.0 (the same as mobile devices).  I quickly found out (and remembered, as I've posted about this in the past) that OpenGL ES doesn't allow variables in for loop expressions.  It must be a constant expression (i.e. loop a fixed number of times). I made a mobile port of my GLSL noise that forced all summation functions (fBm, Turbulence, and Ridged) to loop 8 times.  Even though this changed allowed the code to work properly in WebGL, it was still not working on Android.

I then took a different direction and tried writing a straight Java test app for Android.  I found out there is a major bug where Android won't report the shader compilation errors.  It just gives you an empty string.  Not very helpful.  I managed to get the shader to compile, but I ran into more OpenGL issues due to mismatched vertex attributes.  I cast aside the example in frustration.

Someone who purchased a copy of GPU Noise let me know that Xcode on Mac actually reports shader compilation errors, so I begged a coworker of mine who has a Mac, Unity, and an iOS developer license to give it a try.  As soon as he deployed it to his iPad, we saw the error that has been eluding me this entire time.  There was a "Uniform precision mismatch" with some of my variables.  I did some investigation and found out that vertex shaders in GLSL default to high precision while pixel shaders default to medium.  I hard coded my vertex shaders to use medium precision and now almost all of my functions work on Android!  I say almost because all of the Voronoi 3D Displacement functions seem to peg out the CPU (as before) and cause the device to freeze and crash.  I think they're just too resource intensive to use on current mobile devices (they work on Windows and Mac just fine).  At least the 2D Animated Voronoi functions all work on Android.

Related to an earlier post, I still need to figure out why a Tegra 3 sucks so much.  It's not just speed, but also the rendering quality.  Here are a few comparisons for example.

EVO 3D

Transformer Prime

EVO 3D

Transformer Prime

As you can see, the Transformer Prime looks horrendous!  I'm not sure what's causing such terrible visual artifacts.  Hopefully someone online has an idea.

Until next time...

7 comments:

Jérémie St-Amand said...

How did you manage to force medium precision in the vertex shader? Did you simply write "mediump" in front of EACH variable in the shader?

Patrick McCarthy said...

No, you only have to specify the floating point precision once per file. I use the following line at the top of each of my GLSL shaders:
precision mediump float;

Jérémie St-Amand said...

How is the performance on mobile (iOS and Android)? Could I use Perlin noise with 8 octaves on a mobile platform?

Alexandre Labedade said...
This comment has been removed by the author.
Alexandre Labedade said...

Hi,

Any news about this shader ?
I would like to use it in worldspace coordinates, on billboards, to simulate some smoke... Do you think this could be done with it ?

Patrick McCarthy said...

Sorry for the silence from me. I haven't worked on the shader since this was posted.

So you want to use 4D noise on a 2D surface? I've never tried that so I'm not sure how it would look.

Are you interested in me updating the asset for Unity 4.x?

Alexandre Labedade said...

Hi ! Thanks for the quick reply ;)
And yes ! I would be very happy to play with it in Unity 4.x