SpineEffectNormalmap.fx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. specularResult += lightSpecular * pow(nDotH, specularExponent);
  42. }
  43. struct VertexShaderInput
  44. {
  45. float4 Position : POSITION0;
  46. float4 Color : COLOR0;
  47. float4 TextureCoordinate : TEXCOORD0;
  48. float4 Color2 : COLOR1;
  49. };
  50. struct VertexShaderOutput
  51. {
  52. float4 Position : POSITION0;
  53. float4 Color : COLOR0;
  54. float4 TextureCoordinate : TEXCOORD0;
  55. float4 Color2 : COLOR1;
  56. float3 WorldNormal : TEXCOORD1;
  57. float4 WorldPosition : TEXCOORD2; // for tangent reconstruction
  58. };
  59. VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
  60. {
  61. VertexShaderOutput output;
  62. float4 worldPosition = mul(input.Position, World);
  63. float4 viewPosition = mul(worldPosition, View);
  64. output.Position = mul(viewPosition, Projection);
  65. output.TextureCoordinate = input.TextureCoordinate;
  66. output.Color = input.Color;
  67. output.Color2 = input.Color2;
  68. output.WorldNormal = mul(transpose(View), float4(0, 0, 1, 0)).xyz;
  69. output.WorldPosition = worldPosition;
  70. return output;
  71. }
  72. float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
  73. {
  74. float4 texColor = tex2D(TextureSampler, input.TextureCoordinate);
  75. float3 normal = GetNormal(NormalmapSampler, input.TextureCoordinate, input.WorldPosition, input.WorldNormal);
  76. float3 viewDirection = -input.WorldNormal;
  77. float alpha = texColor.a * input.Color.a;
  78. float4 output;
  79. output.a = alpha;
  80. output.rgb = ((texColor.a - 1.0) * input.Color2.a + 1.0 - texColor.rgb) * input.Color2.rgb + texColor.rgb * input.Color.rgb;
  81. float3 diffuseLight = float3(0, 0, 0);
  82. float3 specularLight = float3(0, 0, 0);
  83. GetLightContributionBlinnPhong(diffuseLight, specularLight,
  84. Light0_Direction, Light0_Diffuse, Light0_Specular, Light0_SpecularExponent, normal, viewDirection);
  85. output.rgb = diffuseLight * output.rgb + specularLight;
  86. return output;
  87. }
  88. technique Technique1
  89. {
  90. pass Pass1
  91. {
  92. // TODO: set renderstates here.
  93. VertexShader = compile vs_3_0 VertexShaderFunction();
  94. PixelShader = compile ps_3_0 PixelShaderFunction();
  95. }
  96. }