From a7b20183f12405497f594b5451a0874a430d1330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 18 Jan 2025 01:46:02 -0300 Subject: [PATCH] gpu actor tracing (NOT WORKING) --- .../rendering/hwrenderer/data/hw_cvars.cpp | 13 ++++- .../rendering/hwrenderer/data/hw_cvars.h | 4 +- .../hwrenderer/data/hw_dynlightdata.h | 8 +++ .../hwrenderer/data/hw_renderstate.h | 8 +++ .../rendering/vulkan/shaders/vk_shader.cpp | 7 +-- .../rendering/vulkan/shaders/vk_shader.h | 4 +- .../rendering/vulkan/vk_renderstate.cpp | 4 ++ src/playsim/actor.h | 7 +-- src/playsim/p_visualthinker.h | 1 + src/rendering/hwrenderer/doom_levelmesh.cpp | 2 +- src/rendering/hwrenderer/hw_dynlightdata.cpp | 17 ++++--- src/rendering/hwrenderer/scene/hw_drawinfo.h | 6 ++- .../hwrenderer/scene/hw_drawstructs.h | 11 +++-- .../hwrenderer/scene/hw_spritelight.cpp | 49 +++++++++++-------- src/rendering/hwrenderer/scene/hw_sprites.cpp | 14 ++++-- src/rendering/hwrenderer/scene/hw_weapon.cpp | 8 ++- .../shaders/binding_struct_definitions.glsl | 1 + wadsrc/static/shaders/scene/light_shadow.glsl | 37 ++++++++------ .../shaders/scene/lightmodel_normal.glsl | 2 +- .../static/shaders/scene/lightmodel_pbr.glsl | 2 +- .../shaders/scene/lightmodel_specular.glsl | 2 +- wadsrc/static/shaders/scene/vert_main.glsl | 4 +- 22 files changed, 135 insertions(+), 76 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_cvars.cpp b/src/common/rendering/hwrenderer/data/hw_cvars.cpp index f3e89e432..029095022 100644 --- a/src/common/rendering/hwrenderer/data/hw_cvars.cpp +++ b/src/common/rendering/hwrenderer/data/hw_cvars.cpp @@ -161,5 +161,14 @@ CUSTOM_CVAR(Int, gl_shadowmap_quality, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, gl_strict_gldefs, true, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) -CVAR(Int, gl_wireframe, 0, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) -CVAR(Color, gl_wireframecolor, -1, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) \ No newline at end of file +CUSTOM_CVAR(Int, gl_wireframe, 0, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) +{ + if (self < 0 || self > 2) self = 0; // default off, 0 = off, 1 = wireframe only, 2 = level + wireframe +} + +CVAR(Color, gl_wireframecolor, -1, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) + +CUSTOM_CVAR(Int, gl_spritelight, 1, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) +{ + if (self < 0 || self > 2) self = 1; // default gpu vertex, 0 = cpu, 1 = gpu vertex, 2 = gpu pixel +} \ No newline at end of file diff --git a/src/common/rendering/hwrenderer/data/hw_cvars.h b/src/common/rendering/hwrenderer/data/hw_cvars.h index 715ffc7cd..92a7d6670 100644 --- a/src/common/rendering/hwrenderer/data/hw_cvars.h +++ b/src/common/rendering/hwrenderer/data/hw_cvars.h @@ -61,4 +61,6 @@ EXTERN_CVAR(Bool, r_dithertransparency) EXTERN_CVAR(Bool, gl_strict_gldefs) EXTERN_CVAR(Int, gl_wireframe) -EXTERN_CVAR(Color, gl_wireframecolor) \ No newline at end of file +EXTERN_CVAR(Color, gl_wireframecolor) + +EXTERN_CVAR(Int, gl_spritelight) \ No newline at end of file diff --git a/src/common/rendering/hwrenderer/data/hw_dynlightdata.h b/src/common/rendering/hwrenderer/data/hw_dynlightdata.h index 11104514f..a0abc850f 100644 --- a/src/common/rendering/hwrenderer/data/hw_dynlightdata.h +++ b/src/common/rendering/hwrenderer/data/hw_dynlightdata.h @@ -24,12 +24,14 @@ #define __GLC_DYNLIGHT_H #include "tarray.h" +#include "vectors.h" enum FDynLightInfoFlags { LIGHTINFO_ATTENUATED = 1, LIGHTINFO_SHADOWMAPPED = 2, LIGHTINFO_SPOT = 4, + LIGHTINFO_TRACE = 8, }; struct FDynLightInfo @@ -78,6 +80,12 @@ struct FDynLightData }; +struct sun_trace_cache_t +{ + DVector3 Pos = DVector3(-12345678.0, -12345678.0, -12345678.0); + bool SunResult = false; +}; + extern thread_local FDynLightData lightdata; diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index caebb928c..80250c21b 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -139,6 +139,7 @@ protected: uint8_t mSplitEnabled : 1; uint8_t mBrightmapEnabled : 1; uint8_t mWireframe : 2; + uint8_t mShadeVertex : 1; FVector4 mWireframeColor; FVector4 uObjectColor; @@ -183,6 +184,7 @@ public: void Reset() { + mShadeVertex = 0; mWireframe = 0; mWireframeColor = toFVector4(PalEntry(0xffffffff)); mTextureEnabled = true; @@ -263,6 +265,12 @@ public: mWireframe = mode; mWireframeColor = toFVector4(color); } + + + void SetShadeVertex(bool value) + { + mShadeVertex = value; + } void SetWireframeColor(FVector4 color) { diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index a933341cd..400510c7a 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -421,12 +421,7 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin if (key.FogBalls) definesBlock << "#define FOGBALLS\n"; - switch (key.ShadeVertex) - { - case 1: definesBlock << "#define SHADE_VERTEX\n"; break; - case 2: definesBlock << "#define SHADE_VERTEX\n#define SHADE_VERTEX_CENTER\n"; break; - //case 3: definesBlock << "#define ???\n"; break; - } + if (key.ShadeVertex) definesBlock << "#define SHADE_VERTEX\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 7f21801f8..471ed7447 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -108,8 +108,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 ShadeVertex : 2; // 0 = nothing, 1 = SHADE_VERTEX, 2 = SHADE_VERTEX_CENTER - uint64_t Unused : 28; + uint64_t ShadeVertex : 1; // SHADE_VERTEX + uint64_t Unused : 29; }; uint64_t AsQWORD = 0; }; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index f51ea542a..ec75c3ef5 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -329,6 +329,8 @@ void VkRenderState::ApplyRenderPass(int dt) pipelineKey.ShaderKey.LightMode = 1; // Software } + pipelineKey.ShaderKey.ShadeVertex = mShadeVertex; + pipelineKey.ShaderKey.UseShadowmap = gl_light_shadows == 1; pipelineKey.ShaderKey.UseRaytrace = gl_light_shadows >= 2; pipelineKey.ShaderKey.UseRaytracePrecise = gl_light_shadows >= 3; @@ -1078,6 +1080,8 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip pipelineKey.ShaderKey.AlphaTestOnly = true; } + pipelineKey.ShaderKey.ShadeVertex = mShadeVertex; + // Global state that don't require rebuilding the mesh pipelineKey.ShaderKey.NoFragmentShader = noFragmentShader; pipelineKey.ShaderKey.UseShadowmap = gl_light_shadows == 1; diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 049dc7dc7..e9b3b7c7a 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -48,6 +48,7 @@ #include "tflags.h" #include "portal.h" #include "bonecomponents.h" +#include "hw_dynlightdata.h" struct subsector_t; struct FBlockNode; @@ -1643,11 +1644,7 @@ public: bool hasmodel; - struct - { - DVector3 Pos = DVector3(-12345678.0, -12345678.0, -12345678.0); - bool SunResult = false; - } StaticLightsTraceCache; + sun_trace_cache_t StaticLightsTraceCache; void InvalidateLightTraceCache() { diff --git a/src/playsim/p_visualthinker.h b/src/playsim/p_visualthinker.h index d4b1e262d..510affacb 100644 --- a/src/playsim/p_visualthinker.h +++ b/src/playsim/p_visualthinker.h @@ -40,6 +40,7 @@ public: // internal only variables particle_t PT; + sun_trace_cache_t StaticLightsTraceCache; DVisualThinker(); void Construct(); diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 694ef3976..d7ee8d2f7 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -350,7 +350,7 @@ void DoomLevelMesh::UploadDynLights(FLevelLocals& doomMap) else { int portalGroup = 0; // What value should this have? - AddLightToList(lightdata, portalGroup, light, false); + AddLightToList(lightdata, portalGroup, light, false, false); CurFrameStats.DynLights++; } } diff --git a/src/rendering/hwrenderer/hw_dynlightdata.cpp b/src/rendering/hwrenderer/hw_dynlightdata.cpp index 6345a5a16..826328160 100644 --- a/src/rendering/hwrenderer/hw_dynlightdata.cpp +++ b/src/rendering/hwrenderer/hw_dynlightdata.cpp @@ -66,7 +66,7 @@ bool GetLight(FDynLightData& dld, int group, Plane & p, FDynamicLight * light, b return false; } - AddLightToList(dld, group, light, false); + AddLightToList(dld, group, light, false, false); return true; } @@ -75,7 +75,7 @@ bool GetLight(FDynLightData& dld, int group, Plane & p, FDynamicLight * light, b // Add one dynamic light to the light data list // //========================================================================== -void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool forceAttenuate) +void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool forceAttenuate, bool doTrace) { FDynLightInfo info = {}; @@ -117,11 +117,11 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f if(light->shadowmapped && screen->mShadowMap->Enabled()) { info.flags |= LIGHTINFO_SHADOWMAPPED; - info.shadowIndex = light->mShadowmapIndex + 1.0f; + info.shadowIndex = light->mShadowmapIndex; } else { - info.shadowIndex = 1025.f; + info.shadowIndex = 1024; } // Store attenuate flag in the sign bit of the float. @@ -145,6 +145,11 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f info.spotDirZ = float(-Angle.Sin() * xzLen); } + if(light->Trace() && doTrace) + { + info.flags |= LIGHTINFO_TRACE; + } + info.x = float(pos.X); info.z = float(pos.Y); info.y = float(pos.Z); @@ -158,7 +163,7 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f dld.arrays[i].Push(info); } -void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVector3& sundir, const FVector3& suncolor) +void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVector3& sundir, const FVector3& suncolor, bool doTrace) { FDynLightInfo info = {}; @@ -171,7 +176,7 @@ void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVec info.r = suncolor.X; info.g = suncolor.Y; info.b = suncolor.Z; - info.flags = LIGHTINFO_ATTENUATED; + info.flags = LIGHTINFO_ATTENUATED | (doTrace ? LIGHTINFO_TRACE : 0); info.strength = 1500.0f; dld.arrays[LIGHTARRAY_NORMAL].Push(info); diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index 987c02fcb..92d17ff95 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -313,8 +313,10 @@ public: void AddOtherFloorPlane(int sector, gl_subsectorrendernode * node, FRenderState& state); void AddOtherCeilingPlane(int sector, gl_subsectorrendernode * node, FRenderState& state); - void GetDynSpriteLight(AActor *self, float x, float y, float z, FLightNode *node, int portalgroup, float *out, bool fullbright); - void GetDynSpriteLight(AActor *thing, particle_t *particle, float *out); + void GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache, double x, double y, double z, FLightNode *node, int portalgroup, float *out, bool fullbright); + void GetDynSpriteLight(AActor *thing, particle_t *particle, sun_trace_cache_t * traceCache, float *out); + + void GetDynSpriteLightList(AActor *self, FDynLightData &modellightdata); void PreparePlayerSprites(sector_t * viewsector, area_t in_area, FRenderState& state); void PrepareTargeterSprites(double ticfrac, FRenderState& state); diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 08994582b..f90fc6b4c 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -370,6 +370,8 @@ public: // //========================================================================== +class DVisualThinker; + class HWSprite { @@ -407,6 +409,7 @@ public: FGameTexture *texture; AActor * actor; particle_t * particle; + DVisualThinker *spr; TArray *lightlist; DRotator Angles; @@ -419,7 +422,7 @@ public: void CreateVertices(HWDrawInfo *di, FRenderState& state); void PutSprite(HWDrawInfo *di, FRenderState& state, bool translucent); void Process(HWDrawInfo *di, FRenderState& state, AActor* thing,sector_t * sector, area_t in_area, int thruportal = false, bool isSpriteShadow = false); - void ProcessParticle (HWDrawInfo *di, FRenderState& state, particle_t *particle, sector_t *sector, class DVisualThinker *spr);//, int shade, int fakeside) + void ProcessParticle (HWDrawInfo *di, FRenderState& state, particle_t *particle, sector_t *sector, DVisualThinker *spr);//, int shade, int fakeside) void AdjustVisualThinker(HWDrawInfo *di, DVisualThinker *spr, sector_t *sector); void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent); @@ -487,13 +490,11 @@ inline float Dist2(float x1,float y1,float x2,float y2) return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } -void hw_GetDynModelLight(HWDrawContext* drawctx, AActor *self, FDynLightData &modellightdata); - extern const float LARGE_VALUE; struct FDynLightData; struct FDynamicLight; bool GetLight(FDynLightData& dld, int group, Plane& p, FDynamicLight* light, bool checkside); -void AddLightToList(FDynLightData &dld, int group, FDynamicLight* light, bool forceAttenuate); -void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVector3& sundir, const FVector3& suncolor); +void AddLightToList(FDynLightData &dld, int group, FDynamicLight* light, bool forceAttenuate, bool doTrace); +void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVector3& sundir, const FVector3& suncolor, bool doTrace); void SetSplitPlanes(FRenderState& state, const secplane_t& top, const secplane_t& bottom); diff --git a/src/rendering/hwrenderer/scene/hw_spritelight.cpp b/src/rendering/hwrenderer/scene/hw_spritelight.cpp index 230cb5664..39fab2f5d 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -39,6 +39,7 @@ #include "hwrenderer/scene/hw_drawstructs.h" #include "models.h" #include // needed for std::floor on mac +#include "hw_cvars.h" template T smoothstep(const T edge0, const T edge1, const T x) @@ -90,20 +91,20 @@ public: } } - bool TraceSunVisibility(float x, float y, float z) + static bool TraceSunVisibility(float x, float y, float z, sun_trace_cache_t *cache, bool moved) { - if (!level.lightmaps || !Actor) + if (!level.lightmaps || !cache) return false; - if (!ActorMoved) + if (!moved) { - bool traceResult = Actor->StaticLightsTraceCache.SunResult; + bool traceResult = cache->SunResult; return traceResult; } else { bool traceResult = level.levelMesh->TraceSky(FVector3(x, y, z), level.SunDirection, 65536.0f); - Actor->StaticLightsTraceCache.SunResult = traceResult; + cache->SunResult = traceResult; return traceResult; } } @@ -126,9 +127,9 @@ float inverseSquareAttenuation(float dist, float radius, float strength) return (b * b) / (dist * dist + 1.0) * strength; } -void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLightNode *node, int portalgroup, float *out, bool fullbright) +void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache, double x, double y, double z, FLightNode *node, int portalgroup, float *out, bool fullbright) { - if (fullbright) + if (fullbright || gl_spritelight > 0) return; FDynamicLight *light; @@ -139,8 +140,13 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLig ActorTraceStaticLight staticLight(self); - if (staticLight.TraceSunVisibility(x, y, z)) + if (ActorTraceStaticLight::TraceSunVisibility(x, y, z, traceCache, (self ? staticLight.ActorMoved : traceCache ? traceCache->Pos != DVector3(x, y, z) : false))) { + if(!self && traceCache) + { + traceCache->Pos = DVector3(x, y, z); + } + out[0] = Level->SunColor.X * Level->SunIntensity; out[1] = Level->SunColor.Y * Level->SunIntensity; out[2] = Level->SunColor.Z * Level->SunIntensity; @@ -239,20 +245,20 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLig } } -void HWDrawInfo::GetDynSpriteLight(AActor *thing, particle_t *particle, float *out) +void HWDrawInfo::GetDynSpriteLight(AActor *thing, particle_t *particle, sun_trace_cache_t * traceCache, float *out) { - if (thing != NULL) + if (thing) { - GetDynSpriteLight(thing, (float)thing->X(), (float)thing->Y(), (float)thing->Center(), thing->section->lighthead, thing->Sector->PortalGroup, out, (thing->flags5 & MF5_BRIGHT)); + GetDynSpriteLight(thing, &thing->StaticLightsTraceCache, thing->X(), thing->Y(), thing->Center(), thing->section->lighthead, thing->Sector->PortalGroup, out, (thing->flags5 & MF5_BRIGHT)); } - else if (particle != NULL) + else if (particle) { - GetDynSpriteLight(NULL, (float)particle->Pos.X, (float)particle->Pos.Y, (float)particle->Pos.Z, particle->subsector->section->lighthead, particle->subsector->sector->PortalGroup, out, (particle->flags & SPF_FULLBRIGHT)); + GetDynSpriteLight(nullptr, traceCache, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector->section->lighthead, particle->subsector->sector->PortalGroup, out, (particle->flags & SPF_FULLBRIGHT)); } } -void hw_GetDynModelLight(HWDrawContext* drawctx, AActor *self, FDynLightData &modellightdata) +void HWDrawInfo::GetDynSpriteLightList(AActor *self, FDynLightData &modellightdata) { modellightdata.Clear(); @@ -274,9 +280,9 @@ void hw_GetDynModelLight(HWDrawContext* drawctx, AActor *self, FDynLightData &mo ActorTraceStaticLight staticLight(self); - if (staticLight.TraceSunVisibility(x, y, z)) + if (gl_spritelight > 0 || ActorTraceStaticLight::TraceSunVisibility(x, y, z, (self ? &self->StaticLightsTraceCache : nullptr), (self ? staticLight.ActorMoved : false))) { - AddSunLightToList(modellightdata, x, y, z, self->Level->SunDirection, self->Level->SunColor * self->Level->SunIntensity); + AddSunLightToList(modellightdata, x, y, z, self->Level->SunDirection, self->Level->SunColor * self->Level->SunIntensity, gl_spritelight > 0); } BSPWalkCircle(self->Level, x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor @@ -298,19 +304,20 @@ void hw_GetDynModelLight(HWDrawContext* drawctx, AActor *self, FDynLightData &mo double distSquared = dx * dx + dy * dy + dz * dz; if (distSquared < radius * radius) // Light and actor touches { - if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector + unsigned index = addedLights.SortedFind(light, false); + if(index == addedLights.Size() || addedLights[index] != light) // Check if we already added this light from a different subsector (use binary search instead of linear search) { FVector3 L(dx, dy, dz); float dist = sqrtf(distSquared); - if (light->TraceActors()) + if (gl_spritelight == 0 && light->TraceActors()) L *= 1.0f / dist; - if (staticLight.TraceLightVisbility(node, L, dist, light->updated)) + if (gl_spritelight > 0 || staticLight.TraceLightVisbility(node, L, dist, light->updated)) { - AddLightToList(modellightdata, group, light, true); + AddLightToList(modellightdata, group, light, true, gl_spritelight > 0); } - addedLights.Push(light); + addedLights.Insert(index, light); } } } diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 1ab44a873..3184a2c8b 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -109,6 +109,7 @@ CVARD(Bool, r_showhitbox, false, CVAR_GLOBALCONFIG | CVAR_CHEAT, "show actor hit void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) { + state.SetShadeVertex(gl_spritelight < 2); bool additivefog = false; bool foglayer = false; int rel = fullbright ? 0 : getExtraLight(); @@ -182,7 +183,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) if (dynlightindex == -1) // only set if we got no light buffer index. This covers all cases where sprite lighting is used. { float out[3] = {}; - di->GetDynSpriteLight(gl_light_sprites ? actor : nullptr, gl_light_particles ? particle : nullptr, out); + di->GetDynSpriteLight(gl_light_sprites ? actor : nullptr, gl_light_particles ? particle : nullptr, (gl_light_particles && spr != nullptr) ? &spr->StaticLightsTraceCache : nullptr, out); state.SetDynLight(out[0], out[1], out[2]); } } @@ -303,8 +304,10 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) { state.SetDepthBias(-1, -128); } - state.SetLightIndex(-1); + + state.SetLightIndex(dynlightindex); state.Draw(DT_TriangleStrip, vertexindex, 4); + state.SetLightIndex(-1); if (foglayer) { @@ -406,6 +409,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) state.SetAddColor(0); state.EnableTexture(true); state.SetDynLight(0, 0, 0); + state.SetShadeVertex(false); } //========================================================================== @@ -630,9 +634,9 @@ bool HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp) inline void HWSprite::PutSprite(HWDrawInfo *di, FRenderState& state, bool translucent) { // That's a lot of checks... - if (modelframe && !modelframe->isVoxel && !(modelframeflags & MDL_NOPERPIXELLIGHTING) && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && di->Level->HasDynamicLights && !di->isFullbrightScene() && !fullbright) + if ((gl_spritelight > 0 || (modelframe && !modelframe->isVoxel && !(modelframeflags & MDL_NOPERPIXELLIGHTING))) && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && di->Level->HasDynamicLights && !di->isFullbrightScene() && !fullbright) { - hw_GetDynModelLight(di->drawctx, actor, lightdata); + di->GetDynSpriteLightList(actor, lightdata); dynlightindex = state.UploadLights(lightdata); } else @@ -1434,6 +1438,7 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto } particle = nullptr; + spr = nullptr; const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD) && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE @@ -1486,6 +1491,7 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, FRenderState& state, particle_t * index = 0; actor = nullptr; this->particle = particle; + this->spr = spr; fullbright = particle->flags & SPF_FULLBRIGHT; if (di->isFullbrightScene()) diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index f5cef7094..993c0f160 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -739,7 +739,11 @@ void HWDrawInfo::PreparePlayerSprites2D(sector_t * viewsector, area_t in_area, F // set the lighting parameters if (hudsprite.RenderStyle.BlendOp != STYLEOP_Shadow && Level->HasDynamicLights && !isFullbrightScene() && gl_light_sprites) { - GetDynSpriteLight(playermo, nullptr, hudsprite.dynrgb); + GetDynSpriteLight(playermo, nullptr, nullptr, hudsprite.dynrgb); + if (gl_spritelight > 0) + { + GetDynSpriteLightList(playermo, lightdata); + } } if (!hudsprite.GetWeaponRect(this, state, psp, spos.X, spos.Y, player, vp.TicFrac)) continue; @@ -842,7 +846,7 @@ void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, F // set the lighting parameters if (hudsprite.RenderStyle.BlendOp != STYLEOP_Shadow && Level->HasDynamicLights && !isFullbrightScene() && gl_light_sprites) { - hw_GetDynModelLight(drawctx, playermo, lightdata); + GetDynSpriteLightList(playermo, lightdata); hudsprite.lightindex = state.UploadLights(lightdata); } diff --git a/wadsrc/static/shaders/binding_struct_definitions.glsl b/wadsrc/static/shaders/binding_struct_definitions.glsl index a5ae8175d..cad7c58e6 100644 --- a/wadsrc/static/shaders/binding_struct_definitions.glsl +++ b/wadsrc/static/shaders/binding_struct_definitions.glsl @@ -138,6 +138,7 @@ struct Fogball #define LIGHTINFO_ATTENUATED 1 #define LIGHTINFO_SHADOWMAPPED 2 #define LIGHTINFO_SPOT 4 +#define LIGHTINFO_TRACE 8 struct DynLightInfo { diff --git a/wadsrc/static/shaders/scene/light_shadow.glsl b/wadsrc/static/shaders/scene/light_shadow.glsl index 7a058e7da..9566fbaec 100644 --- a/wadsrc/static/shaders/scene/light_shadow.glsl +++ b/wadsrc/static/shaders/scene/light_shadow.glsl @@ -1,14 +1,11 @@ // Check if light is in shadow +#include // needed always to do per-pixel tracing of lightmap lights for sprites + #if defined(USE_RAYTRACE) -#include - -float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius) -{ - return traceShadow(lightpos, softShadowRadius); -} +#define shadowAttenuation(lightpos, shadowIndex, softShadowRadius, flags) traceShadow(lightpos, softShadowRadius) #elif defined(USE_SHADOWMAP) @@ -134,19 +131,31 @@ float shadowmapAttenuation(vec3 lightpos, float shadowIndex) #endif } -float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius) +float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius, int flags) { - if (shadowIndex >= 1024) - return 1.0; // No shadowmap available for this light - - return shadowmapAttenuation(lightpos, float(shadowIndex)); + if((flags & LIGHTINFO_TRACE) > 0) + { + return traceShadow(lightpos, softShadowRadius); + } + else + { + if (shadowIndex >= 1024) + return 1.0; // No shadowmap available for this light + return shadowmapAttenuation(lightpos, float(shadowIndex)); + } } - #else -float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius) +float shadowAttenuation(vec3 lightpos, int shadowIndex, float softShadowRadius, int flags) { - return 1.0; + if((flags & LIGHTINFO_TRACE) > 0) + { + return traceShadow(lightpos, softShadowRadius); + } + else + { + return 1.0; + } } #endif diff --git a/wadsrc/static/shaders/scene/lightmodel_normal.glsl b/wadsrc/static/shaders/scene/lightmodel_normal.glsl index 4101e08c0..0024152f1 100644 --- a/wadsrc/static/shaders/scene/lightmodel_normal.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_normal.glsl @@ -28,7 +28,7 @@ // light.radius >= 1000000.0 is sunlight(?), skip attenuation if(light.radius < 1000000.0 && (light.flags & LIGHTINFO_SHADOWMAPPED) != 0) { - attenuation *= shadowAttenuation(light.pos.xyz, light.shadowIndex, light.softShadowRadius); + attenuation *= shadowAttenuation(light.pos.xyz, light.shadowIndex, light.softShadowRadius, light.flags); } return light.color.rgb * attenuation; diff --git a/wadsrc/static/shaders/scene/lightmodel_pbr.glsl b/wadsrc/static/shaders/scene/lightmodel_pbr.glsl index ab2547a5f..d3d53591e 100644 --- a/wadsrc/static/shaders/scene/lightmodel_pbr.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_pbr.glsl @@ -66,7 +66,7 @@ vec3 ProcessLight(const DynLightInfo light, vec3 albedo, float metallic, float r if(light.radius < 1000000.0 && (light.flags & LIGHTINFO_SHADOWMAPPED) != 0) { - attenuation *= shadowAttenuation(light.pos.xyz, light.shadowIndex, light.softShadowRadius); + attenuation *= shadowAttenuation(light.pos.xyz, light.shadowIndex, light.softShadowRadius, light.flags); } vec3 radiance = light.color.rgb * attenuation; diff --git a/wadsrc/static/shaders/scene/lightmodel_specular.glsl b/wadsrc/static/shaders/scene/lightmodel_specular.glsl index 03fae3a69..39fadd34b 100644 --- a/wadsrc/static/shaders/scene/lightmodel_specular.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_specular.glsl @@ -23,7 +23,7 @@ vec2 lightAttenuation(DynLightInfo light, vec3 normal, vec3 viewdir, float gloss // light.radius >= 1000000.0 is sunlight(?), skip attenuation if(light.radius < 1000000.0 && (light.flags & LIGHTINFO_SHADOWMAPPED) != 0) { - attenuation *= shadowAttenuation(light.pos.xyz, light.shadowIndex, light.softShadowRadius); + attenuation *= shadowAttenuation(light.pos.xyz, light.shadowIndex, light.softShadowRadius, light.flags); } } diff --git a/wadsrc/static/shaders/scene/vert_main.glsl b/wadsrc/static/shaders/scene/vert_main.glsl index 0a94c3cd5..d90d3f89e 100644 --- a/wadsrc/static/shaders/scene/vert_main.glsl +++ b/wadsrc/static/shaders/scene/vert_main.glsl @@ -2,8 +2,8 @@ #include "shaders/scene/bones.glsl" #if defined(SHADE_VERTEX) && !defined(PBR) && !defined(SPECULAR) && !defined(SIMPLE) -#undef SHADOWMAP_FILTER -#define SHADOWMAP_FILTER 0 + #undef SHADOWMAP_FILTER + #define SHADOWMAP_FILTER 0 #include #include #include