예제 #1
0
        /// <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);
        }
예제 #2
0
        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
        }