SpriteLine.bsl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. Technique =
  2. {
  3. Language = "HLSL11";
  4. Pass =
  5. {
  6. Target =
  7. {
  8. Blend = true;
  9. Color = { SRCA, SRCIA, ADD };
  10. WriteMask = RGB;
  11. };
  12. DepthRead = false;
  13. DepthWrite = false;
  14. Common =
  15. {
  16. struct VStoFS
  17. {
  18. float4 position : SV_POSITION;
  19. float2 uv : TEXCOORD0;
  20. float3 screenAndLinePos : TEXCOORD1;
  21. };
  22. };
  23. Vertex =
  24. {
  25. float invViewportWidth;
  26. float invViewportHeight;
  27. float4x4 worldTransform;
  28. struct VertexInput
  29. {
  30. float2 position : POSITION;
  31. float2 uv : TEXCOORD0;
  32. uint vertexIdx : SV_VERTEXID;
  33. };
  34. VStoFS main(VertexInput input)
  35. {
  36. float4 tfrmdPos = mul(worldTransform, float4(input.position, 0, 1));
  37. float tfrmdX = -1.0f + (tfrmdPos.x * invViewportWidth);
  38. float tfrmdY = 1.0f - (tfrmdPos.y * invViewportHeight);
  39. VStoFS output;
  40. output.position = float4(tfrmdX, tfrmdY, 0, 1);
  41. output.uv = input.uv;
  42. output.screenAndLinePos.xy = input.position;
  43. uint segmentIdx = input.vertexIdx / 2;
  44. output.screenAndLinePos.z = (float)segmentIdx;
  45. return output;
  46. }
  47. };
  48. Fragment =
  49. {
  50. StructuredBuffer<float2> linePoints;
  51. float lineWidth;
  52. float4 tint;
  53. float getSquaredDistanceToLine(float2 a, float2 b, float2 pt)
  54. {
  55. float2 lineDiff = b - a;
  56. float sqrdLineLength = dot(lineDiff, lineDiff);
  57. float2 pointDiff = pt - a;
  58. if(sqrdLineLength < 0.0001f) // a == b
  59. return dot(pointDiff, pointDiff);
  60. else
  61. {
  62. float t = clamp(dot(pointDiff, lineDiff / sqrdLineLength), 0, 1);
  63. float2 projPoint = a + lineDiff * t;
  64. float2 toLineDiff = projPoint - pt;
  65. return dot(toLineDiff, toLineDiff);
  66. }
  67. }
  68. float4 main(VStoFS input) : SV_Target
  69. {
  70. // Get number of lines
  71. uint numPoints;
  72. uint dummy;
  73. linePoints.GetDimensions(numPoints, dummy);
  74. uint numLines = numPoints / 2 - 1;
  75. // Find nearest line
  76. //// Distance to current line
  77. ///// This will get interpolated between two nearest line segments, truncate to get the line index
  78. int lineIdx = (int)input.screenAndLinePos.z;
  79. float2 a = linePoints.Load(lineIdx * 2 + 0);
  80. float2 b = linePoints.Load(lineIdx * 2 + 1);
  81. float minSquaredDistance = getSquaredDistanceToLine(a, b, input.screenAndLinePos.xy);
  82. //// Distance to previous line
  83. int prevLineIdx = max(0, lineIdx - 1);
  84. a = linePoints.Load(prevLineIdx * 2 + 0);
  85. b = linePoints.Load(prevLineIdx * 2 + 1);
  86. minSquaredDistance = min(minSquaredDistance, getSquaredDistanceToLine(a, b, input.screenAndLinePos.xy));
  87. //// Distance to next line
  88. int nextLineIdx = min((int)numPoints - 1, lineIdx + 1);
  89. a = linePoints.Load(nextLineIdx * 2 + 0);
  90. b = linePoints.Load(nextLineIdx * 2 + 1);
  91. minSquaredDistance = min(minSquaredDistance, getSquaredDistanceToLine(a, b, input.screenAndLinePos.xy));
  92. // TODO - Use a different filter like Gaussian
  93. float weight = clamp(minSquaredDistance / (lineWidth * lineWidth), 0, 1);
  94. return float4(tint.rgb, tint.a * weight);
  95. }
  96. };
  97. };
  98. };
  99. Technique =
  100. {
  101. Language = "HLSL9";
  102. Pass =
  103. {
  104. // TODO
  105. };
  106. };
  107. Technique =
  108. {
  109. Language = "GLSL";
  110. Pass =
  111. {
  112. // TODO
  113. };
  114. };