• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#version 460 core
2#extension GL_ARB_separate_shader_objects : enable
3#extension GL_ARB_shading_language_420pack : enable
4
5// Lume Super Resolution
6// Create new locks mask
7
8// includes
9#include "render/shaders/common/render_color_conversion_common.h"
10#include "render/shaders/common/render_post_process_structs_common.h"
11
12#include "common/bloom_common.h"
13
14// camera data
15struct DefaultCameraMatrixStruct {
16    mat4 view;
17    mat4 proj;
18    mat4 viewProj;
19
20    mat4 viewInv;
21    mat4 projInv;
22    mat4 viewProjInv;
23
24    mat4 viewPrevFrame;
25    mat4 projPrevFrame;
26    mat4 viewProjPrevFrame;
27
28    mat4 shadowViewProj;
29    mat4 shadowViewProjInv;
30
31    // .xy = jitter offset, .zw = jitter offset with baked screen size
32    vec4 jitter;
33    vec4 jitterPrevFrame;
34
35    // .xy = unique id (64-bit), .zw = layer mask (64 bit)
36    uvec4 indices;
37    // .x multi-view camera additional layer count, .yzw 3 multi-view camera indices
38    // yzw are packed, use unpack functions
39    uvec4 multiViewIndices;
40
41    vec4 frustumPlanes[2];
42
43    // .x environment count
44    uvec4 counts;
45    // padding to 256
46    uvec4 pad0;
47    mat4 matPad0;
48    mat4 matPad1;
49};
50
51struct LockPassPushConstant {
52    vec4 renderSizeInvSize;
53    vec4 displaySizeInvSize;
54};
55
56// sets
57
58layout(set = 0, binding = 0) uniform texture2D lockInputLumaTex;
59layout(set = 0, binding = 1, r8) uniform writeonly image2D newLocksTex;
60layout(set = 0, binding = 3, r32ui) uniform writeonly uimage2D prevDepthTex;
61layout(set = 0, binding = 2) uniform sampler uSampler;
62
63layout(push_constant, std430) uniform uPushConstantBlock
64{
65    LockPassPushConstant uPc;
66};
67
68layout(set = 0, binding = 12, std140) uniform uCameraMatrices
69{
70    DefaultCameraMatrixStruct uCameras[16];
71};
72
73layout(constant_id = 0) const uint CORE_POST_PROCESS_FLAGS = 0;
74
75// Constants
76const float cSimilarThreshold = 1.05f;
77
78//---------------- Utility Functions ------------------//
79
80ivec2 RenderSize() {
81    return ivec2(uPc.renderSizeInvSize.x, uPc.renderSizeInvSize.y);
82}
83
84ivec2 DisplaySize() {
85    return ivec2(uPc.displaySizeInvSize.x, uPc.displaySizeInvSize.y);
86}
87
88vec2 RenderSizeVec2() { return uPc.renderSizeInvSize.xy; }
89vec2 DisplaySizeVec2() { return uPc.displaySizeInvSize.xy; }
90
91bool OnScreen(ivec2 pos, ivec2 size) {
92    return (pos.x >= 0 && pos.y >= 0 && pos.x < size.x && pos.y < size.y);
93}
94
95vec2 JitterPixels() { return uCameras[0].jitter.xy; }
96//vec2 JitterPixels() { return vec2(0); }
97
98// Load Luma from the input texture calculated in the Dilate/Reconstruct pass
99float LoadLockInputLuma(ivec2 px)
100{
101    ivec2 sz = RenderSize();
102    px       = clamp(px, ivec2(0), sz - ivec2(1));
103    return texelFetch(sampler2D(lockInputLumaTex, uSampler), px, 0).r;
104}
105
106ivec2 HrPosFromLrPos(vec2 iPxLrPos)
107{
108    vec2 fSrcJitteredPos = vec2(iPxLrPos) + 0.5f - JitterPixels();
109    vec2 fLrPosInHr = (fSrcJitteredPos / RenderSizeVec2()) * DisplaySizeVec2();
110    ivec2 iPxHrPos = ivec2(floor(fLrPosInHr));
111    return iPxHrPos;
112}
113
114void StoreNewLocks(ivec2 coord, float lockValue) {
115    imageStore(newLocksTex, coord, vec4(lockValue, 0, 0, 0));
116}
117
118
119void GatherLockInputLumaRQuad(vec2 baseUv,
120                              out float col00,
121                              out float col10,
122                              out float col01,
123                              out float col11)
124{
125    vec4 g = textureGather(sampler2D(lockInputLumaTex, uSampler), baseUv, 0);
126
127    col01 = g.w;
128    col11 = g.z;
129    col10 = g.y;
130    col00 = g.x;
131}
132
133bool ComputeThinFeatureConfidence(ivec2 pos)
134{
135    const float kSimilarThreshold = 1.05;
136    const float kFp16Max          = 65504.0;
137    const uint  kSetBit4          = 1u << 4;
138
139    const uint rejectionMasks[4] = {
140        (1u<<0)|(1u<<1)|(1u<<3)|(1u<<4),   // upper-left  2�2
141        (1u<<1)|(1u<<2)|(1u<<4)|(1u<<5),   // upper-right 2�2
142        (1u<<3)|(1u<<4)|(1u<<6)|(1u<<7),   // lower-left  2�2
143        (1u<<4)|(1u<<5)|(1u<<7)|(1u<<8)    // lower-right 2�2
144    };
145
146
147    float nucleusLuma      = LoadLockInputLuma(pos);
148    float dissimMin        = kFp16Max;
149    float dissimMax        = 0.0;
150    uint  similarityMask   = kSetBit4;
151
152    //------------------------------------------------------------------
153    //  sample neighbourhood    0 1 2
154    //                          3 4 5
155    //                          6 7 8
156    //------------------------------------------------------------------
157    float luma[9];
158    float dummy;
159
160    vec2 invInputSize = 1.0 / vec2(RenderSize());
161    vec2 baseUv       = vec2(pos) * invInputSize;
162    vec2 unitUv       = invInputSize;          // (1 px, 1 px) in UV
163
164    GatherLockInputLumaRQuad(baseUv,
165                             luma[0], luma[1],
166                             luma[3], luma[4]);
167    GatherLockInputLumaRQuad(baseUv + unitUv,
168                             dummy,
169                             luma[5],
170                             luma[7], luma[8]);
171
172    luma[2] = LoadLockInputLuma(pos + ivec2( 1,-1));
173    luma[6] = LoadLockInputLuma(pos + ivec2(-1, 1));
174
175    int idx = 0;
176    for (int y =-1; y <= 1; ++y)
177        for (int x =-1; x <= 1; ++x, ++idx)
178        {
179            if (x==0 && y==0) continue;
180
181            float s = luma[idx];
182            float ratio = max(s, nucleusLuma) / min(s, nucleusLuma);
183
184            if (ratio < kSimilarThreshold)
185            {
186                similarityMask |= 1u << idx;
187            }
188            else
189            {
190                dissimMin = min(dissimMin, s);
191                dissimMax = max(dissimMax, s);
192            }
193        }
194
195    bool isRidge = (nucleusLuma > dissimMax) || (nucleusLuma < dissimMin);
196    if (!isRidge) return false;
197
198
199    for (int i = 0; i < 4; ++i)
200        if ((similarityMask & rejectionMasks[i]) == rejectionMasks[i])
201            return false;
202
203    return true;
204}
205
206#define cTgs 8
207
208layout(local_size_x = 32, local_size_y = 8, local_size_z = 1) in;
209void main()
210{
211    const ivec2 gid = ivec2(gl_GlobalInvocationID.xy);
212    const ivec2 size = RenderSize();
213
214    if (gid.x >= size.x || gid.y >= size.y) {
215        return;
216    }
217
218    if(ComputeThinFeatureConfidence(gid))
219    {
220        StoreNewLocks(HrPosFromLrPos(gid), 1U);
221    }
222
223    // Clear depth map for next frame
224    uint farPlaneBits = floatBitsToUint(1.0);
225    imageStore(prevDepthTex, gid, uvec4(farPlaneBits, 0, 0, 0));
226}
227