diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index a2412e46b..ccf77b21e 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -112,6 +112,9 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key) { "dithertrans", "shaders/scene/frag_main.glsl", "shaders/scene/material_default.glsl", "shaders/scene/mateffect_default.glsl", "shaders/scene/lightmodel_shared.glsl", "shaders/scene/lightmodel_normal.glsl", "#define NO_ALPHATEST\n#define DITHERTRANS\n" }, }; + VkShaderKey customKey = key; + customKey.AlphaTest = false; + const auto& desc = effectshaders[key.SpecialEffect]; program.vert = LoadVertShader(desc.ShaderName, mainvp, nullptr, desc.defines, key, nullptr); if (!key.NoFragmentShader) @@ -274,7 +277,7 @@ static void AddBuiltinFields(FString &layoutBlock, int &index, bool is_in, const } } -void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader) +void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader) { bool hasClipDistance = fb->GetDevice()->EnabledFeatures.Features.shaderClipDistance; @@ -293,6 +296,17 @@ void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const } layoutBlock << " int uBoneIndexBase; // bone animation\n"; layoutBlock << " int uFogballIndex; // fog balls\n"; + + if(isUberShader) + { + layoutBlock << " int uShaderKey1;\n"; + layoutBlock << " int uShaderKey2;\n"; + } + else + { + layoutBlock << " int unused2;\n"; + layoutBlock << " int unused3;\n"; + } if(shader && shader->Uniforms.UniformStructSize) { @@ -326,7 +340,7 @@ void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const } } -void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defines, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader) +void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defines, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader) { if (fb->IsRayQueryEnabled()) { @@ -352,87 +366,174 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin definesBlock << "#define NO_CLIPDISTANCE_SUPPORT\n"; } - 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.Simple) definesBlock << "#define SIMPLE\n"; - if (key.Simple3D) definesBlock << "#define SIMPLE3D\n"; - - switch(key.LightBlendMode) + if(isUberShader) { - case 0: - definesBlock << "#define LIGHT_BLEND_CLAMPED\n"; - break; - case 1: - definesBlock << "#define LIGHT_BLEND_COLORED_CLAMP\n"; - break; - case 2: - definesBlock << "#define LIGHT_BLEND_UNCLAMPED\n"; - break; - } + //ugh EffectState also controls layout, because specular/pbr/etc defines switch texture indices around for normal/specular/etc - switch(key.LightAttenuationMode) + definesBlock << LoadPrivateShaderLump("shaders/shaderkey.glsl").GetChars() << "\n"; + + definesBlock << "#define UBERSHADERS\n"; + + definesBlock << "#define DO_ALPHATEST ((uShaderKey1 & SK1_ALPHATEST) != 0)\n"; + + //definesBlock << "#define SIMPLE ((uShaderKey1 & SK1_SIMPLE) != 0)\n"; + //definesBlock << "#define SIMPLE3D ((uShaderKey1 & SK1_SIMPLE3D) != 0)\n"; + // controls layout + if (key.Simple) definesBlock << "#define SIMPLE\n"; + if (key.Simple3D) definesBlock << "#define SIMPLE3D\n"; + + definesBlock << "#define SIMPLE2D ((uShaderKey1 & SK1_SIMPLE2D) != 0)\n"; + + definesBlock << "#define TM_STENCIL (SK_GET_TEXTUREMODE() == SK1_TM_STENCIL)\n"; + definesBlock << "#define TM_OPAQUE (SK_GET_TEXTUREMODE() == SK1_TM_OPAQUE)\n"; + definesBlock << "#define TM_INVERSE (SK_GET_TEXTUREMODE() == SK1_TM_INVERSE)\n"; + definesBlock << "#define TM_ALPHATEXTURE (SK_GET_TEXTUREMODE() == SK1_TM_ALPHATEXTURE)\n"; + definesBlock << "#define TM_CLAMPY (SK_GET_TEXTUREMODE() == SK1_TM_CLAMPY)\n"; + definesBlock << "#define TM_INVERTOPAQUE (SK_GET_TEXTUREMODE() == SK1_TM_INVERTOPAQUE)\n"; + definesBlock << "#define TM_FOGLAYER (SK_GET_TEXTUREMODE() == SK1_TM_FOGLAYER)\n"; + + definesBlock << "#define TEXF_ClampY ((uShaderKey1 & SK1_TEXF_CLAMPY) != 0)\n"; + definesBlock << "#define TEXF_Brightmap ((uShaderKey1 & SK1_TEXF_BRIGHTMAP) != 0)\n"; + definesBlock << "#define TEXF_Detailmap ((uShaderKey1 & SK1_TEXF_DETAILMAP) != 0)\n"; + definesBlock << "#define TEXF_Glowmap ((uShaderKey1 & SK1_TEXF_GLOWMAP) != 0)\n"; + + definesBlock << "#define GBUFFER_PASS ((uShaderKey1 & SK1_GBUFFER_PASS) != 0)\n"; + + definesBlock << "#define USE_SHADOWMAP ((uShaderKey1 & SK1_USE_SHADOWMAP) != 0)\n"; + + definesBlock << "#define USE_RAYTRACE ((uShaderKey1 & SK1_USE_RAYTRACE) != 0)\n"; + definesBlock << "#define USE_RAYTRACE_PRECISE ((uShaderKey1 & SK1_USE_RAYTRACE_PRECISE) != 0)\n"; + definesBlock << "#define PRECISE_MIDTEXTURES ((uShaderKey1 & SK1_PRECISE_MIDTEXTURES) != 0)\n"; + + definesBlock << "#define SHADOWMAP_FILTER (SK_GET_SHADOWMAP_FILTER())\n"; + + definesBlock << "#define FOG_BEFORE_LIGHTS ((uShaderKey1 & SK1_FOG_BEFORE_LIGHTS) != 0)\n"; + definesBlock << "#define FOG_AFTER_LIGHTS ((uShaderKey1 & SK1_FOG_AFTER_LIGHTS) != 0)\n"; + definesBlock << "#define FOG_RADIAL ((uShaderKey1 & SK1_FOG_RADIAL) != 0)\n"; + + definesBlock << "#define SWLIGHT_RADIAL ((uShaderKey1 & SK1_SWLIGHT_RADIAL) != 0)\n"; + definesBlock << "#define SWLIGHT_BANDED ((uShaderKey1 & SK1_SWLIGHT_BANDED) != 0)\n"; + + definesBlock << "#define LIGHTMODE_DEFAULT (SK_GET_LIGHTMODE() == SK1_LIGHTMODE_DEFAULT)\n"; + definesBlock << "#define LIGHTMODE_SOFTWARE (SK_GET_LIGHTMODE() == SK1_LIGHTMODE_SOFTWARE)\n"; + definesBlock << "#define LIGHTMODE_VANILLA (SK_GET_LIGHTMODE() == SK1_LIGHTMODE_VANILLA)\n"; + definesBlock << "#define LIGHTMODE_BUILD (SK_GET_LIGHTMODE() == SK1_LIGHTMODE_BUILD)\n"; + + definesBlock << "#define LIGHT_BLEND_CLAMPED (SK_GET_LIGHTBLENDMODE() == SK1_LIGHT_BLEND_CLAMPED)\n"; + definesBlock << "#define LIGHT_BLEND_COLORED_CLAMP (SK_GET_LIGHTBLENDMODE() == SK1_LIGHT_LIGHT_BLEND_COLORED_CLAMP)\n"; + definesBlock << "#define LIGHT_BLEND_UNCLAMPED (SK_GET_LIGHTBLENDMODE() == SK1_LIGHT_BLEND_UNCLAMPED)\n"; + + definesBlock << "#define LIGHT_ATTENUATION_LINEAR ((uShaderKey1 & SK1_TEXTUREMODE) == 0)\n"; + definesBlock << "#define LIGHT_ATTENUATION_INVERSE_SQUARE ((uShaderKey1 & SK1_TEXTUREMODE) != 0)\n"; + + //definesBlock << "#define USE_LEVELMESH (!!(uShaderKey1 & SK1_USE_LEVELMESH))\n"; + // controls layout + if (key.UseLevelMesh) definesBlock << "#define USE_LEVELMESH\n"; + + definesBlock << "#define FOGBALLS ((uShaderKey1 & SK1_FOGBALLS) != 0)\n"; + + //key.NoFragmentShader not used in defines + + definesBlock << "#define USE_DEPTHFADETHRESHOLD ((uShaderKey2 & SK2_USE_DEPTHFADETHRESHOLD) != 0)\n"; + definesBlock << "#define NOT_ALPHATEST_ONLY ((uShaderKey2 & SK2_ALPHATEST_ONLY) == 0)\n"; + + //definesBlock << "#define SHADE_VERTEX ((uShaderKey2 & SK2_SHADE_VERTEX) != 0)\n"; + // controls layout + if (key.ShadeVertex) definesBlock << "#define SHADE_VERTEX\n"; + + definesBlock << "#define LIGHT_NONORMALS ((uShaderKey2 & SK2_LIGHT_NONORMALS) != 0)\n"; + definesBlock << "#define USE_SPRITE_CENTER ((uShaderKey2 & SK2_USE_SPRITECENTER) != 0)\n"; + + definesBlock << "#define uFogEnabled ((uShaderKey1 & SK1_SIMPLE2D) ? -3 : 0)\n"; + } + else { - case 0: - definesBlock << "#define LIGHT_ATTENUATION_LINEAR\n"; - break; - case 1: - definesBlock << "#define LIGHT_ATTENUATION_INVERSE_SQUARE\n"; - break; + if (key.AlphaTest) definesBlock << "#define DO_ALPHATEST\n"; + if (key.Simple) definesBlock << "#define SIMPLE\n"; + if (key.Simple2D) definesBlock << "#define SIMPLE2D\n"; + if (key.Simple3D) definesBlock << "#define SIMPLE3D\n"; + + switch (key.TextureMode) + { + case TM_STENCIL: definesBlock << "#define TM_STENCIL\n"; break; + case TM_OPAQUE: definesBlock << "#define TM_OPAQUE\n"; break; + case TM_INVERSE: definesBlock << "#define TM_INVERSE\n"; break; + case TM_ALPHATEXTURE: definesBlock << "#define TM_ALPHATEXTURE\n"; break; + case TM_CLAMPY: definesBlock << "#define TM_CLAMPY\n"; break; + case TM_INVERTOPAQUE: definesBlock << "#define TM_INVERTOPAQUE\n"; break; + case TM_FOGLAYER: definesBlock << "#define TM_FOGLAYER\n"; break; + } + + if (key.ClampY) definesBlock << "#define TEXF_ClampY\n"; + if (key.Brightmap) definesBlock << "#define TEXF_Brightmap\n"; + if (key.Detailmap) definesBlock << "#define TEXF_Detailmap\n"; + if (key.Glowmap) definesBlock << "#define TEXF_Glowmap\n"; + + if (key.GBufferPass) definesBlock << "#define GBUFFER_PASS\n"; + + if (key.UseShadowmap) definesBlock << "#define USE_SHADOWMAP\n"; + + + if (key.UseRaytrace) definesBlock << "#define USE_RAYTRACE\n"; + if (key.UseRaytracePrecise) definesBlock << "#define USE_RAYTRACE_PRECISE\n"; + if (key.PreciseMidtextureTrace) definesBlock << "#define PRECISE_MIDTEXTURES\n"; + + definesBlock << "#define SHADOWMAP_FILTER " << std::to_string(key.ShadowmapFilter).c_str() << "\n"; + + if (key.FogBeforeLights) definesBlock << "#define FOG_BEFORE_LIGHTS\n"; + if (key.FogAfterLights) definesBlock << "#define FOG_AFTER_LIGHTS\n"; + if (key.FogRadial) definesBlock << "#define FOG_RADIAL\n"; + + if (key.SWLightRadial) definesBlock << "#define SWLIGHT_RADIAL\n"; + if (key.SWLightBanded) definesBlock << "#define SWLIGHT_BANDED\n"; + + switch (key.LightMode) + { + case 0: definesBlock << "#define LIGHTMODE_DEFAULT\n"; break; + case 1: definesBlock << "#define LIGHTMODE_SOFTWARE\n"; break; + case 2: definesBlock << "#define LIGHTMODE_VANILLA\n"; break; + case 3: definesBlock << "#define LIGHTMODE_BUILD\n"; break; + } + + switch(key.LightBlendMode) + { + case 0: + definesBlock << "#define LIGHT_BLEND_CLAMPED\n"; + break; + case 1: + definesBlock << "#define LIGHT_BLEND_COLORED_CLAMP\n"; + break; + case 2: + definesBlock << "#define LIGHT_BLEND_UNCLAMPED\n"; + break; + } + + switch(key.LightAttenuationMode) + { + case 0: + definesBlock << "#define LIGHT_ATTENUATION_LINEAR\n"; + break; + case 1: + definesBlock << "#define LIGHT_ATTENUATION_INVERSE_SQUARE\n"; + break; + } + + if (key.UseLevelMesh) definesBlock << "#define USE_LEVELMESH\n"; + if (key.FogBalls) definesBlock << "#define FOGBALLS\n"; + + //key.NoFragmentShader not used in defines + + if (key.DepthFadeThreshold) definesBlock << "#define USE_DEPTHFADETHRESHOLD\n"; + + if (!key.AlphaTestOnly) definesBlock << "#define NOT_ALPHATEST_ONLY\n"; + + if (key.ShadeVertex) definesBlock << "#define SHADE_VERTEX\n"; + if (key.LightNoNormals) definesBlock << "#define LIGHT_NONORMALS\n"; + if (key.UseSpriteCenter) definesBlock << "#define USE_SPRITE_CENTER\n"; + + definesBlock << ((key.Simple2D) ? "#define uFogEnabled -3\n" : "#define uFogEnabled 0\n"); } - if (key.DepthFadeThreshold) definesBlock << "#define USE_DEPTHFADETHRESHOLD\n"; - - if (key.Simple2D) definesBlock << "#define SIMPLE2D\n"; - if (key.ClampY) definesBlock << "#define TEXF_ClampY\n"; - if (key.Brightmap) definesBlock << "#define TEXF_Brightmap\n"; - if (key.Detailmap) definesBlock << "#define TEXF_Detailmap\n"; - if (key.Glowmap) definesBlock << "#define TEXF_Glowmap\n"; - - if (key.UseRaytrace) definesBlock << "#define USE_RAYTRACE\n"; - if (key.UseRaytracePrecise) definesBlock << "#define USE_RAYTRACE_PRECISE\n"; - if (key.PreciseMidtextureTrace) definesBlock << "#define PRECISE_MIDTEXTURES\n"; - - definesBlock << "#define SHADOWMAP_FILTER "; - definesBlock << std::to_string(key.ShadowmapFilter).c_str(); - definesBlock << "\n"; - - if (key.UseShadowmap) definesBlock << "#define USE_SHADOWMAP\n"; - if (key.UseLevelMesh) definesBlock << "#define USE_LEVELMESH\n"; - - switch (key.TextureMode) - { - case TM_STENCIL: definesBlock << "#define TM_STENCIL\n"; break; - case TM_OPAQUE: definesBlock << "#define TM_OPAQUE\n"; break; - case TM_INVERSE: definesBlock << "#define TM_INVERSE\n"; break; - case TM_ALPHATEXTURE: definesBlock << "#define TM_ALPHATEXTURE\n"; break; - case TM_CLAMPY: definesBlock << "#define TM_CLAMPY\n"; break; - case TM_INVERTOPAQUE: definesBlock << "#define TM_INVERTOPAQUE\n"; break; - case TM_FOGLAYER: definesBlock << "#define TM_FOGLAYER\n"; break; - } - - switch (key.LightMode) - { - case 0: definesBlock << "#define LIGHTMODE_DEFAULT\n"; break; - case 1: definesBlock << "#define LIGHTMODE_SOFTWARE\n"; break; - case 2: definesBlock << "#define LIGHTMODE_VANILLA\n"; break; - case 3: definesBlock << "#define LIGHTMODE_BUILD\n"; break; - } - - if (key.FogBeforeLights) definesBlock << "#define FOG_BEFORE_LIGHTS\n"; - if (key.FogAfterLights) definesBlock << "#define FOG_AFTER_LIGHTS\n"; - if (key.FogRadial) definesBlock << "#define FOG_RADIAL\n"; - if (key.SWLightRadial) definesBlock << "#define SWLIGHT_RADIAL\n"; - if (key.SWLightBanded) definesBlock << "#define SWLIGHT_BANDED\n"; - if (key.FogBalls) definesBlock << "#define FOGBALLS\n"; - - - if (key.ShadeVertex) definesBlock << "#define SHADE_VERTEX\n"; - if (key.LightNoNormals) definesBlock << "#define LIGHT_NONORMALS\n"; - if (key.UseSpriteCenter) definesBlock << "#define USE_SPRITE_CENTER\n"; - - definesBlock << ((key.Simple2D) ? "#define uFogEnabled -3\n" : "#define uFogEnabled 0\n"); - // Setup fake variables for the 'in' attributes that aren't actually available because the garbage shader code thinks they exist // God I hate this engine... :( std::vector definedFields(vertexShaderInputs.size()); @@ -631,19 +732,47 @@ ShaderIncludeResult VkShaderManager::OnInclude(FString headerName, FString inclu return ShaderIncludeResult(headerName.GetChars(), code.GetChars()); } -FString VkShaderManager::LoadPublicShaderLump(const char *lumpname) +FString VkShaderManager::LoadPublicShaderLump(const char *lumpname, bool isUberShader) { int lump = fileSystem.CheckNumForFullName(lumpname, 0); if (lump == -1) lump = fileSystem.CheckNumForFullName(lumpname); if (lump == -1) I_Error("Unable to load '%s'", lumpname); - return GetStringFromLump(lump); + + return LoadShaderLump(lump, isUberShader); } -FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname) +FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname, bool isUberShader) { int lump = fileSystem.CheckNumForFullName(lumpname, 0); if (lump == -1) I_Error("Unable to load '%s'", lumpname); - return GetStringFromLump(lump); + + return LoadShaderLump(lump, isUberShader); +} + +FString VkShaderManager::LoadShaderLump(int lumpnum, bool isUberShader) +{ + FString str = GetStringFromLump(lumpnum); + + if(isUberShader) + { + str.Substitute("#uifdef", "if"); + str.Substitute("#uelifdef", "else if"); + str.Substitute("#uif", "if"); + str.Substitute("#uelif", "else if"); + str.Substitute("#uelse", "else"); + str.Substitute("#uendif", ""); + } + else + { + str.Substitute("#uifdef", "#if defined"); + str.Substitute("#uelifdef", "#elif defined"); + str.Substitute("#uif", "#if"); + str.Substitute("#uelif", "#elif"); + str.Substitute("#uelse", "#else"); + str.Substitute("#uendif", "#endif"); + } + + return str; } VkPPShader* VkShaderManager::GetVkShader(PPShader* shader) diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index 2c774b625..900616a72 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -55,6 +55,7 @@ struct PushConstants int uLightIndex; // dynamic lights int uBoneIndexBase; // bone animation int uFogballIndex; // fog balls + uint64_t shaderKey; }; struct ZMinMaxPushConstants @@ -93,25 +94,25 @@ public: uint64_t GBufferPass : 1; // GBUFFER_PASS uint64_t UseShadowmap : 1; // USE_SHADOWMAP uint64_t UseRaytrace : 1; // USE_RAYTRACE + uint64_t UseRaytracePrecise : 1; // USE_RAYTRACE_PRECISE + uint64_t PreciseMidtextureTrace : 1; // PRECISE_MIDTEXTURES + uint64_t ShadowmapFilter : 4; // SHADOWMAP_FILTER uint64_t FogBeforeLights : 1; // FOG_BEFORE_LIGHTS uint64_t FogAfterLights : 1; // FOG_AFTER_LIGHTS uint64_t FogRadial : 1; // FOG_RADIAL uint64_t SWLightRadial : 1; // SWLIGHT_RADIAL uint64_t SWLightBanded : 1; // SWLIGHT_BANDED uint64_t LightMode : 2; // LIGHTMODE_DEFAULT, LIGHTMODE_SOFTWARE, LIGHTMODE_VANILLA, LIGHTMODE_BUILD + uint64_t LightBlendMode : 2; // LIGHT_BLEND_CLAMPED , LIGHT_BLEND_COLORED_CLAMP , LIGHT_BLEND_UNCLAMPED + uint64_t LightAttenuationMode : 1; // LIGHT_ATTENUATION_LINEAR , LIGHT_ATTENUATION_INVERSE_SQUARE uint64_t UseLevelMesh : 1; // USE_LEVELMESH uint64_t FogBalls : 1; // FOGBALLS uint64_t NoFragmentShader : 1; uint64_t DepthFadeThreshold : 1; uint64_t AlphaTestOnly : 1; // ALPHATEST_ONLY - uint64_t LightBlendMode : 2; // LIGHT_BLEND_CLAMPED , LIGHT_BLEND_COLORED_CLAMP , LIGHT_BLEND_UNCLAMPED - 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 ShadeVertex : 1; // SHADE_VERTEX uint64_t LightNoNormals : 1; // LIGHT_NONORMALS uint64_t UseSpriteCenter : 1; // USE_SPRITE_CENTER - uint64_t PreciseMidtextureTrace : 1; // PRECISE_MIDTEXTURES uint64_t Unused : 26; }; uint64_t AsQWORD = 0; @@ -166,11 +167,13 @@ private: ShaderIncludeResult OnInclude(FString headerName, FString includerName, size_t depth, bool system); FString GetVersionBlock(); - FString LoadPublicShaderLump(const char *lumpname); - FString LoadPrivateShaderLump(const char *lumpname); + FString LoadPublicShaderLump(const char *lumpname, bool isUberShader = false); + FString LoadPrivateShaderLump(const char *lumpname, bool isUberShader = false); + + FString LoadShaderLump(int lumpnum, bool isUberShader); - void BuildLayoutBlock(FString &definesBlock, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader); - void BuildDefinesBlock(FString &definesBlock, const char *defines, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader); + void BuildLayoutBlock(FString &definesBlock, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader = false); + void BuildDefinesBlock(FString &definesBlock, const char *defines, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader = false); VulkanRenderDevice* fb = nullptr; diff --git a/wadsrc/static/shaders/binding_struct_definitions.glsl b/wadsrc/static/shaders/binding_struct_definitions.glsl index 92d9342df..c17852701 100644 --- a/wadsrc/static/shaders/binding_struct_definitions.glsl +++ b/wadsrc/static/shaders/binding_struct_definitions.glsl @@ -149,7 +149,7 @@ struct DynLightInfo vec3 color; float padding1; vec3 spotDir; float padding2; float radius; - float linarity; + float linearity; float softShadowRadius; float strength; float spotInnerAngle; diff --git a/wadsrc/static/shaders/scene/frag_fogboundary.glsl b/wadsrc/static/shaders/scene/frag_fogboundary.glsl index ba8a06587..43d9cb9ec 100644 --- a/wadsrc/static/shaders/scene/frag_fogboundary.glsl +++ b/wadsrc/static/shaders/scene/frag_fogboundary.glsl @@ -4,18 +4,21 @@ void main() // // calculate fog factor // - - #if defined(FOG_RADIAL) + + #uifdef(FOG_RADIAL) float fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); - #else + #uelse float fogdist = max(16.0, pixelpos.w); - #endif + #uendif float fogfactor = exp2 (uFogDensity * fogdist); - + FragColor = vec4(uFogColor.rgb, 1.0 - fogfactor); -#ifdef GBUFFER_PASS + +#uifdef(GBUFFER_PASS) +{ FragFog = vec4(0.0, 0.0, 0.0, 1.0); FragNormal = vec4(0.5, 0.5, 0.5, 1.0); -#endif +} +#uendif } diff --git a/wadsrc/static/shaders/scene/frag_main.glsl b/wadsrc/static/shaders/scene/frag_main.glsl index 465918a01..74fc62452 100644 --- a/wadsrc/static/shaders/scene/frag_main.glsl +++ b/wadsrc/static/shaders/scene/frag_main.glsl @@ -17,10 +17,13 @@ vec3 rgb2hsv(vec3 c) void main() { -#ifdef SIMPLE3D +#uifdef(SIMPLE3D) +{ Material material = CreateMaterial(); FragColor = vec4(material.Base.rgb, 1.0); -#else +} +#uelse +{ #ifdef NO_CLIPDISTANCE_SUPPORT if (ClipDistanceA.x < 0 || ClipDistanceA.y < 0 || ClipDistanceA.z < 0 || ClipDistanceA.w < 0 || ClipDistanceB.x < 0) discard; #endif @@ -32,16 +35,18 @@ void main() Material material = CreateMaterial(); - #ifndef NO_ALPHATEST + #uifdef(DO_ALPHATEST) if (material.Base.a <= uAlphaThreshold) discard; - #endif + #uendif - #ifndef ALPHATEST_ONLY - - #ifdef USE_DEPTHFADETHRESHOLD + #uifdef(NOT_ALPHATEST_ONLY) + { + #uifdef(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 + } + #uendif FragColor = ProcessLightMode(material); @@ -65,10 +70,14 @@ void main() else FragColor *= 0.5; #endif - #ifdef GBUFFER_PASS + #uifdef(GBUFFER_PASS) + { FragFog = vec4(AmbientOcclusionColor(), 1.0); FragNormal = vec4(vEyeNormal.xyz * 0.5 + 0.5, 1.0); - #endif - #endif -#endif + } + #uendif + } + #uendif +} +#uendif } diff --git a/wadsrc/static/shaders/scene/frag_portal.glsl b/wadsrc/static/shaders/scene/frag_portal.glsl index 355cf5282..2d264d855 100644 --- a/wadsrc/static/shaders/scene/frag_portal.glsl +++ b/wadsrc/static/shaders/scene/frag_portal.glsl @@ -2,9 +2,11 @@ void main() { FragColor = vec4(0.0, 1.0, 0.0, 1.0); -#ifdef GBUFFER_PASS +#uifdef(GBUFFER_PASS) +{ FragFog = vec4(0.0, 0.0, 0.0, 1.0); FragNormal = vec4(0.5, 0.5, 0.5, 1.0); -#endif +} +#uendif } diff --git a/wadsrc/static/shaders/scene/frag_stencil.glsl b/wadsrc/static/shaders/scene/frag_stencil.glsl index 0a305b356..51e223558 100644 --- a/wadsrc/static/shaders/scene/frag_stencil.glsl +++ b/wadsrc/static/shaders/scene/frag_stencil.glsl @@ -2,9 +2,11 @@ void main() { FragColor = vec4(1.0, 1.0, 1.0, 0.0); -#ifdef GBUFFER_PASS +#uifdef(GBUFFER_PASS) +{ FragFog = vec4(0.0, 0.0, 0.0, 1.0); FragNormal = vec4(0.5, 0.5, 0.5, 1.0); -#endif +} +#uendif } diff --git a/wadsrc/static/shaders/scene/layout_shared.glsl b/wadsrc/static/shaders/scene/layout_shared.glsl index a4097d681..0da348970 100644 --- a/wadsrc/static/shaders/scene/layout_shared.glsl +++ b/wadsrc/static/shaders/scene/layout_shared.glsl @@ -5,23 +5,23 @@ // material types #if defined(SPECULAR) -#define normaltexture texture2 -#define speculartexture texture3 -#define brighttexture texture4 -#define detailtexture texture5 -#define glowtexture texture6 + #define normaltexture texture2 + #define speculartexture texture3 + #define brighttexture texture4 + #define detailtexture texture5 + #define glowtexture texture6 #elif defined(PBR) -#define normaltexture texture2 -#define metallictexture texture3 -#define roughnesstexture texture4 -#define aotexture texture5 -#define brighttexture texture6 -#define detailtexture texture7 -#define glowtexture texture8 + #define normaltexture texture2 + #define metallictexture texture3 + #define roughnesstexture texture4 + #define aotexture texture5 + #define brighttexture texture6 + #define detailtexture texture7 + #define glowtexture texture8 #else -#define brighttexture texture2 -#define detailtexture texture3 -#define glowtexture texture4 + #define brighttexture texture2 + #define detailtexture texture3 + #define glowtexture texture4 #endif #define BrdfLUT 1 // the BRDF convoluted texture is always in this texture slot @@ -59,14 +59,14 @@ #define uActorCenter data[uDataIndex].uActorCenter #if defined(USE_LEVELMESH) -#define uVertexColor lightdata[uDataIndex].uVertexColor -#define uDesaturationFactor lightdata[uDataIndex].uDesaturationFactor -#define uLightLevel lightdata[uDataIndex].uLightLevel -int uLightIndex; + #define uVertexColor lightdata[uDataIndex].uVertexColor + #define uDesaturationFactor lightdata[uDataIndex].uDesaturationFactor + #define uLightLevel lightdata[uDataIndex].uLightLevel + int uLightIndex; #else -#define uVertexColor data[uDataIndex].uVertexColor -#define uDesaturationFactor data[uDataIndex].uDesaturationFactor -#define uLightLevel data[uDataIndex].uLightLevel + #define uVertexColor data[uDataIndex].uVertexColor + #define uDesaturationFactor data[uDataIndex].uDesaturationFactor + #define uLightLevel data[uDataIndex].uLightLevel #endif #define VULKAN_COORDINATE_SYSTEM diff --git a/wadsrc/static/shaders/scene/light_shadow.glsl b/wadsrc/static/shaders/scene/light_shadow.glsl index 9566fbaec..5db968899 100644 --- a/wadsrc/static/shaders/scene/light_shadow.glsl +++ b/wadsrc/static/shaders/scene/light_shadow.glsl @@ -5,10 +5,11 @@ #if defined(USE_RAYTRACE) -#define shadowAttenuation(lightpos, shadowIndex, softShadowRadius, flags) traceShadow(lightpos, softShadowRadius) +#define shadowAttenuationRaytrace(lightpos, shadowIndex, softShadowRadius, flags) traceShadow(lightpos, softShadowRadius) -#elif defined(USE_SHADOWMAP) +#endif +#if defined(USE_SHADOWMAP) float shadowDirToU(vec2 dir) { if (abs(dir.y) > abs(dir.x)) @@ -124,14 +125,14 @@ float shadowmapAttenuation(vec3 lightpos, float shadowIndex) float v = (shadowIndex + 0.5) / 1024.0; - #if SHADOWMAP_FILTER == 0 + #uif(SHADOWMAP_FILTER == 0) return sampleShadowmap(planePoint, v); - #else + #uelse return sampleShadowmapPCF(planePoint, v); - #endif + #uendif } -float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius, int flags) +float shadowAttenuationShadowMap(vec3 lightpos, int shadowIndex, float softShadowRadius, int flags) { if((flags & LIGHTINFO_TRACE) > 0) { @@ -144,9 +145,10 @@ float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius, return shadowmapAttenuation(lightpos, float(shadowIndex)); } } -#else +#endif -float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius, int flags) +#if !defined(USE_RAYTRACE) && !defined(USE_SHADOWMAP) || defined(UBERSHADERS) +float shadowAttenuationNoShadow(vec3 lightpos, int shadowIndex, float softShadowRadius, int flags) { if((flags & LIGHTINFO_TRACE) > 0) { @@ -157,5 +159,33 @@ float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius, return 1.0; } } - #endif + + +#ifdef UBERSHADERS + + float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius, int flags) + { + if(USE_RAYTRACE) + { + return shadowAttenuationRaytrace(lightpos, shadowIndex, softShadowRadius, flags); + } + else if(USE_SHADOWMAP) + { + return shadowAttenuationShadowMap(lightpos, shadowIndex, softShadowRadius, flags); + } + else + { + return shadowAttenuationNoShadow(lightpos, shadowIndex, softShadowRadius, flags); + } + } + +#else + #if defined(USE_RAYTRACE) + #define shadowAttenuation(lightpos, shadowIndex, softShadowRadius, flags) shadowAttenuationRaytrace(lightpos, shadowIndex, softShadowRadius, flags) + #elif defined(USE_SHADOWMAP) + #define shadowAttenuation shadowAttenuationShadowMap + #else + #define shadowAttenuation shadowAttenuationNoShadow + #endif +#endif \ No newline at end of file diff --git a/wadsrc/static/shaders/scene/light_trace.glsl b/wadsrc/static/shaders/scene/light_trace.glsl index ff71f67d0..97666d647 100644 --- a/wadsrc/static/shaders/scene/light_trace.glsl +++ b/wadsrc/static/shaders/scene/light_trace.glsl @@ -15,9 +15,10 @@ float TraceDynLightRay(vec3 origin, float tmin, vec3 direction, float dist) for (int i = 0; i < 3; i++) { - #ifdef PRECISE_MIDTEXTURES - TraceResult result; - SurfaceInfo surface; + TraceResult result; + SurfaceInfo surface; + #uifdef(PRECISE_MIDTEXTURES) + { bool skip = true; { @@ -87,14 +88,16 @@ float TraceDynLightRay(vec3 origin, float tmin, vec3 direction, float dist) if (alpha <= 0.0) return 0.0; } - #else - TraceResult result = TraceFirstHit(origin, tmin, direction, dist); + } + #uelse + { + result = TraceFirstHit(origin, tmin, direction, dist); // Stop if we hit nothing - the point light is visible. if (result.primitiveIndex == -1) return alpha; - SurfaceInfo surface = GetSurface(result.primitiveIndex); + surface = GetSurface(result.primitiveIndex); // Pass through surface texture alpha = PassRayThroughSurfaceDynLight(surface, GetSurfaceUV(result.primitiveIndex, result.primitiveWeights), alpha); @@ -102,7 +105,8 @@ float TraceDynLightRay(vec3 origin, float tmin, vec3 direction, float dist) // Stop if there is no light left if (alpha <= 0.0) return 0.0; - #endif + } + #uendif // Move to surface hit point origin += direction * result.t; @@ -117,85 +121,102 @@ float TraceDynLightRay(vec3 origin, float tmin, vec3 direction, float dist) float traceHit(vec3 origin, vec3 direction, float dist) { - #if defined(USE_RAYTRACE_PRECISE) + #uifdef(USE_RAYTRACE_PRECISE) return TraceDynLightRay(origin, 0.01f, direction, dist); - #else + #uelse return TraceAnyHit(origin, 0.01f, direction, dist) ? 0.0 : 1.0; - #endif + #uendif } float traceShadow(vec3 lightpos, float softShadowRadius) { vec3 target = lightpos.xyz + 0.01; // nudge light position slightly as Doom maps tend to have their lights perfectly aligned with planes -#ifdef USE_SPRITE_CENTER - vec3 origin = uActorCenter.xyz; - vec3 direction = normalize(target - origin); -#elif defined(LIGHT_NONORMALS) - vec3 origin = pixelpos.xyz; - vec3 direction = normalize(target - origin); - origin -= direction; -#else - vec3 origin = pixelpos.xyz + (vWorldNormal.xyz * 0.1); - vec3 direction = normalize(target - origin); -#endif + vec3 origin; + vec3 direction; + #uifdef(USE_SPRITE_CENTER) + { + origin = uActorCenter.xyz; + direction = normalize(target - origin); + } + #uelifdef(LIGHT_NONORMALS) + { + origin = pixelpos.xyz; + direction = normalize(target - origin); + origin -= direction; + } + #uelse + { + origin = pixelpos.xyz + (vWorldNormal.xyz * 0.1); + direction = normalize(target - origin); + } + #uendif float dist = distance(origin, target); -#if SHADOWMAP_FILTER == 0 - return traceHit(origin, direction, dist); -#else - if (softShadowRadius == 0) - { + #uif(SHADOWMAP_FILTER == 0) return traceHit(origin, direction, dist); - } - else + #uelse + if (softShadowRadius == 0) + { + return traceHit(origin, direction, dist); + } + else + { + vec3 v = (abs(direction.x) > abs(direction.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); + vec3 xdir = normalize(cross(direction, v)); + vec3 ydir = cross(direction, xdir); + + float sum = 0.0; + const int step_count = SHADOWMAP_FILTER * 4; + for (int i = 0; i < step_count; i++) + { + vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * softShadowRadius; + vec3 pos = target + xdir * gridoffset.x + ydir * gridoffset.y; + sum += traceHit(origin, normalize(pos - origin), dist); + } + return (sum / step_count); + } + #uendif +} + +float traceSun(vec3 SunDir) +{ + vec3 origin; + #uifdef(USE_SPRITE_CENTER) { - vec3 v = (abs(direction.x) > abs(direction.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); - vec3 xdir = normalize(cross(direction, v)); - vec3 ydir = cross(direction, xdir); + origin = uActorCenter.xyz; + } + #uelifdef(LIGHT_NONORMALS) + { + origin = pixelpos.xyz; + origin -= SunDir; + } + #uelse + { + origin = pixelpos.xyz + (vWorldNormal.xyz * 0.1); + } + #uendif + + float dist = 65536.0; + + #uif(SHADOWMAP_FILTER == 0) + return TraceDynLightRay(origin, 0.01f, SunDir, dist); + #uelse + { + vec3 target = (SunDir * dist) + origin; + vec3 v = (abs(SunDir.x) > abs(SunDir.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); + vec3 xdir = normalize(cross(SunDir, v)); + vec3 ydir = cross(SunDir, xdir); float sum = 0.0; const int step_count = SHADOWMAP_FILTER * 4; for (int i = 0; i < step_count; i++) { - vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * softShadowRadius; + vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * 100.0; vec3 pos = target + xdir * gridoffset.x + ydir * gridoffset.y; - sum += traceHit(origin, normalize(pos - origin), dist); + sum += TraceDynLightRay(origin, 0.01f, normalize(pos - origin), dist); } return (sum / step_count); } -#endif -} - -float traceSun(vec3 SunDir) -{ -#ifdef USE_SPRITE_CENTER - vec3 origin = uActorCenter.xyz; -#elif defined(LIGHT_NONORMALS) - vec3 origin = pixelpos.xyz; - origin -= SunDir; -#else - vec3 origin = pixelpos.xyz + (vWorldNormal.xyz * 0.1); -#endif - - float dist = 65536.0; - -#if SHADOWMAP_FILTER == 0 - return TraceDynLightRay(origin, 0.01f, SunDir, dist); -#else - vec3 target = (SunDir * dist) + origin; - vec3 v = (abs(SunDir.x) > abs(SunDir.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); - vec3 xdir = normalize(cross(SunDir, v)); - vec3 ydir = cross(SunDir, xdir); - - float sum = 0.0; - const int step_count = SHADOWMAP_FILTER * 4; - for (int i = 0; i < step_count; i++) - { - vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * 100.0; - vec3 pos = target + xdir * gridoffset.x + ydir * gridoffset.y; - sum += TraceDynLightRay(origin, 0.01f, normalize(pos - origin), dist); - } - return (sum / step_count); -#endif + #uendif } \ No newline at end of file diff --git a/wadsrc/static/shaders/scene/lightmode.glsl b/wadsrc/static/shaders/scene/lightmode.glsl index 924243f4f..7a8eb56eb 100644 --- a/wadsrc/static/shaders/scene/lightmode.glsl +++ b/wadsrc/static/shaders/scene/lightmode.glsl @@ -22,15 +22,16 @@ vec4 getLightColor(Material material) { - #if defined(LIGHTMODE_DEFAULT) - vec4 color = Lightmode_Default(); - #elif defined(LIGHTMODE_SOFTWARE) - vec4 color = Lightmode_Software(); - #elif defined(LIGHTMODE_VANILLA) - vec4 color = Lightmode_Vanilla(); - #elif defined(LIGHTMODE_BUILD) - vec4 color = Lightmode_Build(); - #endif + vec4 color; + #uifdef(LIGHTMODE_DEFAULT) + color = Lightmode_Default(); + #uelifdef(LIGHTMODE_SOFTWARE) + color = Lightmode_Software(); + #uelifdef(LIGHTMODE_VANILLA) + color = Lightmode_Vanilla(); + #uelifdef(LIGHTMODE_BUILD) + color = Lightmode_Build(); + #uendif // // handle glowing walls @@ -74,23 +75,24 @@ vec4 getLightColor(Material material) // // colored fog // - #if defined(FOG_AFTER_LIGHTS) + #uifdef(FOG_AFTER_LIGHTS) + { + // calculate fog factor + float fogdist; + #uifdef(FOG_RADIAL) + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); + #uelse + fogdist = max(16.0, pixelpos.w); + #uendif + float fogfactor = exp2 (uFogDensity * fogdist); - // calculate fog factor - #if defined(FOG_RADIAL) - float fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); - #else - float fogdist = max(16.0, pixelpos.w); - #endif - float fogfactor = exp2 (uFogDensity * fogdist); + frag = vec4(mix(uFogColor.rgb, frag.rgb, fogfactor), frag.a); + } + #uendif - frag = vec4(mix(uFogColor.rgb, frag.rgb, fogfactor), frag.a); - - #endif - - #if defined(FOGBALLS) - frag = ProcessFogBalls(frag); - #endif + #uifdef(FOGBALLS) + frag = ProcessFogBalls(frag); + #uendif return frag; } @@ -100,54 +102,80 @@ vec4 getLightColor(Material material) vec3 AmbientOcclusionColor() { // calculate fog factor - #if defined(FOG_RADIAL) - float fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); - #else - float fogdist = max(16.0, pixelpos.w); - #endif + float fogdist; + #uifdef(FOG_RADIAL) + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); + #uelse + fogdist = max(16.0, pixelpos.w); + #uendif float fogfactor = exp2 (uFogDensity * fogdist); vec4 color = vec4(mix(uFogColor.rgb, vec3(0.0), fogfactor), 0.0); - #if defined(FOGBALLS) - color = ProcessFogBalls(color); - #endif + #uifdef(FOGBALLS) + color = ProcessFogBalls(color); + #uendif return color.rgb; } vec4 ProcessLightMode(Material material) { -#ifdef SIMPLE2D // uses the fog color to add a color overlay - #ifdef TM_FOGLAYER - vec4 frag = material.Base; - float gray = grayscale(frag); - vec4 cm = (uObjectColor + gray * (uAddColor - uObjectColor)) * 2; - frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a); - frag *= vColor; - frag.rgb = frag.rgb + uFogColor.rgb; - return frag; - #else - vec4 frag = material.Base * vColor; - frag.rgb = frag.rgb + uFogColor.rgb; - return frag; - #endif -#else - #ifdef TM_FOGLAYER - #if defined(FOG_BEFORE_LIGHTS) || defined(FOG_AFTER_LIGHTS) - #if defined(FOG_RADIAL) - float fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); - #else - float fogdist = max(16.0, pixelpos.w); - #endif - float fogfactor = exp2 (uFogDensity * fogdist); + #uifdef(SIMPLE2D) // uses the fog color to add a color overlay + { + #uifdef(TM_FOGLAYER) + { + vec4 frag = material.Base; + float gray = grayscale(frag); + vec4 cm = (uObjectColor + gray * (uAddColor - uObjectColor)) * 2; + frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a); + frag *= vColor; + frag.rgb = frag.rgb + uFogColor.rgb; + return frag; + } + #uelse + { + vec4 frag = material.Base * vColor; + frag.rgb = frag.rgb + uFogColor.rgb; + return frag; + } + #uendif + } + #uelse + { + #uifdef(TM_FOGLAYER) + { + #uifdef(FOG_BEFORE_LIGHTS) + { + float fogdist; + #uifdef(FOG_RADIAL) + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); + #uelse + fogdist = max(16.0, pixelpos.w); + #uendif + float fogfactor = exp2 (uFogDensity * fogdist); - return vec4(uFogColor.rgb, (1.0 - fogfactor) * material.Base.a * 0.75 * vColor.a); - #else - return vec4(uFogColor.rgb, material.Base.a * 0.75 * vColor.a); - #endif - #else - return getLightColor(material); - #endif -#endif + return vec4(uFogColor.rgb, (1.0 - fogfactor) * material.Base.a * 0.75 * vColor.a); + } + #uelifdef(FOG_AFTER_LIGHTS) + { // duplicated, TODO figure out how to handle || in uifdef + float fogdist; + #uifdef(FOG_RADIAL) + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); + #uelse + fogdist = max(16.0, pixelpos.w); + #uendif + float fogfactor = exp2 (uFogDensity * fogdist); + + return vec4(uFogColor.rgb, (1.0 - fogfactor) * material.Base.a * 0.75 * vColor.a); + } + #uelse + return vec4(uFogColor.rgb, material.Base.a * 0.75 * vColor.a); + #uendif + } + #uelse + return getLightColor(material); + #uendif + } + #uendif } diff --git a/wadsrc/static/shaders/scene/lightmode_build.glsl b/wadsrc/static/shaders/scene/lightmode_build.glsl index 9298a36ff..b1300e2b1 100644 --- a/wadsrc/static/shaders/scene/lightmode_build.glsl +++ b/wadsrc/static/shaders/scene/lightmode_build.glsl @@ -2,11 +2,12 @@ vec4 Lightmode_Build() { // z is the depth in view space, positive going into the screen - #if defined(SWLIGHT_RADIAL) - float z = distance(pixelpos.xyz, uCameraPos.xyz); - #else - float z = pixelpos.w; - #endif + float z; + #uifdef(SWLIGHT_RADIAL) + z = distance(pixelpos.xyz, uCameraPos.xyz); + #uelse + z = pixelpos.w; + #uendif // This is a lot more primitive than Doom's lighting... float numShades = float(uPalLightLevels & 255); diff --git a/wadsrc/static/shaders/scene/lightmode_default.glsl b/wadsrc/static/shaders/scene/lightmode_default.glsl index e26826510..d700d2ec9 100644 --- a/wadsrc/static/shaders/scene/lightmode_default.glsl +++ b/wadsrc/static/shaders/scene/lightmode_default.glsl @@ -3,14 +3,15 @@ vec4 Lightmode_Default() { vec4 color = vColor; - #if defined(FOG_BEFORE_LIGHTS) - + #uifdef(FOG_BEFORE_LIGHTS) + { // calculate fog factor - #if defined(FOG_RADIAL) - float fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); - #else - float fogdist = max(16.0, pixelpos.w); - #endif + float fogdist; + #uifdef(FOG_RADIAL) + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); + #uelse + fogdist = max(16.0, pixelpos.w); + #uendif float fogfactor = exp2 (uFogDensity * fogdist); // brightening around the player for light mode 2 @@ -21,8 +22,8 @@ vec4 Lightmode_Default() // apply light diminishing through fog equation color.rgb = mix(vec3(0.0, 0.0, 0.0), color.rgb, fogfactor); - - #endif + } + #uendif return color; } diff --git a/wadsrc/static/shaders/scene/lightmode_software.glsl b/wadsrc/static/shaders/scene/lightmode_software.glsl index 2b1048e82..54b168340 100644 --- a/wadsrc/static/shaders/scene/lightmode_software.glsl +++ b/wadsrc/static/shaders/scene/lightmode_software.glsl @@ -11,17 +11,18 @@ float SoftwareColormap(float light, float z) vec4 Lightmode_Software() { // z is the depth in view space, positive going into the screen - #if defined(SWLIGHT_RADIAL) - float z = distance(pixelpos.xyz, uCameraPos.xyz); - #else - float z = pixelpos.w; - #endif + float z; + #uifdef(SWLIGHT_RADIAL) + z = distance(pixelpos.xyz, uCameraPos.xyz); + #uelse + z = pixelpos.w; + #uendif float colormap = SoftwareColormap(uLightLevel, z); - #if defined(SWLIGHT_BANDED) + #uifdef(SWLIGHT_BANDED) colormap = floor(colormap) + 0.5; - #endif + #uendif // Result is the normalized colormap index (0 bright .. 1 dark) float newlightlevel = 1.0 - clamp(colormap, 0.0, 31.0) / 32.0; diff --git a/wadsrc/static/shaders/scene/lightmode_vanilla.glsl b/wadsrc/static/shaders/scene/lightmode_vanilla.glsl index a47c09567..a39083bd4 100644 --- a/wadsrc/static/shaders/scene/lightmode_vanilla.glsl +++ b/wadsrc/static/shaders/scene/lightmode_vanilla.glsl @@ -42,17 +42,18 @@ float VanillaColormap(float light, float z) vec4 Lightmode_Vanilla() { // z is the depth in view space, positive going into the screen - #if defined(SWLIGHT_RADIAL) - float z = distance(pixelpos.xyz, uCameraPos.xyz); - #else - float z = pixelpos.w; - #endif + float z; + #uifdef(SWLIGHT_RADIAL) + z = distance(pixelpos.xyz, uCameraPos.xyz); + #uelse + z = pixelpos.w; + #uendif float colormap = VanillaColormap(uLightLevel, z); - #if defined(SWLIGHT_BANDED) + #uifdef(SWLIGHT_BANDED) colormap = floor(colormap) + 0.5; - #endif + #uendif // Result is the normalized colormap index (0 bright .. 1 dark) float newlightlevel = 1.0 - clamp(colormap, 0.0, 31.0) / 32.0; diff --git a/wadsrc/static/shaders/scene/lightmodel_normal.glsl b/wadsrc/static/shaders/scene/lightmodel_normal.glsl index 1dc3db247..b274ccd51 100644 --- a/wadsrc/static/shaders/scene/lightmodel_normal.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_normal.glsl @@ -8,10 +8,15 @@ vec3 lightdir = normalize(light.pos.xyz - pixelpos.xyz); - #ifndef LIGHT_NONORMALS - float dotprod = dot(normal, lightdir); + float dotprod; + + #uifdef(LIGHT_NONORMALS) + #uelse + { + 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. - #endif + } + #uendif float attenuation = distanceAttenuation(lightdistance, light.radius, light.strength, light.linearity); @@ -20,12 +25,13 @@ attenuation *= spotLightAttenuation(light.pos.xyz, light.spotDir.xyz, light.spotInnerAngle, light.spotOuterAngle); } - #ifndef LIGHT_NONORMALS + #uifdef(LIGHT_NONORMALS) + #uelse if ((light.flags & LIGHTINFO_ATTENUATED) != 0) { attenuation *= clamp(dotprod, 0.0, 1.0); } - #endif + #uendif if (attenuation > 0.0) // Skip shadow map test if possible @@ -52,64 +58,62 @@ vec4 dynlight = uDynLightColor; vec3 normal = material.Normal; -#if !defined(SHADE_VERTEX) - if (uLightIndex >= 0) - { - ivec4 lightRange = getLightRange(); - - if (lightRange.z > lightRange.x) + #ifdef SHADE_VERTEX + dynlight.rgb += vLightColor; + #else + if (uLightIndex >= 0) { - // modulated lights - for(int i=lightRange.x; i lightRange.x) { - dynlight.rgb += lightContribution(getLights()[i], normal); - } + // modulated lights + for(int i=lightRange.x; i= 0) - { - ivec4 lightRange = getLightRange(); - if (lightRange.w > lightRange.z) + + vec3 frag; + + #uifdef(LIGHT_BLEND_CLAMPED) + frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); + #uelifdef(LIGHT_BLEND_COLORED_CLAMP) { - vec4 addlight = vec4(0.0,0.0,0.0,0.0); - - // additive lights - for(int i=lightRange.z; i= 0) + { + ivec4 lightRange = getLightRange(); + if (lightRange.w > lightRange.z) + { + vec4 addlight = vec4(0.0,0.0,0.0,0.0); + + // additive lights + for(int i=lightRange.z; i= 1000000.0 is sunlight, skip attenuation - if(light.radius >= 1000000.0) return 1.0; - float a = dist / radius; - float b = clamp(1.0 - a * a * a * a, 0.0, 1.0); - return mix((b * b) / (dist * dist + 1.0) * strength, clamp((radius - dist) / radius, 0.0, 1.0), linearity); + #uifdef(LIGHT_ATTENUATION_INVERSE_SQUARE) + // light.radius >= 1000000.0 is sunlight, skip attenuation + if(light.radius >= 1000000.0) return 1.0; + float a = dist / radius; + float b = clamp(1.0 - a * a * a * a, 0.0, 1.0); + return mix((b * b) / (dist * dist + 1.0) * strength, clamp((radius - dist) / radius, 0.0, 1.0), linearity); + #uelse + return clamp((radius - dist) / radius, 0.0, 1.0); + #uendif } -#else //elif defined(LIGHT_ATTENUATION_LINEAR) - -#define distanceAttenuation(dist, radius, strength, linearity) clamp((radius - dist) / radius, 0.0, 1.0) - -#endif diff --git a/wadsrc/static/shaders/scene/lightmodel_specular.glsl b/wadsrc/static/shaders/scene/lightmodel_specular.glsl index 39fadd34b..1b98fb2d5 100644 --- a/wadsrc/static/shaders/scene/lightmodel_specular.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_specular.glsl @@ -69,25 +69,25 @@ vec3 ProcessMaterialLight(Material material, vec3 color) } } - #if defined(LIGHT_BLEND_CLAMPED) - + #uifdef(LIGHT_BLEND_CLAMPED) + { dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4); - - #elif defined(LIGHT_BLEND_COLORED_CLAMP) - + } + #elifdef(LIGHT_BLEND_COLORED_CLAMP) + { dynlight.rgb = color + desaturate(dynlight).rgb; specular.rgb = desaturate(specular).rgb; dynlight.rgb = ((dynlight.rgb / max(max(max(dynlight.r, dynlight.g), dynlight.b), 1.4) * 1.4)); specular.rgb = ((specular.rgb / max(max(max(specular.r, specular.g), specular.b), 1.4) * 1.4)); - - #else // elif defined(LIGHT_BLEND_UNCLAMPED) - + } + #uelse + { dynlight.rgb = color + desaturate(dynlight).rgb; specular.rgb = desaturate(specular).rgb; - - #endif + } + #uendif vec3 frag = material.Base.rgb * dynlight.rgb + material.Specular * specular.rgb; diff --git a/wadsrc/static/shaders/scene/material.glsl b/wadsrc/static/shaders/scene/material.glsl index ecf857219..09174055f 100644 --- a/wadsrc/static/shaders/scene/material.glsl +++ b/wadsrc/static/shaders/scene/material.glsl @@ -56,18 +56,22 @@ Material CreateMaterial() // OpenGL doesn't care, but Vulkan pukes all over the place if these texture samplings are included in no-texture shaders, even though never called. #ifndef NO_LAYERS - #if defined(TEXF_Brightmap) + #uifdef(TEXF_Brightmap) material.Bright = desaturate(texture(brighttexture, texCoord.st)); - #endif + #uendif - #if defined(TEXF_Detailmap) + #uifdef(TEXF_Detailmap) + { vec4 Detail = texture(detailtexture, texCoord.st * uDetailParms.xy) * uDetailParms.z; material.Base.rgb *= Detail.rgb; - #endif + } + #uendif - #if defined(TEXF_Glowmap) + #uifdef(TEXF_Glowmap) + { material.Glow = desaturate(texture(glowtexture, texCoord.st)); - #endif + } + #uendif #ifdef PBR material.Metallic = texture(metallictexture, texCoord.st).r; diff --git a/wadsrc/static/shaders/scene/material_gettexel.glsl b/wadsrc/static/shaders/scene/material_gettexel.glsl index 0ac8e2156..9238faca6 100644 --- a/wadsrc/static/shaders/scene/material_gettexel.glsl +++ b/wadsrc/static/shaders/scene/material_gettexel.glsl @@ -10,32 +10,34 @@ vec4 getTexel(vec2 st) vec4 texel = texture(tex, st); // Apply texture modes - #if defined(TM_STENCIL) + #uifdef(TM_STENCIL) texel.rgb = vec3(1.0,1.0,1.0); - #elif defined(TM_OPAQUE) + #uelifdef(TM_OPAQUE) texel.a = 1.0; - #elif defined(TM_INVERSE) + #uelifdef(TM_INVERSE) texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, texel.a); - #elif defined(TM_ALPHATEXTURE) + #uelifdef(TM_ALPHATEXTURE) + { float gray = grayscale(texel); texel = vec4(1.0, 1.0, 1.0, gray*texel.a); - #elif defined(TM_CLAMPY) + } + #uelifdef(TM_CLAMPY) if (st.t < 0.0 || st.t > 1.0) { texel.a = 0.0; } - #elif defined(TM_INVERTOPAQUE) + #uelifdef(TM_INVERTOPAQUE) texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, 1.0); - #elif defined(TM_FOGLAYER) + #uelifdef(TM_FOGLAYER) return texel; - #endif + #uendif - #if defined(TEXF_ClampY) + #uifdef(TEXF_ClampY) if (st.t < 0.0 || st.t > 1.0) { texel.a = 0.0; } - #endif + #uendif // Apply the texture modification colors. int blendflags = int(uTextureAddColor.a); // this alpha is unused otherwise diff --git a/wadsrc/static/shaders/scene/vert_main.glsl b/wadsrc/static/shaders/scene/vert_main.glsl index 4774c8db6..ba7b09382 100644 --- a/wadsrc/static/shaders/scene/vert_main.glsl +++ b/wadsrc/static/shaders/scene/vert_main.glsl @@ -34,13 +34,14 @@ attenuation *= spotLightAttenuation(light.pos.xyz, light.spotDir.xyz, light.spotInnerAngle, light.spotOuterAngle); } - #ifndef LIGHT_NONORMALS + #uifdef(LIGHT_NONORMALS) + #uelse if ((light.flags & LIGHTINFO_ATTENUATED) != 0) { float dotprod = dot(vWorldNormal.xyz, lightdir); attenuation *= clamp(dotprod, 0.0, 1.0); } - #endif + #uendif if (attenuation > 0.0) // Skip shadow map test if possible { diff --git a/wadsrc/static/shaders/shaderkey.glsl b/wadsrc/static/shaders/shaderkey.glsl new file mode 100644 index 000000000..9d270e5d2 --- /dev/null +++ b/wadsrc/static/shaders/shaderkey.glsl @@ -0,0 +1,54 @@ + +#define SK1_ALPHATEST (1 << 0) +//#define SK1_SIMPLE (1 << 1) +#define SK1_SIMPLE2D (1 << 2) +//#define SK1_SIMPLE3D (1 << 3) +#define SK1_TEXTUREMODE (7 << 4) +// #define SK1_TM_NORMAL 0 + #define SK1_TM_STENCIL 1 + #define SK1_TM_OPAQUE 2 + #define SK1_TM_INVERSE 3 + #define SK1_TM_ALPHATEXTURE 4 + #define SK1_TM_CLAMPY 5 + #define SK1_TM_INVERTOPAQUE 6 + #define SK1_TM_FOGLAYER 7 +#define SK1_TEXF_CLAMPY (1 << 7) +#define SK1_TEXF_BRIGHTMAP (1 << 8) +#define SK1_TEXF_DETAILMAP (1 << 9) +#define SK1_TEXF_GLOWMAP (1 << 10) +#define SK1_GBUFFER_PASS (1 << 11) +#define SK1_USE_SHADOWMAP (1 << 12) +#define SK1_USE_RAYTRACE (1 << 13) +#define SK1_USE_RAYTRACE_PRECISE (1 << 14) +#define SK1_PRECISE_MIDTEXTURES (1 << 15) +#define SK1_SHADOWMAP_FILTER (15 << 16) +#define SK1_FOG_BEFORE_LIGHTS (1 << 20) +#define SK1_FOG_AFTER_LIGHTS (1 << 21) +#define SK1_FOG_RADIAL (1 << 22) +#define SK1_SWLIGHT_RADIAL (1 << 23) +#define SK1_SWLIGHT_BANDED (1 << 24) +#define SK1_LIGHTMODE (3 << 25) + #define SK1_LIGHTMODE_DEFAULT 0 + #define SK1_LIGHTMODE_SOFTWARE 1 + #define SK1_LIGHTMODE_VANILLA 2 + #define SK1_LIGHTMODE_BUILD 3 +#define SK1_LIGHTBLENDMODE (3 << 27) + #define SK1_LIGHT_BLEND_CLAMPED 1 + #define SK1_LIGHT_LIGHT_BLEND_COLORED_CLAMP 2 + #define SK1_LIGHT_BLEND_UNCLAMPED 3 +#define SK1_LIGHTATTENUATIONMODE (1 << 29) +//#define SK1_USE_LEVELMESH (1 << 30) +#define SK1_FOGBALLS (1 << 31) + +//#define SK2_NOFRAGMENTSHADER (1 << 0) +#define SK2_USE_DEPTHFADETHRESHOLD (1 << 1) +#define SK2_ALPHATEST_ONLY (1 << 2) +//#define SK2_SHADE_VERTEX (1 << 3) +#define SK2_LIGHT_NONORMALS (1 << 4) +#define SK2_USE_SPRITECENTER (1 << 5) + +#define SK_GET_TEXTUREMODE() ((uShaderKey1 & SK1_TEXTUREMODE) >> 4) +#define SK_GET_SHADOWMAP_FILTER() ((uShaderKey1 & SK1_SHADOWMAP_FILTER) >> 16) +#define SK_GET_LIGHTMODE() ((uShaderKey1 & SK1_LIGHTMODE) >> 25) +#define SK_GET_LIGHTBLENDMODE() ((uShaderKey1 & SK1_LIGHTBLENDMODE) >> 27) +