2017-01-21 7 views
1

쉐이더 수정자를 사용한 나의 실험에서 배열 데이터를 쉐이더로 전송할 수 없다는 것을 알았습니다. 내가 SCNProgram을 바꾸기로했습니다 이러한 이유로SCNFloor에 영향을 미치지 않는 SCN 프로그램

Scenekit giving buffer size error while passing array data to uniform array in openGL shader

. 하지만 SCNProgram을 사용하여 추가 한 셰이더가 SCNFloor에서 작동하지 않는다는 것을 알았습니다.

이 문제가 발생하는 특별한 이유가 있습니까?

내가 테스트에 사용하는 슈퍼 간단한 쉐이더.

버텍스 쉐이더

precision highp float; 
attribute vec3 vertex; 
uniform mat4 ModelViewProjectionMatrix; 

void main() 
{ 
    gl_Position = ModelViewProjectionMatrix * vec4(vertex, 1.0); 
} 

조각 쉐이더 당신은 좀 같은 일을 자신의 버트와 파편 쉐이더를 만들기 위해 노력하고 있습니다

precision mediump float; 

void main(void) 
{ 
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); 
} 
+1

문서는 SCN 플로어가 '무한 플로어'라고 말합니다. 여러분의 변형은이를 달성하지 못하기 때문에 다른 버텍스 쉐이더가 바닥에서 실행되고 있다는 가정을 할 수 있습니다. 어떤 결과를 얻었는지 확실하지 않습니다. 그러나 그것이 작동하는 기하학이 단위 쿼드이며, 단지 4 개의 꼭지점과 2 개의 삼각형으로,이 방법으로 변환하면 장면의 중심에 매우 한정된 사각형으로 존재할 수 있습니다. 또 다른 셰이더는 이러한 정점이 실제로 무한처럼 보이도록 (즉, 수평선과 모든 것을 가지며 클리핑되지 않도록) 정점이 어디로 갈 것인지를 결정하기 위해 몇 가지 테스트와 자료를 사용할 수 있습니다. – pailhead

+1

장면 키트를 사용하는 다른 사람을 보는 데 놀랍습니다. 나는 세계에서 지금 일하는 사람들을 포함하여 10 명의 개발자가 있다고 믿는다. – pailhead

+0

감사합니다. @pailhead. 그렇습니다. SceneKit에 대해서도 너무 외로워졌습니다. : D 예, 아마도 이런 종류의 플랫폼 의존 프레임 워크와 시간을 보내는 것은 좋은 생각이 아닙니다.그러나 신속한 익숙한 구문 인 IMHO는 즐겁고 유연한 SceneKit입니다. 그 일을하는 동안 나는 재미 있다고 느낍니다. 그리고 여러분 말이 맞습니다. SCNFloor는 무한 기하학을 가지고 있으며 아마도 변형은 그것에 영향을 줄 수 없습니다. 그러나 적어도 색상을 변경하는 방법이어야합니다. 이 문제와 관련하여 Apple DTS와 통신하여 문제에 대한 샘플 프로젝트 파일을 보냈습니다. 그들이 대답 할 때 나는 그것을 여기에서 나눌 것이다. – ytur

답변

0

마지막으로 Apple 개발자 기술 지원부에서이 문제에 대해 질문했습니다.

여기에 답이 나와 있습니다.

