Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/msdfgen/core/render-sdf.cpp
9903 views
1
2
#include "render-sdf.h"
3
4
#include "arithmetics.hpp"
5
#include "DistanceMapping.h"
6
#include "pixel-conversion.hpp"
7
#include "bitmap-interpolation.hpp"
8
9
namespace msdfgen {
10
11
static float distVal(float dist, DistanceMapping mapping) {
12
return (float) clamp(mapping(dist)+.5);
13
}
14
15
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 1> &sdf, Range sdfPxRange, float sdThreshold) {
16
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
17
if (sdfPxRange.lower == sdfPxRange.upper) {
18
for (int y = 0; y < output.height; ++y) {
19
for (int x = 0; x < output.width; ++x) {
20
float sd;
21
interpolate(&sd, sdf, scale*Point2(x+.5, y+.5));
22
*output(x, y) = float(sd >= sdThreshold);
23
}
24
}
25
} else {
26
sdfPxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height);
27
DistanceMapping distanceMapping = DistanceMapping::inverse(sdfPxRange);
28
float sdBias = .5f-sdThreshold;
29
for (int y = 0; y < output.height; ++y) {
30
for (int x = 0; x < output.width; ++x) {
31
float sd;
32
interpolate(&sd, sdf, scale*Point2(x+.5, y+.5));
33
*output(x, y) = distVal(sd+sdBias, distanceMapping);
34
}
35
}
36
}
37
38
}
39
40
void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 1> &sdf, Range sdfPxRange, float sdThreshold) {
41
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
42
if (sdfPxRange.lower == sdfPxRange.upper) {
43
for (int y = 0; y < output.height; ++y) {
44
for (int x = 0; x < output.width; ++x) {
45
float sd;
46
interpolate(&sd, sdf, scale*Point2(x+.5, y+.5));
47
float v = float(sd >= sdThreshold);
48
output(x, y)[0] = v;
49
output(x, y)[1] = v;
50
output(x, y)[2] = v;
51
}
52
}
53
} else {
54
sdfPxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height);
55
DistanceMapping distanceMapping = DistanceMapping::inverse(sdfPxRange);
56
float sdBias = .5f-sdThreshold;
57
for (int y = 0; y < output.height; ++y) {
58
for (int x = 0; x < output.width; ++x) {
59
float sd;
60
interpolate(&sd, sdf, scale*Point2(x+.5, y+.5));
61
float v = distVal(sd+sdBias, distanceMapping);
62
output(x, y)[0] = v;
63
output(x, y)[1] = v;
64
output(x, y)[2] = v;
65
}
66
}
67
}
68
}
69
70
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 3> &sdf, Range sdfPxRange, float sdThreshold) {
71
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
72
if (sdfPxRange.lower == sdfPxRange.upper) {
73
for (int y = 0; y < output.height; ++y) {
74
for (int x = 0; x < output.width; ++x) {
75
float sd[3];
76
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
77
*output(x, y) = float(median(sd[0], sd[1], sd[2]) >= sdThreshold);
78
}
79
}
80
} else {
81
sdfPxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height);
82
DistanceMapping distanceMapping = DistanceMapping::inverse(sdfPxRange);
83
float sdBias = .5f-sdThreshold;
84
for (int y = 0; y < output.height; ++y) {
85
for (int x = 0; x < output.width; ++x) {
86
float sd[3];
87
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
88
*output(x, y) = distVal(median(sd[0], sd[1], sd[2])+sdBias, distanceMapping);
89
}
90
}
91
}
92
}
93
94
void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 3> &sdf, Range sdfPxRange, float sdThreshold) {
95
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
96
if (sdfPxRange.lower == sdfPxRange.upper) {
97
for (int y = 0; y < output.height; ++y) {
98
for (int x = 0; x < output.width; ++x) {
99
float sd[3];
100
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
101
output(x, y)[0] = float(sd[0] >= sdThreshold);
102
output(x, y)[1] = float(sd[1] >= sdThreshold);
103
output(x, y)[2] = float(sd[2] >= sdThreshold);
104
}
105
}
106
} else {
107
sdfPxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height);
108
DistanceMapping distanceMapping = DistanceMapping::inverse(sdfPxRange);
109
float sdBias = .5f-sdThreshold;
110
for (int y = 0; y < output.height; ++y) {
111
for (int x = 0; x < output.width; ++x) {
112
float sd[3];
113
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
114
output(x, y)[0] = distVal(sd[0]+sdBias, distanceMapping);
115
output(x, y)[1] = distVal(sd[1]+sdBias, distanceMapping);
116
output(x, y)[2] = distVal(sd[2]+sdBias, distanceMapping);
117
}
118
}
119
}
120
}
121
122
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 4> &sdf, Range sdfPxRange, float sdThreshold) {
123
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
124
if (sdfPxRange.lower == sdfPxRange.upper) {
125
for (int y = 0; y < output.height; ++y) {
126
for (int x = 0; x < output.width; ++x) {
127
float sd[4];
128
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
129
*output(x, y) = float(median(sd[0], sd[1], sd[2]) >= sdThreshold);
130
}
131
}
132
} else {
133
sdfPxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height);
134
DistanceMapping distanceMapping = DistanceMapping::inverse(sdfPxRange);
135
float sdBias = .5f-sdThreshold;
136
for (int y = 0; y < output.height; ++y) {
137
for (int x = 0; x < output.width; ++x) {
138
float sd[4];
139
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
140
*output(x, y) = distVal(median(sd[0], sd[1], sd[2])+sdBias, distanceMapping);
141
}
142
}
143
}
144
}
145
146
void renderSDF(const BitmapRef<float, 4> &output, const BitmapConstRef<float, 4> &sdf, Range sdfPxRange, float sdThreshold) {
147
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
148
if (sdfPxRange.lower == sdfPxRange.upper) {
149
for (int y = 0; y < output.height; ++y) {
150
for (int x = 0; x < output.width; ++x) {
151
float sd[4];
152
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
153
output(x, y)[0] = float(sd[0] >= sdThreshold);
154
output(x, y)[1] = float(sd[1] >= sdThreshold);
155
output(x, y)[2] = float(sd[2] >= sdThreshold);
156
output(x, y)[3] = float(sd[3] >= sdThreshold);
157
}
158
}
159
} else {
160
sdfPxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height);
161
DistanceMapping distanceMapping = DistanceMapping::inverse(sdfPxRange);
162
float sdBias = .5f-sdThreshold;
163
for (int y = 0; y < output.height; ++y) {
164
for (int x = 0; x < output.width; ++x) {
165
float sd[4];
166
interpolate(sd, sdf, scale*Point2(x+.5, y+.5));
167
output(x, y)[0] = distVal(sd[0]+sdBias, distanceMapping);
168
output(x, y)[1] = distVal(sd[1]+sdBias, distanceMapping);
169
output(x, y)[2] = distVal(sd[2]+sdBias, distanceMapping);
170
output(x, y)[3] = distVal(sd[3]+sdBias, distanceMapping);
171
}
172
}
173
}
174
}
175
176
void simulate8bit(const BitmapRef<float, 1> &bitmap) {
177
const float *end = bitmap.pixels+1*bitmap.width*bitmap.height;
178
for (float *p = bitmap.pixels; p < end; ++p)
179
*p = pixelByteToFloat(pixelFloatToByte(*p));
180
}
181
182
void simulate8bit(const BitmapRef<float, 3> &bitmap) {
183
const float *end = bitmap.pixels+3*bitmap.width*bitmap.height;
184
for (float *p = bitmap.pixels; p < end; ++p)
185
*p = pixelByteToFloat(pixelFloatToByte(*p));
186
}
187
188
void simulate8bit(const BitmapRef<float, 4> &bitmap) {
189
const float *end = bitmap.pixels+4*bitmap.width*bitmap.height;
190
for (float *p = bitmap.pixels; p < end; ++p)
191
*p = pixelByteToFloat(pixelFloatToByte(*p));
192
}
193
194
}
195
196