SpineEffectNormalmap.fx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. float4x4 World;
  2. float4x4 View;
  3. float4x4 Projection;
  4. // Light0 parameters.
  5. // Default values set below, change them via spineEffect.Parameters["Light0_Direction"] and similar.
  6. float3 Light0_Direction = float3(-0.5265408f, -0.5735765f, -0.6275069f);
  7. float3 Light0_Diffuse = float3(1, 1, 1);
  8. float3 Light0_Specular = float3(1, 1, 1);
  9. float Light0_SpecularExponent = 2.0; // also called "shininess", "specular hardness"
  10. sampler TextureSampler : register(s0);
  11. sampler NormalmapSampler : register(s1);
  12. // TODO: add effect parameters here.
  13. float NormalmapIntensity = 1;
  14. float3 GetNormal(sampler normalmapSampler, float2 uv, float3 worldPos, float3 vertexNormal)
  15. {
  16. // Reconstruct tangent space TBN matrix
  17. float3 pos_dx = ddx(worldPos);
  18. float3 pos_dy = ddy(worldPos);
  19. float3 tex_dx = float3(ddx(uv), 0.0);
  20. float3 tex_dy = float3(ddy(uv), 0.0);
  21. float divisor = (tex_dx.x * tex_dy.y - tex_dy.x * tex_dx.y);
  22. float3 t = (tex_dy.y * pos_dx - tex_dx.y * pos_dy) / divisor;
  23. float divisorBinormal = (tex_dy.y * tex_dx.x - tex_dx.y * tex_dy.x);
  24. float3 b = (tex_dx.x * pos_dy - tex_dy.x * pos_dx) / divisorBinormal;
  25. t = normalize(t - vertexNormal * dot(vertexNormal, t));
  26. b = normalize(b - vertexNormal * dot(vertexNormal, b));
  27. float3x3 tbn = float3x3(t, b, vertexNormal);
  28. float3 n = 2.0 * tex2D(normalmapSampler, uv).rgb - 1.0;
  29. #ifdef INVERT_NORMALMAP_Y
  30. n.y = -n.y;
  31. #endif
  32. n = normalize(mul(n * float3(NormalmapIntensity, NormalmapIntensity, 1.0), tbn));
  33. return n;
  34. }
  35. void GetLightContributionBlinnPhong(inout float3 diffuseResult, inout float3 specularResult,
  36. float3 lightDirection, float3 lightDiffuse, float3 lightSpecular, float specularExponent, float3 normal, float3 viewDirection)
  37. {
  38. diffuseResult += lightDiffuse * max(0.0, dot(normal, -lightDirection));
  39. half3 halfVector = normalize(-lightDirection + viewDirection);
  40. float nDotH = max(0, dot(normal, halfVector));
  41. specularExponent = max(0.00001, specularExponent); // prevent fx compiler error at pow() below
  42. specularResult += lightSpecular * pow(nDotH, specularExponent);
  43. }
  44. struct VertexShaderInput
  45. {
  46. float4 Position : POSITION0;
  47. float4 Color : COLOR0;
  48. float4 TextureCoordinate : TEXCOORD0;
  49. float4 Color2 : COLOR1;
  50. };
  51. struct VertexShaderOutput
  52. {
  53. float4 Position : POSITION0;
  54. float4 Color : COLOR0;
  55. float4 TextureCoordinate : TEXCOORD0;
  56. float4 Color2 : COLOR1;
  57. float3 WorldNormal : TEXCOORD1;
  58. float4 WorldPosition : TEXCOORD2; // for tangent reconstruction
  59. };
  60. VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
  61. {
  62. VertexShaderOutput output;
  63. float4 worldPosition = mul(input.Position, World);
  64. float4 viewPosition = mul(worldPosition, View);
  65. output.Position = mul(viewPosition, Projection);
  66. output.TextureCoordinate = input.TextureCoordinate;
  67. output.Color = input.Color;
  68. output.Color2 = input.Color2;
  69. output.WorldNormal = mul(transpose(View), float4(0, 0, 1, 0)).xyz;
  70. output.WorldPosition = worldPosition;
  71. return output;
  72. }
  73. float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
  74. {
  75. float4 texColor = tex2D(TextureSampler, input.TextureCoordinate);
  76. float3 normal = GetNormal(NormalmapSampler, input.TextureCoordinate, input.WorldPosition, input.WorldNormal);
  77. float3 viewDirection = -input.WorldNormal;
  78. float alpha = texColor.a * input.Color.a;
  79. float4 output;
  80. output.a = alpha;
  81. output.rgb = ((texColor.a - 1.0) * input.Color2.a + 1.0 - texColor.rgb) * input.Color2.rgb + texColor.rgb * input.Color.rgb;
  82. float3 diffuseLight = float3(0, 0, 0);
  83. float3 specularLight = float3(0, 0, 0);
  84. GetLightContributionBlinnPhong(diffuseLight, specularLight,
  85. Light0_Direction, Light0_Diffuse, Light0_Specular, Light0_SpecularExponent, normal, viewDirection);
  86. output.rgb = diffuseLight * output.rgb + specularLight;
  87. return output;
  88. }
  89. technique Technique1
  90. {
  91. pass Pass1
  92. {
  93. // TODO: set renderstates here.
  94. VertexShader = compile vs_3_0 VertexShaderFunction();
  95. PixelShader = compile ps_3_0 PixelShaderFunction();
  96. }
  97. }