Compare commits
	
		
			No commits in common. "4a80ef547b2990a8d37d112c66b6646ae669a4f1" and "cbf309aaa410a9c55891522acf7c4f37ccfde31b" have entirely different histories.
		
	
	
		
			4a80ef547b
			...
			cbf309aaa4
		
	
		| 
						 | 
					@ -149,44 +149,56 @@ public class WorldRep : IChunk
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            public readonly byte[] AsBytesRgba(int layer)
 | 
					            public readonly byte[] AsBytesRgba()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (layer >= Layers)
 | 
					                var length = Width * Height * 4;
 | 
				
			||||||
 | 
					                var bytes = new byte[length];
 | 
				
			||||||
 | 
					                for (var i = 0; i < length; i++)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    throw new ArgumentOutOfRangeException(nameof(layer));
 | 
					                    bytes[i] = 0;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var length = Width * Height * 4;
 | 
					                // TODO: might be faster to do these fors in the switch?
 | 
				
			||||||
                var layerOffset = layer * Bpp * Width * Height;
 | 
					                for (var z = 0; z < Layers; z++)
 | 
				
			||||||
                var bytes = new byte[length];
 | 
					 | 
				
			||||||
                for (var y = 0; y < Height; y++)
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    for (var x = 0; x < Width; x++)
 | 
					                    for (var y = 0; y < Height; y++)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var bIdx = x * 4 + y * 4 * Width;
 | 
					                        for (var x = 0; x < Width; x++)
 | 
				
			||||||
                        var pIdx = x * Bpp + y * Bpp * Width + layerOffset;
 | 
					 | 
				
			||||||
                        switch (Bpp)
 | 
					 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            case 1:
 | 
					                            var pIdx = 0 + x * Bpp + y * Bpp * Width + z * Bpp * Width * Height;
 | 
				
			||||||
                                var raw1 = Pixels[pIdx];
 | 
					                            var r = 0;
 | 
				
			||||||
                                bytes[bIdx] = raw1;
 | 
					                            var g = 0;
 | 
				
			||||||
                                bytes[bIdx + 1] = raw1;
 | 
					                            var b = 0;
 | 
				
			||||||
                                bytes[bIdx + 2] = raw1;
 | 
					                            var a = 0;
 | 
				
			||||||
                                bytes[bIdx + 3] = 255;
 | 
					                            switch (Bpp)
 | 
				
			||||||
                                break;
 | 
					                            {
 | 
				
			||||||
                            case 2:
 | 
					                                case 1:
 | 
				
			||||||
                                var raw2 = Pixels[pIdx] + (Pixels[pIdx + 1] << 8);
 | 
					                                    var raw1 = Pixels[pIdx];
 | 
				
			||||||
                                bytes[bIdx] = (byte)(255 * (raw2 & 31) / 31.0f);
 | 
					                                    r = raw1;
 | 
				
			||||||
                                bytes[bIdx + 1] = (byte)(255 * ((raw2 >> 5) & 31) / 31.0f);
 | 
					                                    g = raw1;
 | 
				
			||||||
                                bytes[bIdx + 2] = (byte)(255 * ((raw2 >> 10) & 31) / 31.0f);
 | 
					                                    b = raw1;
 | 
				
			||||||
                                bytes[bIdx + 3] = 255;
 | 
					                                    a = 255;
 | 
				
			||||||
                                break;
 | 
					                                    break;
 | 
				
			||||||
                            case 4:
 | 
					                                case 2:
 | 
				
			||||||
                                bytes[bIdx] = Pixels[pIdx + 2];
 | 
					                                    var raw2 = Pixels[pIdx] + (Pixels[pIdx + 1] << 8);
 | 
				
			||||||
                                bytes[bIdx + 1] = Pixels[pIdx + 1];
 | 
					                                    r = (int)(255 * (raw2 & 31) / 31.0f);
 | 
				
			||||||
                                bytes[bIdx + 2] = Pixels[pIdx];
 | 
					                                    g = (int)(255 * ((raw2 >> 5) & 31) / 31.0f);
 | 
				
			||||||
                                bytes[bIdx + 3] = Pixels[pIdx + 3];
 | 
					                                    b = (int)(255 * ((raw2 >> 10) & 31) / 31.0f);
 | 
				
			||||||
                                break;
 | 
					                                    a = 255;
 | 
				
			||||||
 | 
					                                    break;
 | 
				
			||||||
 | 
					                                case 4:
 | 
				
			||||||
 | 
					                                    r = Pixels[pIdx + 2];
 | 
				
			||||||
 | 
					                                    g = Pixels[pIdx + 1];
 | 
				
			||||||
 | 
					                                    b = Pixels[pIdx];
 | 
				
			||||||
 | 
					                                    a = Pixels[pIdx + 3];
 | 
				
			||||||
 | 
					                                    break;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            var bIdx = x * 4 + y * 4 * Width;
 | 
				
			||||||
 | 
					                            bytes[bIdx] = (byte)Math.Min(255, bytes[bIdx] + r);
 | 
				
			||||||
 | 
					                            bytes[bIdx + 1] = (byte)Math.Min(255, bytes[bIdx + 1] + g);
 | 
				
			||||||
 | 
					                            bytes[bIdx + 2] = (byte)Math.Min(255, bytes[bIdx + 2] + b);
 | 
				
			||||||
 | 
					                            bytes[bIdx + 3] = (byte)Math.Min(255, bytes[bIdx + 3] + a);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,16 +45,12 @@ public partial class Mission : Node3D
 | 
				
			||||||
	DbFile _file;
 | 
						DbFile _file;
 | 
				
			||||||
	TextureLoader _textureLoader;
 | 
						TextureLoader _textureLoader;
 | 
				
			||||||
	ModelLoader _modelLoader;
 | 
						ModelLoader _modelLoader;
 | 
				
			||||||
	List<ShaderMaterial> _materials;
 | 
					 | 
				
			||||||
	Vector2I _lmLayerMask;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public override void _Ready()
 | 
						public override void _Ready()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp");
 | 
							var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp");
 | 
				
			||||||
		_installPaths = new ResourcePathManager(extractPath);
 | 
							_installPaths = new ResourcePathManager(extractPath);
 | 
				
			||||||
		_modelLoader = new ModelLoader(_installPaths);
 | 
							_modelLoader = new ModelLoader(_installPaths);
 | 
				
			||||||
		_materials = new List<ShaderMaterial>();
 | 
					 | 
				
			||||||
		_lmLayerMask = new Vector2I(~0, ~0);
 | 
					 | 
				
			||||||
		var missionSelector = GetNode<Control>("%MissionSelector") as MissionSelector;
 | 
							var missionSelector = GetNode<Control>("%MissionSelector") as MissionSelector;
 | 
				
			||||||
		missionSelector.pathManager = _installPaths;
 | 
							missionSelector.pathManager = _installPaths;
 | 
				
			||||||
		missionSelector.MissionSelected += (string campaign, string mission) =>
 | 
							missionSelector.MissionSelected += (string campaign, string mission) =>
 | 
				
			||||||
| 
						 | 
					@ -88,10 +84,6 @@ public partial class Mission : Node3D
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Build = true;
 | 
									Build = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (keyEvent.Keycode == Key.O)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				ToggleLightmap();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,8 +93,6 @@ public partial class Mission : Node3D
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			node.QueueFree();
 | 
								node.QueueFree();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		_materials.Clear();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void RebuildMap()
 | 
						public void RebuildMap()
 | 
				
			||||||
| 
						 | 
					@ -121,60 +111,6 @@ public partial class Mission : Node3D
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void ToggleLightmap()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (_lmLayerMask == Vector2I.Zero)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			_lmLayerMask = new Vector2I(~0, ~0);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			_lmLayerMask = Vector2I.Zero;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		foreach (var mat in _materials)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			mat.SetShaderParameter("lightmap_bitmask", _lmLayerMask);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void ToggleLmLayer(uint layer)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (layer >= 64)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			throw new ArgumentOutOfRangeException(nameof(layer));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		static int ToggleBit(int bitIdx, int val)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			var mask = 1 << bitIdx;
 | 
					 | 
				
			||||||
			var isEnabled = (val & mask) != 0;
 | 
					 | 
				
			||||||
			if (isEnabled)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				val &= ~mask;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				val |= mask;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return val;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (layer < 32)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			_lmLayerMask.X = ToggleBit((int)layer, _lmLayerMask.X);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			_lmLayerMask.Y = ToggleBit((int)layer - 32, _lmLayerMask.Y);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		foreach (var mat in _materials)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			mat.SetShaderParameter("lightmap_bitmask", _lmLayerMask);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO: Make this less of a mess
 | 
						// TODO: Make this less of a mess
 | 
				
			||||||
	private ObjectHierarchy BuildHierarchy()
 | 
						private ObjectHierarchy BuildHierarchy()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -303,12 +239,10 @@ public partial class Mission : Node3D
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var albedoTexture = _textureLoader.Get(textureId);
 | 
								var albedoTexture = _textureLoader.Get(textureId);
 | 
				
			||||||
			var mat = BuildMaterial(albedoTexture, lightmapTexture, lmHdr, _lmLayerMask);
 | 
					 | 
				
			||||||
			_materials.Add(mat);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var mesh = new ArrayMesh();
 | 
								var mesh = new ArrayMesh();
 | 
				
			||||||
			mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, surface.BuildSurfaceArray());
 | 
								mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, surface.BuildSurfaceArray());
 | 
				
			||||||
			mesh.SurfaceSetMaterial(0, mat);
 | 
								mesh.SurfaceSetMaterial(0, BuildMaterial(albedoTexture, lightmapTexture, lmHdr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var meshInstance = new MeshInstance3D { Mesh = mesh };
 | 
								var meshInstance = new MeshInstance3D { Mesh = mesh };
 | 
				
			||||||
			AddChild(meshInstance);
 | 
								AddChild(meshInstance);
 | 
				
			||||||
| 
						 | 
					@ -348,11 +282,7 @@ public partial class Mission : Node3D
 | 
				
			||||||
		return new LightmapRectData(cellIdx, polyIdx, textureId, start, end);
 | 
							return new LightmapRectData(cellIdx, polyIdx, textureId, start, end);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static Texture2DArray BuildLightmapTexture(
 | 
						private static Texture BuildLightmapTexture(WorldRep.Cell[] cells, PackingRectangle[] packingRects, Dictionary<int, LightmapRectData> rectDataMap, Dictionary<int, MeshSurfaceData> surfaceDataMap)
 | 
				
			||||||
		WorldRep.Cell[] cells,
 | 
					 | 
				
			||||||
		PackingRectangle[] packingRects,
 | 
					 | 
				
			||||||
		Dictionary<int, LightmapRectData> rectDataMap,
 | 
					 | 
				
			||||||
		Dictionary<int, MeshSurfaceData> surfaceDataMap)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		var bounds = Timing.TimeStage("RectPack", () =>
 | 
							var bounds = Timing.TimeStage("RectPack", () =>
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -360,16 +290,7 @@ public partial class Mission : Node3D
 | 
				
			||||||
			return bounds;
 | 
								return bounds;
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		GD.Print($"Creating lightmap with bounds: ({bounds.Width}, {bounds.Height})");
 | 
							GD.Print($"Creating lightmap with bounds: ({bounds.Width}, {bounds.Height})");
 | 
				
			||||||
 | 
							var image = Image.CreateEmpty((int)bounds.Width, (int)bounds.Height, false, Image.Format.Rgba8);
 | 
				
			||||||
		var lightmapFormat = Image.Format.Rgba8;
 | 
					 | 
				
			||||||
		var lmLayerCount = 33;
 | 
					 | 
				
			||||||
		var lmImages = new Godot.Collections.Array<Image>();
 | 
					 | 
				
			||||||
		lmImages.Resize(lmLayerCount);
 | 
					 | 
				
			||||||
		for (var i = 0; i < lmLayerCount; i++)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			lmImages[i] = Image.CreateEmpty((int)bounds.Width, (int)bounds.Height, false, lightmapFormat);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		foreach (var rect in packingRects)
 | 
							foreach (var rect in packingRects)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (!rectDataMap.ContainsKey(rect.Id)) GD.Print("Invalid rectDataMap key");
 | 
								if (!rectDataMap.ContainsKey(rect.Id)) GD.Print("Invalid rectDataMap key");
 | 
				
			||||||
| 
						 | 
					@ -377,18 +298,9 @@ public partial class Mission : Node3D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (info.cellIndex >= cells.Length) GD.Print($"CellIndex too big: {info.cellIndex}/{cells.Length}");
 | 
								if (info.cellIndex >= cells.Length) GD.Print($"CellIndex too big: {info.cellIndex}/{cells.Length}");
 | 
				
			||||||
			if (info.lightmapIndex >= cells[info.cellIndex].Lightmaps.Length) GD.Print($"LightmapIndex too big: {info.lightmapIndex}/{cells[info.cellIndex].Lightmaps.Length}");
 | 
								if (info.lightmapIndex >= cells[info.cellIndex].Lightmaps.Length) GD.Print($"LightmapIndex too big: {info.lightmapIndex}/{cells[info.cellIndex].Lightmaps.Length}");
 | 
				
			||||||
 | 
					 | 
				
			||||||
			var lightmap = cells[info.cellIndex].Lightmaps[info.lightmapIndex];
 | 
								var lightmap = cells[info.cellIndex].Lightmaps[info.lightmapIndex];
 | 
				
			||||||
			var width = lightmap.Width;
 | 
								var cellLm = Image.CreateFromData(lightmap.Width, lightmap.Height, false, Image.Format.Rgba8, lightmap.AsBytesRgba());
 | 
				
			||||||
			var height = lightmap.Height;
 | 
								image.BlitRect(cellLm, new Rect2I(0, 0, lightmap.Width, lightmap.Height), new Vector2I((int)rect.X, (int)rect.Y));
 | 
				
			||||||
			var layerCount = lightmap.Layers;
 | 
					 | 
				
			||||||
			var srcRect = new Rect2I(0, 0, width, height);
 | 
					 | 
				
			||||||
			var dst = new Vector2I((int)rect.X, (int)rect.Y);
 | 
					 | 
				
			||||||
			for (var i = 0; i < layerCount; i++)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				var cellLm = Image.CreateFromData(width, height, false, lightmapFormat, lightmap.AsBytesRgba(i));
 | 
					 | 
				
			||||||
				lmImages[i].BlitRect(cellLm, srcRect, dst);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!surfaceDataMap.ContainsKey(info.textureId)) GD.Print("Invalid SurfaceDataMap key");
 | 
								if (!surfaceDataMap.ContainsKey(info.textureId)) GD.Print("Invalid SurfaceDataMap key");
 | 
				
			||||||
			surfaceDataMap[info.textureId].TransformUv2s(info.uvStart, info.uvEnd, (uv) =>
 | 
								surfaceDataMap[info.textureId].TransformUv2s(info.uvStart, info.uvEnd, (uv) =>
 | 
				
			||||||
| 
						 | 
					@ -409,9 +321,7 @@ public partial class Mission : Node3D
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var lightmapTexture = new Texture2DArray();
 | 
							return ImageTexture.CreateFromImage(image);
 | 
				
			||||||
		lightmapTexture.CreateFromImages(lmImages);
 | 
					 | 
				
			||||||
		return lightmapTexture;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private int CalcBaseUV(
 | 
						private int CalcBaseUV(
 | 
				
			||||||
| 
						 | 
					@ -538,17 +448,12 @@ public partial class Mission : Node3D
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const string MATERIAL_PATH = "res://project/materials/base.tres";
 | 
						const string MATERIAL_PATH = "res://project/materials/base.tres";
 | 
				
			||||||
	private static ShaderMaterial BuildMaterial(
 | 
						private static Material BuildMaterial(Texture albedoTexture, Texture lightmapTexture, bool lmHdr)
 | 
				
			||||||
		Texture2D albedoTexture,
 | 
					 | 
				
			||||||
		Texture2DArray lightmapTexture,
 | 
					 | 
				
			||||||
		bool lmHdr,
 | 
					 | 
				
			||||||
		Vector2I layerMask)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		var material = ResourceLoader.Load<ShaderMaterial>(MATERIAL_PATH).Duplicate() as ShaderMaterial;
 | 
							var material = ResourceLoader.Load<ShaderMaterial>(MATERIAL_PATH).Duplicate() as ShaderMaterial;
 | 
				
			||||||
		material.SetShaderParameter("texture_albedo", albedoTexture);
 | 
							material.SetShaderParameter("texture_albedo", albedoTexture);
 | 
				
			||||||
		material.SetShaderParameter("lightmap_albedo", lightmapTexture);
 | 
							material.SetShaderParameter("lightmap_albedo", lightmapTexture);
 | 
				
			||||||
		material.SetShaderParameter("lightmap_2x", lmHdr);
 | 
							material.SetShaderParameter("lightmap_2x", lmHdr);
 | 
				
			||||||
		material.SetShaderParameter("lightmap_bitmask", layerMask);
 | 
					 | 
				
			||||||
		return material;
 | 
							return material;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4,9 +4,8 @@
 | 
				
			||||||
code = "shader_type spatial;
 | 
					code = "shader_type spatial;
 | 
				
			||||||
render_mode blend_mix,depth_draw_opaque,cull_back,unshaded;
 | 
					render_mode blend_mix,depth_draw_opaque,cull_back,unshaded;
 | 
				
			||||||
uniform sampler2D texture_albedo : filter_linear_mipmap_anisotropic,repeat_enable;
 | 
					uniform sampler2D texture_albedo : filter_linear_mipmap_anisotropic,repeat_enable;
 | 
				
			||||||
uniform sampler2DArray lightmap_albedo : filter_linear_mipmap_anisotropic,repeat_enable;
 | 
					uniform sampler2D lightmap_albedo : filter_linear_mipmap_anisotropic,repeat_enable;
 | 
				
			||||||
uniform bool lightmap_2x;
 | 
					uniform bool lightmap_2x;
 | 
				
			||||||
uniform ivec2 lightmap_bitmask;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
float srgb_to_linear_e(float input) {
 | 
					float srgb_to_linear_e(float input) {
 | 
				
			||||||
	float output;
 | 
						float output;
 | 
				
			||||||
| 
						 | 
					@ -29,27 +28,11 @@ vec3 srgb_to_linear(vec3 input) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void fragment() {
 | 
					void fragment() {
 | 
				
			||||||
	vec4 albedo_tex = texture(texture_albedo,UV);
 | 
						vec4 albedo_tex = texture(texture_albedo,UV);
 | 
				
			||||||
	if (lightmap_bitmask.x == 0 && lightmap_bitmask.y == 0) {
 | 
						vec4 lightmap_tex = texture(lightmap_albedo,UV2);
 | 
				
			||||||
		ALBEDO = srgb_to_linear(albedo_tex.rgb);
 | 
						if (lightmap_2x) {
 | 
				
			||||||
	} else {
 | 
							lightmap_tex *= 2.0f;
 | 
				
			||||||
		vec4 lightmap_tex = vec4(0.0);
 | 
					 | 
				
			||||||
		int mask = lightmap_bitmask.x;
 | 
					 | 
				
			||||||
		for (int i = 0; i < 33; i++) {
 | 
					 | 
				
			||||||
			if (i == 32) {
 | 
					 | 
				
			||||||
				mask = lightmap_bitmask.y;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			bool layer_enabled = (mask & (1 << (i % 32))) != 0;
 | 
					 | 
				
			||||||
			if (layer_enabled) {
 | 
					 | 
				
			||||||
				lightmap_tex += texture(lightmap_albedo, vec3(UV2, float(i)));
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		lightmap_tex = min(vec4(1.0), lightmap_tex);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (lightmap_2x) {
 | 
					 | 
				
			||||||
			lightmap_tex *= 2.0f;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ALBEDO = srgb_to_linear((albedo_tex * lightmap_tex).rgb);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ALBEDO = srgb_to_linear((albedo_tex * lightmap_tex).rgb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
"
 | 
					"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,4 +40,3 @@ void fragment() {
 | 
				
			||||||
render_priority = 0
 | 
					render_priority = 0
 | 
				
			||||||
shader = SubResource("Shader_eumy4")
 | 
					shader = SubResource("Shader_eumy4")
 | 
				
			||||||
shader_parameter/lightmap_2x = null
 | 
					shader_parameter/lightmap_2x = null
 | 
				
			||||||
shader_parameter/lightmap_bitmask = null
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue