From 3983cbd732d09c46afae8e3cfde9427aa68d672b Mon Sep 17 00:00:00 2001 From: saschawillems Date: Tue, 1 Nov 2016 15:39:54 +0100 Subject: [PATCH] Set SSAO shader constants via specialization --- data/shaders/ssao/ssao.frag | 24 ++++++++++++++---------- data/shaders/ssao/ssao.frag.spv | Bin 5140 -> 5236 bytes ssao/ssao.cpp | 20 +++++++++++++++++--- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/data/shaders/ssao/ssao.frag b/data/shaders/ssao/ssao.frag index 8380f733..4c78d681 100644 --- a/data/shaders/ssao/ssao.frag +++ b/data/shaders/ssao/ssao.frag @@ -7,9 +7,12 @@ layout (binding = 0) uniform sampler2D samplerPositionDepth; layout (binding = 1) uniform sampler2D samplerNormal; layout (binding = 2) uniform sampler2D ssaoNoise; +layout (constant_id = 0) const int SSAO_KERNEL_SIZE = 64; +layout (constant_id = 1) const float SSAO_RADIUS = 0.5; + layout (binding = 3) uniform UBOSSAOKernel { - vec4 samples[64]; // todo: specialization const + vec4 samples[SSAO_KERNEL_SIZE]; } uboSSAOKernel; layout (binding = 4) uniform UBO @@ -21,10 +24,6 @@ layout (location = 0) in vec2 inUV; layout (location = 0) out float outFragColor; -// todo: specialization const -const int kernelSize = 32; -const float radius = 0.5; - void main() { // Get G-Buffer values @@ -35,7 +34,7 @@ void main() ivec2 texDim = textureSize(samplerPositionDepth, 0); ivec2 noiseDim = textureSize(ssaoNoise, 0); const vec2 noiseUV = vec2(float(texDim.x)/float(noiseDim.x), float(texDim.y)/(noiseDim.y)) * inUV; - vec3 randomVec = texture(ssaoNoise, noiseUV).xyz; + vec3 randomVec = texture(ssaoNoise, noiseUV).xyz * 2.0 - 1.0; // Create TBN matrix vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal)); @@ -44,10 +43,10 @@ void main() // Calculate occlusion value float occlusion = 0.0f; - for(int i = 0; i < kernelSize; i++) + for(int i = 0; i < SSAO_KERNEL_SIZE; i++) { vec3 samplePos = TBN * uboSSAOKernel.samples[i].xyz; - samplePos = fragPos + samplePos * radius; + samplePos = fragPos + samplePos * SSAO_RADIUS; // project vec4 offset = vec4(samplePos, 1.0f); @@ -57,11 +56,16 @@ void main() float sampleDepth = -texture(samplerPositionDepth, offset.xy).w; +#define RANGE_CHECK 1 +#ifdef RANGE_CHECK // Range check - float rangeCheck = smoothstep(0.0f, 1.0f, radius / abs(fragPos.z - sampleDepth)); + float rangeCheck = smoothstep(0.0f, 1.0f, SSAO_RADIUS / abs(fragPos.z - sampleDepth)); occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f) * rangeCheck; +#else + occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f); +#endif } - occlusion = 1.0 - (occlusion / float(kernelSize)); + occlusion = 1.0 - (occlusion / float(SSAO_KERNEL_SIZE)); outFragColor = occlusion; } diff --git a/data/shaders/ssao/ssao.frag.spv b/data/shaders/ssao/ssao.frag.spv index 241fd0607fbed0251253e4252940b4371fadd5a3..e8009057ed5e1004405b86bbc0a3039e875e80f8 100644 GIT binary patch literal 5236 zcmZ{mi>2WT3MNR%S)zq^=|zw-PUTYo@bx$tu1Tyv3|Vo`+KkZ`@X%;^vqn^pJg-n zH#_@l)?Ev-nb=vTT#1~U^_BLfE!(y%Z+FI)uR3#ukw<1diqbbf>(6GPi^*EOA-@2; z4UQsCoMYA?~W!6ijYG3U+^w`s?jSm-X{Ijzou-moC=0x6ts(0!|V?*BT z?1e7#oweTBz9Z~KD2<{uS)0(`mmQ0p@`n;#=Di=jlkeY9pERyF`*4|8Z|5b`RQj9f z#pvk7RGX(m*S`;0FZJH+AhP=m?u!1t>`Tb)>$Yy&Hn{ctyw%8gT-e@{M@{kWVP7_l zJ+-@dN373s3w*I>Pdo2)d)|djO)~m2byu@hc%tQC&UH5&wW!;hJ%Zkyt9vAJhv3+c z@qGQ>oFgv#dzXr-&PI-PeKAqAFtbhc_iUGFu)<#4HA~yGJ*i@QmeqJ|3&yxYTMKI#-8qN?9oE9%v($iXHs8;<}(g}V~Mwqw*CR^*+@BY zJa6B-kotXw>I(Y=GUwtj&ir{PNN#nqJy)0g<|D1=EXMnc){-|~+jEvPej(C$pD*fp z&aP8n^_^H++1jwX&p*B982s+l0El|-wOsUnAG*&fZ@#`|z!m+xH!kP>2-0}xwf^ZP z&wniQwO5u_H~tKCw1sZf}?q= z1IQEMz02;MzLTi#U6!-P)ySDZ&S%t~26FnZO}hE^u$On4wMPHVD9)hYXSg%zo{_!0 zuX4tI18H43due-Tqt`u2H$L{~UUc^(p8r8~)|&7?j$yv`667mj2C&~-NOPUpe%ihh za%b^=ndh7?xqra;J{s%Y_xHwU3wu$;_OAFl5q@odC&Kn_tf<)5+jyAmZ$ZTC-&wIe zdw&PQ?^!o1_8I8=Dz^Fl7DT+~;x{~O^Zh1Q?L&vz&n5d@p5J%&NZ|XbJsMlioC~?b>=6g@%BL7r$zax=<8oFHMFGrV)eD9UqAoV@>Rlu5lTde85KNH9o*xvWE z5*Ili#kNj0=WJ~G$oUw$+zs@x#>atmqW8Jz@=@o!()YidHQ4s9=B&k* zkDNhtx#+zP-8%Ba%;WuA51dJ#z2!Cl@67cn#&a`H-o5u7l#9LJgznx){$_Mz;!b}O z-5B|}bDu(&7p@s#CWt$CKDsg0JGTWp?wd01+^5lv*YA8Ak#f${kK796!X8HV{)K(P zVg3t~|E_dq+pvw1kNGY_w~oG;V>`ON^u^uZf$p=pU;3SI2q_=^KZ7n8_QmMVH;?I^ z{}Nyg_up9k*74h>FY+!&uhtpCHYWVL(5-txdam8*=D30zMVGT*aAS${e1gl-t?vqM z54v16cRX>`+`VwSfGcwA=(|8Q_lm@s8{eHP(Vg2loh$eWbZ2q~dj>y=Za?c=PySM5 z16a#EW8BZnkn-wHWG(6Ykjub7xuGqjziG<9albmqDd5uoIi!B2`@RJEd0>r4+4lp; zs}i>#`7dI$+rV1ps+;SaUjWV(wXQ+8)*#PuE%G`r4V+J(aSM@O2KwTCyFPL9F8A4e zy`7o*kzWD!GS25em^ka{|0QBy8z+=_0ExC38D zmvaSo8@inH26ubnoPU_jhTHgld zxi{M10mjHjO*v~8$nOHH#soF_HfOdUduRW6KFw%ob<;5S%d&f|&Q=WXp-T z13y7GUVrraDSCC@pJB@x`~T)O#{9X+pMxWk?fLuybnEq(zhA#hoV?5Va0-rokfUjt|J znf1r-^fTzbNBZaSH=wc40%K1HHQ@a=&iM`@^+)gL(d`}c{s#RZsLuNWw*2$VcL4d@ zQqQs%kbkG^w^ImmvQP_JL{gwO>u#D@gP8$(i3mn(sF` v`oD&5kNErQb@crp&g~6!W8~x9-$Zwh^u>&FQS&e8*3|blQv2VW^x5D)G8D@R literal 5140 zcmZ{mi}K~Ot+0#N%+$)VLjRdk*K)0%XP@uY?X1FjnKNNnq@E0U{=@@6@za`OS-Us2^`TlkF3FEr6v&+1CD=(Q2x76HL zt=Lk)qdT7)*wCh>dF!#8wZ>>Mu`?e@F`JNW9yV{Z%b4xhyX(PNrz^V(Zu{Vt($5H4 zF)}hf)#B;U^(*V8-kt47cAmjq(chDO3Atl%>$YtJTQ}v+M$Y5Hc9%SAigyotvYW7{ zb{Fr8^;r(W7kl=!@^+`^1K89gqbE~$O*RWpv>eR24#QE4y4~3k^v+zJBau4_$9|0E zYxm|HaoOLyR7|zkbF6EN@uG>DZJ@tryGVl-_QH-?+Mex#itSleE6?G>ffi9a9R zc z1;`7RXX8F!!VbHi`lJ5o=)TWU{|xkM{r6%UBOmq8M3)z?sDCdr+5dgO7{3ccoV?uo zf!~F|Z7H@N&UpQEQ|v-?YhDWafpdHA@-g>^(A}3&_T@O_hk@J}br&N)lDH*E^Svi> zk$(>QQV{v)qRU18GIY7f_g={jP~UT339PvSSaT8b0w7;td*3fiT;zNV+d9>pi?HP* z=i}&dchbiip8(d8k2;@3xA!U#y)QzISp~W81r$vj$r}at6@lqW2)Wb>xSb z$NRSyIFmkm%dG?6ncGv0=VqL|d+$3a7kj?}-Mx?ejp)Y2o&FTMG4gTeK8-FfTrIPLimwlVT?r!Padj=s3Nm!sQDU)UX|PNcrf$16?lco#@Utm+77V3SbTQ&shD|*^bl~c~_%X>s*6vO!%)wx9(->xrWir zaRqlBx}5!jt0m6;4Q@BO^Q}n&i;!(#jic=QKIG>TH-&tY80|@5Epye)b6Lj zPoHt~k+%YU@xI)aIC+=*JQEyZre5S%fW3_K`S&Nzdirk%eIV?wq8k(M!=31IcYs?` z&99-Gr!Q*CMUA`Btr2(N9&|ZZaQC9iId5?HCC>SWn9k?DADC~v{sq9E2a)>xRz8IM zIyem6FXuRf{05NMw$?X+dG3w&w}3J7QB%&EjBlPNQKgO05 zu9z*(`X_M4c-ArRPm?Vt;tu=_-FW@c@8{^%d4GW|XYBu**BJBXAb$ytPqydtDCpGd zEq{L=OPsvR`Qx|bSLo&&6Zh%Y=<@E*&FTDpgD&rW9YJcxdH)u@4?GT>$-Vs@kPrL! z=;ry`p#KlR7S$-`OY8-9!Cz`5VsIr+~5NfnC7+ZJhHRMe2{<&!F2o z=6x1@Kd8?8M{N1$m~USxv&=mC|5EdLq|5KqbI3n|KLfu{>h^sa=^TFdo=564CVb9W z^%)a0zJP9i*e{~{9RAJV^S%U(k&l?apicnrmN9m+IpPW7YCOePP{6)yWfd)80 zzV_b}_cGFaeRAd(Nb_$*M*n}H+au2DpXhS0fH>!Wp}QygVkWt$@hZAC^c_QLzs1R3 G1pWu(u)x3o diff --git a/ssao/ssao.cpp b/ssao/ssao.cpp index 337adef4..51b2d9a9 100644 --- a/ssao/ssao.cpp +++ b/ssao/ssao.cpp @@ -25,6 +25,7 @@ #define ENABLE_VALIDATION false #define SSAO_KERNEL_SIZE 32 +#define SSAO_RADIUS 0.5f #if defined(__ANDROID__) #define SSAO_NOISE_DIM 8 @@ -948,9 +949,22 @@ public: // SSAO Pass shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/ssao/ssao.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - pipelineCreateInfo.renderPass = frameBuffers.ssao.renderPass; - pipelineCreateInfo.layout = pipelineLayouts.ssao; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.ssao)); + { + // Set constant parameters via specialization constants + std::array specializationMapEntries; + specializationMapEntries[0] = vkTools::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); // SSAO Kernel size + specializationMapEntries[1] = vkTools::initializers::specializationMapEntry(1, sizeof(uint32_t), sizeof(float)); // SSAO radius + struct { + uint32_t kernelSize = SSAO_KERNEL_SIZE; + float radius = SSAO_RADIUS; + } specializationData; + VkSpecializationInfo specializationInfo = vkTools::initializers::specializationInfo(2, specializationMapEntries.data(), sizeof(specializationData), &specializationData); + shaderStages[1].pSpecializationInfo = &specializationInfo; + pipelineCreateInfo.renderPass = frameBuffers.ssao.renderPass; + pipelineCreateInfo.layout = pipelineLayouts.ssao; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.ssao)); + } + // SSAO blur pass shaderStages[0] = loadShader(getAssetPath() + "shaders/ssao/fullscreen.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);