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

  1. #ifndef QSSHADER_TerrainMaterial_H
  2. #define QSSHADER_TerrainMaterial_H
  3.  
  4. #include "FunctionLib.fxh"
  5. #include "CommonNormalFunc.fxh"
  6. /*
  7.  *    constants
  8.  */
  9. sampler2D         DiffuseMap;
  10. sampler2D         NormalMap;
  11. sampler2D         LowResDiffuseMap;
  12. sampler2D         MaterialMaskSampler;
  13. sampler2D         GrassMaskSampler;
  14. sampler2D       GrassMaskSampler_1;
  15.  
  16. float4          MaterialLodInfo; //x near threshold, y smooth fade len, z 1.0f/y, w for low res diffuse factor
  17.  
  18. //merged layer
  19. sampler2D         DiffuseMap0;
  20. sampler2D         DiffuseMap1;
  21. sampler2D         DiffuseMap2;
  22. sampler2D         DiffuseMap3;
  23. sampler2D         DiffuseMap4;
  24. sampler2D         NormalMap0;
  25. sampler2D         NormalMap1;
  26. sampler2D         NormalMap2;
  27. sampler2D         NormalMap3;
  28. sampler2D         NormalMap4;
  29.  
  30. #if BLINK_NOISE
  31. //To avoid too many textures for terrain shader, only support one globle blink noise texture now.
  32. sampler2D         BlinkNoiseSampler;
  33. float           BlinkNoiseGridUVTileFactor;       // grid tile UI factor
  34. #endif
  35.  
  36. /*
  37.  *    functions
  38.  */
  39. //util functions
  40. int GetLayerNum()
  41. {
  42. #if MERGE_LAYER_1
  43.     return 1;
  44. #elif MERGE_LAYER_2
  45.     return 2;
  46. #elif MERGE_LAYER_3
  47.     return 3;
  48. #elif MERGE_LAYER_4
  49.     return 4;
  50. #elif MERGE_LAYER_5
  51.     return 5;
  52. #endif
  53. }
  54.  
  55. float GetMaskValue(float4 mask, float4 selector, float2 processor)
  56. {
  57.     float maskValue = dot(mask, selector);
  58.     maskValue = maskValue*processor.y+processor.x;
  59.     return maskValue;
  60. }
  61.  
  62. //param is dist on z
  63. float CalcMatLodRatio(float distZ)
  64. {
  65.     return clamp((distZ-MaterialLodInfo.x)*MaterialLodInfo.z, 0.0f, 1.0f);
  66. }
  67.  
  68. void SampleTex(
  69.     //in
  70.     sampler2D diffuseMap, sampler2D normalMap, float2 uv, 
  71.     //out
  72.     out float4 diffuseColor, out float specularValue, out float3 normalTangentSpace
  73.     )
  74. {
  75.     diffuseColor = tex2D(diffuseMap, AnisoSrgb, uv);
  76.     float4 normalColor = tex2D(normalMap, AnisoSrgb, uv);
  77.  
  78. #if SPEC_FROM_ALPHA
  79.     specularValue = normalColor.a;
  80.     normalTangentSpace = BiDecompress(normalColor.xyz);
  81. #else    
  82.     specularValue = normalColor.z;    
  83.     float2 nmXy = BiDecompress(normalColor.xy);
  84.     normalTangentSpace = float3(nmXy, sqrt(1.0f-dot(nmXy,nmXy)));
  85. #endif
  86. }
  87.  
  88. void SampleTexLayer(
  89.     //in
  90.     int layerIdx, float2 uv, float2 specularChannel,
  91.     //out
  92.     out float3 diffuseColor, out float specularValue, out float3 normalTangentSpace
  93.     )
  94. {
  95.     float4 normalColor;
  96.  
  97.     if(0==layerIdx)
  98.     {
  99.         diffuseColor = tex2D(DiffuseMap0, AnisoSrgb, uv).xyz;
  100.         normalColor = tex2D(NormalMap0, AnisoSrgb, uv);
  101.     }
  102.     else if(1==layerIdx)
  103.     {
  104.         diffuseColor = tex2D(DiffuseMap1, AnisoSrgb, uv).xyz;
  105.         normalColor = tex2D(NormalMap1, AnisoSrgb, uv);
  106.     }
  107.     else if(2==layerIdx)
  108.     {
  109.         diffuseColor = tex2D(DiffuseMap2, AnisoSrgb, uv).xyz;
  110.         normalColor = tex2D(NormalMap2, AnisoSrgb, uv);
  111.     }
  112.     else if(3==layerIdx)
  113.     {
  114.         diffuseColor = tex2D(DiffuseMap3, AnisoSrgb, uv).xyz;
  115.         normalColor = tex2D(NormalMap3, AnisoSrgb, uv);
  116.     }
  117.     else if(4==layerIdx)
  118.     {
  119.         diffuseColor = tex2D(DiffuseMap4, AnisoSrgb, uv).xyz;
  120.         normalColor = tex2D(NormalMap4, AnisoSrgb, uv);
  121.     }
  122.  
  123.     specularValue = dot(normalColor.zw, specularChannel);    
  124.     float2 nmXy = BiDecompress(normalColor.xy);
  125.     normalTangentSpace = float3(nmXy, sqrt(saturate(1.0f-dot(nmXy,nmXy))));
  126. }
  127.  
  128. void SampleTex(
  129.     //in
  130.     int layerIdx, float2 uv,
  131.     //out
  132.     out float3 diffuseColor
  133.     )
  134. {
  135.     if(0==layerIdx)
  136.     {
  137.         diffuseColor = tex2D(DiffuseMap0, AnisoSrgb, uv).xyz;
  138.     }
  139.     else if(1==layerIdx)
  140.     {
  141.         diffuseColor = tex2D(DiffuseMap1, AnisoSrgb, uv).xyz;
  142.     }
  143.     else if(2==layerIdx)
  144.     {
  145.         diffuseColor = tex2D(DiffuseMap2, AnisoSrgb, uv).xyz;
  146.     }
  147.     else if(3==layerIdx)
  148.     {
  149.         diffuseColor = tex2D(DiffuseMap3, AnisoSrgb, uv).xyz;
  150.     }
  151.     else //if(4==layerIdx)
  152.     {
  153.         diffuseColor = tex2D(DiffuseMap4, AnisoSrgb, uv).xyz;
  154.     }
  155. }
  156.  
  157. void SampleDiffuseNormal(sampler2D diffuseMap, sampler2D normalMap, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float4 diffuseColor, out float3 worldNormal, out float specularValue)
  158. {
  159. #if PROJ_X
  160.     {        
  161.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  162.  
  163.         float3 normalTangentSpace;
  164.         SampleTex(diffuseMap, normalMap, uv, diffuseColor, specularValue, normalTangentSpace);
  165.         
  166.         float signValue = dot(inNormal, float3(1.0f, 0.0f, 0.0f))<0.0f?1.0f:-1.0f;
  167.  
  168.         float3 tangentBase = float3(0.0f,1.0f,0.0f);    
  169.         float3 normal = inNormal; 
  170.         float3 binormal = cross(normal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  171.         float3 tangent = cross(binormal, normal);
  172.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,normal);
  173.         worldNormal = normalize(mul(normalTangentSpace, tangentMatrix)); 
  174.     }
  175. #endif//PROJ_X
  176.  
  177. #if PROJ_Y
  178.     {        
  179.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  180.  
  181.         float3 normalTangentSpace;
  182.         SampleTex(diffuseMap, normalMap, uv, diffuseColor, specularValue, normalTangentSpace);
  183.  
  184.         float signValue = dot(inNormal, float3(0.0f, -1.0f, 0.0f))<0.0f?1.0f:-1.0f;        
  185.         float3 tangentBase = float3(1.0f,0.0f,0.0f);
  186.  
  187.         float3 normal = inNormal; 
  188.         float3 binormal = cross(normal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  189.         float3 tangent = cross(binormal, normal);
  190.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,normal);
  191.         worldNormal = normalize(mul(normalTangentSpace, tangentMatrix)); 
  192.     }
  193. #endif//PROJ_Y
  194.  
  195. #if PROJ_Z
  196.     {        
  197.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  198.  
  199.         float3 normalTangentSpace;
  200.         SampleTex(diffuseMap, normalMap, uv, diffuseColor, specularValue, normalTangentSpace);
  201.  
  202.         worldNormal = ReorientNormal(inNormal, normalTangentSpace);
  203.     }
  204. #endif//PROJ_Z
  205.  
  206.     worldNormal = normalize(worldNormal);
  207. }
  208.  
  209. void SampleDiffuseNormal(int layerIdx, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float3 diffuseColor, out float3 worldNormal, out float specularValue)
  210. {
  211.     float2 specChannel = selectorV.xy;
  212. #if PROJ_X
  213.     {        
  214.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  215.  
  216.         float3 normalTangentSpace;        
  217.         SampleTexLayer(layerIdx, uv, specChannel, diffuseColor.xyz, specularValue, normalTangentSpace);
  218.  
  219.         //opt for float signValue = dot(inNormal, float3(1.0f, 0.0f, 0.0f))<0.0f?1.0f:-1.0f;
  220.         float signValue = inNormal.x<0.0f ? 1.0f : -1.0f;
  221.  
  222.         //opt for 
  223.         //float3 tangentBase = float3(0.0f,1.0f,0.0f);     
  224.         //float3 binormal = cross(inNormal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  225.         float3 binormal = float3(-inNormal.z, 0.0f, inNormal.x);
  226.         float3 tangent = cross(binormal, inNormal);
  227.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,inNormal);
  228.  
  229.         //opt for
  230.         //worldNormal += normalize(mul(normalTangentSpace, tangentMatrix)); 
  231.         worldNormal += mul(normalTangentSpace, tangentMatrix); 
  232.     }
  233. #endif//PROJ_X
  234.  
  235. #if PROJ_Y
  236.     {        
  237.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  238.  
  239.         float3 normalTangentSpace;
  240.         SampleTexLayer(layerIdx, uv, specChannel, diffuseColor.xyz, specularValue, normalTangentSpace);
  241.  
  242.         //optimize for dot(inNormal, float3(0.0f, -1.0f, 0.0f))<0.0f?1.0f:-1.0f;        
  243.         float signValue = inNormal.y>0.0f?1.0f:-1.0f;                
  244.  
  245.         //opt for
  246.         //float3 tangentBase = float3(1.0f,0.0f,0.0f);
  247.         //float3 binormal = cross(inNormal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  248.         float3 binormal = float3(0.0f, inNormal.z, -inNormal.y);
  249.         float3 tangent = cross(binormal, inNormal);
  250.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,inNormal);
  251.  
  252.         //opt for
  253.         //worldNormal += normalize(mul(normalTangentSpace, tangentMatrix)); 
  254.         worldNormal += mul(normalTangentSpace, tangentMatrix); 
  255.     }
  256. #endif//PROJ_Y
  257.  
  258. #if PROJ_Z
  259.     {        
  260.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  261.  
  262.         float3 normalTangentSpace;
  263.         SampleTexLayer(layerIdx, uv, specChannel, diffuseColor.xyz, specularValue, normalTangentSpace);
  264.  
  265.         worldNormal += ReorientNormal(inNormal, normalTangentSpace);
  266.     }
  267. #endif//PROJ_Z
  268. }
  269.  
  270. //sample diffuse and normal information on multiple direction proj
  271. void SampleDifNormMultiProj(sampler2D diffuseMap, sampler2D normalMap, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float4 diffuseColor, out float3 worldNormal, out float specularValue)
  272. {
  273.     diffuseColor = 0.0f;
  274.     worldNormal = 0.0f;
  275.     specularValue = 0.0f;
  276.  
  277.     float3 factorSrc = inNormal*inNormal;    
  278.     float multiplier = 0.0f;
  279. #if PROJ_X
  280.     multiplier += factorSrc.x;
  281. #endif
  282. #if PROJ_Y
  283.     multiplier += factorSrc.y;
  284. #endif
  285. #if PROJ_Z
  286.     multiplier += factorSrc.z;
  287. #endif
  288.     if(multiplier>0.0f)
  289.     {
  290.         factorSrc /= multiplier;
  291.     }
  292.  
  293. #if PROJ_X
  294.     {
  295.         float factor = abs(factorSrc.x);
  296.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  297.         
  298.         float spec;
  299.         float3 normalTangentSpace;
  300.         float4 dif;
  301.         SampleTex(diffuseMap, normalMap, uv, dif, spec, normalTangentSpace);
  302.         diffuseColor += dif*factor;
  303.         specularValue += spec*factor;
  304.  
  305.         float signValue = dot(inNormal, float3(1.0f, 0.0f, 0.0f))<0.0f?1.0f:-1.0f;
  306.  
  307.         float3 tangentBase = float3(0.0f,1.0f,0.0f);    
  308.         float3 normal = inNormal; 
  309.         float3 binormal = cross(normal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  310.         float3 tangent = cross(binormal, normal);
  311.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,normal);
  312.         worldNormal += normalize(mul(normalTangentSpace, tangentMatrix))*factor; 
  313.     }
  314. #endif//PROJ_X
  315.  
  316. #if PROJ_Y
  317.     {
  318.         float factor = abs(factorSrc.y);
  319.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  320.  
  321.         float spec;
  322.         float3 normalTangentSpace;
  323.         float4 dif;
  324.         SampleTex(diffuseMap, normalMap, uv, dif, spec, normalTangentSpace);
  325.         diffuseColor += dif*factor;
  326.         specularValue += spec*factor;
  327.  
  328.         float signValue = dot(inNormal, float3(0.0f, -1.0f, 0.0f))<0.0f?1.0f:-1.0f;        
  329.         float3 tangentBase = float3(1.0f,0.0f,0.0f);
  330.  
  331.         float3 normal = inNormal; 
  332.         float3 binormal = cross(normal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  333.         float3 tangent = cross(binormal, normal);
  334.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,normal);
  335.         worldNormal += normalize(mul(normalTangentSpace, tangentMatrix))*factor; 
  336.     }
  337. #endif//PROJ_Y
  338.  
  339. #if PROJ_Z
  340.     {
  341.         float factor = abs(factorSrc.z);
  342.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  343.  
  344.         float spec;
  345.         float3 normalTangentSpace;
  346.         float4 dif;
  347.         SampleTex(diffuseMap, normalMap, uv, dif, spec, normalTangentSpace);
  348.         diffuseColor += dif*factor;
  349.         specularValue += spec*factor;
  350.  
  351.         worldNormal += ReorientNormal(inNormal, normalTangentSpace)*factor; 
  352.     }
  353. #endif//PROJ_Z
  354.  
  355.     worldNormal = normalize(worldNormal);
  356. }
  357.  
  358.  
  359. void SampleDifNormMultiProj(int layerIdx, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float3 diffuseColor, out float3 worldNormal, out float specularValue)
  360. {
  361.     //const
  362.     float2 specChannel = selectorV.xy;
  363.  
  364.     diffuseColor = 0.0f;
  365.     worldNormal = 0.0f;
  366.     specularValue = 0.0f;
  367.  
  368.  
  369.  
  370. //#if (PROJ_X+PROJ_Y+PROJ_Z)>1
  371.     float3 factorSrc = inNormal*inNormal;    
  372.     float multiplier = 0.0f;
  373.     #if PROJ_X
  374.         multiplier += factorSrc.x;
  375.     #endif
  376.     #if PROJ_Y
  377.         multiplier += factorSrc.y;
  378.     #endif
  379.     #if PROJ_Z
  380.         multiplier += factorSrc.z;
  381.     #endif
  382.     if(multiplier>0.0f)
  383.     {
  384.         factorSrc /= multiplier;
  385.     }
  386.     else
  387.     {
  388.         factorSrc += 1.0f;
  389.     }
  390.  //#if ((PROJ_X+PROJ_Y+PROJ_Z)==1)
  391.      //factorSrc = 1.0f;
  392.  //#endif
  393.  
  394. //#else
  395. //float3 factorSrc = 1.0f;
  396. //#endif
  397.    
  398.  
  399. #if PROJ_X
  400.     {
  401.         float factor = factorSrc.x;
  402.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  403.  
  404.         float spec;
  405.         float3 normalTangentSpace;
  406.         float3 dif;
  407.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  408.  
  409.         diffuseColor += dif*factor;
  410.         specularValue += spec*factor;
  411.  
  412.         //opt for float signValue = dot(inNormal, float3(1.0f, 0.0f, 0.0f))<0.0f?1.0f:-1.0f;
  413.         float signValue = inNormal.x<0.0f ? 1.0f : -1.0f;
  414.  
  415.         //opt for 
  416.         //float3 tangentBase = float3(0.0f,1.0f,0.0f);     
  417.         //float3 binormal = cross(inNormal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  418.         float3 binormal = float3(-inNormal.z, 0.0f, inNormal.x);
  419.         float3 tangent = cross(binormal, inNormal);
  420.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,inNormal);
  421.  
  422.         //opt for
  423.         //worldNormal += normalize(mul(normalTangentSpace, tangentMatrix))*factor; 
  424.         worldNormal += mul(normalTangentSpace, tangentMatrix)*factor; 
  425.     }
  426. #endif//PROJ_X
  427.  
  428. #if PROJ_Y
  429.     {
  430.         float factor = factorSrc.y;
  431.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  432.  
  433.         float spec;
  434.         float3 normalTangentSpace;
  435.         float3 dif;
  436.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  437.  
  438.         diffuseColor += dif*factor;
  439.         specularValue += spec*factor;
  440.  
  441.         //optimize for dot(inNormal, float3(0.0f, -1.0f, 0.0f))<0.0f?1.0f:-1.0f;        
  442.         float signValue = inNormal.y>0.0f?1.0f:-1.0f;                
  443.  
  444.         //opt for
  445.         //float3 tangentBase = float3(1.0f,0.0f,0.0f);
  446.         //float3 binormal = cross(inNormal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  447.         float3 binormal = float3(0.0f, inNormal.z, -inNormal.y);
  448.         float3 tangent = cross(binormal, inNormal);
  449.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,inNormal);
  450.  
  451.         //opt for
  452.         //worldNormal += normalize(mul(normalTangentSpace, tangentMatrix))*factor; 
  453.         worldNormal += mul(normalTangentSpace, tangentMatrix)*factor; 
  454.     }
  455. #endif//PROJ_Y
  456.  
  457. #if PROJ_Z
  458.     {
  459.         float factor = factorSrc.z;
  460.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  461.  
  462.         float spec;
  463.         float3 normalTangentSpace;
  464.         float3 dif;
  465.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  466.  
  467.         diffuseColor += dif*factor;
  468.         specularValue += spec*factor;
  469.  
  470.         worldNormal +=  ReorientNormal(inNormal, normalTangentSpace)*factor; 
  471.     }
  472. #endif//PROJ_Z
  473.  
  474.     //worldNormal = normalize(worldNormal);
  475. }
  476.  
  477. void SampleDifNormMultiProjBranch(int layerIdx, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float3 diffuseColor, out float3 worldNormal, out float specularValue)
  478. {
  479.     //const
  480.     float2 specChannel = selectorV.xy;
  481.  
  482.     //default value
  483.     diffuseColor = 0.0f;
  484.     worldNormal = 0.0f;
  485.     specularValue = 0.0f;
  486.  
  487.     //proj dir
  488.     bool projX = selectorU.x>0.0f;
  489.     bool projY = selectorU.y>0.0f;
  490.     bool projZ = selectorU.z>0.0f;
  491.  
  492.     //blend factor
  493.     float3 factorSrc = inNormal*inNormal;    
  494.     float multiplier = dot(selectorU.xyz, factorSrc);
  495.  
  496.     if(multiplier>0.0f)
  497.     {
  498.         factorSrc /= multiplier;
  499.     }
  500.  
  501.     if(projX)
  502.     {
  503.         float factor = factorSrc.x;
  504.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  505.  
  506.         float spec;
  507.         float3 normalTangentSpace;
  508.         float3 dif;
  509.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  510.         diffuseColor += dif*factor;
  511.         specularValue += spec*factor;
  512.  
  513.         //opt for float signValue = dot(inNormal, float3(1.0f, 0.0f, 0.0f))<0.0f?1.0f:-1.0f;
  514.         float signValue = inNormal.x<0.0f ? 1.0f : -1.0f;
  515.                 
  516.         //opt for 
  517.         //float3 tangentBase = float3(0.0f,1.0f,0.0f);     
  518.         //float3 binormal = cross(normal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  519.         float3 binormal = float3(-inNormal.z, 0.0f, inNormal.x);
  520.         float3 tangent = cross(binormal, inNormal);
  521.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,inNormal);
  522.         
  523.         //opt for
  524.         //worldNormal += normalize(mul(normalTangentSpace, tangentMatrix))*factor; 
  525.         worldNormal += mul(normalTangentSpace, tangentMatrix)*factor; 
  526.     }
  527.  
  528.     if(projY)
  529.     {
  530.         float factor = factorSrc.y;
  531.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  532.  
  533.         float spec;
  534.         float3 normalTangentSpace;
  535.         float3 dif;
  536.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  537.         diffuseColor += dif*factor;
  538.         specularValue += spec*factor;
  539.  
  540.         //optimize for dot(inNormal, float3(0.0f, -1.0f, 0.0f))<0.0f?1.0f:-1.0f;        
  541.         float signValue = inNormal.y>0.0f?1.0f:-1.0f;                
  542.  
  543.         //opt for
  544.         //float3 tangentBase = float3(1.0f,0.0f,0.0f);
  545.         //opt for float3 binormal = cross(normal, tangentBase);    //need to reverse the cross factor of tangent and normal, as the v dir is the reverse of y dirs
  546.         float3 binormal = float3(inNormal.y, -inNormal.x, 0.0f);
  547.         float3 tangent = cross(binormal, inNormal);
  548.         float3x3 tangentMatrix = float3x3(tangent,binormal*signValue,inNormal);
  549.  
  550.         //opt for
  551.         //worldNormal += normalize(mul(normalTangentSpace, tangentMatrix))*factor; 
  552.         worldNormal += mul(normalTangentSpace, tangentMatrix)*factor; 
  553.     }
  554.     
  555.     if(projZ)
  556.     {
  557.         float factor = factorSrc.z;
  558.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  559.  
  560.         float spec;
  561.         float3 normalTangentSpace;
  562.         float3 dif;
  563.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  564.         diffuseColor += dif*factor;
  565.         specularValue += spec*factor;
  566.                 
  567.         worldNormal +=  ReorientNormal(inNormal, normalTangentSpace)*factor; 
  568.     }
  569.  
  570.     //opt
  571.     //worldNormal = normalize(worldNormal);
  572. }
  573.  
  574. float3 SampleTerrainWorldSpaceNormal(sampler2D normMap, float2 uv)
  575. {
  576.     float4 normalInfo = tex2D(normMap, MipMapLinearClamp, uv);
  577.  
  578. #if DXT5N_NORMAL
  579.     float3 result;    
  580.     result.xy = normalInfo.ag*2.0f-1.0f;
  581.     result.z = sqrt(max(1.0f-dot(result.xy,result.xy),0.0f));    
  582.     return result;
  583. #else
  584.     return normalInfo.xyz*2.0f-1.0f;    
  585. #endif
  586. }
  587.  
  588. void SampleDif(int layerIdx, float3 uvw, float4 selectorU, out float3 diffuseColor)
  589. {
  590.     float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  591.     SampleTex(layerIdx, uv, diffuseColor);
  592. }
  593.  
  594. void SampleDif3Dir(int layerIdx, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float3 diffuseColor)
  595. {
  596.     //default value
  597.     diffuseColor = 0.0f;
  598.  
  599.     //proj dir
  600.     bool projX = selectorU.x>0.0f;
  601.     bool projY = selectorU.y>0.0f;
  602.     bool projZ = selectorU.z>0.0f;
  603.  
  604.     //blend factor
  605.     float3 factorSrc = selectorU.xyz;
  606.     if(selectorU.x+selectorU.y+selectorU.z>1.0f)
  607.     {
  608.         factorSrc = inNormal*inNormal;    
  609.         float multiplier = dot(selectorU.xyz, factorSrc);
  610.  
  611.         if(multiplier>0.0f)
  612.         {
  613.             factorSrc /= multiplier;
  614.         }
  615.     }
  616.  
  617.     if(projX)
  618.     {
  619.         float factor = factorSrc.x;
  620.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  621.  
  622.         float3 dif;
  623.         SampleTex(layerIdx, uv, dif);
  624.         diffuseColor += dif*factor;
  625.     }
  626.  
  627.     if(projY)
  628.     {
  629.         float factor = factorSrc.y;
  630.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  631.  
  632.         float3 dif;
  633.         SampleTex(layerIdx, uv, dif);
  634.         diffuseColor += dif*factor;        
  635.     }
  636.  
  637.     if(projZ)
  638.     {
  639.         float factor = factorSrc.z;
  640.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  641.  
  642.         float3 dif;
  643.         SampleTex(layerIdx, uv, dif);
  644.         diffuseColor += dif*factor;   
  645.     }
  646. }
  647.  
  648. void SampleDif(int layerIdx, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float3 diffuseColor)
  649. {
  650.     //default value
  651.     diffuseColor = 0.0f;
  652.  
  653.     //blend factor
  654.     float3 factorSrc = inNormal*inNormal;    
  655.     float multiplier = 0.0f;
  656. #if PROJ_X
  657.     multiplier += factorSrc.x;
  658. #endif
  659. #if PROJ_Y
  660.     multiplier += factorSrc.y;
  661. #endif
  662. #if PROJ_Z
  663.     multiplier += factorSrc.z;
  664. #endif
  665.  
  666.     if(multiplier>0.0f)
  667.     {
  668.         factorSrc /= multiplier;
  669.     }
  670.  
  671. #if PROJ_X
  672.     {
  673.         float factor = factorSrc.x;
  674.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  675.  
  676.         float3 dif;
  677.         SampleTex(layerIdx, uv, dif);
  678.         diffuseColor += dif*factor;
  679.     }
  680. #endif
  681.  
  682. #if PROJ_Y
  683.     {
  684.         float factor = factorSrc.y;
  685.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  686.  
  687.         float3 dif;
  688.         SampleTex(layerIdx, uv, dif);
  689.         diffuseColor += dif*factor;        
  690.     }
  691. #endif
  692.  
  693. #if PROJ_Z
  694.     {
  695.         float factor = factorSrc.z;
  696.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  697.  
  698.         float3 dif;
  699.         SampleTex(layerIdx, uv, dif);
  700.         diffuseColor += dif*factor;   
  701.     }
  702. #endif
  703. }
  704.  
  705. void SampleDifSpec3Dir(int layerIdx, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float3 diffuseColor, out float specularValue)
  706. {
  707.     float2 specChannel = selectorV.xy;
  708.  
  709.     //default value
  710.     diffuseColor = 0.0f;
  711.     specularValue = 0.0f;
  712.  
  713.     //proj dir
  714.     bool projX = selectorU.x>0.0f;
  715.     bool projY = selectorU.y>0.0f;
  716.     bool projZ = selectorU.z>0.0f;
  717.  
  718.     //blend factor
  719.     float3 factorSrc = selectorU.xyz;
  720.     if(selectorU.x+selectorU.y+selectorU.z>1.0f)
  721.     {
  722.         factorSrc = inNormal*inNormal;    
  723.         float multiplier = dot(selectorU.xyz, factorSrc);
  724.  
  725.         if(multiplier>0.0f)
  726.         {
  727.             factorSrc /= multiplier;
  728.         }
  729.     }
  730.  
  731.     if(projX)
  732.     {
  733.         float factor = factorSrc.x;
  734.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  735.  
  736.         float3 dif;
  737.         float3 normalTangentSpace;        
  738.         float spec;
  739.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  740.         diffuseColor += dif * factor;
  741.         specularValue += spec * factor;
  742.     }
  743.  
  744.     if(projY)
  745.     {
  746.         float factor = factorSrc.y;
  747.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  748.  
  749.         float3 dif;
  750.         float3 normalTangentSpace;        
  751.         float spec;
  752.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  753.         
  754.         diffuseColor += dif*factor;  
  755.         specularValue += spec * factor;
  756.     }
  757.  
  758.     if(projZ)
  759.     {
  760.         float factor = factorSrc.z;
  761.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.y*selectorU.w);
  762.  
  763.         float3 dif;
  764.         float3 normalTangentSpace;        
  765.         float spec;
  766.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  767.  
  768.         diffuseColor += dif*factor;  
  769.         specularValue += spec * factor;
  770.     }
  771. }
  772.  
  773. void SampleDifSpec(int layerIdx, float3 uvw, float3 inNormal, float4 selectorU, float4 selectorV, out float3 diffuseColor, out float specularValue)
  774. {
  775.     float2 specChannel = selectorV.xy ; 
  776.  
  777.     //default value
  778.     diffuseColor = 0.0f;
  779.     specularValue = 0.0f;
  780.  
  781.     //blend factor
  782.     float3 factorSrc = inNormal*inNormal;    
  783.     float multiplier = 0.0f;
  784. #if PROJ_X
  785.     multiplier += factorSrc.x;
  786. #endif
  787. #if PROJ_Y
  788.     multiplier += factorSrc.y;
  789. #endif
  790. #if PROJ_Z
  791.     multiplier += factorSrc.z;
  792. #endif
  793.  
  794.     if(multiplier>0.0f)
  795.     {
  796.         factorSrc /= multiplier;
  797.     }
  798.  
  799. #if PROJ_X
  800.     {
  801.         float factor = factorSrc.x;
  802.         float2 uv = float2(uvw.y*selectorU.w, 1.0f-uvw.z*selectorV.w);
  803.  
  804.         float3 dif;
  805.         float3 normalTangentSpace;        
  806.         float spec;
  807.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  808.  
  809.         diffuseColor += dif*factor;  
  810.         specularValue += spec * factor;
  811.     }
  812. #endif
  813.  
  814. #if PROJ_Y
  815.     {
  816.         float factor = factorSrc.y;
  817.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  818.  
  819.         float3 dif;
  820.         float3 normalTangentSpace;        
  821.         float spec;
  822.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  823.  
  824.         diffuseColor += dif*factor;  
  825.         specularValue += spec * factor;    
  826.     }
  827. #endif
  828.  
  829. #if PROJ_Z
  830.     {
  831.         float factor = factorSrc.z;
  832.         float2 uv = float2(uvw.x*selectorU.w, 1.0f-uvw.z*selectorV.w);
  833.  
  834.         float3 dif;
  835.         float3 normalTangentSpace;        
  836.         float spec;
  837.         SampleTexLayer(layerIdx, uv, specChannel, dif, spec, normalTangentSpace);
  838.  
  839.         diffuseColor += dif*factor;  
  840.         specularValue += spec * factor;
  841.     }
  842. #endif
  843. }
  844.  
  845. void ApplyLowResDif(inout float3 color, float2 uv)
  846. {    
  847.     float lowResFactor = MaterialLodInfo.w;
  848.     color *= tex2D(LowResDiffuseMap, MipMapLinearBorderW, uv).xyz * lowResFactor;
  849. }
  850.  
  851. #endif//QSSHADER_TerrainMaterial_H
  852.  
  853.