From 8d0ab22e0514a37b019ae9f1534ac80529151d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 12 Jan 2025 22:39:36 -0300 Subject: [PATCH] wireframe improvements --- .../hwrenderer/data/hw_renderstate.h | 23 ++- .../rendering/vulkan/shaders/vk_shader.cpp | 1 + .../rendering/vulkan/shaders/vk_shader.h | 3 +- .../rendering/vulkan/vk_renderstate.cpp | 4 + .../hwrenderer/scene/hw_drawinfo.cpp | 2 +- wadsrc/static/shaders/scene/frag_main.glsl | 84 ++++---- wadsrc/static/shaders/scene/includes.glsl | 6 + .../shaders/scene/lightmodel_normal.glsl | 179 +++++++++--------- wadsrc/static/shaders/scene/material.glsl | 86 +++++---- .../shaders/scene/material_notexture.glsl | 6 +- wadsrc/static/shaders/scene/vert_main.glsl | 8 +- 11 files changed, 227 insertions(+), 175 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index 00e3d943d..caebb928c 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -246,12 +246,34 @@ public: mSurfaceUniforms.uVertexNormal = { norm.X, norm.Y, norm.Z, 0.f }; } + void SetWireframe(int mode) + { + mWireframe = mode; + mWireframeColor = toFVector4(PalEntry(0xffffffff)); + } + void SetWireframe(int mode, FVector4 color) { mWireframe = mode; mWireframeColor = color; } + void SetWireframe(int mode, PalEntry color) + { + mWireframe = mode; + mWireframeColor = toFVector4(color); + } + + void SetWireframeColor(FVector4 color) + { + mWireframeColor = color; + } + + void SetWireframeColor(PalEntry color) + { + mWireframeColor = toFVector4(color); + } + void SetNormal(float x, float y, float z) { mSurfaceUniforms.uVertexNormal = { x, y, z, 0.f }; @@ -566,7 +588,6 @@ public: SetMaterial(tex, upscalemask, scaleflags, clampmode, translation.index(), overrideshader, cls); } - void SetClipSplit(float bottom, float top) { mSurfaceUniforms.uClipSplit.X = bottom; diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index ac319726e..1ac965aa8 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -235,6 +235,7 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin if (!key.AlphaTest) definesBlock << "#define NO_ALPHATEST\n"; if (key.GBufferPass) definesBlock << "#define GBUFFER_PASS\n"; if (key.AlphaTestOnly) definesBlock << "#define ALPHATEST_ONLY\n"; + if (key.Simple3D) definesBlock << "#define SIMPLE\n#define SIMPLE3D\n"; switch(key.LightBlendMode) { diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index dbc4cf4cc..98123930c 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -104,7 +104,8 @@ public: uint64_t LightAttenuationMode : 1; // LIGHT_ATTENUATION_LINEAR , LIGHT_ATTENUATION_INVERSE_SQUARE uint64_t UseRaytracePrecise : 1; // USE_RAYTRACE_PRECISE uint64_t ShadowmapFilter : 4; // SHADOWMAP_FILTER - uint64_t Unused : 32; + uint64_t Simple3D : 1; // SIMPLE3D + uint64_t Unused : 31; }; uint64_t AsQWORD = 0; }; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 21709ca16..7afe9b69e 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -283,6 +283,8 @@ void VkRenderState::ApplyRenderPass(int dt) pipelineKey.ShaderKey.Detailmap = (uTextureMode & TEXF_Detailmap) != 0; pipelineKey.ShaderKey.Glowmap = (uTextureMode & TEXF_Glowmap) != 0; + pipelineKey.ShaderKey.Simple3D = mWireframe; // simple notexture drawing for wireframe + pipelineKey.ShaderKey.DepthFadeThreshold = mSurfaceUniforms.uDepthFadeThreshold > 0.0f; // The way GZDoom handles state is just plain insanity! @@ -1115,6 +1117,8 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip if (!mTextureEnabled || mWireframe) pipelineKey.ShaderKey.EffectState = SHADER_NoTexture; + pipelineKey.ShaderKey.Simple3D = mWireframe; // simple notexture drawing for wireframe + mPipelineKey = pipelineKey; PushConstants pushConstants = {}; diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 8c4ac8f83..c0e8016bf 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -1240,7 +1240,7 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state) state.SetFogballIndex(-1); } - state.SetWireframe(0, {}); + state.SetWireframe(0); } diff --git a/wadsrc/static/shaders/scene/frag_main.glsl b/wadsrc/static/shaders/scene/frag_main.glsl index 873299775..d5d9a22ed 100644 --- a/wadsrc/static/shaders/scene/frag_main.glsl +++ b/wadsrc/static/shaders/scene/frag_main.glsl @@ -17,54 +17,58 @@ vec3 rgb2hsv(vec3 c) void main() { -#ifdef NO_CLIPDISTANCE_SUPPORT - if (ClipDistanceA.x < 0 || ClipDistanceA.y < 0 || ClipDistanceA.z < 0 || ClipDistanceA.w < 0 || ClipDistanceB.x < 0) discard; -#endif - -#if defined(USE_LEVELMESH) - const int lightTileSize = 1 + 16 * 4; - uLightIndex = int(uint(gl_FragCoord.x) / 64 + uint(gl_FragCoord.y) / 64 * uLightTilesWidth) * lightTileSize; -#endif - +#ifdef SIMPLE3D Material material = CreateMaterial(); + FragColor = vec4(material.Base.rgb, 1.0); +#else + #ifdef NO_CLIPDISTANCE_SUPPORT + if (ClipDistanceA.x < 0 || ClipDistanceA.y < 0 || ClipDistanceA.z < 0 || ClipDistanceA.w < 0 || ClipDistanceB.x < 0) discard; + #endif -#ifndef NO_ALPHATEST - if (material.Base.a <= uAlphaThreshold) discard; -#endif + #if defined(USE_LEVELMESH) + const int lightTileSize = 1 + 16 * 4; + uLightIndex = int(uint(gl_FragCoord.x) / 64 + uint(gl_FragCoord.y) / 64 * uLightTilesWidth) * lightTileSize; + #endif -#ifndef ALPHATEST_ONLY + Material material = CreateMaterial(); -#ifdef USE_DEPTHFADETHRESHOLD - float behindFragmentDepth = texelFetch(LinearDepth, uViewOffset + ivec2(gl_FragCoord.xy), 0).r; - material.Base.a *= clamp((behindFragmentDepth - pixelpos.w) / uDepthFadeThreshold, 0.0, 1.0); -#endif + #ifndef NO_ALPHATEST + if (material.Base.a <= uAlphaThreshold) discard; + #endif - FragColor = ProcessLightMode(material); + #ifndef ALPHATEST_ONLY -#ifdef DITHERTRANS - int index = (int(pixelpos.x) % 8) * 8 + int(pixelpos.y) % 8; - const float DITHER_THRESHOLDS[64] = - float[64]( - 1.0 / 65.0, 33.0 / 65.0, 9.0 / 65.0, 41.0 / 65.0, 3.0 / 65.0, 35.0 / 65.0, 11.0 / 65.0, 43.0 / 65.0, - 49.0 / 65.0, 17.0 / 65.0, 57.0 / 65.0, 25.0 / 65.0, 51.0 / 65.0, 19.0 / 65.0, 59.0 / 65.0, 27.0 / 65.0, - 13.0 / 65.0, 45.0 / 65.0, 5.0 / 65.0, 37.0 / 65.0, 15.0 / 65.0, 47.0 / 65.0, 7.0 / 65.0, 39.0 / 65.0, - 61.0 / 65.0, 29.0 / 65.0, 53.0 / 65.0, 21.0 / 65.0, 63.0 / 65.0, 31.0 / 65.0, 55.0 / 65.0, 23.0 / 65.0, - 4.0 / 65.0, 36.0 / 65.0, 12.0 / 65.0, 44.0 / 65.0, 2.0 / 65.0, 34.0 / 65.0, 10.0 / 65.0, 42.0 / 65.0, - 52.0 / 65.0, 20.0 / 65.0, 60.0 / 65.0, 28.0 / 65.0, 50.0 / 65.0, 18.0 / 65.0, 58.0 / 65.0, 26.0 / 65.0, - 16.0 / 65.0, 48.0 / 65.0, 8.0 / 65.0, 40.0 / 65.0, 14.0 / 65.0, 46.0 / 65.0, 6.0 / 65.0, 38.0 / 65.0, - 64.0 / 65.0, 32.0 / 65.0, 56.0 / 65.0, 24.0 / 65.0, 62.0 / 65.0, 30.0 / 65.0, 54.0 / 65.0, 22.0 /65.0 - ); + #ifdef USE_DEPTHFADETHRESHOLD + float behindFragmentDepth = texelFetch(LinearDepth, uViewOffset + ivec2(gl_FragCoord.xy), 0).r; + material.Base.a *= clamp((behindFragmentDepth - pixelpos.w) / uDepthFadeThreshold, 0.0, 1.0); + #endif - vec3 fragHSV = rgb2hsv(FragColor.rgb); - float brightness = clamp(1.5*fragHSV.z, 0.1, 1.0); - if (DITHER_THRESHOLDS[index] < brightness) discard; - else FragColor *= 0.5; -#endif + FragColor = ProcessLightMode(material); -#ifdef GBUFFER_PASS - FragFog = vec4(AmbientOcclusionColor(), 1.0); - FragNormal = vec4(vEyeNormal.xyz * 0.5 + 0.5, 1.0); -#endif + #ifdef DITHERTRANS + int index = (int(pixelpos.x) % 8) * 8 + int(pixelpos.y) % 8; + const float DITHER_THRESHOLDS[64] = + float[64]( + 1.0 / 65.0, 33.0 / 65.0, 9.0 / 65.0, 41.0 / 65.0, 3.0 / 65.0, 35.0 / 65.0, 11.0 / 65.0, 43.0 / 65.0, + 49.0 / 65.0, 17.0 / 65.0, 57.0 / 65.0, 25.0 / 65.0, 51.0 / 65.0, 19.0 / 65.0, 59.0 / 65.0, 27.0 / 65.0, + 13.0 / 65.0, 45.0 / 65.0, 5.0 / 65.0, 37.0 / 65.0, 15.0 / 65.0, 47.0 / 65.0, 7.0 / 65.0, 39.0 / 65.0, + 61.0 / 65.0, 29.0 / 65.0, 53.0 / 65.0, 21.0 / 65.0, 63.0 / 65.0, 31.0 / 65.0, 55.0 / 65.0, 23.0 / 65.0, + 4.0 / 65.0, 36.0 / 65.0, 12.0 / 65.0, 44.0 / 65.0, 2.0 / 65.0, 34.0 / 65.0, 10.0 / 65.0, 42.0 / 65.0, + 52.0 / 65.0, 20.0 / 65.0, 60.0 / 65.0, 28.0 / 65.0, 50.0 / 65.0, 18.0 / 65.0, 58.0 / 65.0, 26.0 / 65.0, + 16.0 / 65.0, 48.0 / 65.0, 8.0 / 65.0, 40.0 / 65.0, 14.0 / 65.0, 46.0 / 65.0, 6.0 / 65.0, 38.0 / 65.0, + 64.0 / 65.0, 32.0 / 65.0, 56.0 / 65.0, 24.0 / 65.0, 62.0 / 65.0, 30.0 / 65.0, 54.0 / 65.0, 22.0 /65.0 + ); + vec3 fragHSV = rgb2hsv(FragColor.rgb); + float brightness = clamp(1.5*fragHSV.z, 0.1, 1.0); + if (DITHER_THRESHOLDS[index] < brightness) discard; + else FragColor *= 0.5; + #endif + + #ifdef GBUFFER_PASS + FragFog = vec4(AmbientOcclusionColor(), 1.0); + FragNormal = vec4(vEyeNormal.xyz * 0.5 + 0.5, 1.0); + #endif + #endif #endif } diff --git a/wadsrc/static/shaders/scene/includes.glsl b/wadsrc/static/shaders/scene/includes.glsl index 83ac427b3..4b6bb7640 100644 --- a/wadsrc/static/shaders/scene/includes.glsl +++ b/wadsrc/static/shaders/scene/includes.glsl @@ -7,3 +7,9 @@ #include "shaders/scene/light_spot.glsl" #endif + +#ifdef SIMPLE3D + +#include "shaders/scene/material.glsl" + +#endif \ No newline at end of file diff --git a/wadsrc/static/shaders/scene/lightmodel_normal.glsl b/wadsrc/static/shaders/scene/lightmodel_normal.glsl index 266fef963..72016e587 100644 --- a/wadsrc/static/shaders/scene/lightmodel_normal.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_normal.glsl @@ -1,97 +1,104 @@ -vec3 lightContribution(int i, vec3 normal) -{ - vec4 lightpos = lights[i]; - vec4 lightcolor = lights[i+1]; - vec4 lightspot1 = lights[i+2]; - vec4 lightspot2 = lights[i+3]; - - float radius = abs(lightpos.w); - - float lightdistance = distance(lightpos.xyz, pixelpos.xyz); - if (radius < lightdistance) - return vec3(0.0); // Early out lights touching surface but not this fragment - - vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz); - float dotprod = dot(normal, lightdir); - if (dotprod < -0.0001) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases. Note that this can cause precision issues. - - float attenuation = distanceAttenuation(lightdistance, radius, lightspot2.w, lightspot1.w); - - if (lightpos.w < 0.0) - attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y); // Sign bit is the spotlight flag - - if (lightcolor.a < 0.0) // Sign bit is the attenuated light flag +#ifndef SIMPLE3D + vec3 lightContribution(int i, vec3 normal) { - attenuation *= clamp(dotprod, 0.0, 1.0); - } + vec4 lightpos = lights[i]; + vec4 lightcolor = lights[i+1]; + vec4 lightspot1 = lights[i+2]; + vec4 lightspot2 = lights[i+3]; + + float radius = abs(lightpos.w); - if (attenuation > 0.0) // Skip shadow map test if possible - { - attenuation *= shadowAttenuation(lightpos, lightcolor.a, lightspot2.z); - return lightcolor.rgb * attenuation; - } - else - { - return vec3(0.0); - } -} + float lightdistance = distance(lightpos.xyz, pixelpos.xyz); + if (radius < lightdistance) + return vec3(0.0); // Early out lights touching surface but not this fragment -vec3 ProcessMaterialLight(Material material, vec3 color) -{ - vec4 dynlight = uDynLightColor; - vec3 normal = material.Normal; + vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz); + float dotprod = dot(normal, lightdir); + if (dotprod < -0.0001) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases. Note that this can cause precision issues. - if (uLightIndex >= 0) - { - ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1); - if (lightRange.z > lightRange.x) + float attenuation = distanceAttenuation(lightdistance, radius, lightspot2.w, lightspot1.w); + + if (lightpos.w < 0.0) + attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y); // Sign bit is the spotlight flag + + if (lightcolor.a < 0.0) // Sign bit is the attenuated light flag { - // modulated lights - for(int i=lightRange.x; i= 0) - { - ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1); - if (lightRange.w > lightRange.z) + if (attenuation > 0.0) // Skip shadow map test if possible { - vec4 addlight = vec4(0.0,0.0,0.0,0.0); - - // additive lights - for(int i=lightRange.z; i= 0) + { + ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1); + if (lightRange.z > lightRange.x) + { + // modulated lights + for(int i=lightRange.x; i= 0) + { + ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1); + if (lightRange.w > lightRange.z) + { + vec4 addlight = vec4(0.0,0.0,0.0,0.0); + + // additive lights + for(int i=lightRange.z; i