From 1cb4845fb76717e568676491e331cf98e4a1ff56 Mon Sep 17 00:00:00 2001 From: Kane Rogers Date: Mon, 25 Oct 2021 17:00:38 +1100 Subject: [PATCH] Add simple debug interface Fixes #96 --- hotham/shaders/pbr.frag.spv | Bin 25460 -> 28468 bytes hotham/src/resources/vulkan_context.rs | 12 +++++++++- hotham/src/shaders/pbr.frag | 32 +++++++++++++++++++++++++ hotham/src/shaders/pbr.frag.spv | Bin 24108 -> 28996 bytes 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/hotham/shaders/pbr.frag.spv b/hotham/shaders/pbr.frag.spv index 6651eebb7e3ec7932d6bf65942a1a6c716810777..b4fa86ec72497aaab0caf9b676e22f8325e36b32 100644 GIT binary patch delta 3434 zcmZ9OTW^&`6o#kWyA)`tr6LNVloAD{f{5aQQ>j2aK`V+VnrhV|B49y~h{UZyjQ9No z-k50Og{ct51Y#OB;RooAA}XGbC@N4-&$IVlaok@R=6&C_X3d(l=Iggly;t|fvAUK* z{mjOc>eBc$A-!09y``mfaziSnzG6y){X6=%rj+Cxi^FZLFE`KcOpQ3E^jjgN-OTyu zOk=R7)Xv&b=JFUmFs)SByoeAjNMEx|7x`FSYIqws#xF4ldi^)YjEK@dOs1(KIoA1U@k|&^4zt2IaHr{+~0SPW9b*C+4mT0 zH~Rri{nhGbKZ4Z`6Tm?4F#iM}$@tIkcj3LPd7t?t+;xsu=#OiD0iP_CDvMpP9%q~S zE11m64of+W-BLS4_MXgBc$%R(GxbQRy*7`fp}B^zbTpi5tNf$^*(v$wG!DEWaq&ETJd&l%CdP zTssbYoVmIB4vvSrer44bG1MzD7FU88EP^y)bR)SvY=+yro;0q^C&1O3ibF@crk136 zOFzLis(cPMt9&0x7|xfc6-_-lIuWcE9i0UBv7_3~WlU#yRdCmjBv=O-88Q z?0hu!=;#GtwY;NK;3EVyurJ0`c;3+q;jVK;N2h_+rxbaCTo5h22yA9LL`N?Mt2^?? zZuqB8yA|~0p3>8Xt-Z#kkBQpt8Q``{s)C*B0Oy^W30Ip@>6A3@)bXrShOu}%vrb)# zrXHP|1y+krT@LoKQ`#I@SAz3IuU9&y8=x;IyD!pmUn6%Jnz(%@Vry= z;jVK;r>+94&$Cl5h)yj4o0$&LsjI>24juC}n!DQVuRPw7-t^9F3|NJ{Q?T?Dr%ajwO1ebnPzOTg+5&lAHKUYw=q zSvpN=8G_=HN^sN^Hf z^YOzSe+F*C=H<#i*f*o8$4$NktQI$UHQ2|StnD_&28KNr$642a`Ck9`H>U@ocC%hI z^|;BmgVpkzycTYe3~Uqcfaf>)PPpqFag*19)z^BHT@W3=3v6aOScL_&cRkp|VpF?( zH=6qX>WBUwuxr)5#r~{Pv$9si(_4kG#fN@%scO_IT6Qnk06N<`dEO$w_~Cm$HhuK% z1Iw?kCiMV#63MDZEHz_&z#5Y(2|Vc_j{O+7GOww=6aJuk5Ka9MK1bjWfz|vi>JPL5 zu#f%L_Ao=u;Npn=2)H)(CO_I5wz1d`+M{5^a<&_p<(^dAX0V!@4l?_U^2({pz4(tY z`$BGE=3HqjGyl>y{%c@N!rrJ4Lym)=q5GJc9AQu71)APe zxt(&VLi|Mp!x=TisiS7lmmzcY721q?1Jj!YQ5Qrr>IuxKL#)0-Ut#JX-f|92PY?fN z#R8sLu>{kb?<CMl(_05oS)v)mHzxZy`PRPjZmRd0f0nstAOHXW diff --git a/hotham/src/resources/vulkan_context.rs b/hotham/src/resources/vulkan_context.rs index 999a5301..8503684c 100644 --- a/hotham/src/resources/vulkan_context.rs +++ b/hotham/src/resources/vulkan_context.rs @@ -1082,12 +1082,22 @@ fn vulkan_init_legacy( .application_name(&app_name) .api_version(vk::make_api_version(0, 1, 2, 0)); + let validation_features_enables = [ + // vk::ValidationFeatureEnableEXT::BEST_PRACTICES, + ]; + let validation_features_disables = []; + let mut validation_features = vk::ValidationFeaturesEXT::builder() + .enabled_validation_features(&validation_features_enables) + .disabled_validation_features(&validation_features_disables); + + // TODO: Disable validation in release let instance = entry .create_instance( &vk::InstanceCreateInfo::builder() .application_info(&app_info) .enabled_extension_names(&vk_instance_ext_ptrs) - .enabled_layer_names(&layer_names), + .enabled_layer_names(&layer_names) + .push_next(&mut validation_features), None, ) .expect("Vulkan error creating Vulkan instance"); diff --git a/hotham/src/shaders/pbr.frag b/hotham/src/shaders/pbr.frag index b88c76cb..1e75b9d5 100644 --- a/hotham/src/shaders/pbr.frag +++ b/hotham/src/shaders/pbr.frag @@ -354,6 +354,37 @@ void main() outColor = vec4(color, baseColor.a); // Debugging + + // Shader inputs debug visualization + // "none", "Base Color Texture", "Normal Texture", "Occlusion Texture", "Emissive Texture", "Metalic (?)", "Roughness (?)" + if (uboParams.debugViewInputs > 0.0) { + int index = int(uboParams.debugViewInputs); + switch (index) { + case 1: + outColor.rgba = material.baseColorTextureSet > -1 ? texture(colorMap, material.baseColorTextureSet == 0 ? inUV0 : inUV1) : vec4(1.0f); + break; + case 2: + outColor.rgb = (material.normalTextureSet > -1) ? texture(normalMap, material.normalTextureSet == 0 ? inUV0 : inUV1).rgb : normalize(inNormal); + break; + case 3: + outColor.rgb = (material.occlusionTextureSet > -1) ? texture(aoMap, material.occlusionTextureSet == 0 ? inUV0 : inUV1).rrr : vec3(0.0f); + break; + case 4: + outColor.rgb = (material.emissiveTextureSet > -1) ? texture(emissiveMap, material.emissiveTextureSet == 0 ? inUV0 : inUV1).rgb : vec3(0.0f); + break; + case 5: + outColor.rgb = texture(physicalDescriptorMap, inUV0).bbb; + break; + case 6: + outColor.rgb = texture(physicalDescriptorMap, inUV0).ggg; + break; + case 7: + outColor.rgba = material.baseColorTextureSet > -1 ? texture(colorMap, material.baseColorTextureSet == 0 ? inUV0 : inUV1) * material.baseColorFactor: vec4(1.0f); + break; + } + outColor = SRGBtoLINEAR(outColor); + } + // "none", "Diff (l,n)", "F (l,h)", "G (l,v,h)", "D (h)", "Specular" if (uboParams.debugViewEquation > 0.0) { int index = int(uboParams.debugViewEquation); @@ -375,4 +406,5 @@ void main() break; } } + } diff --git a/hotham/src/shaders/pbr.frag.spv b/hotham/src/shaders/pbr.frag.spv index 24da8d0c6875e4047af8d1f95c1b5cf93ae8b399..1353e8073a065d97ce69b3ac5e591040dc412974 100644 GIT binary patch literal 28996 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 literal 24108 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 B7!m*g