Отправить текстуру в SCNProgram

Я передаю текстуру шейдеру с помощью SCNProgram и Metal. Проблема в том, что при передаче текстуры выделяется огромный объем памяти. Текстуры рамсера неблшой, примерно 50-100 кб. Приложение вылетает при достижении критического сектора использования памяти. Импортирую 25 разных моделей с их текстурами. Функция 1 загружает объект из файла obj. Функция 2, отправляет данные во фрагментный шейдер. Есть ли другие способы передать текстуру шейдеру без использования SCNMaterialProperty?

      // 1
func load(name: String) -> SCNNode? {
        guard let url = Bundle.main.url(
                forResource: name,
                withExtension: "obj",
                subdirectory: "Models.scnassets") else { return nil }
        let asset = MDLAsset(url: url)
        let mesh = asset.object(at: 0) as! MDLMesh
        mesh.addTangentBasis(forTextureCoordinateAttributeNamed: MDLVertexAttributeTextureCoordinate, normalAttributeNamed: MDLVertexAttributeNormal, tangentAttributeNamed: MDLVertexAttributeTangent)
        let scene = SCNNode(geometry: SCNGeometry(mdlMesh: mesh))
        scene.name = name
        return scene
    }
    
    //2
    func congigurate(model: inout SCNNode,
                     usePBR: Bool) {
        
        
        let program = SCNProgram()
        program.fragmentFunctionName = usePBR ? "fragment_mainPBR" : "fragment_main"
        program.vertexFunctionName = "vertex_main"

        //0 Загрузка уровня
        guard let name = model.name else { fatalError("Lost name") }
        let materialLevel = SCNMaterial()
        
        
        var ligth = Light(position: [50, 50, 50],
                      color: [0.98, 0.95, 0.8],
                      specularColor: [1, 1, 1],
                      intensity: 1.0,
                      attenuation: [1, 1, 1],
                      type: .Sunlight,
                      coneAngle: 45,
                      coneDirection: [50, 50, 50],
                      coneAttenuation: 1)
        
        var materal = Material(baseColor: [0.46, 0.68, 0.68],
                                  specularColor: [1, 1, 1],
                                  roughness: 0.9,
                                  metallic: 0.25,
                                  ambientOcclusion: [0.1, 0.1, 0.1],
                                  shininess: 1000.0,
                                  hasAlbedoTexture: true,
                                  hasNormalTexture: false,
                                  hasRougnessTexture: false,
                                  hasMetalnesTexture: false,
                                  hasAOTexture: false)
        
        
        // SET TEXTURE
        if materal.hasAlbedoTexture {
            
            let albedoModel = UIImage(named: "\(name)Albedo")!
            let texture = SCNMaterialProperty(contents: albedoModel)
            materialLevel.setValue(texture, forKey: "baseColorTexture")
        } else {
            materialLevel.setValue(NSNull(), forKey: "baseColorTexture")
        }

        // Устаовка текстуры карты нормалей в материале
        if materal.hasNormalTexture {
            let normalModel = UIImage(named: "\(name)Normal")!
            let texture = SCNMaterialProperty(contents: normalModel)
            materialLevel.setValue(texture, forKey: "normalTexture")
        } else {
            materialLevel.setValue(NSNull(), forKey: "normalTexture")
        }

        // Установка текстуры карты металличности из материала
        if materal.hasMetalnesTexture{
            let metalnesModel = UIImage(named: "\(name)Metal")!
            let metalnesProperty = SCNMaterialProperty(contents: metalnesModel)
            materialLevel.setValue(metalnesProperty, forKey: "metallicTexture")
        } else {
            materialLevel.setValue(NSNull(), forKey: "metallicTexture")
        }

        // Установка карты шерховатоси из материала
        if materal.hasRougnessTexture {
            let roungnesModel = UIImage(named: "\(name)Roug")!
            let roungnesProperty = SCNMaterialProperty(contents: roungnesModel)
            materialLevel.setValue(roungnesProperty, forKey: "roughnessTexture")
        } else {
            materialLevel.setValue(NSNull(), forKey: "roughnessTexture")
        }
        
        // Установка карты глубокого затинения из материала
        if materal.hasAOTexture {
            let ambientModel = UIImage(named: "\(name)AO")!
            let ambientProperty = SCNMaterialProperty(contents: ambientModel)
            materialLevel.setValue(ambientProperty, forKey: "aoTexture")
        } else {
            materialLevel.setValue(NSNull(), forKey: "aoTexture")
        }
        
        materialLevel.setValue(NSData(bytes: &materal, length: Material.stride), forKey: "material")
        
        materialLevel.setValue(NSData(bytes: &ligth, length: Light.stride), forKey: "lights")
        
        materialLevel.program = program
        
        model.geometry?.materials = [materialLevel]
        
    }

0 ответов

Другие вопросы по тегам