불행하게도 바닥을 그늘지게하는 방법은 없습니다. SceneKit 팀은 SCNFloor가 이 SCNProgram과 함께 사용하지 않는 다른 종류의 객체임을 인정합니다. 또한, .fragment 쉐이더 엔트리 포인트를 사용하여 작동하지 않습니다 중 하나 (예 :

func setFragmentEntryPoint(_ node: SCNNode) { 

    print(#function + " setting fragment entry point for \(node)") 

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.milliseconds(2500)) { 

     let geometry = node.geometry! 

     let dict: [SCNShaderModifierEntryPoint:String] = [.fragment : 
      "_output.color = vec4(0.0, 1.0, 0.0, 1.0);"] 

     geometry.shaderModifiers = dict 


    } 
} 

이 동작을 고려 SceneKit 팀을 예상 할 수 있지만, 당신은 여전히 버그 리포트를 제출할 수있다이 경우에하는 것입니다 으로 API 개선 요청을 해석하십시오.

+0

혹시 게시 한 셰이더를 사용해 보셨습니까? – pailhead

+0

안녕하세요 @pailhead, 당신의 예를보고 고마워요.하지만 솔직히 저는 그것 때문에 아프고 SceneKit에서 쉐이더를 사용하려했습니다. 잠시 후, 그들은 위에서 보았 듯이 이미 질문에 대답했습니다. – ytur

1

. 나는 WebGL을/GLSL의 ES2와 비슷한 일을, 아니면 그냥 기존의 바닥 색조, 고체를 칠했습니다

uniform mat4 uCameraWM; //camera world matrix 
uniform vec2 uCamAspFov; //x:aspect ratio y:tan(fov/2) 


varying vec3 vVDw; //view direction 

void main(){ 

//construct frustum, scale and transform a unit quad 

vec4 viewDirWorld = vec4(
    position.x * uCamAspFov.x, 
    position.y, 
    -uCamAspFov.y, //move it to where 1:aspect fits 
    0. 
); 

vVDw = (uCameraWM * viewDirWorld).xyz; //transform to world 


gl_Position = vec4(position.xy , 0. , 1.); //draw a full screen quad 

} 

파편 : 합니다 (cruft에 무시 포인트는 비행기와 뷰 방향 선을 교차하는 것입니다 , 매핑, 당신은) 그것을 폐기하는 대신

uniform float uHeight; 


uniform sampler2D uTexDiff; 
uniform sampler2D uTexNorm; 
uniform sampler2D uTexMask; 

varying vec2 vUv; 

varying vec3 vVDw; 

struct Plane 
{ 
    vec3 point; 
    vec3 normal; 
    float d; 
}; 


bool rpi(in Plane p , in vec3 p0 , in vec3 vd , out vec3 wp) 
{ 

    float t; 

    t = -(dot(p0 , p.normal) + p.d)/dot(vd , p.normal); 

    wp = p0 + t * vd; 

    return t > 0. ? true : false; 

} 

void main(){ 


    Plane plane; 

    plane.point = vec3(0. , uHeight , 0.); 
    plane.normal = vec3(0. , 1. , .0); 
    plane.d = -dot(plane.point , plane.normal); 



    vec3 ld = normalize(vec3(1.,1.,1.)); 

    vec3 norm = plane.normal; 
    float ndl = dot(norm , ld) ; 



    vec2 uv; 
    vec3 wp; 
    vec3 viewDir = normalize(vVDw); 

    vec3 h = normalize((-viewDir + ld)); 

    float spec = clamp(dot(h , norm) , .0 , 1.); 

    // spec = pow(spec , 5.); 

    if(dot(plane.normal , cameraPosition) < 0.) discard; 

    if(!rpi(plane , cameraPosition , viewDir , wp)) discard; 

    uv = wp.xz; 

    vec2 uvm = uv * .0105; 
    vec2 uvt = uv * .2; 

    vec4 tmask = texture2D(uTexMask , uvm); 

    vec2 ch2Scale = vec2(1.8,1.8); 
    vec2 ch2Scale2 = vec2(1.6,1.6); 

    vec2 t1 = uvt * ch2Scale2 - vec2(tmask.z , -tmask.z) ; 
    // vec2 t2 = uvt * ch2Scale + tmask.z ; 
    // vec2 t3 = uvt + vec2(0. , mask.z-.5) * 1.52; 


    vec3 diffLevels = (texture2D(uTexDiff , t1)).xyz; 

    // vec3 diffuse2 = (texture2D(uTexDiff, fract(t1) * vec2(.5,1.) + vec2(.5,.0))).xyz; 
    // vec3 diffuse1 = (texture2D(uTexDiff, fract(t2) * vec2(.5,1.))).xyz; 


    // vec4 normalMap2 = texture2D(uTexNorm, fract(t1) * vec2(.5,1.) + vec2(.5,.0)); 
    // vec4 normalMap1 = texture2D(uTexNorm, fract(t2) * vec2(.5,1.)); 

    float diffLevel = mix(diffLevels.y, diffLevels.x, tmask.x); 
    diffLevel = mix(diffLevel , diffLevels.z, tmask.y); 

    // vec3 normalMix = mix(normalMap1.xyz, normalMap2.xyz, tmask.x); 


    // vec2 g = fract(uv*.1) - .5; 

    // float e = .1; 
    // g = -abs(g) + e; 

    float fog = distance(wp.xz , cameraPosition.xz); 

    // float r = max(smoothstep(0.,e,g.x) , smoothstep(0.,e,g.y)); 

    gl_FragColor.w = 1.; 

    gl_FragColor.xyz = vec3(tmask.xxx); 
    gl_FragColor.xyz = vec3(diffLevel) * ndl + spec * .5; 

} 

그러나 전체를 하늘 부분에 큐브 맵을 볼 수, 더 나은 조언은 scenekit에 포기하고 자신에게 좌절의 톤을 저장하는 것입니다.