diff --git a/src/d_main.cpp b/src/d_main.cpp index df1051af5..70e29266f 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -401,9 +401,9 @@ void D_Render(std::function action, bool interpolate) for (auto Level : AllLevels()) { // Check for the presence of dynamic lights at the start of the frame once. - if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4) || Level->LightProbes.Size() > 0) + if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4) || Level->LMTextureCount > 0) { - Level->HasDynamicLights = Level->lights || Level->LightProbes.Size() > 0; + Level->HasDynamicLights = Level->lights || Level->LMTextureCount > 0; } else Level->HasDynamicLights = false; // lights are off so effectively we have none. if (interpolate) Level->interpolator.DoInterpolations(I_GetTimeFrac()); diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 9953a3e7d..8cd6b3542 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -459,13 +459,6 @@ public: int LMTextureCount = 0; int LMTextureSize = 0; TArray LMTextureData; - TArray LightProbes; - int LPMinX = 0; - int LPMinY = 0; - int LPWidth = 0; - int LPHeight = 0; - static const int LPCellSize = 32; - TArray LPCells; // Portal information. FDisplacementTable Displacements; diff --git a/src/gamedata/r_defs.h b/src/gamedata/r_defs.h index 273ffebfc..947adab89 100644 --- a/src/gamedata/r_defs.h +++ b/src/gamedata/r_defs.h @@ -61,7 +61,6 @@ class AActor; struct FSection; struct FLevelLocals; struct LightmapSurface; -struct LightProbe; const uint16_t NO_INDEX = 0xffffu; const uint32_t NO_SIDE = 0xffffffffu; @@ -1706,18 +1705,6 @@ struct LightmapSurface float *TexCoords; }; -struct LightProbe -{ - float X, Y, Z; - float Red, Green, Blue; -}; - -struct LightProbeCell -{ - LightProbe* FirstProbe = nullptr; - int NumProbes = 0; -}; - // // OTHER TYPES // diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 9e4126196..65ad0e2c0 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3330,17 +3330,11 @@ void MapLoader::SetSideLightmap(const LightmapSurface &surface) void MapLoader::LoadLightmap(MapData *map) { // We have to reset everything as FLevelLocals is recycled between maps - Level->LightProbes.Reset(); - Level->LPCells.Reset(); Level->LMTexCoords.Reset(); Level->LMSurfaces.Reset(); Level->LMTextureData.Reset(); Level->LMTextureCount = 0; Level->LMTextureSize = 0; - Level->LPMinX = 0; - Level->LPMinY = 0; - Level->LPWidth = 0; - Level->LPHeight = 0; if (!Args->CheckParm("-enablelightmaps")) return; // this feature is still too early WIP to allow general access @@ -3379,61 +3373,8 @@ void MapLoader::LoadLightmap(MapData *map) if (numLightProbes > 0) { - Level->LightProbes.Resize(numLightProbes); - fr.Read(&Level->LightProbes[0], sizeof(LightProbe) * numLightProbes); - - // Sort the light probes so that they are ordered by cell. - // This lets us point at the first probe knowing all other probes in the cell will follow. - // Also improves locality. - - double rcpCellSize = 1.0 / Level->LPCellSize; - auto cellCompareLess = [=](const LightProbe& a, const LightProbe& b) - { - double cellY_A = std::floor(a.Y * rcpCellSize); - double cellY_B = std::floor(b.Y * rcpCellSize); - if (cellY_A != cellY_B) - return cellY_A < cellY_B; - double cellX_A = std::floor(a.X * rcpCellSize); - double cellX_B = std::floor(b.X * rcpCellSize); - return cellX_A < cellX_B; - }; - std::sort(Level->LightProbes.begin(), Level->LightProbes.end(), cellCompareLess); - - // Find probe bounds and the grid that covers it - float probesMinX = Level->LightProbes[0].X; - float probesMaxX = Level->LightProbes[0].X; - float probesMinY = Level->LightProbes[0].Y; - float probesMaxY = Level->LightProbes[0].Y; - for (const LightProbe& p : Level->LightProbes) - { - probesMinX = std::min(probesMinX, p.X); - probesMaxX = std::max(probesMaxX, p.X); - probesMinY = std::min(probesMinY, p.Y); - probesMaxY = std::max(probesMaxY, p.Y); - } - Level->LPMinX = (int)std::floor(probesMinX * rcpCellSize); - Level->LPMinY = (int)std::floor(probesMinY * rcpCellSize); - Level->LPWidth = (int)std::floor(probesMaxX * rcpCellSize) + 1 - Level->LPMinX; - Level->LPHeight = (int)std::floor(probesMaxY * rcpCellSize) + 1 - Level->LPMinY; - - // Place probes in a grid for faster search - Level->LPCells.Resize(Level->LPWidth * Level->LPHeight); - int minX = Level->LPMinX; - int minY = Level->LPMinY; - int width = Level->LPWidth; - int height = Level->LPHeight; - for (LightProbe& p : Level->LightProbes) - { - int gridX = (int)std::floor(p.X * rcpCellSize) - minX; - int gridY = (int)std::floor(p.Y * rcpCellSize) - minY; - if (gridX >= 0 && gridY >= 0 && gridX < width && gridY < height) - { - LightProbeCell& cell = Level->LPCells[gridX + (size_t)gridY * width]; - if (!cell.FirstProbe) - cell.FirstProbe = &p; - cell.NumProbes++; - } - } + Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported alpha version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n"); + return; } Level->LMTexCoords.Resize(numTexCoords * 2); diff --git a/src/rendering/hwrenderer/scene/hw_decal.cpp b/src/rendering/hwrenderer/scene/hw_decal.cpp index 980fc52a5..0803e4e00 100644 --- a/src/rendering/hwrenderer/scene/hw_decal.cpp +++ b/src/rendering/hwrenderer/scene/hw_decal.cpp @@ -59,21 +59,7 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state) if (!di->isFullbrightScene()) DecalColor = DecalColor.Modulate(frontsector->SpecialColors[sector_t::sprites]); state.SetObjectColor(DecalColor); - state.SetLightIndex(dynlightindex); - - // add light probe contribution - if (di->Level->LightProbes.Size() > 0) - { - double x, y; - decal->GetXY(decal->Side, x, y); - LightProbe *probe = FindLightProbe(di->Level, x, y, decal->GetRealZ(decal->Side) * 0.5); - if (probe) - { - state.SetDynLight(probe->Red, probe->Green, probe->Blue); - } - } - state.SetTextureMode(decal->RenderStyle); state.SetRenderStyle(decal->RenderStyle); state.SetMaterial(texture, UF_Sprite, 0, CLAMP_XY, decal->Translation, -1); @@ -197,6 +183,11 @@ void HWWall::DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArraylinedef; @@ -342,7 +333,31 @@ void HWWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &nor dv[UL].u = dv[LL].u = lefttex / decalscale; dv[LR].u = dv[UR].u = righttex / decalscale; dv[LL].v = dv[LR].v = 1.f; - + + // lightmap texture index + for (i = 0; i < 4; i++) + { + dv[i].lindex = lindex; + } + + // lightmap texture coordinates + float tleft = left / linelength; + float tright = right / linelength; + float tuplft = ztop[0] != zbottom[0] ? (dv[UL].z - zbottom[0]) / (ztop[0] - zbottom[0]) : 0.0f; + float tuprgt = ztop[1] != zbottom[1] ? (dv[UR].z - zbottom[1]) / (ztop[1] - zbottom[1]) : 0.0f; + float tlolft = ztop[0] != zbottom[0] ? (dv[LL].z - zbottom[0]) / (ztop[0] - zbottom[0]) : 0.0f; + float tlorgt = ztop[1] != zbottom[1] ? (dv[LR].z - zbottom[1]) / (ztop[1] - zbottom[1]) : 0.0f; + + dv[LL].lu = mix(lightuv[LOLFT].u, lightuv[LORGT].u, tleft); + dv[LR].lu = mix(lightuv[LOLFT].u, lightuv[LORGT].u, tright); + dv[UL].lu = mix(lightuv[UPLFT].u, lightuv[UPRGT].u, tleft); + dv[UR].lu = mix(lightuv[UPLFT].u, lightuv[UPRGT].u, tright); + + dv[LL].lv = mix(lightuv[LOLFT].v, lightuv[UPLFT].v, tlolft); + dv[LR].lv = mix(lightuv[LORGT].v, lightuv[UPRGT].v, tlorgt); + dv[UL].lv = mix(lightuv[LOLFT].v, lightuv[UPLFT].v, tuplft); + dv[UR].lv = mix(lightuv[LORGT].v, lightuv[UPRGT].v, tuprgt); + // now clip to the top plane float vzt = (ztop[UL] - ztop[LL]) / linelength; float topleft = ztop[LL] + vzt * left; @@ -356,8 +371,12 @@ void HWWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &nor { // decal has to be clipped at the top // let texture clamping handle all extreme cases - dv[UL].v = (dv[UL].z - topleft) / (dv[UL].z - dv[LL].z)*dv[LL].v; - dv[UR].v = (dv[UR].z - topright) / (dv[UR].z - dv[LR].z)*dv[LR].v; + float t0 = (dv[UL].z - topleft) / (dv[UL].z - dv[LL].z); + float t1 = (dv[UR].z - topright) / (dv[UR].z - dv[LR].z); + dv[UL].v = t0 * dv[LL].v; + dv[UR].v = t1 * dv[LR].v; + dv[UL].lv = mix(dv[UL].lv, dv[LL].lv, t0); + dv[UR].lv = mix(dv[UR].lv, dv[LR].lv, t1); dv[UL].z = topleft; dv[UR].z = topright; } @@ -375,8 +394,12 @@ void HWWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &nor { // decal has to be clipped at the bottom // let texture clamping handle all extreme cases - dv[LL].v = (dv[UL].z - bottomleft) / (dv[UL].z - dv[LL].z)*(dv[LL].v - dv[UL].v) + dv[UL].v; - dv[LR].v = (dv[UR].z - bottomright) / (dv[UR].z - dv[LR].z)*(dv[LR].v - dv[UR].v) + dv[UR].v; + float t0 = (dv[UL].z - bottomleft) / (dv[UL].z - dv[LL].z); + float t1 = (dv[UR].z - bottomright) / (dv[UR].z - dv[LR].z); + dv[LL].v = t0 * (dv[LL].v - dv[UL].v) + dv[UL].v; + dv[LR].v = t1 * (dv[LR].v - dv[UR].v) + dv[UR].v; + dv[LL].lv = mix(dv[UL].lv, dv[LL].lv, t0); + dv[LR].lv = mix(dv[UR].lv, dv[LR].lv, t1); dv[LL].z = bottomleft; dv[LR].z = bottomright; } @@ -427,7 +450,7 @@ void HWWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &nor for (i = 0; i < 4; i++) { - verts.first[i].Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v); + verts.first[i].Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v, dv[i].lu, dv[i].lv, dv[i].lindex); } } diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index cf6c53027..6f4959f7b 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -401,6 +401,7 @@ struct DecalVertex { float x, y, z; float u, v; + float lu, lv, lindex; }; struct HWDecal @@ -433,7 +434,6 @@ inline float Dist2(float x1,float y1,float x2,float y2) bool hw_SetPlaneTextureRotation(const HWSectorPlane * secplane, FGameTexture * gltexture, VSMatrix &mat); void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata); -LightProbe* FindLightProbe(FLevelLocals* level, float x, float y, float z); extern const float LARGE_VALUE; diff --git a/src/rendering/hwrenderer/scene/hw_spritelight.cpp b/src/rendering/hwrenderer/scene/hw_spritelight.cpp index 64f98f650..73f5867da 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -46,61 +46,6 @@ T smoothstep(const T edge0, const T edge1, const T x) return t * t * (3.0 - 2.0 * t); } -LightProbe* FindLightProbe(FLevelLocals* level, float x, float y, float z) -{ - LightProbe* foundprobe = nullptr; - if (level->LightProbes.Size() > 0) - { -#if 1 - double rcpCellSize = 1.0 / level->LPCellSize; - int gridCenterX = (int)std::floor(x * rcpCellSize) - level->LPMinX; - int gridCenterY = (int)std::floor(y * rcpCellSize) - level->LPMinY; - int gridWidth = level->LPWidth; - int gridHeight = level->LPHeight; - float lastdist = 0.0f; - for (int gridY = gridCenterY - 1; gridY <= gridCenterY + 1; gridY++) - { - for (int gridX = gridCenterX - 1; gridX <= gridCenterX + 1; gridX++) - { - if (gridX >= 0 && gridY >= 0 && gridX < gridWidth && gridY < gridHeight) - { - const LightProbeCell& cell = level->LPCells[gridX + (size_t)gridY * gridWidth]; - for (int i = 0; i < cell.NumProbes; i++) - { - LightProbe* probe = cell.FirstProbe + i; - float dx = probe->X - x; - float dy = probe->Y - y; - float dz = probe->Z - z; - float dist = dx * dx + dy * dy + dz * dz; - if (!foundprobe || dist < lastdist) - { - foundprobe = probe; - lastdist = dist; - } - } - } - } - } -#else - float lastdist = 0.0f; - for (unsigned int i = 0; i < level->LightProbes.Size(); i++) - { - LightProbe *probe = &level->LightProbes[i]; - float dx = probe->X - x; - float dy = probe->Y - y; - float dz = probe->Z - z; - float dist = dx * dx + dy * dy + dz * dz; - if (i == 0 || dist < lastdist) - { - foundprobe = probe; - lastdist = dist; - } - } -#endif - } - return foundprobe; -} - static bool TraceLightVisbility(FLightNode* node, const FVector3& L, float dist) { FDynamicLight* light = node->lightsource;