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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在纹理的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);
}

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

答案

首先,着色器不是绘制对象材质的唯一方法。另一个可能适合你的选择是使用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

以上是关于在纹理的SceneKit绘画与纹理坐标的主要内容,如果未能解决你的问题,请参考以下文章

片段着色器究竟如何用于纹理?

初识OpenGL (-)纹理(Texture)

初识OpenGL (-)纹理(Texture)

初识OpenGL (-)纹理(Texture)

openGL 纹理05

传递给片段着色器的纹理坐标全部为 0