forked from microsoft/terminal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshader_ps.hlsl
156 lines (146 loc) · 5.46 KB
/
shader_ps.hlsl
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
146
147
148
149
150
151
152
153
154
155
156
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "dwrite.hlsl"
#include "shader_common.hlsl"
cbuffer ConstBuffer : register(b0)
{
float4 backgroundColor;
float2 backgroundCellSize;
float2 backgroundCellCount;
float4 gammaRatios;
float enhancedContrast;
float underlineWidth;
float curlyLineHeight;
float underlineCellOffset;
}
Texture2D<float4> background : register(t0);
Texture2D<float4> glyphAtlas : register(t1);
struct Output
{
float4 color;
float4 weights;
};
// clang-format off
Output main(PSData data) : SV_Target
// clang-format on
{
float4 color;
float4 weights;
switch (data.shadingType)
{
case SHADING_TYPE_TEXT_BACKGROUND:
{
const float2 cell = data.position.xy / backgroundCellSize;
color = all(cell < backgroundCellCount) ? background[cell] : backgroundColor;
weights = float4(1, 1, 1, 1);
break;
}
case SHADING_TYPE_TEXT_GRAYSCALE:
{
// These are independent of the glyph texture and could be moved to the vertex shader or CPU side of things.
const float4 foreground = premultiplyColor(data.color);
const float blendEnhancedContrast = DWrite_ApplyLightOnDarkContrastAdjustment(enhancedContrast, data.color.rgb);
const float intensity = DWrite_CalcColorIntensity(data.color.rgb);
// These aren't.
const float4 glyph = glyphAtlas[data.texcoord];
const float contrasted = DWrite_EnhanceContrast(glyph.a, blendEnhancedContrast);
const float alphaCorrected = DWrite_ApplyAlphaCorrection(contrasted, intensity, gammaRatios);
color = alphaCorrected * foreground;
weights = color.aaaa;
break;
}
case SHADING_TYPE_TEXT_CLEARTYPE:
{
// These are independent of the glyph texture and could be moved to the vertex shader or CPU side of things.
const float blendEnhancedContrast = DWrite_ApplyLightOnDarkContrastAdjustment(enhancedContrast, data.color.rgb);
// These aren't.
const float4 glyph = glyphAtlas[data.texcoord];
const float3 contrasted = DWrite_EnhanceContrast3(glyph.rgb, blendEnhancedContrast);
const float3 alphaCorrected = DWrite_ApplyAlphaCorrection3(contrasted, data.color.rgb, gammaRatios);
weights = float4(alphaCorrected * data.color.a, 1);
color = weights * data.color;
break;
}
case SHADING_TYPE_TEXT_PASSTHROUGH:
{
color = glyphAtlas[data.texcoord];
weights = color.aaaa;
break;
}
case SHADING_TYPE_DOTTED_LINE:
{
const bool on = frac(data.position.x / (2.0f * underlineWidth)) < 0.5f;
color = on * premultiplyColor(data.color);
weights = color.aaaa;
break;
}
case SHADING_TYPE_DOTTED_LINE_WIDE:
{
const bool on = frac(data.position.x / (4.0f * underlineWidth)) < 0.5f;
color = on * premultiplyColor(data.color);
weights = color.aaaa;
break;
}
case SHADING_TYPE_DASHED_LINE:
{
const bool on = frac(data.position.x / backgroundCellSize.x) < 0.5f;
color = on * premultiplyColor(data.color);
weights = color.aaaa;
break;
}
case SHADING_TYPE_DASHED_LINE_WIDE:
{
const bool on = frac(data.position.x / (2.0f * backgroundCellSize.x)) < 0.5f;
color = on * premultiplyColor(data.color);
weights = color.aaaa;
break;
}
case SHADING_TYPE_CURLY_LINE:
{
const float strokeWidthHalf = underlineWidth / 2.0f;
const int cellIdxY = data.position.y / backgroundCellSize.y;
const float cellPosY = cellIdxY * backgroundCellSize.y;
const float centerY = cellPosY + underlineCellOffset + strokeWidthHalf;
const float Pi = radians(180);
const float freq = 2.0f * Pi / backgroundCellSize.x;
const float amp = curlyLineHeight - 1.0f; // -1.0f avoids clipping at the peak
const float s = sin(data.position.x * freq);
const float d = abs(centerY + s * amp - data.position.y);
const float a = 1 - saturate(d - strokeWidthHalf);
color = a * premultiplyColor(data.color);
weights = color.aaaa;
break;
}
case SHADING_TYPE_CURLY_LINE_WIDE:
{
float strokeWidthHalf = underlineWidth / 2.0f;
const int cellIdxY = data.position.y / backgroundCellSize.y;
const float cellPosY = cellIdxY * backgroundCellSize.y;
float centerY = cellPosY + underlineCellOffset + strokeWidthHalf;
const float Pi = radians(180);
float freq = 2.0f * Pi / backgroundCellSize.x;
float amp = curlyLineHeight - 1.0f; // -1.0f avoids clipping at the peak
// In 'Wide' case, we need to draw the same wave on an area twice as big.
strokeWidthHalf *= 2;
centerY -= curlyLineHeight + strokeWidthHalf;
freq /= 2;
amp *= 2;
const float s = sin(data.position.x * freq);
const float d = abs(centerY + s * amp - data.position.y);
const float a = 1 - saturate(d - strokeWidthHalf);
color = a * premultiplyColor(data.color);
weights = color.aaaa;
break;
}
default:
{
color = premultiplyColor(data.color);
weights = color.aaaa;
break;
}
}
Output output;
output.color = color;
output.weights = weights;
return output;
}