This commit is contained in:
Perfare 2022-03-22 22:54:49 +08:00
parent b1205808e2
commit 44514a4e10
2 changed files with 61 additions and 31 deletions

View File

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

View File

@ -19,6 +19,7 @@ namespace AssetStudio
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes))) using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
{ {
var program = new ShaderProgram(blobReader, shader.version); var program = new ShaderProgram(blobReader, shader.version);
program.Read(blobReader, 0);
return header + program.Export(Encoding.UTF8.GetString(shader.m_Script)); return header + program.Export(Encoding.UTF8.GetString(shader.m_Script));
} }
} }
@ -33,16 +34,25 @@ namespace AssetStudio
private static string ConvertSerializedShader(Shader shader) private static string ConvertSerializedShader(Shader shader)
{ {
var shaderPrograms = new ShaderProgram[shader.platforms.Length]; var length = shader.platforms.Length;
for (var i = 0; i < shader.platforms.Length; i++) var shaderPrograms = new ShaderProgram[length];
for (var i = 0; i < length; i++)
{ {
var compressedBytes = new byte[shader.compressedLengths[i]]; for (var j = 0; j < shader.offsets[i].Length; j++)
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);
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
{ {
shaderPrograms[i] = new ShaderProgram(blobReader, shader.version); 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);
}
} }
} }
@ -854,29 +864,49 @@ namespace AssetStudio
"///////////////////////////////////////////\n"; "///////////////////////////////////////////\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 class ShaderProgram
{ {
public ShaderSubProgramEntry[] entries;
public ShaderSubProgram[] m_SubPrograms; public ShaderSubProgram[] m_SubPrograms;
public ShaderProgram(BinaryReader reader, int[] version) public ShaderProgram(BinaryReader reader, int[] version)
{ {
var subProgramsCapacity = reader.ReadInt32(); var subProgramsCapacity = reader.ReadInt32();
m_SubPrograms = new ShaderSubProgram[subProgramsCapacity]; entries = new ShaderSubProgramEntry[subProgramsCapacity];
int entrySize;
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
entrySize = 12;
}
else
{
entrySize = 8;
}
for (int i = 0; i < subProgramsCapacity; i++) for (int i = 0; i < subProgramsCapacity; i++)
{ {
reader.BaseStream.Position = 4 + i * entrySize; entries[i] = new ShaderSubProgramEntry(reader, version);
var offset = reader.ReadInt32(); }
reader.BaseStream.Position = offset; m_SubPrograms = new ShaderSubProgram[subProgramsCapacity];
m_SubPrograms[i] = new ShaderSubProgram(reader); }
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);
}
} }
} }