diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj
index 93d89a3..59b0e1b 100644
--- a/AssetStudio/AssetStudio.csproj
+++ b/AssetStudio/AssetStudio.csproj
@@ -85,6 +85,14 @@
Libraries\OpenTK.GLControl.dll
False
+
+ Libraries\SharpDX.dll
+ False
+
+
+ Libraries\SharpDX.D3DCompiler.dll
+ False
+
Libraries\SharpDX.Mathematics.dll
False
@@ -198,6 +206,7 @@
+
diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs
index 1902876..5d080aa 100644
--- a/AssetStudio/AssetStudioForm.cs
+++ b/AssetStudio/AssetStudioForm.cs
@@ -816,11 +816,9 @@ namespace AssetStudio
}
case ClassIDType.Shader:
{
- Shader m_TextAsset = new Shader(reader);
- string m_Script_Text = Encoding.UTF8.GetString(m_TextAsset.m_Script);
- m_Script_Text = Regex.Replace(m_Script_Text, "(? m_MatrixParams { get; set; }
+ public List m_VectorParams { get; set; }
+
+ public StructParameter(BinaryReader reader)
+ {
+ var m_NameIndex = reader.ReadInt32();
+ var m_Index = reader.ReadInt32();
+ var m_ArraySize = reader.ReadInt32();
+ var m_StructSize = reader.ReadInt32();
+
+ int numVectorParams = reader.ReadInt32();
+ m_VectorParams = new List(numVectorParams);
+ for (int i = 0; i < numVectorParams; i++)
+ {
+ m_VectorParams.Add(new VectorParameter(reader));
+ }
+
+ int numMatrixParams = reader.ReadInt32();
+ m_MatrixParams = new List(numMatrixParams);
+ for (int i = 0; i < numMatrixParams; i++)
+ {
+ m_MatrixParams.Add(new MatrixParameter(reader));
+ }
+ }
+ }
+
+ public class SamplerParameter
+ {
+ public uint sampler { get; set; }
+ public int bindPoint { get; set; }
+
+ public SamplerParameter(BinaryReader reader)
+ {
+ sampler = reader.ReadUInt32();
+ bindPoint = reader.ReadInt32();
+ }
+ }
+
+ public class SerializedTextureProperty
+ {
+ public string m_DefaultName { get; set; }
+ public int m_TexDim { get; set; }
+
+ public SerializedTextureProperty(BinaryReader reader)
+ {
+ m_DefaultName = reader.ReadAlignedString();
+ m_TexDim = reader.ReadInt32();
+ }
+ }
+
+ public class SerializedProperty
+ {
+ public string m_Name { get; set; }
+ public string m_Description { get; set; }
+ public List m_Attributes { get; set; }
+ public int m_Type { get; set; }
+ public uint m_Flags { get; set; }
+ public List m_DefValue { get; set; }
+ public SerializedTextureProperty m_DefTexture { get; set; }
+
+ public SerializedProperty(BinaryReader reader)
+ {
+ m_Name = reader.ReadAlignedString();
+ m_Description = reader.ReadAlignedString();
+
+ int numAttributes = reader.ReadInt32();
+ m_Attributes = new List(numAttributes);
+ for (int i = 0; i < numAttributes; i++)
+ {
+ m_Attributes.Add(reader.ReadAlignedString());
+ }
+
+ m_Type = reader.ReadInt32();
+ m_Flags = reader.ReadUInt32();
+
+ int numValues = 4;
+ m_DefValue = new List(numValues);
+ for (int i = 0; i < numValues; i++)
+ {
+ m_DefValue.Add(reader.ReadSingle());
+ }
+
+ m_DefTexture = new SerializedTextureProperty(reader);
+ }
+ }
+
+ public class SerializedProperties
+ {
+ public List m_Props { get; set; }
+
+ public SerializedProperties(BinaryReader reader)
+ {
+ int numProps = reader.ReadInt32();
+ m_Props = new List(numProps);
+ for (int i = 0; i < numProps; i++)
+ {
+ m_Props.Add(new SerializedProperty(reader));
+ }
+ }
+ }
+
+ public class SerializedShaderFloatValue
+ {
+ public float val { get; set; }
+ public string name { get; set; }
+
+ public SerializedShaderFloatValue(BinaryReader reader)
+ {
+ val = reader.ReadSingle();
+ name = reader.ReadAlignedString();
+ }
+ }
+
+ public class SerializedShaderRTBlendState
+ {
+ public SerializedShaderFloatValue srcBlend { get; set; }
+ public SerializedShaderFloatValue destBlend { get; set; }
+ public SerializedShaderFloatValue srcBlendAlpha { get; set; }
+ public SerializedShaderFloatValue destBlendAlpha { get; set; }
+ public SerializedShaderFloatValue blendOp { get; set; }
+ public SerializedShaderFloatValue blendOpAlpha { get; set; }
+ public SerializedShaderFloatValue colMask { get; set; }
+
+ public SerializedShaderRTBlendState(BinaryReader reader)
+ {
+ srcBlend = new SerializedShaderFloatValue(reader);
+ destBlend = new SerializedShaderFloatValue(reader);
+ srcBlendAlpha = new SerializedShaderFloatValue(reader);
+ destBlendAlpha = new SerializedShaderFloatValue(reader);
+ blendOp = new SerializedShaderFloatValue(reader);
+ blendOpAlpha = new SerializedShaderFloatValue(reader);
+ colMask = new SerializedShaderFloatValue(reader);
+ }
+ }
+
+ public class SerializedStencilOp
+ {
+ public SerializedShaderFloatValue pass { get; set; }
+ public SerializedShaderFloatValue fail { get; set; }
+ public SerializedShaderFloatValue zFail { get; set; }
+ public SerializedShaderFloatValue comp { get; set; }
+
+ public SerializedStencilOp(BinaryReader reader)
+ {
+ pass = new SerializedShaderFloatValue(reader);
+ fail = new SerializedShaderFloatValue(reader);
+ zFail = new SerializedShaderFloatValue(reader);
+ comp = new SerializedShaderFloatValue(reader);
+ }
+ }
+
+ public class SerializedShaderVectorValue
+ {
+ public SerializedShaderFloatValue x { get; set; }
+ public SerializedShaderFloatValue y { get; set; }
+ public SerializedShaderFloatValue z { get; set; }
+ public SerializedShaderFloatValue w { get; set; }
+ public string name { get; set; }
+
+ public SerializedShaderVectorValue(BinaryReader reader)
+ {
+ x = new SerializedShaderFloatValue(reader);
+ y = new SerializedShaderFloatValue(reader);
+ z = new SerializedShaderFloatValue(reader);
+ w = new SerializedShaderFloatValue(reader);
+ name = reader.ReadAlignedString();
+ }
+ }
+
+ public class SerializedShaderState
+ {
+ public string m_Name { get; set; }
+ public SerializedShaderRTBlendState rtBlend0 { get; set; }
+ public SerializedShaderRTBlendState rtBlend1 { get; set; }
+ public SerializedShaderRTBlendState rtBlend2 { get; set; }
+ public SerializedShaderRTBlendState rtBlend3 { get; set; }
+ public SerializedShaderRTBlendState rtBlend4 { get; set; }
+ public SerializedShaderRTBlendState rtBlend5 { get; set; }
+ public SerializedShaderRTBlendState rtBlend6 { get; set; }
+ public SerializedShaderRTBlendState rtBlend7 { get; set; }
+ public bool rtSeparateBlend { get; set; }
+ public SerializedShaderFloatValue zClip { get; set; }
+ public SerializedShaderFloatValue zTest { get; set; }
+ public SerializedShaderFloatValue zWrite { get; set; }
+ public SerializedShaderFloatValue culling { get; set; }
+ public SerializedShaderFloatValue offsetFactor { get; set; }
+ public SerializedShaderFloatValue offsetUnits { get; set; }
+ public SerializedShaderFloatValue alphaToMask { get; set; }
+ public SerializedStencilOp stencilOp { get; set; }
+ public SerializedStencilOp stencilOpFront { get; set; }
+ public SerializedStencilOp stencilOpBack { get; set; }
+ public SerializedShaderFloatValue stencilReadMask { get; set; }
+ public SerializedShaderFloatValue stencilWriteMask { get; set; }
+ public SerializedShaderFloatValue stencilRef { get; set; }
+ public SerializedShaderFloatValue fogStart { get; set; }
+ public SerializedShaderFloatValue fogEnd { get; set; }
+ public SerializedShaderFloatValue fogDensity { get; set; }
+ public SerializedShaderVectorValue fogColor { get; set; }
+ public int fogMode { get; set; }
+ public int gpuProgramID { get; set; }
+ public SerializedTagMap m_Tags { get; set; }
+ public int m_LOD { get; set; }
+ public bool lighting { get; set; }
+
+ public SerializedShaderState(ObjectReader reader)
+ {
+ var version = reader.version;
+
+ m_Name = reader.ReadAlignedString();
+ rtBlend0 = new SerializedShaderRTBlendState(reader);
+ rtBlend1 = new SerializedShaderRTBlendState(reader);
+ rtBlend2 = new SerializedShaderRTBlendState(reader);
+ rtBlend3 = new SerializedShaderRTBlendState(reader);
+ rtBlend4 = new SerializedShaderRTBlendState(reader);
+ rtBlend5 = new SerializedShaderRTBlendState(reader);
+ rtBlend6 = new SerializedShaderRTBlendState(reader);
+ rtBlend7 = new SerializedShaderRTBlendState(reader);
+ rtSeparateBlend = reader.ReadBoolean();
+ reader.AlignStream(4);
+ if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
+ {
+ zClip = new SerializedShaderFloatValue(reader);
+ }
+ zTest = new SerializedShaderFloatValue(reader);
+ zWrite = new SerializedShaderFloatValue(reader);
+ culling = new SerializedShaderFloatValue(reader);
+ offsetFactor = new SerializedShaderFloatValue(reader);
+ offsetUnits = new SerializedShaderFloatValue(reader);
+ alphaToMask = new SerializedShaderFloatValue(reader);
+ stencilOp = new SerializedStencilOp(reader);
+ stencilOpFront = new SerializedStencilOp(reader);
+ stencilOpBack = new SerializedStencilOp(reader);
+ stencilReadMask = new SerializedShaderFloatValue(reader);
+ stencilWriteMask = new SerializedShaderFloatValue(reader);
+ stencilRef = new SerializedShaderFloatValue(reader);
+ fogStart = new SerializedShaderFloatValue(reader);
+ fogEnd = new SerializedShaderFloatValue(reader);
+ fogDensity = new SerializedShaderFloatValue(reader);
+ fogColor = new SerializedShaderVectorValue(reader);
+ fogMode = reader.ReadInt32();
+ gpuProgramID = reader.ReadInt32();
+ m_Tags = new SerializedTagMap(reader);
+ m_LOD = reader.ReadInt32();
+ lighting = reader.ReadBoolean();
+ reader.AlignStream(4);
+ }
+ }
+
+ public class ShaderBindChannel
+ {
+ public sbyte source { get; set; }
+ public sbyte target { get; set; }
+
+ public ShaderBindChannel(BinaryReader reader)
+ {
+ source = reader.ReadSByte();
+ target = reader.ReadSByte();
+ }
+ }
+
+ public class ParserBindChannels
+ {
+ public List m_Channels { get; set; }
+ public uint m_SourceMap { get; set; }
+
+ public ParserBindChannels(BinaryReader reader)
+ {
+ int numChannels = reader.ReadInt32();
+ m_Channels = new List(numChannels);
+ for (int i = 0; i < numChannels; i++)
+ {
+ m_Channels.Add(new ShaderBindChannel(reader));
+ }
+ reader.AlignStream(4);
+
+ m_SourceMap = reader.ReadUInt32();
+ }
+ }
+
+ public class VectorParameter
+ {
+ public int m_NameIndex { get; set; }
+ public int m_Index { get; set; }
+ public int m_ArraySize { get; set; }
+ public sbyte m_Type { get; set; }
+ public sbyte m_Dim { get; set; }
+
+ public VectorParameter(BinaryReader reader)
+ {
+ m_NameIndex = reader.ReadInt32();
+ m_Index = reader.ReadInt32();
+ m_ArraySize = reader.ReadInt32();
+ m_Type = reader.ReadSByte();
+ m_Dim = reader.ReadSByte();
+ reader.AlignStream(4);
+ }
+ }
+
+ public class MatrixParameter
+ {
+ public int m_NameIndex { get; set; }
+ public int m_Index { get; set; }
+ public int m_ArraySize { get; set; }
+ public sbyte m_Type { get; set; }
+ public sbyte m_RowCount { get; set; }
+
+ public MatrixParameter(BinaryReader reader)
+ {
+ m_NameIndex = reader.ReadInt32();
+ m_Index = reader.ReadInt32();
+ m_ArraySize = reader.ReadInt32();
+ m_Type = reader.ReadSByte();
+ m_RowCount = reader.ReadSByte();
+ reader.AlignStream(4);
+ }
+ }
+
+ public class TextureParameter
+ {
+ public int m_NameIndex { get; set; }
+ public int m_Index { get; set; }
+ public int m_SamplerIndex { get; set; }
+ public sbyte m_Dim { get; set; }
+
+ public TextureParameter(ObjectReader reader)
+ {
+ var version = reader.version;
+
+ m_NameIndex = reader.ReadInt32();
+ m_Index = reader.ReadInt32();
+ m_SamplerIndex = reader.ReadInt32();
+ if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
+ {
+ var m_MultiSampled = reader.ReadBoolean();
+ }
+ m_Dim = reader.ReadSByte();
+ reader.AlignStream(4);
+ }
+ }
+
+ public class BufferBinding
+ {
+ public int m_NameIndex { get; set; }
+ public int m_Index { get; set; }
+
+ public BufferBinding(BinaryReader reader)
+ {
+ m_NameIndex = reader.ReadInt32();
+ m_Index = reader.ReadInt32();
+ }
+ }
+
+ public class ConstantBuffer
+ {
+ public int m_NameIndex { get; set; }
+ public List m_MatrixParams { get; set; }
+ public List m_VectorParams { get; set; }
+ public List m_StructParams { get; set; }
+ public int m_Size { get; set; }
+
+ public ConstantBuffer(ObjectReader reader)
+ {
+ var version = reader.version;
+
+ m_NameIndex = reader.ReadInt32();
+
+ int numMatrixParams = reader.ReadInt32();
+ m_MatrixParams = new List(numMatrixParams);
+ for (int i = 0; i < numMatrixParams; i++)
+ {
+ m_MatrixParams.Add(new MatrixParameter(reader));
+ }
+
+ int numVectorParams = reader.ReadInt32();
+ m_VectorParams = new List(numVectorParams);
+ for (int i = 0; i < numVectorParams; i++)
+ {
+ m_VectorParams.Add(new VectorParameter(reader));
+ }
+ if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
+ {
+ int numStructParams = reader.ReadInt32();
+ m_StructParams = new List(numStructParams);
+ for (int i = 0; i < numStructParams; i++)
+ {
+ m_StructParams.Add(new StructParameter(reader));
+ }
+ }
+ m_Size = reader.ReadInt32();
+ }
+ }
+
+ public class UAVParameter
+ {
+ public int m_NameIndex { get; set; }
+ public int m_Index { get; set; }
+ public int m_OriginalIndex { get; set; }
+
+ public UAVParameter(BinaryReader reader)
+ {
+ m_NameIndex = reader.ReadInt32();
+ m_Index = reader.ReadInt32();
+ m_OriginalIndex = reader.ReadInt32();
+ }
+ }
+
+ public class SerializedSubProgram
+ {
+ public uint m_BlobIndex { get; set; }
+ public ParserBindChannels m_Channels { get; set; }
+ public List m_KeywordIndices { get; set; }
+ public sbyte m_ShaderHardwareTier { get; set; }
+ public sbyte m_GpuProgramType { get; set; }
+ public List m_VectorParams { get; set; }
+ public List m_MatrixParams { get; set; }
+ public List m_TextureParams { get; set; }
+ public List m_BufferParams { get; set; }
+ public List m_ConstantBuffers { get; set; }
+ public List m_ConstantBufferBindings { get; set; }
+ public List m_UAVParams { get; set; }
+ public List m_Samplers { get; set; }
+
+ public SerializedSubProgram(ObjectReader reader)
+ {
+ var version = reader.version;
+
+ m_BlobIndex = reader.ReadUInt32();
+ m_Channels = new ParserBindChannels(reader);
+
+ int numIndices = reader.ReadInt32();
+ m_KeywordIndices = new List(numIndices);
+ for (int i = 0; i < numIndices; i++)
+ {
+ m_KeywordIndices.Add(reader.ReadUInt16());
+ }
+ if (version[0] >= 2017) //2017 and up
+ {
+ reader.AlignStream(4);
+ }
+ m_ShaderHardwareTier = reader.ReadSByte();
+ m_GpuProgramType = reader.ReadSByte();
+ reader.AlignStream(4);
+
+ int numVectorParams = reader.ReadInt32();
+ m_VectorParams = new List(numVectorParams);
+ for (int i = 0; i < numVectorParams; i++)
+ {
+ m_VectorParams.Add(new VectorParameter(reader));
+ }
+
+ int numMatrixParams = reader.ReadInt32();
+ m_MatrixParams = new List(numMatrixParams);
+ for (int i = 0; i < numMatrixParams; i++)
+ {
+ m_MatrixParams.Add(new MatrixParameter(reader));
+ }
+
+ int numTextureParams = reader.ReadInt32();
+ m_TextureParams = new List(numTextureParams);
+ for (int i = 0; i < numTextureParams; i++)
+ {
+ m_TextureParams.Add(new TextureParameter(reader));
+ }
+
+ int numBufferParams = reader.ReadInt32();
+ m_BufferParams = new List(numBufferParams);
+ for (int i = 0; i < numBufferParams; i++)
+ {
+ m_BufferParams.Add(new BufferBinding(reader));
+ }
+
+ int numConstantBuffers = reader.ReadInt32();
+ m_ConstantBuffers = new List(numConstantBuffers);
+ for (int i = 0; i < numConstantBuffers; i++)
+ {
+ m_ConstantBuffers.Add(new ConstantBuffer(reader));
+ }
+
+ int numConstantBufferBindings = reader.ReadInt32();
+ m_ConstantBufferBindings = new List(numConstantBufferBindings);
+ for (int i = 0; i < numConstantBufferBindings; i++)
+ {
+ m_ConstantBufferBindings.Add(new BufferBinding(reader));
+ }
+
+ int numUAVParams = reader.ReadInt32();
+ m_UAVParams = new List(numUAVParams);
+ for (int i = 0; i < numUAVParams; i++)
+ {
+ m_UAVParams.Add(new UAVParameter(reader));
+ }
+
+ if (version[0] >= 2017) //2017 and up
+ {
+ int numSamplers = reader.ReadInt32();
+ m_Samplers = new List(numSamplers);
+ for (int i = 0; i < numSamplers; i++)
+ {
+ m_Samplers.Add(new SamplerParameter(reader));
+ }
+ }
+ if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
+ {
+ var m_ShaderRequirements = reader.ReadInt32();
+ }
+ }
+ }
+
+ public class SerializedProgram
+ {
+ public List m_SubPrograms { get; set; }
+
+ public SerializedProgram(ObjectReader reader)
+ {
+ int numSubPrograms = reader.ReadInt32();
+ m_SubPrograms = new List(numSubPrograms);
+ for (int i = 0; i < numSubPrograms; i++)
+ {
+ m_SubPrograms.Add(new SerializedSubProgram(reader));
+ }
+ }
+ }
+
+ public class SerializedPass
+ {
+ public List> m_NameIndices { get; set; }
+ public int m_Type { get; set; }
+ public SerializedShaderState m_State { get; set; }
+ public uint m_ProgramMask { get; set; }
+ public SerializedProgram progVertex { get; set; }
+ public SerializedProgram progFragment { get; set; }
+ public SerializedProgram progGeometry { get; set; }
+ public SerializedProgram progHull { get; set; }
+ public SerializedProgram progDomain { get; set; }
+ public bool m_HasInstancingVariant { get; set; }
+ public string m_UseName { get; set; }
+ public string m_Name { get; set; }
+ public string m_TextureName { get; set; }
+ public SerializedTagMap m_Tags { get; set; }
+
+ public SerializedPass(ObjectReader reader)
+ {
+ var version = reader.version;
+
+ int numIndices = reader.ReadInt32();
+ m_NameIndices = new List>(numIndices);
+ for (int i = 0; i < numIndices; i++)
+ {
+ m_NameIndices.Add(new KeyValuePair(reader.ReadAlignedString(), reader.ReadInt32()));
+ }
+
+ m_Type = reader.ReadInt32();
+ m_State = new SerializedShaderState(reader);
+ m_ProgramMask = reader.ReadUInt32();
+ progVertex = new SerializedProgram(reader);
+ progFragment = new SerializedProgram(reader);
+ progGeometry = new SerializedProgram(reader);
+ progHull = new SerializedProgram(reader);
+ progDomain = new SerializedProgram(reader);
+ m_HasInstancingVariant = reader.ReadBoolean();
+ if (version[0] >= 2018) //2018 and up
+ {
+ var m_HasProceduralInstancingVariant = reader.ReadBoolean();
+ }
+ reader.AlignStream(4);
+ m_UseName = reader.ReadAlignedString();
+ m_Name = reader.ReadAlignedString();
+ m_TextureName = reader.ReadAlignedString();
+ m_Tags = new SerializedTagMap(reader);
+ }
+ }
+
+ public class SerializedTagMap
+ {
+ public List> tags { get; set; }
+
+ public SerializedTagMap(BinaryReader reader)
+ {
+ int numTags = reader.ReadInt32();
+ tags = new List>(numTags);
+ for (int i = 0; i < numTags; i++)
+ {
+ tags.Add(new KeyValuePair(reader.ReadAlignedString(), reader.ReadAlignedString()));
+ }
+ }
+ }
+
+ public class SerializedSubShader
+ {
+ public List m_Passes { get; set; }
+ public SerializedTagMap m_Tags { get; set; }
+ public int m_LOD { get; set; }
+
+ public SerializedSubShader(ObjectReader reader)
+ {
+ int numPasses = reader.ReadInt32();
+ m_Passes = new List(numPasses);
+ for (int i = 0; i < numPasses; i++)
+ {
+ m_Passes.Add(new SerializedPass(reader));
+ }
+
+ m_Tags = new SerializedTagMap(reader);
+ m_LOD = reader.ReadInt32();
+ }
+ }
+
+ public class SerializedShaderDependency
+ {
+ public string from { get; set; }
+ public string to { get; set; }
+
+ public SerializedShaderDependency(BinaryReader reader)
+ {
+ from = reader.ReadAlignedString();
+ to = reader.ReadAlignedString();
+ }
+ }
+
+ public class SerializedShader
+ {
+ public SerializedProperties m_PropInfo { get; set; }
+ public List m_SubShaders { get; set; }
+ public string m_Name { get; set; }
+ public string m_CustomEditorName { get; set; }
+ public string m_FallbackName { get; set; }
+ public List m_Dependencies { get; set; }
+ public bool m_DisableNoSubshadersMessage { get; set; }
+
+ public SerializedShader(ObjectReader reader)
+ {
+ m_PropInfo = new SerializedProperties(reader);
+
+ int numSubShaders = reader.ReadInt32();
+ m_SubShaders = new List(numSubShaders);
+ for (int i = 0; i < numSubShaders; i++)
+ {
+ m_SubShaders.Add(new SerializedSubShader(reader));
+ }
+
+ m_Name = reader.ReadAlignedString();
+ m_CustomEditorName = reader.ReadAlignedString();
+ m_FallbackName = reader.ReadAlignedString();
+
+ int numDependencies = reader.ReadInt32();
+ m_Dependencies = new List(numDependencies);
+ for (int i = 0; i < numDependencies; i++)
+ {
+ m_Dependencies.Add(new SerializedShaderDependency(reader));
+ }
+
+ m_DisableNoSubshadersMessage = reader.ReadBoolean();
+ reader.AlignStream(4);
+ }
+ }
+
+ public class Shader : NamedObject
{
public byte[] m_Script;
+ //5.3 - 5.4
+ public uint decompressedSize;
+ public byte[] m_SubProgramBlob;
+ //5.5 and up
+ public SerializedShader m_ParsedForm;
+ public List platforms;
+ public List offsets;
+ public List compressedLengths;
+ public List decompressedLengths;
+ public byte[] compressedBlob;
public Shader(ObjectReader reader) : base(reader)
{
- if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5.0 and up
+ if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up
{
- var str = reader.Dump();
- m_Script = Encoding.UTF8.GetBytes(str ?? "Serialized Shader can't be read");
+ m_ParsedForm = new SerializedShader(reader);
+ int numPlatforms = reader.ReadInt32();
+ platforms = new List(numPlatforms);
+ for (int i = 0; i < numPlatforms; i++)
+ {
+ platforms.Add(reader.ReadUInt32());
+ }
+
+ int numOffsets = reader.ReadInt32();
+ offsets = new List(numOffsets);
+ for (int i = 0; i < numOffsets; i++)
+ {
+ offsets.Add(reader.ReadUInt32());
+ }
+
+ int numCompressedLengths = reader.ReadInt32();
+ compressedLengths = new List(numCompressedLengths);
+ for (int i = 0; i < numCompressedLengths; i++)
+ {
+ compressedLengths.Add(reader.ReadUInt32());
+ }
+
+ int numDecompressedLengths = reader.ReadInt32();
+ decompressedLengths = new List(numDecompressedLengths);
+ for (int i = 0; i < numDecompressedLengths; i++)
+ {
+ decompressedLengths.Add(reader.ReadUInt32());
+ }
+
+ compressedBlob = reader.ReadBytes(reader.ReadInt32());
}
else
{
m_Script = reader.ReadBytes(reader.ReadInt32());
+ reader.AlignStream(4);
+ var m_PathName = reader.ReadAlignedString();
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
{
- reader.AlignStream(4);
- var m_PathName = reader.ReadAlignedString();
- var decompressedSize = reader.ReadUInt32();
- var m_SubProgramBlob = reader.ReadBytes(reader.ReadInt32());
- var decompressedBytes = new byte[decompressedSize];
- using (var decoder = new Lz4DecoderStream(new MemoryStream(m_SubProgramBlob)))
- {
- decoder.Read(decompressedBytes, 0, (int)decompressedSize);
- }
-
- m_Script = m_Script.Concat(decompressedBytes.ToArray()).ToArray();
+ decompressedSize = reader.ReadUInt32();
+ m_SubProgramBlob = reader.ReadBytes(reader.ReadInt32());
}
}
}
diff --git a/AssetStudio/Libraries/SharpDX.D3DCompiler.dll b/AssetStudio/Libraries/SharpDX.D3DCompiler.dll
new file mode 100644
index 0000000..bd4f26c
Binary files /dev/null and b/AssetStudio/Libraries/SharpDX.D3DCompiler.dll differ
diff --git a/AssetStudio/Libraries/SharpDX.Mathematics.dll b/AssetStudio/Libraries/SharpDX.Mathematics.dll
index 4c0da9c..75bbb0d 100644
Binary files a/AssetStudio/Libraries/SharpDX.Mathematics.dll and b/AssetStudio/Libraries/SharpDX.Mathematics.dll differ
diff --git a/AssetStudio/Libraries/SharpDX.dll b/AssetStudio/Libraries/SharpDX.dll
index baa26ad..e06ed56 100644
Binary files a/AssetStudio/Libraries/SharpDX.dll and b/AssetStudio/Libraries/SharpDX.dll differ
diff --git a/AssetStudio/StudioClasses/Exporter.cs b/AssetStudio/StudioClasses/Exporter.cs
index 72d48d4..1557f4c 100644
--- a/AssetStudio/StudioClasses/Exporter.cs
+++ b/AssetStudio/StudioClasses/Exporter.cs
@@ -86,7 +86,8 @@ namespace AssetStudio
var exportFullName = exportPath + reader.exportName + ".shader";
if (ExportFileExists(exportFullName))
return false;
- File.WriteAllBytes(exportFullName, m_Shader.m_Script);
+ var str = ShaderConverter.Convert(m_Shader);
+ File.WriteAllText(exportFullName, str ?? "Serialized Shader can't be read");
return true;
}
diff --git a/AssetStudio/StudioClasses/ShaderConverter.cs b/AssetStudio/StudioClasses/ShaderConverter.cs
new file mode 100644
index 0000000..50088a2
--- /dev/null
+++ b/AssetStudio/StudioClasses/ShaderConverter.cs
@@ -0,0 +1,229 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using Lz4;
+using SharpDX.D3DCompiler;
+
+namespace AssetStudio
+{
+ public static class ShaderConverter
+ {
+ public static string Convert(Shader shader)
+ {
+ if (shader.m_SubProgramBlob != null) //5.3 - 5.4
+ {
+ var decompressedBytes = new byte[shader.decompressedSize];
+ using (var decoder = new Lz4DecoderStream(new MemoryStream(shader.m_SubProgramBlob)))
+ {
+ decoder.Read(decompressedBytes, 0, (int)shader.decompressedSize);
+ }
+ using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
+ {
+ var program = new ShaderProgram(blobReader);
+ return program.Export(Encoding.UTF8.GetString(shader.m_Script));
+ }
+ }
+
+ if (shader.compressedBlob != null) //5.5 and up
+ {
+ //TODO
+ /*for (var i = 0; i < shader.platforms.Count; i++)
+ {
+ var compressedBytes = new byte[shader.compressedLengths[i]];
+ Array.Copy(shader.compressedBlob, shader.offsets[i], compressedBytes, 0, shader.compressedLengths[i]);
+ var decompressedBytes = new byte[shader.decompressedLengths[i]];
+ using (var decoder = new Lz4DecoderStream(new MemoryStream(compressedBytes)))
+ {
+ decoder.Read(decompressedBytes, 0, (int)shader.decompressedLengths[i]);
+ }
+ using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
+ {
+ new ShaderProgram(blobReader);
+ }
+ }*/
+ return shader.reader.Dump();
+ }
+ return Encoding.UTF8.GetString(shader.m_Script);
+ }
+ }
+
+ public class ShaderProgram
+ {
+ public ShaderSubProgram[] m_SubPrograms;
+
+ public ShaderProgram(BinaryReader reader)
+ {
+ var subProgramsCapacity = reader.ReadInt32();
+ m_SubPrograms = new ShaderSubProgram[subProgramsCapacity];
+ for (int i = 0; i < subProgramsCapacity; i++)
+ {
+ reader.BaseStream.Position = 4 + i * 8;
+ var offset = reader.ReadInt32();
+ reader.BaseStream.Position = offset;
+ m_SubPrograms[i] = new ShaderSubProgram(reader);
+ }
+ }
+
+ public string Export(string shader)
+ {
+ var evaluator = new MatchEvaluator(match =>
+ {
+ var index = int.Parse(match.Groups[1].Value);
+ return m_SubPrograms[index].Export();
+ });
+ shader = Regex.Replace(shader, "GpuProgramIndex (.+)", evaluator);
+ return shader;
+ }
+ }
+
+ public class ShaderSubProgram
+ {
+ private int magic;
+ public ShaderGpuProgramType m_ProgramType;
+ public string[] m_Keywords;
+ public byte[] m_ProgramCode;
+
+ public ShaderSubProgram(BinaryReader reader)
+ {
+ //LoadGpuProgramFromData
+ // 201509030 - Unity 5.3
+ // 201510240 - Unity 5.4
+ // 201608170 - Unity 5.5
+ // 201609010 - Unity 5.6, 2017.1 & 2017.2
+ // 201708220 - Unity 2017.3, Unity 2017.4 & Unity 2018.1
+ // 201802150 - Unity 2018.2
+ magic = reader.ReadInt32();
+ m_ProgramType = (ShaderGpuProgramType)reader.ReadInt32();
+ reader.BaseStream.Position += 12;
+ if (magic >= 201608170) //5.5.0 and up
+ {
+ reader.BaseStream.Position += 4;
+ }
+ var keywordCount = reader.ReadInt32();
+ m_Keywords = new string[keywordCount];
+ for (int i = 0; i < keywordCount; i++)
+ {
+ m_Keywords[i] = reader.ReadAlignedString();
+ }
+ m_ProgramCode = reader.ReadBytes(reader.ReadInt32());
+ reader.AlignStream(4);
+
+ //TODO
+ }
+
+ public string Export()
+ {
+ var sb = new StringBuilder();
+ if (m_Keywords.Length > 0)
+ {
+ sb.Append("Keywords { ");
+ foreach (string keyword in m_Keywords)
+ {
+ sb.Append($"\"{keyword}\" ");
+ }
+ sb.Append("}\n");
+ }
+
+ sb.Append("\"\n");
+ if (m_ProgramCode.Length > 0)
+ {
+ switch (m_ProgramType)
+ {
+ case ShaderGpuProgramType.kShaderGpuProgramGLLegacy:
+ case ShaderGpuProgramType.kShaderGpuProgramGLES31AEP:
+ case ShaderGpuProgramType.kShaderGpuProgramGLES31:
+ case ShaderGpuProgramType.kShaderGpuProgramGLES3:
+ case ShaderGpuProgramType.kShaderGpuProgramGLES:
+ case ShaderGpuProgramType.kShaderGpuProgramGLCore32:
+ case ShaderGpuProgramType.kShaderGpuProgramGLCore41:
+ case ShaderGpuProgramType.kShaderGpuProgramGLCore43:
+ sb.Append(Encoding.UTF8.GetString(m_ProgramCode));
+ break;
+ case ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM20:
+ case ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM30:
+ case ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM20:
+ case ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM30:
+ {
+ var shaderBytecode = new ShaderBytecode(m_ProgramCode);
+ sb.Append(shaderBytecode.Disassemble());
+ break;
+ }
+ case ShaderGpuProgramType.kShaderGpuProgramDX10Level9Vertex:
+ case ShaderGpuProgramType.kShaderGpuProgramDX10Level9Pixel:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM40:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM50:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM40:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM50:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM40:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM50:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11HullSM50:
+ case ShaderGpuProgramType.kShaderGpuProgramDX11DomainSM50:
+ {
+ int start = 6;
+ if (magic == 201509030) // 5.3
+ {
+ start = 5;
+ }
+ var buff = new byte[m_ProgramCode.Length - start];
+ Buffer.BlockCopy(m_ProgramCode, start, buff, 0, buff.Length);
+ var shaderBytecode = new ShaderBytecode(buff);
+ sb.Append(shaderBytecode.Disassemble());
+ break;
+ }
+ case ShaderGpuProgramType.kShaderGpuProgramMetalVS:
+ case ShaderGpuProgramType.kShaderGpuProgramMetalFS:
+ using (var reader = new BinaryReader(new MemoryStream(m_ProgramCode)))
+ {
+ var fourCC = reader.ReadUInt32();
+ if (fourCC == 0xf00dcafe)
+ {
+ int offset = reader.ReadInt32();
+ reader.BaseStream.Position = offset;
+ }
+ var entryName = reader.ReadStringToNull();
+ var buff = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
+ sb.Append(Encoding.UTF8.GetString(buff));
+ }
+ break;
+ default:
+ sb.Append($"/*Unsupported program data {m_ProgramType}*/");
+ break;
+ }
+ }
+ sb.Append('"');
+ return sb.ToString();
+ }
+ }
+
+ public enum ShaderGpuProgramType
+ {
+ kShaderGpuProgramUnknown = 0,
+ kShaderGpuProgramGLLegacy = 1,
+ kShaderGpuProgramGLES31AEP = 2,
+ kShaderGpuProgramGLES31 = 3,
+ kShaderGpuProgramGLES3 = 4,
+ kShaderGpuProgramGLES = 5,
+ kShaderGpuProgramGLCore32 = 6,
+ kShaderGpuProgramGLCore41 = 7,
+ kShaderGpuProgramGLCore43 = 8,
+ kShaderGpuProgramDX9VertexSM20 = 9,
+ kShaderGpuProgramDX9VertexSM30 = 10,
+ kShaderGpuProgramDX9PixelSM20 = 11,
+ kShaderGpuProgramDX9PixelSM30 = 12,
+ kShaderGpuProgramDX10Level9Vertex = 13,
+ kShaderGpuProgramDX10Level9Pixel = 14,
+ kShaderGpuProgramDX11VertexSM40 = 15,
+ kShaderGpuProgramDX11VertexSM50 = 16,
+ kShaderGpuProgramDX11PixelSM40 = 17,
+ kShaderGpuProgramDX11PixelSM50 = 18,
+ kShaderGpuProgramDX11GeometrySM40 = 19,
+ kShaderGpuProgramDX11GeometrySM50 = 20,
+ kShaderGpuProgramDX11HullSM50 = 21,
+ kShaderGpuProgramDX11DomainSM50 = 22,
+ kShaderGpuProgramMetalVS = 23,
+ kShaderGpuProgramMetalFS = 24,
+ kShaderGpuProgramSPIRV = 25,
+ kShaderGpuProgramConsole = 26,
+ };
+}
diff --git a/AssetStudio/StudioClasses/Studio.cs b/AssetStudio/StudioClasses/Studio.cs
index 7d3deab..1fb80dd 100644
--- a/AssetStudio/StudioClasses/Studio.cs
+++ b/AssetStudio/StudioClasses/Studio.cs
@@ -203,25 +203,36 @@ namespace AssetStudio
var m_Texture2D = new Texture2D(objectReader, false);
if (!string.IsNullOrEmpty(m_Texture2D.path))
assetItem.FullSize = objectReader.byteSize + m_Texture2D.size;
- goto case ClassIDType.NamedObject;
+ assetItem.Text = m_Texture2D.m_Name;
+ exportable = true;
+ break;
}
case ClassIDType.AudioClip:
{
var m_AudioClip = new AudioClip(objectReader, false);
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
assetItem.FullSize = objectReader.byteSize + m_AudioClip.m_Size;
- goto case ClassIDType.NamedObject;
+ assetItem.Text = m_AudioClip.m_Name;
+ exportable = true;
+ break;
}
case ClassIDType.VideoClip:
{
var m_VideoClip = new VideoClip(objectReader, false);
if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath))
assetItem.FullSize = objectReader.byteSize + (long)m_VideoClip.m_Size;
- goto case ClassIDType.NamedObject;
+ assetItem.Text = m_VideoClip.m_Name;
+ exportable = true;
+ break;
}
- case ClassIDType.NamedObject:
- case ClassIDType.Mesh:
case ClassIDType.Shader:
+ {
+ var m_Shader = new Shader(objectReader);
+ assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
+ exportable = true;
+ break;
+ }
+ case ClassIDType.Mesh:
case ClassIDType.TextAsset:
case ClassIDType.AnimationClip:
case ClassIDType.Font: