Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- float4 BasisToQuaternion(float3 T, float3 B, float3 N)
- {
- float4 q;
- q.x = N.y - B.z;
- q.y = T.z - N.x;
- q.z = B.x - T.y;
- q.w = 1 + T.x + B.y + N.z;
- float l = length(q);
- return q * rcp(l + 0.000000001);
- }
- void QuaternionToBasis(float4 q, out float3 T, out float3 B, out float3 N)
- {
- T = float3( 1, 0, 0)
- + float3(-2, 2, 2) * q.y * q.yxw
- + float3(-2, -2, 2) * q.z * q.zwx;
- B = float3( 0, 1, 0)
- + float3( 2, -2, 2) * q.z * q.wzy
- + float3( 2, -2, -2) * q.x * q.yxw;
- N = float3( 0, 0, 1)
- + float3( 2, 2, -2) * q.x * q.zwx
- + float3(-2, 2, -2) * q.y * q.wzy;
- T = normalize(T);
- B = normalize(B);
- N = normalize(N);
- }
- float3 PackBFNormal( float3 n )
- {
- float3 n_abs = abs(n);
- float n_max = max(n_abs.z, max(n_abs.y, n_abs.x));
- float2 uv = n_abs.z<n_max?(n_abs.y<n_max?n_abs.yz:n_abs.xz):n_abs.xy;
- uv = uv.x < uv.y ? uv.yx : uv.xy;
- uv.y /= uv.x;
- n /= n_max;
- #ifdef _ENGINE_
- float scale = Tex2D(s_bestFit, uv).a;
- #else
- uv = (floor(uv*1023.9999)+0.5)/1024;
- float scale = Tex2Dlod(s_bestFit, float4(uv.x, 1-uv.y,0,0)).a;
- #endif
- n *= scale;
- return n*0.5+0.5;
- }
- float3 UnpackBFNormal( float3 n )
- {
- return normalize(n*2-1);
- }
- void PackNormalTangent( float3 n, float3 t, out float3 outN, out float3 outT )
- {
- #define USE_BFN
- #ifdef USE_BFN
- outN = PackBFNormal(n);
- outT = PackBFNormal(t);
- #else
- float3 b = cross(n, t);
- float4 q = BasisToQuaternion(t,b,n);
- q = sqrt(abs(q)) * sign(q);
- q = q * 0.5 + 0.5;
- outN = q.xyz;
- outT = q.www;
- #endif
- }
- void UnpackNormalTangent( float3 n, float3 t, out float3 outN, out float3 outT )
- {
- #ifdef USE_BFN
- outN = UnpackBFNormal(n);
- outT = UnpackBFNormal(t);
- #else
- float4 q = float4(n,t.x);
- q = q*2-1;
- q = q*q * sign(q);
- float3 B;
- QuaternionToBasis(q, outT, B, outN);
- #endif
- }
- int MaximalComponent(float4 q)
- {
- float4 a = abs(q);
- float mc = max( max(a.x, a.y), max(a.z, a.w) );
- FLATTEN int index = (mc == a.x) ? 0 : ((mc == a.y) ? 1 : ((mc == a.z) ? 2 : 3));
- return index;
- }
- float4 QuaternionTo10_10_10_2( float4 q )
- {
- int index = MaximalComponent(q);
- FLATTEN if(index == 0) q = q.yzwx;
- FLATTEN if(index == 1) q = q.xzwy;
- FLATTEN if(index == 2) q = q.xywz;
- q.rgb = saturate(q.xyz * (q.w > 0 ? 1 : -1) * sqrtHalf + 0.5);
- q.a = index / 3.0f;
- return q;
- }
- float4 QuaternionFrom10_10_10_2( float4 q )
- {
- int index = (int)(q.a * 3);
- q.xyz = q.rgb*sqrtTwo-sqrtHalf;
- q.w = sqrt(1-dot(q.xyz,q.xyz));
- FLATTEN if(index == 0) q = q.wxyz;
- FLATTEN if(index == 1) q = q.xwyz;
- FLATTEN if(index == 2) q = q.xywz;
- return q;
- }
- float Test_Random(float3 t, float3 b, float3 n)
- {
- float s = 16777619/10;
- return frac( frac(abs(dot(n,(float3)s*0.1))) + frac(abs(dot(1-t,(float3)s*0.2))) + frac(abs(dot(b,(float3)s*0.3))));
- }
- void Test_RandomScale(inout float3 t, inout float3 b, inout float3 n)
- {
- float r = Test_Random(t,b,n);
- float3 a = abs(n);
- float m = rcp(max( max(a.x,a.y), a.z ));
- r = lerp(0.7,m,r);
- n *= r;
- b *= r;
- t *= r;
- }
- float2 OctWrap( float2 v )
- {
- return ( 1.0 - abs( v.yx ) ) * ( v.xy >= 0.0 ? 1.0 : -1.0 );
- }
- float2 NormalToOctahedron( float3 n )
- {
- n /= ( abs( n.x ) + abs( n.y ) + abs( n.z ) );
- n.xy = n.z >= 0.0 ? n.xy : OctWrap( n.xy );
- n.xy = n.xy * 0.5 + 0.5;
- return n.xy;
- }
- float3 OctahedronToNormal( float2 encN )
- {
- encN = encN * 2.0 - 1.0;
- float3 n;
- n.z = 1.0 - abs( encN.x ) - abs( encN.y );
- n.xy = n.z >= 0.0 ? encN.xy : OctWrap( encN.xy );
- n = normalize( n );
- return n;
- }
- void Test_QuantizeTBN_Quat4x8( inout float3 t, inout float3 b, inout float3 n )
- {
- b = cross(n, t);
- float4 q = BasisToQuaternion(t,b,n);
- q = saturate(q * 0.5 + 0.5);
- q = floor( q * 255 + 0.5 ) / 255;
- q = q*2-1;
- QuaternionToBasis(q, t, b, n);
- }
- void Test_QuantizeTBN_Quat4x10( inout float3 t, inout float3 b, inout float3 n )
- {
- b = cross(n, t);
- float4 q = BasisToQuaternion(t,b,n);
- q = saturate(q * 0.5 + 0.5);
- q = floor( q * 1023 + 0.5 ) / 1023;
- q = q*2-1;
- QuaternionToBasis(q, t, b, n);
- }
- void Test_QuantizeTBN_Quat4x16( inout float3 t, inout float3 b, inout float3 n )
- {
- b = cross(n, t);
- float4 q = BasisToQuaternion(t,b,n);
- q = saturate(q * 0.5 + 0.5);
- q = floor( q * 65535 + 0.5 ) / 65535;
- q = q*2-1;
- QuaternionToBasis(q, t, b, n);
- }
- void Test_QuantizeTBN_Quat3x10_2( inout float3 t, inout float3 b, inout float3 n )
- {
- b = cross(n, t);
- float4 q = BasisToQuaternion(t,b,n);
- q = QuaternionTo10_10_10_2( q );
- q.rgb = floor( q.rgb * 1023 + 0.5 ) / 1023;
- q.a = floor( q.a * 3 + 0.5 ) / 3;
- q = saturate(q);
- q = QuaternionFrom10_10_10_2( q );
- QuaternionToBasis(q, t, b, n);
- }
- void Test_QuantizeTBN_Quat3x8( inout float3 t, inout float3 b, inout float3 n )
- {
- b = cross(n, t);
- float4 q = BasisToQuaternion(t,b,n);
- q.xyz *= q.w>0?1:-1;
- q = saturate(q * 0.5 + 0.5);
- q.rgb = floor( q.rgb * 255 + 0.5 ) / 255;
- q.a = 0;
- q = saturate(q);
- q.xyz = q.rgb*2-1;
- q.w = 1-dot(q.xyz,q.xyz);
- q.w = q.w <= 0 ? 0 : sqrt(q.w);
- QuaternionToBasis(q, t, b, n);
- }
- void Test_QuantizeTBN_Quat3x10( inout float3 t, inout float3 b, inout float3 n )
- {
- b = cross(n, t);
- float4 q = BasisToQuaternion(t,b,n);
- q.xyz *= q.w>0?1:-1;
- q = saturate(q * 0.5 + 0.5);
- q.rgb = floor( q.rgb * 1023 + 0.5 ) / 1023;
- q.a = 0;
- q = saturate(q);
- q.xyz = q.rgb*2-1;
- q.w = 1-dot(q.xyz,q.xyz);
- q.w = q.w <= 0 ? 0 : sqrt(q.w);
- QuaternionToBasis(q, t, b, n);
- }
- void Test_QuantizeTBN_4x8_2( inout float3 t, inout float3 b, inout float3 n )
- {
- float ns = n.z > 0 ? 1 : -1;
- float ts = t.z > 0 ? 1 : -1;
- n = n*0.5+0.5; n.z = 0;
- t = t*0.5+0.5; t.z = 0;
- n = floor( n * 255 + 0.5 ) / 255;
- t = floor( t * 255 + 0.5 ) / 255;
- n = n*2-1;
- t = t*2-1;
- float ln = 1-dot(n.xy,n.xy);
- float lt = 1-dot(t.xy,t.xy);
- n.z = ln <= 0.0000001 ? 0 : sqrt(ln)*ns;
- t.z = lt <= 0.0000001 ? 0 : sqrt(lt)*ts;
- b = cross(n, t);
- }
- void Test_QuantizeTBN_6x8( inout float3 t, inout float3 b, inout float3 n )
- {
- n = n*0.5+0.5;
- t = t*0.5+0.5;
- n = floor( n * 255 + 0.5 ) / 255;
- t = floor( t * 255 + 0.5 ) / 255;
- n = normalize(n*2-1);
- t = normalize(t*2-1);
- b = cross(n, t);
- }
- void Test_QuantizeTBN_6x8BFN( inout float3 t, inout float3 b, inout float3 n )
- {
- n = PackBFNormal(n);
- t = PackBFNormal(t);
- n = floor( n * 255 + 0.5 ) / 255;
- t = floor( t * 255 + 0.5 ) / 255;
- n = UnpackBFNormal(n);
- t = UnpackBFNormal(t);
- b = cross(n, t);
- }
- void Test_QuantizeTBN_6x8Noise( inout float3 t, inout float3 b, inout float3 n )
- {
- Test_RandomScale( t, b, n );
- n = n*0.5+0.5;
- t = t*0.5+0.5;
- n = floor( n * 255 + 0.5 ) / 255;
- t = floor( t * 255 + 0.5 ) / 255;
- n = normalize(n*2-1);
- t = normalize(t*2-1);
- b = cross(n, t);
- }
- void Test_QuantizeTBN_6x10( inout float3 t, inout float3 b, inout float3 n )
- {
- n = n*0.5+0.5;
- t = t*0.5+0.5;
- n = floor( n * 1023 + 0.5 ) / 1023;
- t = floor( t * 1023 + 0.5 ) / 1023;
- n = normalize(n*2-1);
- t = normalize(t*2-1);
- b = cross(n, t);
- }
- float4 Test_Quantize( float4 o, float maxValue )
- {
- return floor( saturate(o) * maxValue + 0.5 ) / maxValue;
- }
- void Test_QuantizeTBN_Octahedron4x( float bits, bool noise, inout float3 t, inout float3 b, inout float3 n )
- {
- float maxValue = exp2(bits);
- float4 o;
- o.xy = NormalToOctahedron(n);
- o.zw = NormalToOctahedron(t);
- if( noise )
- o += Test_Random(t,b,n)/maxValue-(0.5/maxValue);
- o = Test_Quantize( o, maxValue );
- n = OctahedronToNormal(o.xy);
- t = OctahedronToNormal(o.zw);
- b = cross(n, t);
- }
- void Test_QuantizeTBN_Octahedron4x8( inout float3 t, inout float3 b, inout float3 n )
- {
- float4 o;
- o.xy = NormalToOctahedron(n);
- o.zw = NormalToOctahedron(t);
- o = floor( o * 255 + 0.5 ) / 255;
- n = OctahedronToNormal(o.xy);
- t = OctahedronToNormal(o.zw);
- b = cross(n, t);
- }
- void Test_QuantizeTBN_Octahedron4x8Noise( inout float3 t, inout float3 b, inout float3 n )
- {
- float4 o;
- o.xy = NormalToOctahedron(n) + Test_Random(t,b,n)/256-(0.5/256);
- o.zw = NormalToOctahedron(t) + Test_Random(t,b,n)/256-(0.5/256);
- o = floor( saturate(o) * 255 + 0.5 ) / 255;
- n = OctahedronToNormal(o.xy);
- t = OctahedronToNormal(o.zw);
- b = cross(n, t);
- }
- void Test_QuantizeTBN_Octahedron4x10( inout float3 t, inout float3 b, inout float3 n )
- {
- float4 o;
- o.xy = NormalToOctahedron(n);
- o.zw = NormalToOctahedron(t);
- o = floor( o * 1023 + 0.5 ) / 1023;
- n = OctahedronToNormal(o.xy);
- t = OctahedronToNormal(o.zw);
- b = cross(n, t);
- }
- void Test_QuantizeTBN_Octahedron4x16( inout float3 t, inout float3 b, inout float3 n )
- {
- float4 o;
- o.xy = NormalToOctahedron(n);
- o.zw = NormalToOctahedron(t);
- o = floor( o * 65535 + 0.5 ) / 65535;
- n = OctahedronToNormal(o.xy);
- t = OctahedronToNormal(o.zw);
- b = cross(n, t);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement