• URGENT: flipped normal issue part 2

Hi Todd,

I had your shaders consistently working with flipped normals (0,0,1) on Unity 5.4.2. And, found no solution since you all were using 5.5

Now I switched to 5.5.3f1, and the shaders are correctly working only in the editor (0,0,-1), but on Android/iOS, they're lit from the opposite side again!

So I'm forced to always use (0,0,1) in the editor to produce working build, having to continuously flip normals while editing.
I tried different workarounds for runtime flipping but they're all too heavy for mobile.

Could you please have a look at the shaders again?

Addendum:

It works with correct normals in the Unity Editor, and on iPhone4s or lower.
On Android and iPhone5s or higher they're flipped.

Sorry for pestering you like this from several communication ways, but we're risking to botch a deadline, and not even Esoteric are helping :-/

Related Discussions
...

Hey man

So I haven't looked at the shaders for a while but now I look at them again with fresh eyes I think I was confused about the fixed normal's stuff when I wrote it originally.

I was using the UNITY_REVERSED_Z define to flip the normal but that define is only used for reading from the z buffer, which is back to front on certain platforms (so it flips on like PC but wont on android/iPhone).

Instead I think the fixed normal should always be (0,0,1). The camera in unity always points down negative Z axis locally no matter what platform so to face into the camera normal's need to be positive Z or yeah, (0,0,1).

I can throw over some shaders for you to test, which hopefully work with setting the fixed normal to (0,0,1) on all platforms.

ToddRivers wrote

Hey man

So I haven't looked at the shaders for a while but now I look at them again with fresh eyes I think I was confused about the fixed normal's stuff when I wrote it originally.

I was using the UNITY_REVERSED_Z define to flip the normal but that define is only used for reading from the z buffer, which is back to front on certain platforms (so it flips on like PC but wont on android/iPhone).

Instead I think the fixed normal should always be (0,0,1). The camera in unity always points down negative Z axis locally no matter what platform so to face into the camera normal's need to be positive Z or yeah, (0,0,1).

I can throw over some shaders for you to test, which hopefully work with setting the fixed normal to (0,0,1) on all platforms.

Hi there!

Thanks, I'm going to submit our game on both stores today, so that would be really appreciated.

I still have no idea about the fact they work correct with this setup:

Correct lighting:
(0,0,1) on Android
(0,0,1) iPhone 4s and lower
(0,0, -1) iPhone 5s or higher
(0,0,-1) Unity Editor.

Is there, just in case, a simple workaround I can do to flip the normals depending on platform, or model version?

I'm crossing my fingers new version is going to fix all this, or I'm going to lose a slice of users! 🙁

Hmm the simplest hacky workaround would be to put platform defines around the code that flips the fixed normal, like this:

inline float3 getFixedNormal()
{
   float3 normal = _FixedNormal.xyz;
#if UNITY_REVERSED_Z
   normal.z = -normal.z;
#endif
#if defined(SHADER_API_MOBILE)
   normal.z = -normal.z;
#endif
   return normal;
}

But!! if your saying there's a difference between iPhone 4 and 5 that won't work as there is no way of the shader knowing what version of iPhone it is.

I'm pretty sure this is Unity's fault not mine or esoterics. To explain the situation, since 5.5 Unity reverses the Z direction on certain platforms as it gives more precise depth values - see 'The Depth (Z) direction in Shaders' on this page.
https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
When they do that UNITY_REVERSED_Z should be defined, and when they do I flip the fixed normal.

If a platform isn't working it's because it is reversing the z direction and not defining UNITY_REVERSED_Z or it has defined it but isn't reversing z.
Either way its out of our control as its all internal to Unity.

ToddRivers wrote

Hmm the simplest hacky workaround would be to put platform defines around the code that flips the fixed normal, like this:

inline float3 getFixedNormal()
{
   float3 normal = _FixedNormal.xyz;
#if UNITY_REVERSED_Z
   normal.z = -normal.z;
#endif
#if defined(SHADER_API_MOBILE)
   normal.z = -normal.z;
#endif
   return normal;
}

But!! if your saying there's a difference between iPhone 4 and 5 that won't work as there is no way of the shader knowing what version of iPhone it is.

