2014-09-30 101 views
1

我有一个我加载到Scenekit中的Collada模型。 当我在模型上执行命中测试时,我能够检索命中的模型的纹理坐标。IOS8 Scenekit在纹理坐标上绘画

有了这些纹理坐标,我应该可以用颜色替换纹理坐标。 所以这种方式,我应该可以借鉴模型

如果我错了,纠正我到目前为止。

我读了很多文章到现在,但我只是没有让我的着色器正确。 (虽然我没有得到一些时髦的效果;-)

我的顶点着色器:

precision highp float; 

attribute vec4 position; 
attribute vec2 textureCoordinate; 
attribute vec2 aTexureCoordForColor; //coordinates from the hittest 

uniform mat4 modelViewProjection; 

varying vec2 aTexureCoordForColorVarying; // passing to the fragment shader here 
varying vec2 texCoord; 

void main(void) { 
     // Pass along to the fragment shader 
     texCoord = textureCoordinate; 
     aTexureCoordForColorVarying = aTexureCoordForColor; //assigning here 
     // output the projected position 
     gl_Position = modelViewProjection * position; 
} 

我的片段着色器

precision highp float; 

uniform sampler2D yourTexture; 

uniform vec2 uResolution; 
uniform int uTexureCoordsCount; 

varying vec2 texCoord; 
varying vec2 aTexureCoordForColorVarying; 

void main(void) { 

     ??????????? no idea anymore what to do here 
     gl_FragColor = texture2D(yourTexture, texCoord); 
// 

如果您需要更多的代码,请让我知道。

回答

6

首先,着色器不是绘制物体材质的唯一方法。另一个可能适用于您的选项是使用SpriteKit场景作为素材的内容 - 请参阅this answer以获取帮助。

如果你坚持着色器路线,你不需要重写整个着色器程序来绘制现有纹理。 (如果你这样做了,那么你会失去SceneKit程序为你提供的东西,比如光照和凹凸贴图,除非你真的想要重新设计这些轮子。)而是使用着色器修改器 - 插入到GLSL中的一小段代码SceneKit着色器程序。 SCNShadable reference解释如何使用这些。

第三,我不确定你是否以最好的方式为着色器提供了纹理坐标。您希望每个片段都能为点击点获取相同的texcoord值,因此将它作为属性传递给GL并在顶点和片段之间插入它是没有意义的。只需将其作为统一标准传递,然后使用键值编码将材料设置在材质上。 (见SCNShadable reference again的信息与KVC结合材质参数。)

最后,让你的问题的重点... :)

要改变片段着色器的输出颜色(或着色器修改器)在一组特定的纹理坐标处或其附近,只需将您的传入点击坐标与当前用于常规纹理查找的texcoords集相比较即可。下面是这样做,会着色器修改路线的例子:

uniform vec2 clickTexcoord; 
// set this from ObjC/Swift code with setValue:forKey: 
// and an NSValue with CGPoint data 

uniform float radius = 0.01; 
// change this to determine how large an area to highlight 

uniform vec3 paintColor = vec4(0.0, 1.0, 0.0); 
// nice and green; you can change this with KVC, too 

#pragma body 

if (distance(_surface.diffuseTexcoord.x, clickTexcoord.x) < radius) { 
    _surface.diffuse.rgb = paintColor 
} 

用这个例子作为SCNShaderModifierEntryPointSurface着色剂和照明/阴影仍将被应用于结果。如果您希望绘画覆盖照明,请改为使用SCNShaderModifierEntryPointFragment着色器修改器,并使用GLSL片段集_output.color.rgb而不是_surface.color.rgb

+0

哇......这是迄今为止最好的信息......谢谢。我将处理这些信息,并让您知道哪些方法最有效。 – Vilois 2014-10-01 09:14:06

+0

是的..谢谢....事情现在有了很多更清楚的.....我添加了shaderModifier,稍微加大了上面的代码,但总的来说它是一样的.....非常感谢你 – Vilois 2014-10-01 11:43:45

+0

@rickster你的回答很清楚,我认为这会帮助我解决我自己的问题。它没有解决,所以我已经发布了一个问题http://stackoverflow.com/questions/38999782/how-to-use-a-shadermodifier-to-alter-the-color-of-specific-triangles希望像你这样的人能够帮助你。顺便说一句,你提供的第一个链接“这个答案”实际上链接到相同的“SCNShadable参考”;那是故意的。另外,在你最后的笔记中你提到_surface.color,我认为你的意思是_surface.diffuse。 – PKCLsoft 2016-08-19 03:34:37