Advertisement
Guest User

Untitled

a guest
Nov 19th, 2015
409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.61 KB | None | 0 0
  1. float4 BasisToQuaternion(float3 T, float3 B, float3 N)
  2. {
  3.     float4 q;
  4.     q.x = N.y - B.z;
  5.     q.y = T.z - N.x;
  6.     q.z = B.x - T.y;
  7.     q.w = 1 + T.x + B.y + N.z;
  8.     float l = length(q);
  9.     return q * rcp(l + 0.000000001);
  10. }
  11. void QuaternionToBasis(float4 q, out float3 T, out float3 B, out float3 N)
  12. {
  13.     T = float3( 1,  0,  0)
  14.       + float3(-2,  2,  2) * q.y * q.yxw
  15.       + float3(-2, -2,  2) * q.z * q.zwx;
  16.     B = float3( 0,  1,  0)
  17.       + float3( 2, -2,  2) * q.z * q.wzy
  18.       + float3( 2, -2, -2) * q.x * q.yxw;
  19.     N = float3( 0,  0,  1)
  20.       + float3( 2,  2, -2) * q.x * q.zwx
  21.       + float3(-2,  2, -2) * q.y * q.wzy;
  22.     T = normalize(T);
  23.     B = normalize(B);
  24.     N = normalize(N);
  25. }
  26. float3 PackBFNormal( float3 n )
  27. {
  28.     float3 n_abs = abs(n);
  29.     float n_max = max(n_abs.z, max(n_abs.y, n_abs.x));
  30.     float2 uv = n_abs.z<n_max?(n_abs.y<n_max?n_abs.yz:n_abs.xz):n_abs.xy;
  31.     uv = uv.x < uv.y ? uv.yx : uv.xy;
  32.     uv.y /= uv.x;
  33.     n /= n_max;
  34. #ifdef _ENGINE_
  35.     float scale = Tex2D(s_bestFit, uv).a;
  36. #else
  37.     uv = (floor(uv*1023.9999)+0.5)/1024;
  38.     float scale = Tex2Dlod(s_bestFit, float4(uv.x, 1-uv.y,0,0)).a;
  39. #endif
  40.     n *= scale;
  41.     return n*0.5+0.5;
  42. }
  43. float3 UnpackBFNormal( float3 n )
  44. {
  45.     return normalize(n*2-1);
  46. }
  47.  
  48. void PackNormalTangent( float3 n, float3 t, out float3 outN, out float3 outT )
  49. {
  50. #define USE_BFN
  51. #ifdef USE_BFN
  52.     outN = PackBFNormal(n);
  53.     outT = PackBFNormal(t);
  54. #else
  55.     float3 b = cross(n, t);
  56.     float4 q = BasisToQuaternion(t,b,n);
  57.     q = sqrt(abs(q)) * sign(q);
  58.     q = q * 0.5 + 0.5;
  59.     outN = q.xyz;
  60.     outT = q.www;
  61. #endif
  62. }
  63. void UnpackNormalTangent( float3 n, float3 t, out float3 outN, out float3 outT )
  64. {
  65. #ifdef USE_BFN
  66.     outN = UnpackBFNormal(n);
  67.     outT = UnpackBFNormal(t);
  68. #else
  69.     float4 q = float4(n,t.x);
  70.     q = q*2-1;
  71.     q = q*q * sign(q);
  72.     float3 B;
  73.     QuaternionToBasis(q, outT, B, outN);
  74. #endif
  75. }
  76.  
  77. int MaximalComponent(float4 q)
  78. {
  79.     float4 a = abs(q);
  80.     float mc = max( max(a.x, a.y), max(a.z, a.w) );
  81.     FLATTEN int index = (mc == a.x) ? 0 : ((mc == a.y) ? 1 : ((mc == a.z) ? 2 : 3));
  82.     return index;
  83. }
  84. float4 QuaternionTo10_10_10_2( float4 q )
  85. {
  86.     int index = MaximalComponent(q);
  87.     FLATTEN if(index == 0) q = q.yzwx;
  88.     FLATTEN if(index == 1) q = q.xzwy;
  89.     FLATTEN if(index == 2) q = q.xywz;
  90.     q.rgb = saturate(q.xyz * (q.w > 0 ? 1 : -1) * sqrtHalf + 0.5);
  91.     q.a = index / 3.0f;
  92.     return q;
  93. }
  94. float4 QuaternionFrom10_10_10_2( float4 q )
  95. {
  96.     int index = (int)(q.a * 3);
  97.     q.xyz = q.rgb*sqrtTwo-sqrtHalf;
  98.     q.w = sqrt(1-dot(q.xyz,q.xyz));
  99.     FLATTEN if(index == 0) q = q.wxyz;
  100.     FLATTEN if(index == 1) q = q.xwyz;
  101.     FLATTEN if(index == 2) q = q.xywz;
  102.     return q;
  103. }
  104.  
  105. float Test_Random(float3 t, float3 b, float3 n)
  106. {
  107.     float s = 16777619/10;
  108.     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))));
  109. }
  110. void Test_RandomScale(inout float3 t, inout float3 b, inout float3 n)
  111. {
  112.     float r = Test_Random(t,b,n);
  113.     float3 a = abs(n);
  114.     float m = rcp(max( max(a.x,a.y), a.z ));
  115.     r = lerp(0.7,m,r);
  116.     n *= r;
  117.     b *= r;
  118.     t *= r;
  119. }
  120.  
  121. float2 OctWrap( float2 v )
  122. {
  123.     return ( 1.0 - abs( v.yx ) ) * ( v.xy >= 0.0 ? 1.0 : -1.0 );
  124. }
  125. float2 NormalToOctahedron( float3 n )
  126. {
  127.     n /= ( abs( n.x ) + abs( n.y ) + abs( n.z ) );
  128.     n.xy = n.z >= 0.0 ? n.xy : OctWrap( n.xy );
  129.     n.xy = n.xy * 0.5 + 0.5;
  130.     return n.xy;
  131. }
  132. float3 OctahedronToNormal( float2 encN )
  133. {
  134.     encN = encN * 2.0 - 1.0;
  135.     float3 n;
  136.     n.z = 1.0 - abs( encN.x ) - abs( encN.y );
  137.     n.xy = n.z >= 0.0 ? encN.xy : OctWrap( encN.xy );
  138.     n = normalize( n );
  139.     return n;
  140. }
  141.  
  142.  
  143.  
  144. void Test_QuantizeTBN_Quat4x8( inout float3 t, inout float3 b, inout float3 n )
  145. {
  146.     b = cross(n, t);
  147.     float4 q = BasisToQuaternion(t,b,n);
  148.     q = saturate(q * 0.5 + 0.5);
  149.     q = floor( q * 255 + 0.5 ) / 255;
  150.     q = q*2-1;
  151.     QuaternionToBasis(q, t, b, n);
  152. }
  153. void Test_QuantizeTBN_Quat4x10( inout float3 t, inout float3 b, inout float3 n )
  154. {
  155.     b = cross(n, t);
  156.     float4 q = BasisToQuaternion(t,b,n);
  157.     q = saturate(q * 0.5 + 0.5);
  158.     q = floor( q * 1023 + 0.5 ) / 1023;
  159.     q = q*2-1;
  160.     QuaternionToBasis(q, t, b, n);
  161. }
  162. void Test_QuantizeTBN_Quat4x16( inout float3 t, inout float3 b, inout float3 n )
  163. {
  164.     b = cross(n, t);
  165.     float4 q = BasisToQuaternion(t,b,n);
  166.     q = saturate(q * 0.5 + 0.5);
  167.     q = floor( q * 65535 + 0.5 ) / 65535;
  168.     q = q*2-1;
  169.     QuaternionToBasis(q, t, b, n);
  170. }
  171. void Test_QuantizeTBN_Quat3x10_2( inout float3 t, inout float3 b, inout float3 n )
  172. {
  173.     b = cross(n, t);
  174.     float4 q = BasisToQuaternion(t,b,n);
  175.     q = QuaternionTo10_10_10_2( q );
  176.     q.rgb = floor( q.rgb * 1023 + 0.5 ) / 1023;
  177.     q.a   = floor( q.a   *    3 + 0.5 ) /    3;
  178.     q = saturate(q);
  179.     q = QuaternionFrom10_10_10_2( q );
  180.     QuaternionToBasis(q, t, b, n);
  181. }
  182. void Test_QuantizeTBN_Quat3x8( inout float3 t, inout float3 b, inout float3 n )
  183. {
  184.     b = cross(n, t);
  185.     float4 q = BasisToQuaternion(t,b,n);
  186.     q.xyz *= q.w>0?1:-1;
  187.     q = saturate(q * 0.5 + 0.5);
  188.     q.rgb = floor( q.rgb * 255 + 0.5 ) / 255;
  189.     q.a = 0;
  190.     q = saturate(q);
  191.     q.xyz = q.rgb*2-1;
  192.     q.w = 1-dot(q.xyz,q.xyz);
  193.     q.w = q.w <= 0 ? 0 : sqrt(q.w);
  194.     QuaternionToBasis(q, t, b, n);
  195. }
  196. void Test_QuantizeTBN_Quat3x10( inout float3 t, inout float3 b, inout float3 n )
  197. {
  198.     b = cross(n, t);
  199.     float4 q = BasisToQuaternion(t,b,n);
  200.     q.xyz *= q.w>0?1:-1;
  201.     q = saturate(q * 0.5 + 0.5);
  202.     q.rgb = floor( q.rgb * 1023 + 0.5 ) / 1023;
  203.     q.a = 0;
  204.     q = saturate(q);
  205.     q.xyz = q.rgb*2-1;
  206.     q.w = 1-dot(q.xyz,q.xyz);
  207.     q.w = q.w <= 0 ? 0 : sqrt(q.w);
  208.     QuaternionToBasis(q, t, b, n);
  209. }
  210.  
  211. void Test_QuantizeTBN_4x8_2( inout float3 t, inout float3 b, inout float3 n )
  212. {
  213.     float ns = n.z > 0 ? 1 : -1;
  214.     float ts = t.z > 0 ? 1 : -1;
  215.     n = n*0.5+0.5; n.z = 0;
  216.     t = t*0.5+0.5; t.z = 0;
  217.     n = floor( n * 255 + 0.5 ) / 255;
  218.     t = floor( t * 255 + 0.5 ) / 255;
  219.     n = n*2-1;
  220.     t = t*2-1;
  221.     float ln = 1-dot(n.xy,n.xy);
  222.     float lt = 1-dot(t.xy,t.xy);
  223.     n.z = ln <= 0.0000001 ? 0 : sqrt(ln)*ns;
  224.     t.z = lt <= 0.0000001 ? 0 : sqrt(lt)*ts;
  225.     b = cross(n, t);
  226. }
  227. void Test_QuantizeTBN_6x8( inout float3 t, inout float3 b, inout float3 n )
  228. {
  229.     n = n*0.5+0.5;
  230.     t = t*0.5+0.5;
  231.     n = floor( n * 255 + 0.5 ) / 255;
  232.     t = floor( t * 255 + 0.5 ) / 255;
  233.     n = normalize(n*2-1);
  234.     t = normalize(t*2-1);
  235.     b = cross(n, t);
  236. }
  237. void Test_QuantizeTBN_6x8BFN( inout float3 t, inout float3 b, inout float3 n )
  238. {
  239.     n = PackBFNormal(n);
  240.     t = PackBFNormal(t);
  241.     n = floor( n * 255 + 0.5 ) / 255;
  242.     t = floor( t * 255 + 0.5 ) / 255;
  243.     n = UnpackBFNormal(n);
  244.     t = UnpackBFNormal(t);
  245.     b = cross(n, t);
  246. }
  247. void Test_QuantizeTBN_6x8Noise( inout float3 t, inout float3 b, inout float3 n )
  248. {
  249.     Test_RandomScale( t, b, n );
  250.     n = n*0.5+0.5;
  251.     t = t*0.5+0.5;
  252.     n = floor( n * 255 + 0.5 ) / 255;
  253.     t = floor( t * 255 + 0.5 ) / 255;
  254.     n = normalize(n*2-1);
  255.     t = normalize(t*2-1);
  256.     b = cross(n, t);
  257. }
  258. void Test_QuantizeTBN_6x10( inout float3 t, inout float3 b, inout float3 n )
  259. {
  260.     n = n*0.5+0.5;
  261.     t = t*0.5+0.5;
  262.     n = floor( n * 1023 + 0.5 ) / 1023;
  263.     t = floor( t * 1023 + 0.5 ) / 1023;
  264.     n = normalize(n*2-1);
  265.     t = normalize(t*2-1);
  266.     b = cross(n, t);
  267. }
  268.  
  269. float4 Test_Quantize( float4 o, float maxValue )
  270. {
  271.     return floor( saturate(o) * maxValue + 0.5 ) / maxValue;
  272. }
  273.  
  274.  
  275. void Test_QuantizeTBN_Octahedron4x( float bits, bool noise, inout float3 t, inout float3 b, inout float3 n )
  276. {
  277.     float maxValue = exp2(bits);
  278.     float4 o;
  279.     o.xy = NormalToOctahedron(n);
  280.     o.zw = NormalToOctahedron(t);
  281.     if( noise )
  282.         o += Test_Random(t,b,n)/maxValue-(0.5/maxValue);
  283.     o = Test_Quantize( o, maxValue );
  284.     n = OctahedronToNormal(o.xy);
  285.     t = OctahedronToNormal(o.zw);
  286.     b = cross(n, t);
  287. }
  288.  
  289. void Test_QuantizeTBN_Octahedron4x8( inout float3 t, inout float3 b, inout float3 n )
  290. {
  291.     float4 o;
  292.     o.xy = NormalToOctahedron(n);
  293.     o.zw = NormalToOctahedron(t);
  294.     o = floor( o * 255 + 0.5 ) / 255;
  295.     n = OctahedronToNormal(o.xy);
  296.     t = OctahedronToNormal(o.zw);
  297.     b = cross(n, t);
  298. }
  299. void Test_QuantizeTBN_Octahedron4x8Noise( inout float3 t, inout float3 b, inout float3 n )
  300. {
  301.     float4 o;
  302.     o.xy = NormalToOctahedron(n) + Test_Random(t,b,n)/256-(0.5/256);
  303.     o.zw = NormalToOctahedron(t) + Test_Random(t,b,n)/256-(0.5/256);
  304.     o = floor( saturate(o) * 255 + 0.5 ) / 255;
  305.     n = OctahedronToNormal(o.xy);
  306.     t = OctahedronToNormal(o.zw);
  307.     b = cross(n, t);
  308. }
  309. void Test_QuantizeTBN_Octahedron4x10( inout float3 t, inout float3 b, inout float3 n )
  310. {
  311.     float4 o;
  312.     o.xy = NormalToOctahedron(n);
  313.     o.zw = NormalToOctahedron(t);
  314.     o = floor( o * 1023 + 0.5 ) / 1023;
  315.     n = OctahedronToNormal(o.xy);
  316.     t = OctahedronToNormal(o.zw);
  317.     b = cross(n, t);
  318. }
  319. void Test_QuantizeTBN_Octahedron4x16( inout float3 t, inout float3 b, inout float3 n )
  320. {
  321.     float4 o;
  322.     o.xy = NormalToOctahedron(n);
  323.     o.zw = NormalToOctahedron(t);
  324.     o = floor( o * 65535 + 0.5 ) / 65535;
  325.     n = OctahedronToNormal(o.xy);
  326.     t = OctahedronToNormal(o.zw);
  327.     b = cross(n, t);
  328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement