2014-09-30 2 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에 전달하고 정점과 조각 단계 사이에 보간하는 것이 중요하지 않습니다. 유니폼으로 전달하고 키 - 값 코딩으로 유니폼을 설정하십시오. (KVC와 쉐이더 매개 변수를 바인딩에 대한 정보에 대한 SCNShadable reference again를 참조하십시오.)

을 마지막으로, 귀하의 질문의 주요 지점에서 얻을 ...

:이 조각 쉐이더의 출력 색상을 변경 (또는 쉐이더 수정 자)를 특정 텍스처 좌표 세트에서 또는 근처에 배치하려면 전달 된 클릭 좌표를 일반 텍스처 조회에 사용되는 현재 텍 스코드 세트와 비교하십시오.

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 쉐이더 수정자를 사용하고 _surface.color.rgb 대신 GLSL 스 니펫 집합을 _output.color.rgb으로 설정하십시오.

+0

와우 ... 이것은 지금까지 최고의 정보입니다 ... 감사합니다. 이 정보를 가지고 최선을 다해 알려 드리겠습니다. – Vilois

+0

네 .. 고마워요 .... 일들이 훨씬 더 명확 해졌습니다. ..... shaderModifier를 추가했습니다. 위 코드를 약간 변경했으나 일반적으로 동일합니다 ..... 감사합니다. – Vilois

+0

@rickster 당신의 대답은 명확하고 내 문제를 해결하는 데 도움이 될 것이라고 생각했습니다.문제가 해결되지 않아 http://stackoverflow.com/questions/38999782/how-to-use-a-shadermodifier-to-alter-the-color-of-specific-triangles에 질문을 게시했습니다. 당신 자신 같은 사람이 도울 수 있기를 희망하면서 BTW, 당신이 제공 한 첫 번째 링크 "이 대답"은 실제로 동일한 "SCNShadable 참조"에 연결됩니다. 그것은 신중한 것입니다. 또한 마지막 메모에서 _surface.color를 언급하고 나는 당신이 _surface.diffuse를 의미한다고 생각합니다. – PKCLsoft