1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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;
}
|