diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index 4d4a20696..369914ba0 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -141,6 +141,7 @@ class FRenderState uint8_t mWireframe : 2; uint8_t mShadeVertex : 1; uint8_t mLightNoNormals : 1; + uint8_t mUseSpriteCenter : 1; FVector4 mWireframeColor; FVector4 uObjectColor; @@ -185,6 +186,7 @@ class FRenderState void Reset() { + mUseSpriteCenter = 0; mLightNoNormals = 0; mShadeVertex = 0; mWireframe = 0; @@ -279,6 +281,11 @@ class FRenderState mLightNoNormals = value; } + void SetUseSpriteCenter(bool value) + { + mUseSpriteCenter = value; + } + void SetWireframeColor(FVector4 color) { mWireframeColor = color; @@ -294,6 +301,11 @@ class FRenderState mSurfaceUniforms.uVertexNormal = { x, y, z, 0.f }; } + void SetActorCenter(float x, float y, float z) + { + mSurfaceUniforms.uActorCenter = { x, y, z }; + } + void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) { mSurfaceUniforms.uVertexColor = { r, g, b, a }; diff --git a/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h b/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h index 263c47421..7166fb092 100644 --- a/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h +++ b/src/common/rendering/hwrenderer/data/hw_surfaceuniforms.h @@ -45,7 +45,9 @@ struct SurfaceUniforms float uAlphaThreshold; int uTextureIndex; float uDepthFadeThreshold; - float padding3; + float padding1; + FVector3 uActorCenter; + float padding2; }; struct SurfaceLightUniforms diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index d65027e0b..4ed014b55 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -423,6 +423,7 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin 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"); } diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index df7a0e71c..cb8d2c501 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -110,7 +110,8 @@ class VkShaderKey uint64_t ShadowmapFilter : 4; // SHADOWMAP_FILTER uint64_t ShadeVertex : 1; // SHADE_VERTEX uint64_t LightNoNormals : 1; // LIGHT_NONORMALS - uint64_t Unused : 28; + uint64_t UseSpriteCenter : 1; // USE_SPRITE_CENTER + uint64_t Unused : 27; }; uint64_t AsQWORD = 0; }; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 0d40075f0..e80f7d1c7 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -331,6 +331,7 @@ void VkRenderState::ApplyRenderPass(int dt) pipelineKey.ShaderKey.ShadeVertex = mShadeVertex; pipelineKey.ShaderKey.LightNoNormals = mLightNoNormals; + pipelineKey.ShaderKey.UseSpriteCenter = mUseSpriteCenter; pipelineKey.ShaderKey.UseShadowmap = gl_light_shadows == 1; pipelineKey.ShaderKey.UseRaytrace = gl_light_shadows >= 2; @@ -1082,6 +1083,8 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip } pipelineKey.ShaderKey.ShadeVertex = mShadeVertex; + pipelineKey.ShaderKey.LightNoNormals = mLightNoNormals; + pipelineKey.ShaderKey.UseSpriteCenter = mUseSpriteCenter; // Global state that don't require rebuilding the mesh pipelineKey.ShaderKey.NoFragmentShader = noFragmentShader; diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 0fc4995c6..b7f6878cd 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -294,10 +294,21 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) SetSplitPlanes(state, topp, bottomp); } + if(actor) + { + state.SetActorCenter(actor->X(), actor->Center(), actor->Y()); + } + if (!modelframe) { + state.SetLightNoNormals(true); state.SetNormal(0, 0, 0); + if(actor && gl_spritelight < 2) + { + state.SetUseSpriteCenter(true); + } + CreateVertices(di, state); if (polyoffset) @@ -305,7 +316,6 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) state.SetDepthBias(-1, -128); } - state.SetLightNoNormals(true); state.SetLightIndex(dynlightindex); state.Draw(DT_TriangleStrip, vertexindex, 4); state.SetLightIndex(-1); @@ -320,6 +330,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) state.SetTextureMode(TM_NORMAL); } state.SetLightNoNormals(false); + state.SetUseSpriteCenter(false); } else { diff --git a/wadsrc/static/shaders/binding_struct_definitions.glsl b/wadsrc/static/shaders/binding_struct_definitions.glsl index cad7c58e6..d71fda5c9 100644 --- a/wadsrc/static/shaders/binding_struct_definitions.glsl +++ b/wadsrc/static/shaders/binding_struct_definitions.glsl @@ -115,7 +115,9 @@ struct SurfaceUniforms float uAlphaThreshold; int uTextureIndex; float uDepthFadeThreshold; - float padding3; + float padding1; + vec3 uActorCenter; + float padding2; }; struct SurfaceLightUniforms diff --git a/wadsrc/static/shaders/scene/layout_shared.glsl b/wadsrc/static/shaders/scene/layout_shared.glsl index 7d57809ba..5ba001bad 100644 --- a/wadsrc/static/shaders/scene/layout_shared.glsl +++ b/wadsrc/static/shaders/scene/layout_shared.glsl @@ -56,6 +56,7 @@ #define uAlphaThreshold data[uDataIndex].uAlphaThreshold #define uTextureIndex data[uDataIndex].uTextureIndex #define uDepthFadeThreshold data[uDataIndex].uDepthFadeThreshold +#define uActorCenter data[uDataIndex].uActorCenter #if defined(USE_LEVELMESH) #define uVertexColor lightdata[uDataIndex].uVertexColor diff --git a/wadsrc/static/shaders/scene/light_trace.glsl b/wadsrc/static/shaders/scene/light_trace.glsl index 24c38f901..bc9e34768 100644 --- a/wadsrc/static/shaders/scene/light_trace.glsl +++ b/wadsrc/static/shaders/scene/light_trace.glsl @@ -47,7 +47,10 @@ float traceHit(vec3 origin, vec3 direction, float dist) 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 LIGHT_NONORMALS +#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; diff --git a/wadsrc/static/shaders/scene/vert_main.glsl b/wadsrc/static/shaders/scene/vert_main.glsl index 527520abb..395724f6d 100644 --- a/wadsrc/static/shaders/scene/vert_main.glsl +++ b/wadsrc/static/shaders/scene/vert_main.glsl @@ -2,6 +2,7 @@ #include "shaders/scene/bones.glsl" #if defined(SHADE_VERTEX) && !defined(PBR) && !defined(SPECULAR) && !defined(SIMPLE) + #undef SHADOWMAP_FILTER #define SHADOWMAP_FILTER 0 #include @@ -10,12 +11,21 @@ vec3 lightValue(DynLightInfo light) { +#ifdef USE_SPRITE_CENTER + float lightdistance = distance(light.pos.xyz, uActorCenter.xyz); + + if (light.radius < lightdistance) + return vec3(0.0); // Early out lights touching surface but not this fragment + + vec3 lightdir = normalize(light.pos.xyz - uActorCenter.xyz); +#else float lightdistance = distance(light.pos.xyz, pixelpos.xyz); if (light.radius < lightdistance) return vec3(0.0); // Early out lights touching surface but not this fragment vec3 lightdir = normalize(light.pos.xyz - pixelpos.xyz); +#endif float attenuation = distanceAttenuation(lightdistance, light.radius, light.strength, light.linearity); @@ -54,11 +64,6 @@ vec3 ProcessVertexLight() { - #if defined(USE_LEVELMESH) - const int lightTileSize = 1; - uLightIndex = int(uint(gl_FragCoord.x) / 64 + uint(gl_FragCoord.y) / 64 * uLightTilesWidth) * lightTileSize; - #endif - vec3 light = vec3(0.0); if (uLightIndex >= 0) @@ -83,6 +88,7 @@ return light; } + #endif void ModifyVertex();