显示拉伸 material 应用于 SCNGeometrySource 节点
Display stretched material apply on SCNGeometrySource node
我使用 SCNGeometrySource 使用自定义选择的 SCNVector3 点创建了 SCNNode,并应用图像 material 来显示非常拉伸的 material。如何在 SCNGeometrySource 节点上正确应用 material。
func getsquareDrawnLineFrom(pos1: SCNVector3,
pos2: SCNVector3,
pos3: SCNVector3) -> SCNNode {
let square = SquareplanlineFrom(vector1: pos1, vector2: pos2, vector3: pos3)
//SCNGeometrySource.Semantic.texcoord
//SCNGeometrySource.Semantic.normal
let material = SCNMaterial()
// material.diffuse.contents = UIColor.lightGray
material.diffuse.contents = UIImage(named: "grid")
material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
square.materials = [material]
let square1 = SCNNode(geometry: square)
square1.name = "tringle"
return square1
}
// get line geometry between two vectors
func SquareplanlineFrom(vector1: SCNVector3,
vector2: SCNVector3, vector3: SCNVector3) -> SCNGeometry {
let normalsPerFace = 3
let indices: [Int32] = [0, 1, 2]
let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])
let normals:[SCNVector3] = [
vector1,
vector2,
vector3].map{[SCNVector3](repeating:[=11=],count:normalsPerFace)}.flatMap{[=11=]}
let normalSource = SCNGeometrySource(normals: normals)
let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
let textcoord = SCNGeometrySource(textureCoordinates: [cgp1,cgp2,cgp3])
// let texcoord = SCNGeometrySource(textureCoordinates: [])
// let normalSource = SCNGeometrySource(normals: [vector1, vector2, vector3])
let element = SCNGeometryElement(indices: indices,
primitiveType: .triangles)
return SCNGeometry(sources: [source,normalSource,textcoord], elements: [element])
}
你的情况是纹理的比例问题:
我不知道你的模型的大小,但我认为问题是 – 你增加了比例,尽管你必须减少它才能正确放置纹理。
Tip: My texture's size is 2K square (2048x2048, 72dpi).
这是一个代码(抱歉,我使用的是 macOS 版本):
func getSquareDrawnLineFrom(pos1: SCNVector3,
pos2: SCNVector3,
pos3: SCNVector3) -> SCNNode {
let square = squarePlanLineFrom(vector1: pos1,
vector2: pos2,
vector3: pos3)
let material = SCNMaterial()
material.diffuse.contents = NSImage.Name("art.scnassets/jaguar.jpg")
// your scale
// material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
material.isDoubleSided = true
material.diffuse.contentsTransform = .init(m11: 0.05, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 0.05, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0, m42: 0, m43: 0, m44: 1)
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
square.materials = [material]
let square1 = SCNNode(geometry: square)
scene.rootNode.addChildNode(square1)
square1.name = "triangle"
return square1
}
func squarePlanLineFrom(vector1: SCNVector3,
vector2: SCNVector3,
vector3: SCNVector3) -> SCNGeometry {
let normalsPerFace = 3
let indices: [Int32] = [0, 1, 2]
let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])
let vec = [vector1, vector2, vector3].map { [SCNVector3](repeating: [=10=],
count: normalsPerFace) }.flatMap{ [=10=] }
let normals: [SCNVector3] = vec
let normalSource = SCNGeometrySource(normals: normals)
let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
let textcoord = SCNGeometrySource(textureCoordinates: [cgp1, cgp2, cgp3])
let element = SCNGeometryElement(indices: indices,
primitiveType: .triangles)
return SCNGeometry(sources: [source, normalSource, textcoord],
elements: [element])
}
let instance = getSquareDrawnLineFrom(pos1: SCNVector3(x: 0, y: 0, z: 0),
pos2: SCNVector3(x: 8, y: 5, z: 0),
pos3: SCNVector3(x:-8, y: 5, z: 0))
但有时可能是法线的方向问题:
开发人员通常 创建平行于表面的矢量 ,因此纹理被拉伸(纹理的一行像素沿整个表面复制)。 但是几何体的法线必须垂直于表面,而不是平行。
我使用 SCNGeometrySource 使用自定义选择的 SCNVector3 点创建了 SCNNode,并应用图像 material 来显示非常拉伸的 material。如何在 SCNGeometrySource 节点上正确应用 material。
func getsquareDrawnLineFrom(pos1: SCNVector3,
pos2: SCNVector3,
pos3: SCNVector3) -> SCNNode {
let square = SquareplanlineFrom(vector1: pos1, vector2: pos2, vector3: pos3)
//SCNGeometrySource.Semantic.texcoord
//SCNGeometrySource.Semantic.normal
let material = SCNMaterial()
// material.diffuse.contents = UIColor.lightGray
material.diffuse.contents = UIImage(named: "grid")
material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
square.materials = [material]
let square1 = SCNNode(geometry: square)
square1.name = "tringle"
return square1
}
// get line geometry between two vectors
func SquareplanlineFrom(vector1: SCNVector3,
vector2: SCNVector3, vector3: SCNVector3) -> SCNGeometry {
let normalsPerFace = 3
let indices: [Int32] = [0, 1, 2]
let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])
let normals:[SCNVector3] = [
vector1,
vector2,
vector3].map{[SCNVector3](repeating:[=11=],count:normalsPerFace)}.flatMap{[=11=]}
let normalSource = SCNGeometrySource(normals: normals)
let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
let textcoord = SCNGeometrySource(textureCoordinates: [cgp1,cgp2,cgp3])
// let texcoord = SCNGeometrySource(textureCoordinates: [])
// let normalSource = SCNGeometrySource(normals: [vector1, vector2, vector3])
let element = SCNGeometryElement(indices: indices,
primitiveType: .triangles)
return SCNGeometry(sources: [source,normalSource,textcoord], elements: [element])
}
你的情况是纹理的比例问题:
我不知道你的模型的大小,但我认为问题是 – 你增加了比例,尽管你必须减少它才能正确放置纹理。
Tip: My texture's size is 2K square (2048x2048, 72dpi).
这是一个代码(抱歉,我使用的是 macOS 版本):
func getSquareDrawnLineFrom(pos1: SCNVector3,
pos2: SCNVector3,
pos3: SCNVector3) -> SCNNode {
let square = squarePlanLineFrom(vector1: pos1,
vector2: pos2,
vector3: pos3)
let material = SCNMaterial()
material.diffuse.contents = NSImage.Name("art.scnassets/jaguar.jpg")
// your scale
// material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
material.isDoubleSided = true
material.diffuse.contentsTransform = .init(m11: 0.05, m12: 0, m13: 0, m14: 0,
m21: 0, m22: 0.05, m23: 0, m24: 0,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: 0, m42: 0, m43: 0, m44: 1)
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
square.materials = [material]
let square1 = SCNNode(geometry: square)
scene.rootNode.addChildNode(square1)
square1.name = "triangle"
return square1
}
func squarePlanLineFrom(vector1: SCNVector3,
vector2: SCNVector3,
vector3: SCNVector3) -> SCNGeometry {
let normalsPerFace = 3
let indices: [Int32] = [0, 1, 2]
let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])
let vec = [vector1, vector2, vector3].map { [SCNVector3](repeating: [=10=],
count: normalsPerFace) }.flatMap{ [=10=] }
let normals: [SCNVector3] = vec
let normalSource = SCNGeometrySource(normals: normals)
let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
let textcoord = SCNGeometrySource(textureCoordinates: [cgp1, cgp2, cgp3])
let element = SCNGeometryElement(indices: indices,
primitiveType: .triangles)
return SCNGeometry(sources: [source, normalSource, textcoord],
elements: [element])
}
let instance = getSquareDrawnLineFrom(pos1: SCNVector3(x: 0, y: 0, z: 0),
pos2: SCNVector3(x: 8, y: 5, z: 0),
pos3: SCNVector3(x:-8, y: 5, z: 0))
但有时可能是法线的方向问题:
开发人员通常 创建平行于表面的矢量 ,因此纹理被拉伸(纹理的一行像素沿整个表面复制)。 但是几何体的法线必须垂直于表面,而不是平行。