public static void CreateTemplateFileForShader(Shader shader) { ShaderMapping mapping = CreateTemplateForShader(shader); string filePath = Path.Combine(Application.dataPath, GetFileNameForShaderMapping(shader.name) + "-Template.json"); WriteToJsonFile(mapping, filePath); }
/// <summary> /// Get a material data to match the passed material if one exisits in the cache otherwise create a new one /// </summary> /// <param name="material"></param> /// <returns></returns> public static MaterialInfo GetOrCreateMaterialData(Material material, ShaderMapping mapping = null) { if (_materialDataCache.ContainsKey(material.GetInstanceID())) { return(_materialDataCache[material.GetInstanceID()]); } else { return(CreateMaterialData(material, mapping)); } }
/// <summary> /// Create a new material data based off of the pass material also adds the new data to the cache /// </summary> /// <param name="material"></param> /// <returns></returns> public static MaterialInfo CreateMaterialData(Material material, ShaderMapping mapping = null) { // fetch the shadermapping for this materials shader if (mapping == null && material != null) { mapping = ShaderMappingIO.ReadFromJsonFile(material.shader); if (mapping == null) // if we fail to find a mapping try and load the default { mapping = ShaderMappingIO.ReadFromJsonFile(ShaderMappingIO.GetPathForShaderMappingFile("Default")); } } MaterialInfo matdata = new MaterialInfo { id = material != null?material.GetInstanceID() : 0, mapping = mapping }; // process uniforms UniformMappedData[] uniformDatas = mapping.GetUniformDatasFromMaterial(material); foreach (UniformMappedData uniData in uniformDatas) { VkDescriptorType descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_MAX_ENUM; uint descriptorCount = 1; if (uniData.mapping.uniformType == UniformMapping.UniformType.Texture2DUniform) { Texture tex = uniData.data as Texture; if (tex == null) { continue; } // get imagedata for the texture ImageData imageData = TextureConverter.GetOrCreateImageData(tex); // get descriptor for the image data DescriptorImageData descriptorImage = GetOrCreateDescriptorImageData(imageData, uniData.mapping.vsgBindingIndex); matdata.imageDescriptors.Add(descriptorImage); descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; } else if (uniData.mapping.uniformType == UniformMapping.UniformType.Texture2DArrayUniform) { Texture2DArray tex = uniData.data as Texture2DArray; if (tex == null) { continue; } ImageData[] imageDatas = TextureConverter.GetOrCreateImageData(tex); DescriptorImageData descriptorImage = GetOrCreateDescriptorImageData(imageDatas, uniData.mapping.vsgBindingIndex); matdata.imageDescriptors.Add(descriptorImage); descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorCount = (uint)imageDatas.Length; } else if (uniData.mapping.uniformType == UniformMapping.UniformType.FloatUniform) { float value = (float)uniData.data; if (value == float.NaN) { continue; } // get descriptor for the image data DescriptorFloatUniformData descriptorFloat = new DescriptorFloatUniformData { id = material.GetInstanceID(), binding = uniData.mapping.vsgBindingIndex, value = value }; matdata.floatDescriptors.Add(descriptorFloat); descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; } else if (uniData.mapping.uniformType == UniformMapping.UniformType.Vec4Uniform || uniData.mapping.uniformType == UniformMapping.UniformType.ColorUniform) { Vector4 vector = Vector4.zero; if (uniData.mapping.uniformType == UniformMapping.UniformType.Vec4Uniform) { vector = (Vector4)uniData.data; } if (uniData.mapping.uniformType == UniformMapping.UniformType.ColorUniform) { Color color = (Color)uniData.data; vector = new Vector4(color.r, color.g, color.b, color.a); } if (vector == null) { continue; } // get descriptor for the image data DescriptorVectorUniformData descriptorVector = new DescriptorVectorUniformData { id = material.GetInstanceID(), binding = uniData.mapping.vsgBindingIndex, value = NativeUtils.ToNative(vector) }; matdata.vectorDescriptors.Add(descriptorVector); descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; } if (descriptorType == VkDescriptorType.VK_DESCRIPTOR_TYPE_MAX_ENUM) { continue; } // add any custom defines related to the texture if (uniData.mapping.vsgDefines != null && uniData.mapping.vsgDefines.Count > 0) { matdata.customDefines.AddRange(uniData.mapping.vsgDefines); } // create the descriptor binding to match the descriptor image VkDescriptorSetLayoutBinding descriptorBinding = new VkDescriptorSetLayoutBinding { binding = (uint)uniData.mapping.vsgBindingIndex, descriptorType = descriptorType, descriptorCount = descriptorCount, stageFlags = uniData.mapping.stages, pImmutableSamplers = System.IntPtr.Zero }; matdata.descriptorBindings.Add(descriptorBinding); } if (material != null) { string rendertype = material.GetTag("RenderType", true, "Opaque"); matdata.useAlpha = rendertype.Contains("Transparent") ? 1 : 0; if (matdata.useAlpha == 1) { matdata.customDefines.Add("VSG_BLEND"); } string lightmode = material.GetTag("LightMode", true, "ForwardBase"); if (lightmode != "Always") { matdata.customDefines.Add("VSG_LIGHTING"); } } // lastly process shaders now we know the defines etc it will use string customDefinesStr = string.Join(",", matdata.customDefines.ToArray()); matdata.shaderStages = GetOrCreateShaderStagesInfo(mapping.shaders.ToArray(), customDefinesStr, null); // add to the cache (double check it doesn't exist already) if (material != null && !_materialDataCache.ContainsKey(matdata.id)) { _materialDataCache[matdata.id] = matdata; } return(matdata); }
// // function for creating a template shadermapping json file for a specific shader public static ShaderMapping CreateTemplateForShader(Shader shader) { ShaderMapping mapping = new ShaderMapping() { unityShaderName = shader.name, shaders = new List <ShaderResource>() { new ShaderResource() { sourceFile = shader.name, stages = VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT | VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT } } }; mapping.vertexDependancies = new List <VertexAttributeDependancies> { new VertexAttributeDependancies { attributeType = VertexAttribute.Position, dependantDefines = new List <string> { "ALL" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.Normal, dependantDefines = new List <string> { "VSG_LIGHTING", "VSG_NORMAL_MAP" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.Tangent, dependantDefines = new List <string> { "VSG_NORMAL_MAP" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.Color, dependantDefines = new List <string> { "NONE" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.TexCoord0, dependantDefines = new List <string> { "VSG_DIFFUSE_MAP", "VSG_NORMAL_MAP" } } }; for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); i++) { ShaderUtil.ShaderPropertyType proptype = ShaderUtil.GetPropertyType(shader, i); string propname = ShaderUtil.GetPropertyName(shader, i); if (proptype == ShaderUtil.ShaderPropertyType.TexEnv) { TextureDimension texdims = ShaderUtil.GetTexDim(shader, i); UniformMapping.UniformType textype = UniformMapping.UniformType.UnkownUniform; switch (texdims) { case TextureDimension.Tex2D: { textype = UniformMapping.UniformType.Texture2DUniform; break; } case TextureDimension.Tex2DArray: { textype = UniformMapping.UniformType.Texture2DArrayUniform; break; } default: break; } if (textype == UniformMapping.UniformType.UnkownUniform) { continue; } mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = textype }); } else if (proptype == ShaderUtil.ShaderPropertyType.Float || proptype == ShaderUtil.ShaderPropertyType.Range) { mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = UniformMapping.UniformType.FloatUniform }); } else if (proptype == ShaderUtil.ShaderPropertyType.Vector) { mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = UniformMapping.UniformType.Vec4Uniform }); } else if (proptype == ShaderUtil.ShaderPropertyType.Color) { mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = UniformMapping.UniformType.ColorUniform }); } } return(mapping); }
public static void WriteToJsonFile(ShaderMapping mapping, string filePath) { string contents = JsonUtility.ToJson(mapping, true); File.WriteAllText(filePath, contents); }