/// <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); }
private static void ExportTerrainMesh(Terrain terrain, ExportSettings settings, List <PipelineData> storePipelines = null) { TerrainConverter.TerrainInfo terrainInfo = TerrainConverter.CreateTerrainInfo(terrain, settings); if (terrainInfo == null || ((terrainInfo.diffuseTextureDatas.Count == 0 || terrainInfo.maskTextureDatas.Count == 0) && terrainInfo.customMaterial == null)) { return; } // add stategroup and pipeline for shader GraphBuilderInterface.unity2vsg_AddStateGroupNode(); PipelineData pipelineData = new PipelineData(); pipelineData.hasNormals = 1; pipelineData.uvChannelCount = 1; pipelineData.useAlpha = 0; if (terrainInfo.customMaterial == null) { pipelineData.descriptorBindings = NativeUtils.WrapArray(terrainInfo.descriptorBindings.ToArray()); ShaderStagesInfo shaderStagesInfo = MaterialConverter.GetOrCreateShaderStagesInfo(terrainInfo.shaderMapping.shaders.ToArray(), string.Join(",", terrainInfo.shaderDefines.ToArray()), terrainInfo.shaderConsts.ToArray()); pipelineData.shaderStages = shaderStagesInfo.ToNative(); pipelineData.id = NativeUtils.ToNative(NativeUtils.GetIDForPipeline(pipelineData)); storePipelines.Add(pipelineData); if (GraphBuilderInterface.unity2vsg_AddBindGraphicsPipelineCommand(pipelineData, 1) == 1) { if (terrainInfo.diffuseTextureDatas.Count > 0) { DescriptorImageData layerDiffuseTextureArray = MaterialConverter.GetOrCreateDescriptorImageData(terrainInfo.diffuseTextureDatas.ToArray(), 0); GraphBuilderInterface.unity2vsg_AddDescriptorImage(layerDiffuseTextureArray); } if (terrainInfo.diffuseScales.Count > 0) { DescriptorVectorArrayUniformData scalesDescriptor = new DescriptorVectorArrayUniformData(); scalesDescriptor.binding = 2; scalesDescriptor.value = NativeUtils.WrapArray(terrainInfo.diffuseScales.ToArray()); GraphBuilderInterface.unity2vsg_AddDescriptorBufferVectorArray(scalesDescriptor); } DescriptorVectorUniformData sizeDescriptor = new DescriptorVectorUniformData(); sizeDescriptor.binding = 3; sizeDescriptor.value = NativeUtils.ToNative(terrainInfo.terrainSize); GraphBuilderInterface.unity2vsg_AddDescriptorBufferVector(sizeDescriptor); if (terrainInfo.maskTextureDatas.Count > 0) { DescriptorImageData layerMaskTextureArray = MaterialConverter.GetOrCreateDescriptorImageData(terrainInfo.maskTextureDatas.ToArray(), 1); GraphBuilderInterface.unity2vsg_AddDescriptorImage(layerMaskTextureArray); } GraphBuilderInterface.unity2vsg_CreateBindDescriptorSetCommand(1); GraphBuilderInterface.unity2vsg_AddVertexIndexDrawNode(MeshConverter.GetOrCreateVertexIndexDrawData(terrainInfo.terrainMesh)); GraphBuilderInterface.unity2vsg_EndNode(); // step out of vertex index draw node } } else { pipelineData.descriptorBindings = NativeUtils.WrapArray(terrainInfo.customMaterial.descriptorBindings.ToArray()); pipelineData.shaderStages = terrainInfo.customMaterial.shaderStages.ToNative(); pipelineData.id = NativeUtils.ToNative(NativeUtils.GetIDForPipeline(pipelineData)); storePipelines.Add(pipelineData); if (GraphBuilderInterface.unity2vsg_AddBindGraphicsPipelineCommand(pipelineData, 1) == 1) { BindDescriptors(terrainInfo.customMaterial, true); GraphBuilderInterface.unity2vsg_AddVertexIndexDrawNode(MeshConverter.GetOrCreateVertexIndexDrawData(terrainInfo.terrainMesh)); GraphBuilderInterface.unity2vsg_EndNode(); // step out of vertex index draw node } } GraphBuilderInterface.unity2vsg_EndNode(); // step out of stategroup node }