home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 18759 / ROE.7z / QSClothWind.h < prev    next >
Encoding:
C/C++ Source or Header  |  2020-09-17  |  5.4 KB  |  181 lines

  1. #ifndef QSClothWind_h__
  2. #define QSClothWind_h__
  3.  
  4. #include "QSVertexProcessUtils.h"
  5.  
  6. #if CLOTH_WIND
  7. #include "QSGameTime.h"
  8. sampler2D    ClothWrinkleSampler;
  9. sampler2D    ClothWrinkleNormalSampler;
  10. float4        ClothWindParam;
  11. float4        ClothWindMotion;
  12.  
  13. #define time        GameTime.x
  14. #define speed        ClothWindParam.x // 0.02
  15. #define tiling        ClothWindParam.y // 0.4
  16. #define offsetAmp    ClothWindParam.z
  17. #define normalAmp    ClothWindParam.w
  18. #define windDir        ClothWindMotion.xyz
  19.  
  20. #define xDir        float3(1, 0, 0)
  21. #define yDir        float3(0, 1, 0)
  22. #define zDir        float3(0, 0, 1)
  23.  
  24. float4 GetRotateQuat(float3 from, float3 to)
  25. {
  26.     const float3 hv = normalize(from + to);
  27.     return float4(cross(from, hv), dot(from, hv));
  28. }
  29.  
  30. float3 Rotate(float4 rot, float3 pos)
  31. {
  32.     float qs = rot.w;
  33.     float3 qv = rot.xyz;
  34.  
  35.     return (qs * qs - dot(qv, qv)) * pos + 2 * qs * cross(qv, pos) + 2 * dot(qv, pos) * qv;
  36. }
  37.  
  38. bool AffectByWind(float wrinkleBlend)
  39. {
  40.     return abs(wrinkleBlend) > 0.001;
  41. }
  42.  
  43. void GetSmoothNormalAndWrinkleBlend(VsIn param, float2 boneUv, out float3 smoothNormal, out float wrinkleBlend)
  44. {
  45. #if VERTEX_COMPRESSION
  46.     float3 vertexColor = DecompressColorbToFloat(param.vertexColor).xyz;
  47. #else
  48.     float3 vertexColor = param.vertexColor;
  49. #endif
  50.  
  51.     wrinkleBlend = vertexColor.z;
  52.  
  53.     const float2 normxy = vertexColor.xy * 2 - 1;
  54.     const float normz = sqrt(1 - saturate(dot(normxy, normxy)));
  55.     smoothNormal = normalize(float3(normxy, normz));
  56.  
  57. #if SKINNING
  58.     VertexTransformCalc_SkinningDir(smoothNormal, param.blendWeight, param.blendIndices, boneUv, smoothNormal);
  59. #endif
  60. }
  61.  
  62. float3 GetSamplePos(float3 pos)
  63. {
  64.     return pos * tiling + fmod(time * speed * normalize(windDir), 100);
  65. }
  66.  
  67. float SampleOffsetInVs(sampler2D s, float2 uv)
  68. {
  69.     return tex2Dlod(s, float4(uv, 0, 0)).x * offsetAmp;
  70. }
  71.  
  72. float3 SampleNormal(sampler2D s, float2 uv)
  73. {
  74.     float4 color = tex2D(s, uv);
  75.     float2 normalxy = BiDecompress(color.rg) * normalAmp;
  76.     float normalz = sqrt(1.0f - saturate(dot(normalxy, normalxy)));
  77.     return float3(normalxy, normalz);
  78. }
  79.  
  80. void ClothWindPosition(inout float3 pos, float wrinkleBlend, float3 smoothNormalWS, float3 samplePos)
  81. {
  82.     if (!AffectByWind(wrinkleBlend))
  83.     {
  84.         return;
  85.     }
  86.  
  87.     const float2 sampleXz = samplePos.xz;
  88.     const float2 sampleYz = samplePos.yz;
  89.  
  90.     const float xzRatio = abs(dot(smoothNormalWS, yDir));
  91.     const float yzRatio = abs(dot(smoothNormalWS, xDir));
  92.  
  93.     const float wrinkleOffsetXz = SampleOffsetInVs(ClothWrinkleSampler, sampleXz) * xzRatio;
  94.     const float wrinkleOffsetYz = SampleOffsetInVs(ClothWrinkleSampler, sampleYz) * yzRatio;
  95.     
  96.     pos += (wrinkleOffsetXz + wrinkleOffsetYz) * wrinkleBlend *smoothNormalWS;
  97. }
  98.  
  99. void ClothWindNormal(inout float3 normal, inout float3 binormal, inout float3 tangent, float3 smoothNormal, float wrinkleBlend, float3 samplePos)
  100. {
  101.     if (!AffectByWind(wrinkleBlend))
  102.     {
  103.         return;
  104.     }
  105.  
  106.     const float2 sampleXz = samplePos.xz;
  107.     const float2 sampleYz = samplePos.yz;
  108.  
  109.     const float3 smoothNormalXy = normalize(float3(smoothNormal.xy, 0));
  110.  
  111.     const float xzDot = dot(smoothNormalXy, yDir);
  112.     const float yzDot = dot(smoothNormalXy, xDir);
  113.  
  114.     const float xzRatio = abs(xzDot);
  115.     const float yzRatio = abs(yzDot);
  116.  
  117.     const float xzRev = (xzDot > 0) ? 1 : -1;
  118.     const float yzRev = (yzDot > 0) ? 1 : -1;
  119.  
  120.     const float3 wrinkleNormalXzTS = SampleNormal(ClothWrinkleNormalSampler, sampleXz);
  121.     const float3 wrinkleNormalYzTS = SampleNormal(ClothWrinkleNormalSampler, sampleYz);
  122.  
  123.     const float3x3 xzTBN = float3x3(xDir, -zDir, yDir * xzRev);  // normal along y axis
  124.     const float3 wrinkleNormalXzMS = mul(wrinkleNormalXzTS, xzTBN);
  125.  
  126.     const float3x3 yzTBN = float3x3(yDir, -zDir, xDir * yzRev);  // normal along x axis
  127.     const float3 wrinkleNormalYzMS = mul(wrinkleNormalYzTS, yzTBN);
  128.  
  129.     float3 wrinkleNormalMS = normalize(wrinkleNormalXzMS * xzRatio + wrinkleNormalYzMS * yzRatio);
  130.     wrinkleNormalMS = normalize(lerp(smoothNormalXy, wrinkleNormalMS, wrinkleBlend));
  131.  
  132.     const float4 rot = GetRotateQuat(
  133.         mul(smoothNormalXy, (float3x3)worldMatrix),
  134.         mul(wrinkleNormalMS, (float3x3)worldMatrix));
  135.  
  136.     normal = Rotate(rot, normal);
  137.     binormal = Rotate(rot, binormal);
  138.     tangent = Rotate(rot, tangent);
  139. }
  140.  
  141. #if LIGHTING || ELECTRONIZE
  142. void ClothWindVs(inout float3 pos, out float4 smoothNormal, out float4 wrinkleParam, VsIn param, float2 boneUv)
  143. {
  144.     float3 smoothNorm;
  145.     float wrinkleBlend;
  146.     GetSmoothNormalAndWrinkleBlend(param, boneUv, smoothNorm, wrinkleBlend);
  147.         
  148.     const float3 wrinkleSamplePos = GetSamplePos(param.pos);
  149.     ClothWindPosition(pos, wrinkleBlend, smoothNorm, wrinkleSamplePos);
  150.  
  151.     smoothNormal = float4(smoothNorm, 1);
  152.     wrinkleParam = float4(wrinkleSamplePos, wrinkleBlend);
  153. }
  154. #endif
  155.  
  156. #if DEPTH
  157. void ClothWindVs(inout float3 pos, VsIn param, float2 boneUv)
  158. {
  159.     float3 smoothNormal;
  160.     float wrinkleBlend;
  161.     GetSmoothNormalAndWrinkleBlend(param, boneUv, smoothNormal, wrinkleBlend);
  162.  
  163.     const float3 wrinkleSamplePos = GetSamplePos(param.pos);
  164.     ClothWindPosition(pos, wrinkleBlend, smoothNormal, wrinkleSamplePos);
  165. }
  166. #endif
  167.  
  168. #if LIGHTING
  169. void ClothWindPs(inout VsOut param)
  170. {
  171.     // cloth wind lighting ps
  172.     const float3 wrinkleSamplePos = param.wrinkleParam.xyz;
  173.     const float wrinkleBlend = param.wrinkleParam.w;
  174.     const float3 smoothNormal = normalize(param.smoothNormal.xyz);
  175.     ClothWindNormal(param.normal, param.binormal, param.tangent, smoothNormal, wrinkleBlend, wrinkleSamplePos);
  176. }
  177. #endif
  178.  
  179. #endif // CLOTH_WIND
  180.  
  181. #endif // QSClothWind_h__