Skip to content

Commit 32ef32e

Browse files
committed
Reduced Lanczos texture reads and stabilized weights near zero
1 parent 0705e07 commit 32ef32e

2 files changed

Lines changed: 29 additions & 15 deletions

File tree

‎common/graphics/renderer.cpp‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,9 @@ void Renderer::drawTonemapping(Attachment& result, Encoder<CommandBuffer>& cmd,
754754
auto& pso = (settings.vidResIndex==0) ? shaders.tonemapping : shaders.tonemappingUpscale;
755755
cmd.setFramebuffer({ {result, Tempest::Discard, Tempest::Preserve} });
756756
cmd.setBinding(0, wview.sceneGlobals().uboGlobal[SceneGlobals::V_Main]);
757-
cmd.setBinding(1, sceneLinear, Sampler::nearest(ClampMode::ClampToEdge)); // Lanczos upscale requires nearest sampling
757+
const auto sampler = settings.vidResIndex==0 ? Sampler::nearest(ClampMode::ClampToEdge) :
758+
Sampler::bilinear(ClampMode::ClampToEdge);
759+
cmd.setBinding(1, sceneLinear, sampler);
758760
cmd.setPushData(p);
759761
cmd.setPipeline(pso);
760762
cmd.draw(nullptr, 0, 3);
@@ -805,7 +807,8 @@ void Renderer::drawCMAA2(Tempest::Attachment& result, Tempest::Encoder<Tempest::
805807
auto& psoTone = (settings.vidResIndex==0) ? shaders.tonemapping : shaders.tonemappingUpscale;
806808
cmd.setFramebuffer({{result, Tempest::Discard, Tempest::Preserve}});
807809
cmd.setBinding(0, wview.sceneGlobals().uboGlobal[SceneGlobals::V_Main]);
808-
cmd.setBinding(1, sceneLinear, Sampler::nearest());
810+
const auto sampler = settings.vidResIndex==0 ? Sampler::nearest() : Sampler::bilinear(ClampMode::ClampToEdge);
811+
cmd.setBinding(1, sceneLinear, sampler);
809812
cmd.setPushData(&p, sizeof(p));
810813
cmd.setPipeline(psoTone);
811814
cmd.draw(nullptr, 0, 3);

‎shader/upscale/lanczos.glsl‎

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33

44
float lanczosWeight(float x, float r) {
55
const float PI_SQ = 9.8696044010893586188344910;
6-
if(x == 0.0)
6+
// Use the analytic limit near zero to avoid unstable GPU sine/division results.
7+
if(abs(x) < 0.0001)
78
return 1.;
89
return (r * sin(M_PI * x) * sin(M_PI * (x / r) )) / (PI_SQ * x*x);
910
}
1011

11-
float lanczosWeight(vec2 x, float r) {
12-
return lanczosWeight(x.x, r) * lanczosWeight(x.y, r);
13-
}
14-
1512
vec3 lanczosUpscale(in sampler2D img, vec2 coord) {
1613
const int r = 2;
1714

@@ -20,20 +17,34 @@ vec3 lanczosUpscale(in sampler2D img, vec2 coord) {
2017
coord += -0.5 * resInv;
2118
vec2 ccoord = floor(coord * res) * resInv;
2219

20+
// Evaluate each one-dimensional weight once.
21+
// Keep the original footprint, including its omitted four corner samples.
22+
vec2 weights[5];
23+
[[unroll]]
24+
for(int i = -r; i <= r; ++i) {
25+
vec2 d = ((vec2(i) * resInv + ccoord - coord) * res);
26+
weights[i+r] = vec2(lanczosWeight(d.x, float(r)), lanczosWeight(d.y, float(r)));
27+
}
28+
29+
// The weights at offsets zero and one have the same sign.
30+
// A bilinear read combines them without replacing the Lanczos kernel.
31+
// The caller must use a linear, clamp-to-edge sampler.
32+
vec2 centerWeight = weights[2] + weights[3];
33+
vec2 centerOffset = clamp(weights[3] / centerWeight, vec2(0), vec2(1));
34+
vec2 offsets[4] = vec2[4](vec2(-2), vec2(-1), centerOffset, vec2(2));
35+
vec2 merged[4] = vec2[4](weights[0], weights[1], centerWeight, weights[4]);
36+
2337
vec3 total = vec3(0);
2438
[[unroll]]
25-
for(int x = -r; x <= r; x++) {
39+
for(int x = 0; x < 4; x++) {
2640
[[unroll]]
27-
for(int y = -r; y <= r; y++) {
28-
if(abs(x)==r && abs(y)==r)
41+
for(int y = 0; y < 4; y++) {
42+
if((x==0 || x==3) && (y==0 || y==3))
2943
continue;
3044

31-
vec2 offs = vec2(x,y);
32-
vec2 sco = offs * resInv + ccoord;
33-
vec2 d = ((sco - coord) * res);
34-
45+
vec2 sco = vec2(offsets[x].x, offsets[y].y) * resInv + ccoord;
3546
vec3 val = textureLod(img, sco+0.5*resInv, 0.0).rgb;
36-
float weight = lanczosWeight(d, float(r));
47+
float weight = merged[x].x * merged[y].y;
3748

3849
total += val * weight;
3950
}

0 commit comments

Comments
 (0)