I'm pretty sure this is Unity's fault not mine or esoterics. To explain the situation, since 5.5 Unity reverses the Z direction on certain platforms as it gives more precise depth values - see 'The Depth (Z) direction in Shaders' on this page.
https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
When they do that UNITY_REVERSED_Z should be defined, and when they do I flip the fixed normal.

If a platform isn't working it's because it is reversing the z direction and not defining UNITY_REVERSED_Z or it has defined it but isn't reversing z.
Either way its out of our control as its all internal to Unity.

Ugh. This is bad news 🙁

I manually changed all normals to the appropriate direction for every build, but I had to sacrifice iPhone devices prior to iPhone 5.

I don't know if I can manually check the phone model version at runtime (it's not even a problem about the OS version!) and if I'm going to be able to set the normals at runtime using defines or tweaking a list of materials stored somewhere, but definitely I'm not going to make it by the deadline 🙁

Which issue should the above code fix? Or, was it just a sample, and I have to manually define SHADER_API_MOBILE on each mobile build?

Could you please tweak the shaders, if needed (since you said you relised they should not consider the Reversed Z) for future use? I may have maybe an extra week for fixing them, hopefully.

Yeah sorry I was wrong about not needing to reverse the Z direction. At least I think so.
In order to properly know what's going on inside Unity I would need access to different platforms to and see what Unity defines on each, and whether or not Z reversing is happening.
That's a lot of work and I'm just a struggling indie who made these sharers on the side - I don't have the time or resources to be able to do that unfortunately.

If you're really struggling you could get one of your coders to set a shader global variable for the normal direction, set it in code to be (0,0,1) or (0,0,-1) based on platform (in C# you can get a lot more platform information than in shaders) and then modify the shaders to use the global instead of a per material value like they do at the mo.

Ok good news! (I think)

So having done a little bit of research I think Unity always uses a left handed coordinate system for its camera matrices EVEN when the Z buffer is reversed.
This means the camera always looks down the negative z axis, even when UNITY_REVERSED_Z is defined.

SO!! I am now pretty sure I can remove the code for flipping the fixed normal when UNITY_REVERSED_Z is defined.
Basically meaning you can define the fixed normal as (0,0,1) on all platforms. I'm going to sanity check it but I'm pretty it all works.

ToddRivers wrote

Ok good news! (I think)

So having done a little bit of research I think Unity always uses a left handed coordinate system for its camera matrices EVEN when the Z buffer is reversed.
This means the camera always looks down the negative z axis, even when UNITY_REVERSED_Z is defined.

SO!! I am now pretty sure I can remove the code for flipping the fixed normal when UNITY_REVERSED_Z is defined.
Basically meaning you can define the fixed normal as (0,0,1) on all platforms. I'm going to sanity check it but I'm pretty it all works.

These are good news indeed!

You proved to be more helpful and supportive than the whole Esoteric team... and my team also bought 3 licenses from them, leaving me with no support for the shaders they included - and that should reasonably support!

May I put you in the special thanks?
If so, could you please provide your full name (optionally a nick to be inserted in the middle, and an optional company) - or even something different you'd like to promote? (I'm not sure I can push every kind of content tho, but I may try to 🙂 )

Hey!
Heh you can if you want, my real name is Tom Raggett - Todd Rivers is a character from one of my favourite tv shows. (Which I always recommend to people! - http://www.imdb.com/title/tt0397150/)

Hopefully it does finally sort out those issues, I tested it on android and pc and think the theory is sound, but yeah other platforms are as yet untested 🙂

ToddRivers wrote

Hey!
Heh you can if you want, my real name is Tom Raggett - Todd Rivers is a character from one of my favourite tv shows. (Which I always recommend to people! - http://www.imdb.com/title/tt0397150/)

Hopefully it does finally sort out those issues, I tested it on android and pc and think the theory is sound, but yeah other platforms are as yet untested 🙂

Nice 🙂

Actually, the shaders from your trunk appear as unlit and with black borders around every piece of the atlas (no transparency nor prealpha mul)

I made the same changes you did, but on the Spine shaders, and they seem to be working kind of fine now, same texures, same settings. I'm not sure, but something is different between the version you got on GitHub and the Spine one.