在纹理的SceneKit绘画与纹理坐标

时间:2014-09-30 20:03:25

标签: opengl-es ios8 glsl shader scenekit

我有一个Collada模型,我加载到SceneKit中。当我在模型上执行hittest时,我能够检索被击中的模型的纹理坐标。

使用这些纹理坐标,我应该能够用颜色替换纹理坐标。 所以这种方式我应该可以在模型上绘图

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

到目前为止,我读了很多文章,但我不能让我的着色器正确。 (虽然我确实得到了一些时髦的效果; - )

我的顶点着色器:

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);
}

如果您需要更多代码,请告诉我们。

1 个答案:

答案 0 :(得分:6)

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

如果您坚持着色器路线,则无需重写整个着色器程序,只需在现有纹理上绘制。 (如果你这样做,你会丢失SceneKit程序为你提供的东西,比如照明和凹凸贴图。除非你真的想要,否则重新发明这些轮子。)相反,使用着色器修饰符 - 一小段GLSL插入到SceneKit着色器程序。 SCNShadable reference解释了如何使用它们。

第三,我不确定您是以最佳方式为着色器提供纹理坐标。您希望每个片段为点击的点获得相同的texcoord值,因此将它作为属性传递到GL并在顶点和片段阶段之间进行插值几乎没有意义。只需将其作为制服传递,并使用键值编码在材质上设置该制服。 (有关使用KVC绑定着色器参数的信息,请参阅SCNShadable reference again。)

最后,要了解问题的主要内容......:)

要在特定纹理坐标集处或附近更改片段着色器(或着色器修改器)的输出颜色,只需将传入的点击坐标与用于常规纹理的当前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