public static alien_mtl Load(string FullFilePath) { alien_mtl Result = new alien_mtl(); BinaryReader Stream = new BinaryReader(File.OpenRead(FullFilePath)); alien_mtl_header Header = Utilities.Consume <alien_mtl_header>(ref Stream); Result.MaterialNames = new List <string>(Header.MaterialCount); for (int MaterialIndex = 0; MaterialIndex < Header.MaterialCount; ++MaterialIndex) { Result.MaterialNames.Add(Utilities.ReadString(ref Stream)); } Stream.BaseStream.Position = Header.FirstMaterialOffset + Marshal.SizeOf(Header.BytesRemainingAfterThis); Result.Header = Header; Result.Materials = Utilities.ConsumeArray <alien_mtl_material>(ref Stream, Header.MaterialCount); Result.TextureReferenceCounts = new List <int>(Result.Header.MaterialCount); for (int MaterialIndex = 0; MaterialIndex < Header.MaterialCount; ++MaterialIndex) { alien_mtl_material Material = Result.Materials[MaterialIndex]; int count = 0; for (int I = 0; I < Material.TextureReferences.Length; ++I) { alien_mtl_texture_reference Pair = Material.TextureReferences[I]; if (Pair.TextureTableIndex == 2 || Pair.TextureTableIndex == 0) { count++; } } Result.TextureReferenceCounts.Add(count); } return(Result); }
public void LoadMaterial(int MTLIndex) { alien_mtl_material InMaterial = Result.ModelsMTL.Materials[MTLIndex]; int RemappedIndex = Result.ShadersIDXRemap.Datas[InMaterial.UberShaderIndex].Index; alien_shader_pak_shader Shader = Result.ShadersPAK.Shaders[RemappedIndex]; Material toReturn = new Material(UnityEngine.Shader.Find("Standard")); toReturn.name = Result.ModelsMTL.MaterialNames[MTLIndex]; List <alien_slot_ids> SlotOffsets = new List <alien_slot_ids>(); alien_shader_category ShaderCategory = (alien_shader_category)Shader.Header2.ShaderCategory; switch (ShaderCategory) { case alien_shader_category.AlienShaderCategory_Particle: SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.COLOR_RAMP_MAP); break; case alien_shader_category.AlienShaderCategory_Ribbon: SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.COLOR_RAMP_MAP); break; case alien_shader_category.AlienShaderCategory_Environment: SlotOffsets.Add(alien_slot_ids.OPACITY); SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.OCCLUSION); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.FRESNEL_LUT); SlotOffsets.Add(alien_slot_ids.PARALLAX_MAP); SlotOffsets.Add(alien_slot_ids.OPACITY_NOISE_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.DIRT_MAP); SlotOffsets.Add(alien_slot_ids.WETNESS_NOISE); break; case alien_shader_category.AlienShaderCategory_DecalEnvironment: SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.PARALLAX_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.ALPHA_THRESHOLD); break; case alien_shader_category.AlienShaderCategory_Character: SlotOffsets.Add(alien_slot_ids.DIRT_MAP); SlotOffsets.Add(alien_slot_ids.OPACITY_NOISE_MAP); SlotOffsets.Add(alien_slot_ids.OPACITY); SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.OCCLUSION); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.IRRADIANCE_MAP); break; case alien_shader_category.AlienShaderCategory_Skin: SlotOffsets.Add(alien_slot_ids.CONVOLVED_DIFFUSE); SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.WRINKLE_MASK); SlotOffsets.Add(alien_slot_ids.WRINKLE_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.IRRADIANCE_MAP); SlotOffsets.Add(alien_slot_ids.DIRT_MAP); SlotOffsets.Add(alien_slot_ids.OPACITY_NOISE_MAP); break; case alien_shader_category.AlienShaderCategory_Hair: SlotOffsets.Add(alien_slot_ids.FLOW_MAP); SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.IRRADIANCE_MAP); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); break; case alien_shader_category.AlienShaderCategory_Eye: SlotOffsets.Add(alien_slot_ids.CONVOLVED_DIFFUSE); SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); //IrisMap SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); //VeinsMap SlotOffsets.Add(alien_slot_ids.SCATTER_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.IRRADIANCE_MAP); break; case alien_shader_category.AlienShaderCategory_SkinOcclusion: SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); break; case alien_shader_category.AlienShaderCategory_Decal: SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.EMISSIVE); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.PARALLAX_MAP); SlotOffsets.Add(alien_slot_ids.BURN_THROUGH); SlotOffsets.Add(alien_slot_ids.LIQUIFY); SlotOffsets.Add(alien_slot_ids.ALPHA_THRESHOLD); SlotOffsets.Add(alien_slot_ids.LIQUIFY2); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.COLOR_RAMP); break; case alien_shader_category.AlienShaderCategory_FogPlane: SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); // TODO: Should be 'DiffuseMapStatic' - but I am not using that yet. In order to keep the light cones // visually appealing and not slabs of solid white, I am using normal diffuse for now. SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP_STATIC); break; case alien_shader_category.AlienShaderCategory_Refraction: SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.ALPHA_MASK); SlotOffsets.Add(alien_slot_ids.FLOW_MAP); SlotOffsets.Add(alien_slot_ids.ALPHA_THRESHOLD); //Material->Material.BaseColor = { }; break; case alien_shader_category.AlienShaderCategory_NonInteractiveWater: SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.ALPHA_MASK); SlotOffsets.Add(alien_slot_ids.FLOW_MAP); break; case alien_shader_category.AlienShaderCategory_LowLODCharacter: SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.LOW_LOD_CHARACTER_MASK); SlotOffsets.Add(alien_slot_ids.IRRADIANCE_MAP); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); break; case alien_shader_category.AlienShaderCategory_LightDecal: SlotOffsets.Add(alien_slot_ids.EMISSIVE); break; case alien_shader_category.AlienShaderCategory_SpaceSuitVisor: SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.MASKING_MAP); SlotOffsets.Add(alien_slot_ids.FACE_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.UNSCALED_DIRT_MAP); SlotOffsets.Add(alien_slot_ids.DIRT_MAP); break; case alien_shader_category.AlienShaderCategory_Planet: SlotOffsets.Add(alien_slot_ids.ATMOSPHERE_MAP); SlotOffsets.Add(alien_slot_ids.DETAIL_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.FLOW_MAP); break; case alien_shader_category.AlienShaderCategory_LightMapEnvironment: SlotOffsets.Add(alien_slot_ids.LIGHT_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.DIRT_MAP); SlotOffsets.Add(alien_slot_ids.OPACITY_NOISE_MAP); SlotOffsets.Add(alien_slot_ids.OPACITY); SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.NONE); //Occlusion? SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.NONE); break; case alien_shader_category.AlienShaderCategory_Terrain: SlotOffsets.Add(alien_slot_ids.DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_DIFFUSE_MAP); SlotOffsets.Add(alien_slot_ids.NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_NORMAL_MAP); SlotOffsets.Add(alien_slot_ids.SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.SECONDARY_SPECULAR_MAP); SlotOffsets.Add(alien_slot_ids.NONE); SlotOffsets.Add(alien_slot_ids.OPACITY_NOISE_MAP); SlotOffsets.Add(alien_slot_ids.ENVIRONMENT_MAP); SlotOffsets.Add(alien_slot_ids.NONE); break; //Unsupported shader slot types - draw transparent for now default: toReturn.name = "UNRESOLVED: " + ShaderCategory.ToString(); toReturn.color = new Color(0, 0, 0, 0); toReturn.SetFloat("_Mode", 1.0f); toReturn.EnableKeyword("_ALPHATEST_ON"); LoadedMaterials[MTLIndex] = toReturn; return; } List <Texture> availableTextures = new List <Texture>(); for (int SlotIndex = 0; SlotIndex < Shader.Header.TextureLinkCount; ++SlotIndex) { int PairIndex = Shader.TextureLinks[SlotIndex]; // NOTE: PairIndex == 255 means no index. if (PairIndex < Result.ModelsMTL.TextureReferenceCounts[MTLIndex]) { alien_mtl_texture_reference Pair = InMaterial.TextureReferences[PairIndex]; if (Pair.TextureTableIndex == 0) { availableTextures.Add(LoadedTexturesLevel[Pair.TextureIndex].texture); } else if (Pair.TextureTableIndex == 2) { availableTextures.Add(LoadedTexturesGlobal[Pair.TextureIndex].texture); } else { availableTextures.Add(null); } } else { availableTextures.Add(null); } } //Apply materials for (int i = 0; i < SlotOffsets.Count; i++) { if (i >= availableTextures.Count) { continue; } switch (SlotOffsets[i]) { case alien_slot_ids.DIFFUSE_MAP: toReturn.SetTexture("_MainTex", availableTextures[i]); break; case alien_slot_ids.DETAIL_MAP: toReturn.EnableKeyword("_DETAIL_MULX2"); toReturn.SetTexture("_DetailMask", availableTextures[i]); break; case alien_slot_ids.EMISSIVE: toReturn.EnableKeyword("_EMISSION"); toReturn.SetTexture("_EmissionMap", availableTextures[i]); break; case alien_slot_ids.PARALLAX_MAP: toReturn.EnableKeyword("_PARALLAXMAP"); toReturn.SetTexture("_ParallaxMap", availableTextures[i]); break; case alien_slot_ids.OCCLUSION: toReturn.SetTexture("_OcclusionMap", availableTextures[i]); break; case alien_slot_ids.SPECULAR_MAP: toReturn.EnableKeyword("_METALLICGLOSSMAP"); toReturn.SetTexture("_MetallicGlossMap", availableTextures[i]); //TODO _SPECGLOSSMAP? toReturn.SetFloat("_Glossiness", 0.0f); toReturn.SetFloat("_GlossMapScale", 0.0f); break; case alien_slot_ids.NORMAL_MAP: toReturn.EnableKeyword("_NORMALMAP"); toReturn.SetTexture("_BumpMap", availableTextures[i]); break; } } //Apply properties MaterialPropertyIndex cstIndex = GetMaterialPropertyIndex(MTLIndex); BinaryReader cstReader = new BinaryReader(new MemoryStream(Result.ModelsCST)); int baseOffset = Result.ModelsMTL.Header.CSTOffsets[2] + (InMaterial.CSTOffsets[2] * 4); if (CSTIndexValid(cstIndex.DiffuseIndex, ref Shader)) { Vector4 colour = LoadFromCST <Vector4>(ref cstReader, baseOffset + (Shader.CSTLinks[2][cstIndex.DiffuseIndex] * 4)); toReturn.SetColor("_Color", colour); if (colour.w != 1) { toReturn.SetFloat("_Mode", 1.0f); toReturn.EnableKeyword("_ALPHATEST_ON"); } } if (CSTIndexValid(cstIndex.DiffuseUVMultiplierIndex, ref Shader)) { float offset = LoadFromCST <float>(ref cstReader, baseOffset + (Shader.CSTLinks[2][cstIndex.DiffuseUVMultiplierIndex] * 4)); toReturn.SetTextureScale("_MainTex", new Vector2(offset, offset)); } if (CSTIndexValid(cstIndex.DiffuseUVAdderIndex, ref Shader)) { float offset = LoadFromCST <float>(ref cstReader, baseOffset + (Shader.CSTLinks[2][cstIndex.DiffuseUVAdderIndex] * 4)); toReturn.SetTextureOffset("_MainTex", new Vector2(offset, offset)); } if (CSTIndexValid(cstIndex.NormalUVMultiplierIndex, ref Shader)) { float offset = LoadFromCST <float>(ref cstReader, baseOffset + (Shader.CSTLinks[2][cstIndex.NormalUVMultiplierIndex] * 4)); toReturn.SetTextureScale("_BumpMap", new Vector2(offset, offset)); toReturn.SetFloat("_BumpScale", offset); } if (CSTIndexValid(cstIndex.OcclusionUVMultiplierIndex, ref Shader)) { float offset = LoadFromCST <float>(ref cstReader, baseOffset + (Shader.CSTLinks[2][cstIndex.OcclusionUVMultiplierIndex] * 4)); toReturn.SetTextureScale("_OcclusionMap", new Vector2(offset, offset)); } if (CSTIndexValid(cstIndex.SpecularUVMultiplierIndex, ref Shader)) { float offset = LoadFromCST <float>(ref cstReader, baseOffset + (Shader.CSTLinks[2][cstIndex.SpecularUVMultiplierIndex] * 4)); toReturn.SetTextureScale("_MetallicGlossMap", new Vector2(offset, offset)); toReturn.SetFloat("_GlossMapScale", offset); } if (CSTIndexValid(cstIndex.SpecularFactorIndex, ref Shader)) { float spec = LoadFromCST <float>(ref cstReader, baseOffset + (Shader.CSTLinks[2][cstIndex.SpecularFactorIndex] * 4)); toReturn.SetFloat("_Glossiness", spec); toReturn.SetFloat("_GlossMapScale", spec); } cstReader.Close(); LoadedMaterials[MTLIndex] = toReturn; }