diff options
Diffstat (limited to 'src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl')
-rw-r--r-- | src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl | 77 |
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; +} |