在SceneKit中重复平面上的纹理

时间:2017-07-05 08:11:54

标签: swift xcode textures repeat

我想要在SCNPlane上重复一个32x32 .png图像。我得到的代码(见下文)导致图像被拉伸以适应平面的大小,而不是重复。

CODE:

let planeGeo = SCNPlane(width: 15, height: 15)

let imageMaterial = SCNMaterial()
imageMaterial.diffuse.contents = UIImage(named: "art.scnassets/grid.png")

planeGeo.firstMaterial = imageMaterial

let plane = SCNNode(geometry: planeGeo)

plane.geometry?.firstMaterial?.diffuse.wrapS = SCNWrapMode.repeat
plane.geometry?.firstMaterial?.diffuse.wrapT = SCNWrapMode.repeat

4 个答案:

答案 0 :(得分:9)

我修好了。似乎图像被放大了。如果我imageMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0),图像会重复。

答案 1 :(得分:6)

在ARKit中实现平面可视化时遇到了同样的问题。我想将检测到的平面可视化为棋盘图案。我通过使用正确配置的SCNNode创建名为“PlaneNode”的自定义SCNMaterial来修复它。材质使用wrapS,wrapT = .repeat并根据平面本身的大小正确计算尺度。

看起来像这样:

enter image description here

看看下面的代码,内联注释包含解释。

class PlaneNode : SCNNode {

    init(planeAnchor: ARPlaneAnchor) {
        super.init()
        // Create the 3D plane geometry with the dimensions reported
        // by ARKit in the ARPlaneAnchor instance
        let planeGeometry = SCNPlane(width:CGFloat(planeAnchor.extent.x), height:CGFloat(planeAnchor.extent.z))
        // Instead of just visualizing the grid as a gray plane, we will render
        // it in some Tron style colours.
        let material = SCNMaterial()
        material.diffuse.contents = PaintCode.imageOfViewARPlane
        //the scale gives the number of times the image is repeated
        //ARKit givest the width and height in meters, in this case we want to repeat
        //the pattern each 2cm = 0.02m so we divide the width/height to find the number of patterns
        //we then round this so that we always have a clean repeat and not a truncated one
        let scaleX = (Float(planeGeometry.width)  / 0.02).rounded()
        let scaleY = (Float(planeGeometry.height) / 0.02).rounded()
        //we then apply the scaling
        material.diffuse.contentsTransform = SCNMatrix4MakeScale(scaleX, scaleY, 0)
        //set repeat mode in both direction otherwise the patern is stretched!
        material.diffuse.wrapS = .repeat
        material.diffuse.wrapT = .repeat
        //apply material
        planeGeometry.materials = [material];
        //make a node for it
        self.geometry = planeGeometry
        // Move the plane to the position reported by ARKit
        position.x = planeAnchor.center.x
        position.y = 0
        position.z = planeAnchor.center.z
        // Planes in SceneKit are vertical by default so we need to rotate
        // 90 degrees to match planes in ARKit
        transform =  SCNMatrix4MakeRotation(-Float.pi / 2.0, 1.0, 0.0, 0.0);
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func update(planeAnchor: ARPlaneAnchor) {
        guard let planeGeometry = geometry as? SCNPlane else {
            fatalError("update(planeAnchor: ARPlaneAnchor) called on node that has no SCNPlane geometry")
        }
        //update the size
        planeGeometry.width = CGFloat(planeAnchor.extent.x)
        planeGeometry.height = CGFloat(planeAnchor.extent.z)
        //and material properties
        let scaleX = (Float(planeGeometry.width)  / 0.02).rounded()
        let scaleY = (Float(planeGeometry.height) / 0.02).rounded()
        planeGeometry.firstMaterial?.diffuse.contentsTransform = SCNMatrix4MakeScale(scaleX, scaleY, 0)
        // Move the plane to the position reported by ARKit
        position.x = planeAnchor.center.x
        position.y = 0
        position.z = planeAnchor.center.z

    }
}

答案 2 :(得分:0)

您可以从“场景工具箱”查看器中学习它,假设您的场景工具箱中有SCNplane

创建场景文件拖动平面

尺寸为12英寸(米)为0.3048

然后选择漫反射中的图像

enter image description here

现在您有一个带有4个网格的图像,如图像

enter image description here

我们希望每个盒子都以英寸为单位显示,因此对于12英寸,我们需要12个盒子* 12个盒子,因为我们有12英寸盒子

进行计算。首先,我们需要将0.3048米转换为英寸

这是米/ 0.0254 的答案是12。

但是我们需要在每个英寸上显示每个网格,因此我们还需要除以12/4 = 3

现在转到显示材料检查器并将比例值更改为3

您可以看到12英寸平面的12个盒子。

希望对您有帮助

答案 3 :(得分:0)

要在SceneKit编辑器中执行此操作,请在场景中选择您的平面(如果需要,添加一个平面),然后选择右上角的“材料检查器”选项卡。然后,在“属性”下及其显示为“漫反射”的位置,选择您的纹理。现在,通过单击“漫反射”左侧的克拉来扩展漫反射部分,然后向下滑至显示“缩放”的位置。在这里,您可以增加缩放比例,以便纹理可以看起来重复而不是拉伸。对于这个问题,OP必须将缩放比例设置为32x32。

enter image description here