Compare commits
	
		
			4 Commits
		
	
	
		
			ca017e3f7b
			...
			fe100bb938
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
								 | 
						fe100bb938 | |
| 
							
							
								
								 | 
						f6bcce9778 | |
| 
							
							
								
								 | 
						99697180cd | |
| 
							
							
								
								 | 
						ff91ad567b | 
| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
namespace KeepersCompound.LGS.Database.Chunks;
 | 
			
		||||
 | 
			
		||||
public enum SoftnessMode
 | 
			
		||||
{
 | 
			
		||||
    Standard,
 | 
			
		||||
    HighFourPoint,
 | 
			
		||||
    HighFivePoint,
 | 
			
		||||
    HighNinePoint,
 | 
			
		||||
    MediumFourPoint,
 | 
			
		||||
    MediumFivePoint,
 | 
			
		||||
    MediumNinePoint,
 | 
			
		||||
    LowFourPoint,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class LmParams : IChunk
 | 
			
		||||
{
 | 
			
		||||
    public enum LightingMode
 | 
			
		||||
    {
 | 
			
		||||
        Quick,
 | 
			
		||||
        Raycast,
 | 
			
		||||
        Objcast,
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public enum DepthMode
 | 
			
		||||
    {
 | 
			
		||||
        Lm16,
 | 
			
		||||
        Lm32,
 | 
			
		||||
        Lm32x,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ChunkHeader Header { get; set; }
 | 
			
		||||
    public float Attenuation { get; set; }
 | 
			
		||||
    public float Saturation { get; set; }
 | 
			
		||||
    public LightingMode ShadowType { get; set; }
 | 
			
		||||
    public SoftnessMode ShadowSoftness { get; set; }
 | 
			
		||||
    public float CenterWeight { get; set; }
 | 
			
		||||
    public DepthMode ShadowDepth { get; set; }
 | 
			
		||||
    public bool LightmappedWater { get; set; }
 | 
			
		||||
    public int LightmapScale { get; set; }
 | 
			
		||||
    
 | 
			
		||||
    private int _dataSize;
 | 
			
		||||
    private uint _unknown;
 | 
			
		||||
    
 | 
			
		||||
    public void ReadData(BinaryReader reader, DbFile.TableOfContents.Entry entry)
 | 
			
		||||
    {
 | 
			
		||||
        _dataSize = reader.ReadInt32();
 | 
			
		||||
        Attenuation = reader.ReadSingle();
 | 
			
		||||
        Saturation = reader.ReadSingle();
 | 
			
		||||
        ShadowType = (LightingMode)reader.ReadUInt32();
 | 
			
		||||
        ShadowSoftness = (SoftnessMode)reader.ReadUInt32();
 | 
			
		||||
        CenterWeight = reader.ReadSingle();
 | 
			
		||||
        ShadowDepth = (DepthMode)reader.ReadUInt32();
 | 
			
		||||
        LightmappedWater = reader.ReadBoolean();
 | 
			
		||||
        reader.ReadBytes(3);
 | 
			
		||||
        LightmapScale = reader.ReadInt32();
 | 
			
		||||
        _unknown = reader.ReadUInt32();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void WriteData(BinaryWriter writer)
 | 
			
		||||
    {
 | 
			
		||||
        writer.Write(_dataSize);
 | 
			
		||||
        writer.Write(Attenuation);
 | 
			
		||||
        writer.Write(Saturation);
 | 
			
		||||
        writer.Write((uint)ShadowType);
 | 
			
		||||
        writer.Write((uint)ShadowSoftness);
 | 
			
		||||
        writer.Write(CenterWeight);
 | 
			
		||||
        writer.Write((uint)ShadowDepth);
 | 
			
		||||
        writer.Write(LightmappedWater);
 | 
			
		||||
        writer.Write(new byte[3]);
 | 
			
		||||
        writer.Write(LightmapScale);
 | 
			
		||||
        writer.Write(_unknown);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +150,7 @@ public class DbFile
 | 
			
		|||
            "TXLIST" => new TxList(),
 | 
			
		||||
            "WREXT" => new WorldRep(),
 | 
			
		||||
            "BRLIST" => new BrList(),
 | 
			
		||||
            "LM_PARAM" => new LmParams(),
 | 
			
		||||
            "RENDPARAMS" => new RendParams(),
 | 
			
		||||
            "P$ModelName" => new PropertyChunk<PropLabel>(),
 | 
			
		||||
            "P$Scale" => new PropertyChunk<PropVector>(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,9 +10,10 @@ public class LightMapper
 | 
			
		|||
{
 | 
			
		||||
    private class Settings
 | 
			
		||||
    {
 | 
			
		||||
        public bool Hdr;
 | 
			
		||||
        public bool MultiSampling;
 | 
			
		||||
        public Vector3 AmbientLight;
 | 
			
		||||
        public bool Hdr;
 | 
			
		||||
        public SoftnessMode MultiSampling;
 | 
			
		||||
        public float MultiSamplingCenterWeight;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ResourcePathManager.CampaignResources _campaign;
 | 
			
		||||
| 
						 | 
				
			
			@ -36,10 +37,11 @@ public class LightMapper
 | 
			
		|||
        _lights = [];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void Light(bool multiSampling)
 | 
			
		||||
    public void Light()
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: Throw?
 | 
			
		||||
        if (!_mission.TryGetChunk<RendParams>("RENDPARAMS", out var rendParams) ||
 | 
			
		||||
            !_mission.TryGetChunk<LmParams>("LM_PARAM", out var lmParams) ||
 | 
			
		||||
            !_mission.TryGetChunk<WorldRep>("WREXT", out var worldRep))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,13 +51,16 @@ public class LightMapper
 | 
			
		|||
        {
 | 
			
		||||
            Hdr = worldRep.DataHeader.LightmapFormat == 2,
 | 
			
		||||
            AmbientLight = rendParams.ambientLight * 255,
 | 
			
		||||
            MultiSampling = multiSampling,
 | 
			
		||||
            MultiSampling = lmParams.ShadowSoftness,
 | 
			
		||||
            MultiSamplingCenterWeight = lmParams.CenterWeight,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        Timing.TimeStage("Gather Lights", BuildLightList);
 | 
			
		||||
        Timing.TimeStage("Set Light Indices", SetCellLightIndices);
 | 
			
		||||
        Timing.TimeStage("Trace Scene", () => TraceScene(settings));
 | 
			
		||||
        Timing.TimeStage("Update AnimLight Cell Mapping", SetAnimLightCellMaps);
 | 
			
		||||
 | 
			
		||||
        // lmParams.ShadowType = LmParams.LightingMode.Raycast;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void Save(string missionName)
 | 
			
		||||
| 
						 | 
				
			
			@ -435,26 +440,11 @@ public class LightMapper
 | 
			
		|||
                            var pos = topLeft;
 | 
			
		||||
                            pos += x * 0.25f * renderPoly.TextureVectors.Item1;
 | 
			
		||||
                            pos += y * 0.25f * renderPoly.TextureVectors.Item2;
 | 
			
		||||
 | 
			
		||||
                            var hit = false;
 | 
			
		||||
                            var strength = 0f;
 | 
			
		||||
 | 
			
		||||
                            if (settings.MultiSampling)
 | 
			
		||||
                            {
 | 
			
		||||
                                var xOffset = 0.25f * 0.25f * renderPoly.TextureVectors.Item1;
 | 
			
		||||
                                var yOffset = 0.25f * 0.25f * renderPoly.TextureVectors.Item2;
 | 
			
		||||
                                hit |= TracePixel(light, pos - xOffset - yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength);
 | 
			
		||||
                                hit |= TracePixel(light, pos + xOffset - yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength);
 | 
			
		||||
                                hit |= TracePixel(light, pos - xOffset + yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength);
 | 
			
		||||
                                hit |= TracePixel(light, pos + xOffset + yOffset, renderPoly.Center, plane, planeMapper, v2ds, ref strength);
 | 
			
		||||
                                strength /= 4f;
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                hit |= TracePixel(light, pos, renderPoly.Center, plane, planeMapper, v2ds, ref strength);
 | 
			
		||||
                            }
 | 
			
		||||
                            
 | 
			
		||||
                            if (hit)
 | 
			
		||||
                            if (TracePixelMultisampled(
 | 
			
		||||
                                    settings.MultiSampling, light, pos, renderPoly.Center, plane, planeMapper, v2ds,
 | 
			
		||||
                                    renderPoly.TextureVectors.Item1, renderPoly.TextureVectors.Item2,
 | 
			
		||||
                                    settings.MultiSamplingCenterWeight, out var strength))
 | 
			
		||||
                            {
 | 
			
		||||
                                // If we're an anim light there's a lot of stuff we need to update
 | 
			
		||||
                                // Firstly we need to add the light to the cells anim light palette
 | 
			
		||||
| 
						 | 
				
			
			@ -484,6 +474,73 @@ public class LightMapper
 | 
			
		|||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public bool TracePixelMultisampled(
 | 
			
		||||
        SoftnessMode mode,
 | 
			
		||||
        Light light,
 | 
			
		||||
        Vector3 pos,
 | 
			
		||||
        Vector3 polyCenter,
 | 
			
		||||
        Plane plane,
 | 
			
		||||
        MathUtils.PlanePointMapper planeMapper,
 | 
			
		||||
        Vector2[] v2ds,
 | 
			
		||||
        Vector3 texU,
 | 
			
		||||
        Vector3 texV,
 | 
			
		||||
        float centerWeight,
 | 
			
		||||
        out float strength)
 | 
			
		||||
    {
 | 
			
		||||
        bool FourPoint(float offsetScale, out float strength)
 | 
			
		||||
        {
 | 
			
		||||
            var hit = false;
 | 
			
		||||
            var xOffset = texU / offsetScale;
 | 
			
		||||
            var yOffset = texV / offsetScale;
 | 
			
		||||
            hit |= TracePixel(light, pos - xOffset - yOffset, polyCenter, plane, planeMapper, v2ds, out var strength1);
 | 
			
		||||
            hit |= TracePixel(light, pos + xOffset - yOffset, polyCenter, plane, planeMapper, v2ds, out var strength2);
 | 
			
		||||
            hit |= TracePixel(light, pos - xOffset + yOffset, polyCenter, plane, planeMapper, v2ds, out var strength3);
 | 
			
		||||
            hit |= TracePixel(light, pos + xOffset + yOffset, polyCenter, plane, planeMapper, v2ds, out var strength4);
 | 
			
		||||
            strength = (strength1 + strength2 + strength3 + strength4) / 4f;
 | 
			
		||||
            return hit;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        bool FivePoint(float offsetScale, out float strength)
 | 
			
		||||
        {
 | 
			
		||||
            var hit = false;
 | 
			
		||||
            hit |= TracePixel(light, pos, polyCenter, plane, planeMapper, v2ds, out var centerStrength);
 | 
			
		||||
            hit |= FourPoint(offsetScale, out strength);
 | 
			
		||||
            strength = (1.0f - centerWeight) * strength + centerWeight * centerStrength;
 | 
			
		||||
            return hit;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        bool NinePoint(float offsetScale, out float strength)
 | 
			
		||||
        {
 | 
			
		||||
            var hit = false;
 | 
			
		||||
            var xOffset = texU / offsetScale;
 | 
			
		||||
            var yOffset = texV / offsetScale;
 | 
			
		||||
            hit |= TracePixel(light, pos - xOffset - yOffset, polyCenter, plane, planeMapper, v2ds, out var s1);
 | 
			
		||||
            hit |= TracePixel(light, pos + xOffset - yOffset, polyCenter, plane, planeMapper, v2ds, out var s2);
 | 
			
		||||
            hit |= TracePixel(light, pos - xOffset + yOffset, polyCenter, plane, planeMapper, v2ds, out var s3);
 | 
			
		||||
            hit |= TracePixel(light, pos + xOffset + yOffset, polyCenter, plane, planeMapper, v2ds, out var s4);
 | 
			
		||||
            hit |= TracePixel(light, pos - xOffset, polyCenter, plane, planeMapper, v2ds, out var s5);
 | 
			
		||||
            hit |= TracePixel(light, pos + xOffset, polyCenter, plane, planeMapper, v2ds, out var s6);
 | 
			
		||||
            hit |= TracePixel(light, pos - yOffset, polyCenter, plane, planeMapper, v2ds, out var s7);
 | 
			
		||||
            hit |= TracePixel(light, pos + yOffset, polyCenter, plane, planeMapper, v2ds, out var s8);
 | 
			
		||||
            hit |= TracePixel(light, pos, polyCenter, plane, planeMapper, v2ds, out var centerStrength);
 | 
			
		||||
            strength = (s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8) / 8f;
 | 
			
		||||
            strength = (1.0f - centerWeight) * strength + centerWeight * centerStrength;
 | 
			
		||||
            return hit;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mode switch {
 | 
			
		||||
            SoftnessMode.Standard when light.QuadLit => FourPoint(4f, out strength),
 | 
			
		||||
            SoftnessMode.HighFourPoint => FourPoint(4f, out strength),
 | 
			
		||||
            SoftnessMode.HighFivePoint => FivePoint(4f, out strength),
 | 
			
		||||
            SoftnessMode.HighNinePoint => NinePoint(4f, out strength),
 | 
			
		||||
            SoftnessMode.MediumFourPoint => FourPoint(8f, out strength),
 | 
			
		||||
            SoftnessMode.MediumFivePoint => FivePoint(8f, out strength),
 | 
			
		||||
            SoftnessMode.MediumNinePoint => NinePoint(8f, out strength),
 | 
			
		||||
            SoftnessMode.LowFourPoint => FourPoint(16f, out strength),
 | 
			
		||||
            _ => TracePixel(light, pos, polyCenter, plane, planeMapper, v2ds, out strength)
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private bool TracePixel(
 | 
			
		||||
        Light light,
 | 
			
		||||
        Vector3 pos,
 | 
			
		||||
| 
						 | 
				
			
			@ -491,8 +548,10 @@ public class LightMapper
 | 
			
		|||
        Plane plane,
 | 
			
		||||
        MathUtils.PlanePointMapper planeMapper,
 | 
			
		||||
        Vector2[] v2ds,
 | 
			
		||||
        ref float strength)
 | 
			
		||||
        out float strength)
 | 
			
		||||
    {
 | 
			
		||||
        strength = 0f;
 | 
			
		||||
        
 | 
			
		||||
        // Embree has robustness issues when hitting poly edges which
 | 
			
		||||
        // results in false misses. To alleviate this we pre-push everything
 | 
			
		||||
        // slightly towards the center of the poly.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,15 +21,13 @@ public class LightCommand : ICommand
 | 
			
		|||
    public required string MissionName { get; init; }
 | 
			
		||||
    [CommandOption("output", 'o', Description = "Name of output file excluding extension.")]
 | 
			
		||||
    public string OutputName { get; init; } = "kc_lit";
 | 
			
		||||
    [CommandOption("multiSampling", 'm', Description = "Enables multi-sampled shadows. Higher quality but slower.")]
 | 
			
		||||
    public bool MultiSampling { get; init; } = false;
 | 
			
		||||
 | 
			
		||||
    public ValueTask ExecuteAsync(IConsole console)
 | 
			
		||||
    {
 | 
			
		||||
        Timing.Reset();
 | 
			
		||||
            
 | 
			
		||||
        var lightMapper = new LightMapper(InstallPath, CampaignName, MissionName);
 | 
			
		||||
        lightMapper.Light(MultiSampling);
 | 
			
		||||
        lightMapper.Light();
 | 
			
		||||
        lightMapper.Save(OutputName);
 | 
			
		||||
            
 | 
			
		||||
        Timing.LogAll();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue