Compare commits
No commits in common. "cb526c634c7fff77b8fe89766de796722b7e8036" and "196e97a8fdfed3c3bfbeefcd7573c3a651b1efdb" have entirely different histories.
cb526c634c
...
196e97a8fd
|
@ -243,32 +243,6 @@ public class WorldRep : IChunk
|
|||
Pixels[idx + 3] = 255;
|
||||
}
|
||||
|
||||
public void AddLight(int layer, int x, int y, Vector3 color, float strength, bool hdr)
|
||||
{
|
||||
if (hdr)
|
||||
{
|
||||
strength /= 2.0f;
|
||||
}
|
||||
|
||||
// We need to make sure we don't go over (255, 255, 255).
|
||||
// If we just do Max(color, (255, 255, 255)) then we change
|
||||
// the hue/saturation of coloured lights. Got to make sure we
|
||||
// maintain the colour ratios.
|
||||
var c = color * strength;
|
||||
var ratio = 0.0f;
|
||||
foreach (var e in new float[] { c.X, c.Y, c.Z })
|
||||
{
|
||||
ratio = Math.Max(ratio, e / 255.0f);
|
||||
}
|
||||
|
||||
if (ratio > 1.0f)
|
||||
{
|
||||
c /= ratio;
|
||||
}
|
||||
|
||||
AddLight(layer, x, y, (byte)c.X, (byte)c.Y, (byte)c.Z);
|
||||
}
|
||||
|
||||
public readonly void Write(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(Pixels);
|
||||
|
|
|
@ -52,7 +52,7 @@ class Program
|
|||
if (!mis.Chunks.TryGetValue("RENDPARAMS", out var rendParamsRaw))
|
||||
return;
|
||||
var ambient = ((RendParams)rendParamsRaw).ambientLight * 255;
|
||||
Timing.TimeStage("Light", () => CastSceneParallel(scene, worldRep, [.. lights], ambient));
|
||||
Timing.TimeStage("Light", () => CastScene(scene, worldRep, [.. lights], ambient));
|
||||
|
||||
var dir = Path.GetDirectoryName(misPath);
|
||||
var filename = Path.GetFileNameWithoutExtension(misPath);
|
||||
|
@ -214,12 +214,16 @@ class Program
|
|||
return new TriangleMesh([.. vertices], [.. indices]);
|
||||
}
|
||||
|
||||
private static void CastSceneParallel(Raytracer scene, WorldRep wr, Light[] lights, Vector3 ambientLight)
|
||||
private static void CastScene(Raytracer scene, WorldRep wr, Light[] lights, Vector3 ambientLight)
|
||||
{
|
||||
var hdr = wr.DataHeader.LightmapFormat == 2;
|
||||
|
||||
Parallel.ForEach(wr.Cells, cell =>
|
||||
var cells = wr.Cells;
|
||||
for (var cellIdx = 0; cellIdx < cells.Length; cellIdx++)
|
||||
{
|
||||
Console.Write($"\rLighting cell... {cellIdx + 1}/{cells.Length}");
|
||||
|
||||
var cell = cells[cellIdx];
|
||||
var numPolys = cell.PolyCount;
|
||||
var numRenderPolys = cell.RenderPolyCount;
|
||||
var numPortalPolys = cell.PortalPolyCount;
|
||||
|
@ -228,7 +232,7 @@ class Program
|
|||
// Portal polys can be render polys (e.g. water) but we're ignoring them for now
|
||||
if (numRenderPolys == 0 || numPortalPolys >= numPolys)
|
||||
{
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
var maxPolyIdx = Math.Min(numRenderPolys, numPolys - numPortalPolys);
|
||||
|
@ -335,8 +339,36 @@ class Program
|
|||
var hit = hitResult && Math.Abs(hitResult.Distance - direction.Length()) < MathUtils.Epsilon;
|
||||
if (hit)
|
||||
{
|
||||
var strength = CalculateLightStrengthAtPoint(light, pos, plane);
|
||||
lightmap.AddLight(0, x, y, light.color, strength, hdr);
|
||||
// Calculate light strength at a given point. As far as I can tell
|
||||
// this is exact to Dark (I'm a genius??). It's just an inverse distance
|
||||
// falloff with diffuse angle, except we have to scale the length.
|
||||
var dir = light.position - pos;
|
||||
var angle = Vector3.Dot(Vector3.Normalize(dir), plane.Normal);
|
||||
var len = dir.Length();
|
||||
var slen = len / 4.0f;
|
||||
var strength = (angle + 1.0f) / slen;
|
||||
if (hdr)
|
||||
{
|
||||
strength /= 2;
|
||||
}
|
||||
|
||||
// We need to make sure we don't go over (255, 255, 255).
|
||||
// If we just do Max(color, (255, 255, 255)) then we change
|
||||
// the hue/saturation of coloured lights. Got to make sure we
|
||||
// maintain the colour ratios.
|
||||
var c = light.color * strength;
|
||||
var ratio = 0.0f;
|
||||
foreach (var e in new float[] { c.X, c.Y, c.Z })
|
||||
{
|
||||
ratio = Math.Max(ratio, e / 255.0f);
|
||||
}
|
||||
|
||||
if (ratio > 1.0f)
|
||||
{
|
||||
c /= ratio;
|
||||
}
|
||||
|
||||
lightmap.AddLight(0, x, y, (byte)c.X, (byte)c.Y, (byte)c.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,21 +376,9 @@ class Program
|
|||
|
||||
cellIdxOffset += poly.VertexCount;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static float CalculateLightStrengthAtPoint(Light light, Vector3 point, Plane plane)
|
||||
{
|
||||
// Calculate light strength at a given point. As far as I can tell
|
||||
// this is exact to Dark (I'm a genius??). It's just an inverse distance
|
||||
// falloff with diffuse angle, except we have to scale the length.
|
||||
var dir = light.position - point;
|
||||
var angle = Vector3.Dot(Vector3.Normalize(dir), plane.Normal);
|
||||
var len = dir.Length();
|
||||
var slen = len / 4.0f;
|
||||
var strength = (angle + 1.0f) / slen;
|
||||
|
||||
return strength;
|
||||
Console.Write("\n");
|
||||
}
|
||||
|
||||
private static void ResetLightmap(Vector3 ambientLight, WorldRep.Cell.Lightmap lightmap, bool hdr)
|
||||
|
@ -368,11 +388,17 @@ class Program
|
|||
lightmap.Pixels[i] = 0;
|
||||
}
|
||||
|
||||
var c = ambientLight;
|
||||
if (hdr)
|
||||
{
|
||||
c /= 2.0f;
|
||||
}
|
||||
|
||||
for (var y = 0; y < lightmap.Height; y++)
|
||||
{
|
||||
for (var x = 0; x < lightmap.Width; x++)
|
||||
{
|
||||
lightmap.AddLight(0, x, y, ambientLight, 1.0f, hdr);
|
||||
lightmap.AddLight(0, x, y, (byte)c.X, (byte)c.Y, (byte)c.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue