Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

ShadowProjectVertex.hlsl 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #if !defined(SHADOW_PROJECT_VERTEX)
  2. #define SHADOW_PROJECT_VERTEX
  3. #define ToFloat(x) x
  4. #define Deg2Rad(x) (x * 3.14159265359f / 180)
  5. #define MIN_SHADOW_Y 0.000001f
  6. struct Attributes
  7. {
  8. float3 vertex : POSITION;
  9. float4 packed0 : TANGENT;
  10. };
  11. struct Varyings
  12. {
  13. float4 vertex : SV_POSITION;
  14. float2 shadow : TEXCOORD0;
  15. };
  16. uniform float3 _LightPos;
  17. uniform float4x4 _ShadowModelMatrix; // This is a custom model matrix without scaling
  18. uniform float4x4 _ShadowModelInvMatrix;
  19. uniform float3 _ShadowModelScale; // This is the scale
  20. uniform float _ShadowRadius;
  21. uniform float _ShadowContractionDistance;
  22. uniform float _SoftShadowAngle;
  23. float AngleFromDir(float3 dir)
  24. {
  25. // Assumes dir is normalized. Will return -180 to 180
  26. float angle = acos(dir.x);
  27. float gt180 = ceil(saturate(-dir.y)); // Greater than 180
  28. return gt180 * -angle + (1 - gt180) * angle;
  29. }
  30. float3 DirFromAngle(float angle)
  31. {
  32. return float3(cos(angle), sin(angle), 0);
  33. }
  34. float2 CalculateShadowValue(float shadowType)
  35. {
  36. float isLeft = ToFloat(shadowType == 1);
  37. float isRight = ToFloat(shadowType == 3);
  38. return float2(-isLeft + isRight, isLeft + isRight);
  39. }
  40. float3 SoftShadowDir(float3 lightDir, float3 vertex0, float3 vertex1, float angleOp, float softShadowAngle)
  41. {
  42. float lightAngle = AngleFromDir(lightDir);
  43. float edgeAngle = AngleFromDir(normalize(vertex1 - vertex0));
  44. float softAngle = lightAngle + angleOp * softShadowAngle;
  45. return DirFromAngle(softAngle);
  46. }
  47. float4 ProjectShadowVertexToWS(float2 vertex, float2 otherEndPt, float2 contractDir, float shadowType, float3 lightPos, float3 shadowModelScale, float4x4 shadowModelMatrix, float4x4 shadowModelInvMatrix, float shadowContractionDistance, float shadowRadius, float softShadowAngle)
  48. {
  49. float3 vertexOS0 = float3(vertex.x * shadowModelScale.x, vertex.y * shadowModelScale.y, 0);
  50. float3 vertexOS1 = float3(otherEndPt.x * shadowModelScale.x, otherEndPt.y * shadowModelScale.y, 0); // the tangent has the adjacent point stored in zw
  51. float3 lightPosOS = float3(mul(shadowModelInvMatrix, float4(lightPos.x, lightPos.y, lightPos.z, 1)).xy, 0); // Transform the light into local space
  52. float3 unnormalizedLightDir0 = vertexOS0 - lightPosOS;
  53. float3 unnormalizedLightDir1 = vertexOS1 - lightPosOS;
  54. float3 lightDir0 = normalize(unnormalizedLightDir0);
  55. float3 lightDir1 = normalize(unnormalizedLightDir1);
  56. float3 avgLightDir = normalize(lightDir0 + lightDir1);
  57. float isSoftShadow = ToFloat(shadowType >= 1);
  58. float isHardShadow = ToFloat(shadowType == 0);
  59. float isShadowVertex = saturate(isSoftShadow + isHardShadow);
  60. float3 softShadowDir = SoftShadowDir(lightDir0, vertexOS0, vertexOS1, shadowType - 2, softShadowAngle);
  61. float3 hardShadowDir = lightDir0;
  62. float3 shadowDir = isSoftShadow * softShadowDir + isHardShadow * hardShadowDir;
  63. float lightDistance = length(unnormalizedLightDir0);
  64. float hardShadowLength = max(shadowRadius / dot(lightDir0, avgLightDir), lightDistance);
  65. float softShadowLength = shadowRadius * (1 / cos(softShadowAngle));
  66. // Tests to make sure the light is between 0-90 degrees to the normal. Will be one if it is, zero if not.
  67. float3 shadowOffset = (isSoftShadow * softShadowLength + isHardShadow * hardShadowLength) * shadowDir;
  68. float3 contractedVertexPos = vertexOS0 + float3(shadowContractionDistance * contractDir.xy, 0);
  69. // If we are suppose to extrude this point, then
  70. float3 finalVertexOS = isShadowVertex * (lightPosOS + shadowOffset) + (1 - isShadowVertex) * contractedVertexPos;
  71. return mul(shadowModelMatrix, float4(finalVertexOS, 1));
  72. }
  73. Varyings ProjectShadow(Attributes v)
  74. {
  75. Varyings o;
  76. float2 otherEndPt = v.packed0.zw;
  77. float shadowType = v.packed0.x;
  78. float2 position = v.vertex.xy;
  79. float softShadowAngle = _SoftShadowAngle;
  80. float2 contractDir = 0;
  81. float4 positionWS = ProjectShadowVertexToWS(position, otherEndPt, contractDir, shadowType, _LightPos, _ShadowModelScale, _ShadowModelMatrix, _ShadowModelInvMatrix, _ShadowContractionDistance, _ShadowRadius, softShadowAngle);
  82. o.vertex = mul(GetWorldToHClipMatrix(), positionWS);
  83. o.shadow = CalculateShadowValue(shadowType);
  84. return o;
  85. }
  86. #endif