SceneKit – 自定义几何体上的拉伸纹理
SceneKit – Stretched texture on a Custom Geometry
我想用 ARKit 使用自定义多边形平铺地面,自定义多边形由用户使用水平平面上的选定位置创建,但是平铺被拉伸并且无法正确显示,也许问题出在纹理坐标上,这段代码有什么问题?
let vertices: [SCNVector3] = ... //Selected positions by user
var indices: [Int32] = [Int32(vertices.count)]
var index: Int32 = 0
for _ in vertices {
indices.append(index)
index += 1
}
let textureCoordinates = [ CGPoint(x: 0, y: 0),
CGPoint(x: 1, y: 0),
CGPoint(x: 0, y: 1),
CGPoint(x: 1, y: 1)
]
let vertexSource = SCNGeometrySource(vertices: vertices)
let uvSource = SCNGeometrySource(textureCoordinates: textureCoordinates)
let indexData = Data(bytes: indices,
count: indices.count * MemoryLayout<Int32>.size)
let element = SCNGeometryElement(data: indexData,
primitiveType: .polygon,
primitiveCount: 1,
bytesPerIndex: MemoryLayout<Int32>.size)
let geometry = SCNPlane(sources: [vertexSource, uvSource],
elements: [element]) //Creating geometry
//Tile material creation
let material = SCNMaterial()
material.isDoubleSided = true
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
//Tile image to tile polygon
material.diffuse.contents = UIImage(named: "tile")!
material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
geometry.firstMaterial = material
//Tiled Plan to put on the ground
let plane = SCNNode(geometry: geometry)
//Add custom polygon to sceneView
sceneView.scene.rootNode.addChildNode(plane)
编辑:
感谢 Andy,我更改了 contentsTransform
,在变换比例上做了一些小改动,但仍然有同样的问题:
.init(
m11: 5, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 5, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0.5, m42: 0, m43: 0, m44: 1)
我的期望:
会发生什么:
纹理拉伸 由于 UV 贴图上的错误纹理映射而发生。您必须使用 m41
(翻译 X)和 m42
(翻译 Y)元素,它们包含在 SCNMatrix4 的第四列中。这就是当矩阵元素 m41
等于零时拉伸的样子:
material.diffuse.contentsTransform = .init(
m11: 0.04, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 0.04, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0, m42: 0, m43: 0, m44: 1)
偏移纹理
当您沿 X 轴移动纹理时,一切都改变了:
material.diffuse.contentsTransform = .init(
m11: 0.04, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 0.04, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0.5, m42: 0, m43: 0, m44: 1)
我想用 ARKit 使用自定义多边形平铺地面,自定义多边形由用户使用水平平面上的选定位置创建,但是平铺被拉伸并且无法正确显示,也许问题出在纹理坐标上,这段代码有什么问题?
let vertices: [SCNVector3] = ... //Selected positions by user
var indices: [Int32] = [Int32(vertices.count)]
var index: Int32 = 0
for _ in vertices {
indices.append(index)
index += 1
}
let textureCoordinates = [ CGPoint(x: 0, y: 0),
CGPoint(x: 1, y: 0),
CGPoint(x: 0, y: 1),
CGPoint(x: 1, y: 1)
]
let vertexSource = SCNGeometrySource(vertices: vertices)
let uvSource = SCNGeometrySource(textureCoordinates: textureCoordinates)
let indexData = Data(bytes: indices,
count: indices.count * MemoryLayout<Int32>.size)
let element = SCNGeometryElement(data: indexData,
primitiveType: .polygon,
primitiveCount: 1,
bytesPerIndex: MemoryLayout<Int32>.size)
let geometry = SCNPlane(sources: [vertexSource, uvSource],
elements: [element]) //Creating geometry
//Tile material creation
let material = SCNMaterial()
material.isDoubleSided = true
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
//Tile image to tile polygon
material.diffuse.contents = UIImage(named: "tile")!
material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
geometry.firstMaterial = material
//Tiled Plan to put on the ground
let plane = SCNNode(geometry: geometry)
//Add custom polygon to sceneView
sceneView.scene.rootNode.addChildNode(plane)
编辑:
感谢 Andy,我更改了 contentsTransform
,在变换比例上做了一些小改动,但仍然有同样的问题:
.init(
m11: 5, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 5, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0.5, m42: 0, m43: 0, m44: 1)
我的期望:
会发生什么:
纹理拉伸 由于 UV 贴图上的错误纹理映射而发生。您必须使用 m41
(翻译 X)和 m42
(翻译 Y)元素,它们包含在 SCNMatrix4 的第四列中。这就是当矩阵元素 m41
等于零时拉伸的样子:
material.diffuse.contentsTransform = .init(
m11: 0.04, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 0.04, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0, m42: 0, m43: 0, m44: 1)
偏移纹理
当您沿 X 轴移动纹理时,一切都改变了:
material.diffuse.contentsTransform = .init(
m11: 0.04, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 0.04, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0.5, m42: 0, m43: 0, m44: 1)