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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
/*
* Copyright (C) 2005-2015 Team XBMC
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*
*/
texture2D g_Texture;
texture2D g_KernelTexture;
float4 g_StepXY;
float2 g_viewPort;
SamplerState RGBSampler : IMMUTABLE
{
AddressU = CLAMP;
AddressV = CLAMP;
Filter = MIN_MAG_POINT_MIP_LINEAR;
};
SamplerState KernelSampler : IMMUTABLE
{
AddressU = CLAMP;
AddressV = CLAMP;
Filter = MIN_MAG_MIP_LINEAR;
};
struct VS_INPUT
{
float4 Position : POSITION;
float2 TextureUV : TEXCOORD0;
};
struct VS_OUTPUT
{
float2 TextureUV : TEXCOORD0;
float4 Position : SV_POSITION;
};
//
// VS for rendering in screen space
//
VS_OUTPUT VS(VS_INPUT In)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Position.x = (In.Position.x / (g_viewPort.x / 2.0)) - 1;
output.Position.y = -(In.Position.y / (g_viewPort.y / 2.0)) + 1;
output.Position.z = output.Position.z;
output.Position.w = 1.0;
output.TextureUV = In.TextureUV;
return output;
}
inline half4 weight(float pos)
{
#ifdef HAS_RGBA
half4 w = g_KernelTexture.Sample(KernelSampler, pos);
#else
half4 w = g_KernelTexture.Sample(KernelSampler, pos).bgra;
#endif
#ifndef HAS_FLOAT_TEXTURE
w = w * 2.0 - 1.0;
#endif
return w;
}
inline half3 pixel(float xpos, float ypos)
{
return g_Texture.Sample(RGBSampler, float2(xpos, ypos)).rgb;
}
// Code for first pass - horizontal
inline half3 getLine(float ypos, float4 xpos, half4 linetaps)
{
return
pixel(xpos.r, ypos) * linetaps.r +
pixel(xpos.g, ypos) * linetaps.g +
pixel(xpos.b, ypos) * linetaps.b +
pixel(xpos.a, ypos) * linetaps.a;
}
float4 CONVOLUTION4x4Horiz(in float2 TextureUV : TEXCOORD0) : SV_TARGET
{
float2 f = frac(TextureUV / g_StepXY.xy + 0.5);
half4 linetaps = weight(1.0 - f.x);
// kernel generation code made sure taps add up to 1, no need to adjust here.
float xystart = (-1.0 - f.x) * g_StepXY.x + TextureUV.x;
float4 xpos = xystart + g_StepXY.x * float4(0.0, 1.0, 2.0, 3.0);
return float4(getLine(TextureUV.y, xpos, linetaps), 1.0f);
}
// Code for second pass - vertical
inline half3 getRow(float xpos, float4 ypos, half4 columntaps)
{
return
pixel(xpos, ypos.r) * columntaps.r +
pixel(xpos, ypos.g) * columntaps.g +
pixel(xpos, ypos.b) * columntaps.b +
pixel(xpos, ypos.a) * columntaps.a;
}
float4 CONVOLUTION4x4Vert(in float2 TextureUV : TEXCOORD0) : SV_TARGET
{
float2 f = frac(TextureUV / g_StepXY.zw + 0.5);
half4 columntaps = weight(1.0 - f.y);
// kernel generation code made sure taps add up to 1, no need to adjust here.
float xystart = (-1.0 - f.y) * g_StepXY.w + TextureUV.y;
float4 ypos = xystart + g_StepXY.w * float4(0.0, 1.0, 2.0, 3.0);
return float4(getRow(TextureUV.x, ypos, columntaps), 1.0f);
}
technique11 SCALER_T
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0_level_9_1, VS() ) );
SetPixelShader( CompileShader( ps_4_0_level_9_3, CONVOLUTION4x4Horiz() ) );
}
pass P1
{
SetVertexShader( CompileShader( vs_4_0_level_9_1, VS() ) );
SetPixelShader( CompileShader( ps_4_0_level_9_3, CONVOLUTION4x4Vert() ) );
}
};
|