This commit is contained in:
Perfare 2022-03-22 22:54:49 +08:00 committed by VaDiM
parent 54445475a3
commit 23ac590648
2 changed files with 61 additions and 31 deletions

View File

@ -959,9 +959,9 @@ namespace AssetStudio
//5.5 and up
public SerializedShader m_ParsedForm;
public ShaderCompilerPlatform[] platforms;
public uint[] offsets;
public uint[] compressedLengths;
public uint[] decompressedLengths;
public uint[][] offsets;
public uint[][] compressedLengths;
public uint[][] decompressedLengths;
public byte[] compressedBlob;
public Shader(ObjectReader reader) : base(reader)
@ -972,15 +972,15 @@ namespace AssetStudio
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
offsets = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
compressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
decompressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
offsets = reader.ReadUInt32ArrayArray();
compressedLengths = reader.ReadUInt32ArrayArray();
decompressedLengths = reader.ReadUInt32ArrayArray();
}
else
{
offsets = reader.ReadUInt32Array();
compressedLengths = reader.ReadUInt32Array();
decompressedLengths = reader.ReadUInt32Array();
offsets = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
compressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
decompressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
}
compressedBlob = reader.ReadUInt8Array();
reader.AlignStream();

View File

@ -19,6 +19,7 @@ namespace AssetStudio
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
{
var program = new ShaderProgram(blobReader, shader.version);
program.Read(blobReader, 0);
return header + program.Export(Encoding.UTF8.GetString(shader.m_Script));
}
}
@ -33,17 +34,26 @@ namespace AssetStudio
private static string ConvertSerializedShader(Shader shader)
{
var shaderPrograms = new ShaderProgram[shader.platforms.Length];
for (var i = 0; i < shader.platforms.Length; i++)
var length = shader.platforms.Length;
var shaderPrograms = new ShaderProgram[length];
for (var i = 0; i < length; i++)
{
var compressedBytes = new byte[shader.compressedLengths[i]];
Buffer.BlockCopy(shader.compressedBlob, (int)shader.offsets[i], compressedBytes, 0, (int)shader.compressedLengths[i]);
var decompressedBytes = new byte[shader.decompressedLengths[i]];
LZ4Codec.Decode(compressedBytes, decompressedBytes);
for (var j = 0; j < shader.offsets[i].Length; j++)
{
var offset = shader.offsets[i][j];
var compressedLength = shader.compressedLengths[i][j];
var decompressedLength = shader.decompressedLengths[i][j];
var decompressedBytes = new byte[decompressedLength];
LZ4Codec.Decode(shader.compressedBlob, (int)offset, (int)compressedLength, decompressedBytes, 0, (int)decompressedLength);
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
{
if (j == 0)
{
shaderPrograms[i] = new ShaderProgram(blobReader, shader.version);
}
shaderPrograms[i].Read(blobReader, j);
}
}
}
return ConvertSerializedShader(shader.m_ParsedForm, shader.platforms, shaderPrograms);
@ -854,31 +864,51 @@ namespace AssetStudio
"///////////////////////////////////////////\n";
}
public class ShaderSubProgramEntry
{
public int Offset;
public int Length;
public int Segment;
public ShaderSubProgramEntry(BinaryReader reader, int[] version)
{
Offset = reader.ReadInt32();
Length = reader.ReadInt32();
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
Segment = reader.ReadInt32();
}
}
}
public class ShaderProgram
{
public ShaderSubProgramEntry[] entries;
public ShaderSubProgram[] m_SubPrograms;
public ShaderProgram(BinaryReader reader, int[] version)
{
var subProgramsCapacity = reader.ReadInt32();
m_SubPrograms = new ShaderSubProgram[subProgramsCapacity];
int entrySize;
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
entrySize = 12;
}
else
{
entrySize = 8;
}
entries = new ShaderSubProgramEntry[subProgramsCapacity];
for (int i = 0; i < subProgramsCapacity; i++)
{
reader.BaseStream.Position = 4 + i * entrySize;
var offset = reader.ReadInt32();
reader.BaseStream.Position = offset;
entries[i] = new ShaderSubProgramEntry(reader, version);
}
m_SubPrograms = new ShaderSubProgram[subProgramsCapacity];
}
public void Read(BinaryReader reader, int segment)
{
for (int i = 0; i < entries.Length; i++)
{
var entry = entries[i];
if (entry.Segment == segment)
{
reader.BaseStream.Position = entry.Offset;
m_SubPrograms[i] = new ShaderSubProgram(reader);
}
}
}
public string Export(string shader)
{