2017-01-21 9 views
1

私の実験では、シェーダー修飾子を使って、配列データをシェーダーに転送できないことがわかりました。私はSCNProgramを試してみることにしました。このためSCNFloorに影響しないSCNプログラム

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

。しかし、SCNProgramを使って追加したシェーダは、SCNFloorでは動作しません。

この問題が発生する特別な理由はありますか?

私がテストに使うスーパーシンプルなシェーダ。あなたはちょっと同じことを行うために、独自のヴェールとFRAGシェーダを作ってみることができます

頂点シェーダ

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

SCNFloorは「無限床」です。あなたの変換はそれを達成するつもりはないので、別の頂点シェーダが床で実行されていることを前提にすることができます。あなたはどんな結果が得られているか分かりません。しかし、それが動作するジオメトリがユニットクワッドであり、ちょうど4つの頂点、2つの三角形であり、このように変換することで、シーンの中心にある非常に限定された四角形にすることができます。別のシェーダは、これらの頂点が実際には無限に見えるようにするためにいくつかのテストや物事を行うことができます(水平線を持ち、すべてがクリップされません)。 – pailhead

+1

シーンキットを使用している他の人には驚くべきことです。私はそれに取り組んだ人々を含め、現在世界に10人のデベロッパーがいると思いますか? – pailhead

+0

ありがとう@pailhead。はい、私はそれに取り組んで以来、私はSceneKitについてとても寂しいと感じています。 :D はい、この種のプラットフォームに依存するフレームワークに時間を費やすのは良い考えではないかもしれません。しかし、IMHOは、使い慣れた迅速なシンタックスのシンタックスであり、SceneKitは楽しくて柔軟性があります。私はそれに取り組んでいる間、楽しい気分です。 そして、そうです、SCNFloorは無限幾何学であり、おそらく変換はそれに影響を与えません。しかし、少なくとも色を変える方法でなければなりません。 この問題に関連して、Apple DTSと連絡を取り、問題のサンプルプロジェクトファイルを送信しました。彼らが応答するときに私はここでそれを共有します。 – ytur

答えて

0

最後に、アップルデベロッパーのテクニカルサポートが私にこの問題について質問した質問に答えました。

ここに答えがあります。

残念ながら、フロアをシェードする方法はありません。 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 

} 

FRAG: (嫌なものを無視し、ポイントが平面と視線方向の線と交差することです、それをマップする、あなたは)それを捨てるのではなく、

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にあきらめ、自分自身に不満のTONを保存することです。

関連する問題