float range not being clamped to 0..1 on color ?

Hey guys, as far as I understand, if you do something like this:

struct v2f
{
        float4 vertex : POSITION;
        float3 normal : COLOR; // or TEXCOORD
};

v2f vert (appdata v)
{
        v2f o;
        o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
        o.normal = float3(-1,0,0); // this
        return o;
}

o.normal will be clamped to the 0…1 range, so it will be (0,0,0,1), so you have to do something like normal * 0.5 + 0.5 to compress it, and then in the fragment shader uncompress it with ( normal - 0.5 ) * 2.
But for some reason, having this fragment program:

fixed3 frag (v2f i) : SV_Target
{  
       return i.normal * -1;
}

the result is ALWAYS red ( since (-1,0,0) * -1 = (1,0,0) ), if unity were to clamp those values, then the result should be black since (0,0,0) * -1 = (0,0,0). So either there’s something that I didn’t read in the documentation, or I’m doing something wrong. Does someone have any clue whats going on ? Cheers

Sounds like you’re describing the packing/unpacking usually done when retrieving normals out of textures. There is no clamping happening between fragment and vertex shaders. The normal that arrives in the fragment shader is simply an interpolated between whatever values you gave in the vertex shader to the triangle’s vertices.

Actually the shader doesn’t even know you’re planning to use that float3 value as a normal in the first place. There are some reserved variable names that Unity will handle differently, but only for surface shaders: see Unity - Manual: Writing Surface Shaders at the bottom.

Wow that explains it, thanks! The thing that threw me off was this http://docs.unity3d.com/Manual/ShaderTut2.html
if you scroll to where they show an example of how to display normals, they say

and in some other forum posts that I found, they talked about how unity clamps the color values to 0…1, so I was quite confused by that. Thanks for clearing that up.