aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl')
-rw-r--r--src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl b/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl
new file mode 100644
index 0000000000..05b1c6e9d4
--- /dev/null
+++ b/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl
@@ -0,0 +1,77 @@
+struct VSInput
+{
+ float4 position : POSITION;
+ float2 coord : TEXCOORD0;
+ float2 offset : TEXCOORD1;
+ float2 coordOffset : TEXCOORD2;
+};
+
+cbuffer ConstantBuffer : register(b0)
+{
+ float4x4 mvp;
+ float opacity;
+ float2 pixelSize;
+};
+
+struct PSInput
+{
+ float4 position : SV_POSITION;
+ float2 coord : TEXCOORD0;
+ float vertexOpacity : TEXCOORD3;
+};
+
+Texture2D tex : register(t0);
+SamplerState samp : register(s0);
+
+PSInput VS_SmoothTexture(VSInput input)
+{
+ PSInput result;
+
+ float4 pos = mul(mvp, input.position);
+ float2 coord = input.coord;
+
+ if (input.offset.x != 0.0) {
+ // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL).
+ float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x;
+ float2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ pos += scale * delta;
+ coord.x += scale * input.coordOffset.x;
+ }
+
+ if (input.offset.y != 0.0) {
+ float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y;
+ float2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ pos += scale * delta;
+ coord.y += scale * input.coordOffset.y;
+ }
+
+ if ((input.offset.x != 0.0 || input.offset.y != 0.0) && (input.coordOffset.x == 0.0 && input.coordOffset.y == 0.0))
+ result.vertexOpacity = 0.0;
+ else
+ result.vertexOpacity = opacity;
+
+ result.position = pos;
+ result.coord = coord;
+ return result;
+}
+
+float4 PS_SmoothTexture(PSInput input) : SV_TARGET
+{
+ return tex.Sample(samp, input.coord) * input.vertexOpacity;
+}