如何基于用户输入缩放SCNSceneKit中T恤3D模型的材质图像?
调整SceneKit中T恤模型的条纹材质宽度
核心思路
通过调整纹理的缩放变换矩阵实时改变条纹宽度,无需重新加载图像,效率更高且能实时响应用户输入。
修改后的实现代码
首先将材质对象提升为类属性,方便后续动态修改:
// 类内定义可全局访问的材质属性 var tShirtMaterial: MDLMaterial? func AddNode(scene:SCNScene, viewerSetup: Insert3DViewer, modelSetup: Insert3DModel) -> SCNNode { guard let url = Bundle.main.url(forAuxiliaryExecutable: modelSetup.mesh) else { fatalError("Failed to find model file.") } let asset = MDLAsset(url: url) guard let object = asset.object(at: 0) as? MDLMesh else { fatalError("Failed to get mesh from asset.") } // 创建材质并配置纹理 let scatteringFunction = MDLScatteringFunction() let material = MDLMaterial(name: "baseMaterial", scatteringFunction: scatteringFunction) guard let meshUrl = Bundle.main.url(forResource: modelSetup.material, withExtension: "") else { fatalError("Failed to find texture file.") } // 配置纹理属性,设置重复环绕模式避免边缘拉伸 let textureProperty = MDLMaterialProperty(name: modelSetup.material, semantic: .baseColor, url: meshUrl) textureProperty.textureSamplerValue.wrapS = .repeat textureProperty.textureSamplerValue.wrapT = .repeat material.setProperty(textureProperty) // 保存材质引用,供后续调整宽度使用 tShirtMaterial = material for submesh in object.submeshes! { if let submesh = submesh as? MDLSubmesh { submesh.material = material } } return SCNNode(mdlObject: object) }
添加响应用户输入的条纹宽度调整方法:
/// 根据用户输入的缩放值调整条纹宽度 /// - Parameter scale: 缩放系数,值越大条纹越宽,值越小条纹越密集 func adjustStripeWidth(scale: CGFloat) { guard let material = tShirtMaterial, let textureProperty = material.property(with: .baseColor) else { return } // 水平条纹调整x轴缩放,垂直条纹调整y轴缩放 textureProperty.textureSamplerValue.transform = CATransform3DMakeScale(scale, 1, 1) // 垂直条纹请使用:CATransform3DMakeScale(1, scale, 1) }
关键说明
- 纹理环绕模式:设置为
.repeat可让缩放后的纹理自动重复平铺,避免出现空白或拉伸失真 - 缩放系数逻辑:
scale大于1时,条纹被放大(宽度增加);小于1时,条纹被缩小(宽度变窄、数量增多) - 方向适配:根据条纹是水平/垂直方向,对应调整x/y轴的缩放参数即可
内容的提问来源于stack exchange,提问作者Vimalkumar N.M.
相关产品推荐
相关产品推荐

