I am trying to texture the a custom plane shape I created in scenekit on iOS9. I need the texture to spread out and stretch over the entire surface. I have a vertex and fragment shader on an SCNprogram. But it seems I am doing something wrong and fiddling with this all day, I have come to the conclusion that somehow the Texture coordinates I specify are not correct.
我试图纹理我在iOS9上的scenekit中创建的自定义平面形状。我需要将纹理展开并在整个表面上伸展。我在SCN程序上有一个顶点和片段着色器。但是看起来我做错了什么并整天摆弄这个,我得出的结论是,我指定的纹理坐标不正确。
My question is, when creating a geometry, does SceneKit create the texture coordinates automatically so when I specify CGpoint(0,0) for one corner of the texture, it automatically maps it to the bottom left corner of the geometry? Or do I have to manually specify the texture coordinates/uv for the geometry I create?
我的问题是,在创建几何体时,SceneKit是否会自动创建纹理坐标,因此当我为纹理的一个角指定CGpoint(0,0)时,它会自动将其映射到几何体的左下角?或者我是否必须手动指定我创建的几何体的纹理坐标/ uv?
This problem is a part of a larger question posted here : Custom Shader SCNProgram iOS 9 Scenekit
此问题是此处发布的更大问题的一部分:Custom Shader SCNProgram iOS 9 Scenekit
Please help, I have spent all day tinkering but no success :(
请帮忙,我整天都在修补但没有成功:(
EDIT:Based on Locks response below, I have changed the frag shader to help me troubleshoot it. What it gives I believe makes sense?? See pic below. There does seem to be an issue with my UVs. But why? I can't understand.
编辑:根据下面的锁定响应,我已经更改了frag着色器以帮助我排除故障。它给我的信念是否有道理?见下图。我的UV似乎确实存在问题。但为什么?我无法理解。
1 个解决方案
#1
2
Yes, when creating custom geometry you will also need to create UV coordinates for each vertex. This isn't too much on what you'll already be doing to create custom geometry, just fit the following bits in.
是的,在创建自定义几何体时,您还需要为每个顶点创建UV坐标。这对于您已经在创建自定义几何体所做的事情来说并不是太多,只需要符合以下几点。
var uvList:[vector_float2] = []
//fill UV list with texture coords
let uvData = NSData(bytes: uvList, length: uvList.count * sizeof(vector_float2))
let uvSource = SCNGeometrySource(data: uvData,
semantic: SCNGeometrySourceSemanticTexcoord,
vectorCount: uvList.count,
floatComponents: true,
componentsPerVector: 2,
bytesPerComponent: sizeof(Float),
dataOffset: 0,
dataStride: sizeof(vector_float2))
let geo = SCNGeometry(
sources: [vertexSource, normalSource, colourSource, uvSource],
elements: [indexElement])
Then to check if your texture coordinates are correct, I'd change your fragment shader to display them. Something like the following (been a while since I've written an OpenGL shader).
然后检查你的纹理坐标是否正确,我会更改你的片段着色器来显示它们。像下面这样的东西(自从我编写OpenGL着色器以来已经有一段时间了)。
void main() {
gl_FragColor = vec4(texCoord.x, texCoord.y, 0, 1);
}
The red and green shading of your object should then inform you what texture coordinates are where on your model. If that checks out ok, then switch back to reading data from the texture.
然后,对象的红色和绿色阴影应通知您模型上的纹理坐标。如果检查结果正常,则切换回从纹理中读取数据。
#1
2
Yes, when creating custom geometry you will also need to create UV coordinates for each vertex. This isn't too much on what you'll already be doing to create custom geometry, just fit the following bits in.
是的,在创建自定义几何体时,您还需要为每个顶点创建UV坐标。这对于您已经在创建自定义几何体所做的事情来说并不是太多,只需要符合以下几点。
var uvList:[vector_float2] = []
//fill UV list with texture coords
let uvData = NSData(bytes: uvList, length: uvList.count * sizeof(vector_float2))
let uvSource = SCNGeometrySource(data: uvData,
semantic: SCNGeometrySourceSemanticTexcoord,
vectorCount: uvList.count,
floatComponents: true,
componentsPerVector: 2,
bytesPerComponent: sizeof(Float),
dataOffset: 0,
dataStride: sizeof(vector_float2))
let geo = SCNGeometry(
sources: [vertexSource, normalSource, colourSource, uvSource],
elements: [indexElement])
Then to check if your texture coordinates are correct, I'd change your fragment shader to display them. Something like the following (been a while since I've written an OpenGL shader).
然后检查你的纹理坐标是否正确,我会更改你的片段着色器来显示它们。像下面这样的东西(自从我编写OpenGL着色器以来已经有一段时间了)。
void main() {
gl_FragColor = vec4(texCoord.x, texCoord.y, 0, 1);
}
The red and green shading of your object should then inform you what texture coordinates are where on your model. If that checks out ok, then switch back to reading data from the texture.
然后,对象的红色和绿色阴影应通知您模型上的纹理坐标。如果检查结果正常,则切换回从纹理中读取数据。