summaryrefslogtreecommitdiffstatshomepage
path: root/hlsl/downsample.fx
blob: 3afcdc703dd2a95d166d461be15937945987fb8f (plain) (blame)
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
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Downsample Effect
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Sampler Definitions
//-----------------------------------------------------------------------------

texture DiffuseTexture;

sampler DiffuseSampler = sampler_state
{
	Texture = <DiffuseTexture>;
	MipFilter = LINEAR;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	AddressU = CLAMP;
	AddressV = CLAMP;
	AddressW = CLAMP;
};

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

struct VS_OUTPUT
{
	float4 Position : POSITION;
	float4 Color : COLOR0;
	float4 TexCoord01 : TEXCOORD0;
	float4 TexCoord23 : TEXCOORD1;
};

struct VS_INPUT
{
	float4 Position : POSITION;
	float4 Color : COLOR0;
	float2 TexCoord : TEXCOORD0;
};

struct PS_INPUT
{
	float4 Color : COLOR0;
	float4 TexCoord01 : TEXCOORD0;
	float4 TexCoord23 : TEXCOORD1;
};

//-----------------------------------------------------------------------------
// Downsample Vertex Shader
//-----------------------------------------------------------------------------

uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 SourceDims;
uniform float2 SourceRect;
uniform float2 QuadDims;

uniform bool VectorScreen;

static const float2 Coord0Offset = float2(-0.5f, -0.5f);
static const float2 Coord1Offset = float2( 0.5f, -0.5f);
static const float2 Coord2Offset = float2(-0.5f,  0.5f);
static const float2 Coord3Offset = float2( 0.5f,  0.5f);

VS_OUTPUT vs_main(VS_INPUT Input)
{
	VS_OUTPUT Output = (VS_OUTPUT)0;

	float2 TargetTexelDims = 1.0f / TargetDims;
	float2 ScreenTexelDims = 1.0f / ScreenDims;
	float2 SourceTexelDims = 1.0f / SourceDims;

	Output.Position = float4(Input.Position.xyz, 1.0f);
	Output.Position.xy /= ScreenDims;
	Output.Position.y = 1.0f - Output.Position.y; // flip y
	Output.Position.xy -= 0.5f; // center
	Output.Position.xy *= 2.0f; // zoom

	Output.Color = Input.Color;

	float2 TexCoord = Input.Position.xy / ScreenDims;
	TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)

	float2 VectorTexelOffset = ScreenTexelDims * -0.5;
	float2 RasterTexelOffset = SourceTexelDims * (0.5f * SourceRect) * (1.0f - (QuadDims / ScreenDims));

	TexCoord += VectorScreen 
		? VectorTexelOffset
		: RasterTexelOffset;

	Output.TexCoord01.xy = TexCoord + Coord0Offset * TargetTexelDims;
	Output.TexCoord01.zw = TexCoord + Coord1Offset * TargetTexelDims;
	Output.TexCoord23.xy = TexCoord + Coord2Offset * TargetTexelDims;
	Output.TexCoord23.zw = TexCoord + Coord3Offset * TargetTexelDims;

	return Output;
}

//-----------------------------------------------------------------------------
// Downsample Pixel Shader
//-----------------------------------------------------------------------------

float4 ps_main(PS_INPUT Input) : COLOR
{
	float3 texel0 = tex2D(DiffuseSampler, Input.TexCoord01.xy).rgb;
	float3 texel1 = tex2D(DiffuseSampler, Input.TexCoord01.zw).rgb;
	float3 texel2 = tex2D(DiffuseSampler, Input.TexCoord23.xy).rgb;
	float3 texel3 = tex2D(DiffuseSampler, Input.TexCoord23.zw).rgb;

	float3 outTexel = (texel0 + texel1 + texel2 + texel3) / 4.0;

	return float4(outTexel, 1.0f);
}

//-----------------------------------------------------------------------------
// Downsample Technique
//-----------------------------------------------------------------------------

technique DefaultTechnique
{
	pass Pass0
	{
		Lighting = FALSE;

		VertexShader = compile vs_2_0 vs_main();
		PixelShader = compile ps_2_0 ps_main();
	}
}