2016-11-02 12 views
6

में अपरिवर्तना अनुकरण एक परियोजना के लिए आईओएस 9 ऐप बनाने की कोशिश कर रहा हूं जो glenses नामक इन विशेष प्रकार के सैद्धांतिक लेंस के साथ 3 डी दृश्यों को कल्पना करेगा।SceneKit

टीआईएम नामक एक रे ट्रेसिंग प्रोग्राम पहले से ही इन ग्लेशंस को और अधिक अनुकरण करने के लिए जमीन से लिखा गया है, लेकिन यह केवल आईओएस को बंद करने के लिए अक्षम है।

साइट को खोजने से मेरी समझ (यानी this उत्तर और शेडर्स पर कई अन्य) यह है कि यह संभव होना चाहिए लेकिन मुझे वांछित प्रभाव प्राप्त करने में कठिनाई हो रही है।

मैंने तय कर लिया है कि मैं पहली बार और अधिक जटिल Glens प्रकार अपवर्तन पर जाने से पहले अपवर्तन का एक सरल फार्म को लागू करने से शुरू होगा:

मैं एक बैरल विरूपण (मछली नेत्र लेंस) प्रभाव कैमरे पर काम कर पाने में सक्षम था SCNTechnique का उपयोग करते हुए, ऐसा लगता है कि आप केवल कैमरे या पूरे दृश्य पर तकनीक का उपयोग कर सकते हैं, न कि ज्यामिति के व्यक्तिगत टुकड़े।

var shaders = [SCNShaderModifierEntryPoint: String]() 

    try! shaders[SCNShaderModifierEntryPoint.fragment] = String(contentsOfFile: Bundle.main.path(forResource: "FishEye", ofType: "fsh")!, encoding: String.Encoding.utf8) 

    try! shaders[SCNShaderModifierEntryPoint.geometry] = String(contentsOfFile: Bundle.main.path(forResource: "FishEye", ofType: "vsh")!, encoding: String.Encoding.utf8) 

    let material = SCNMaterial() 
    material.shaderModifiers = shaders 
    object.geometry?.materials = [material] 

मैं थोड़ा संशोधित करते थे shaders here पाया:

fisheye.vsh

उसके बाद मैं SCNMaterial के shaderModifiers संपत्ति का उपयोग कर ओपन कोड इंजेक्शन लगाने के द्वारा बैरल विरूपण ज्यामिति के लिए आवेदन किया प्रभाव प्राप्त करने की कोशिश की

varying vec2 uv; 

#pragma body 

gl_Position = a_position; 
uv = a_position.xy; 

fisheye.fsh

uniform sampler2D colorSampler; 
const float PI = 3.1415926535; 
const float barrelPower = 0.5; 
uniform vec2 rg; 
uniform vec2 uv2; 
varying vec2 uv; 
uniform float d; 
uniform vec2 xy; 
uniform vec2 Vertex_UV; 

vec2 Distort(vec2 p) 
{ 
    float theta = atan(p.y, p.x); 
    float radius = length(p); 
    radius = pow(radius, barrelPower); 
    p.x = radius * cos(theta); 
    p.y = radius * sin(theta); 
    return 0.5 * (p + 1.0); 
} 

#pragma body 
#pragma transparent 

vec2 xy = 2.0 * Vertex_UV.xy - 1.0; 
vec2 rg = 2.0 * uv.xy - 1.0; 
vec2 uv2; 
float d = length(xy); 
if (d < 1.0){ 
    uv2 = Distort(xy); 
}else{ 
    uv2 = uv.xy; 
} 

gl_FragColor = texture2D(colorSampler, uv2); 

ये शेडर्स संकलित और दृश्य में मेरे ऑब्जेक्ट पर लोड हो गए हैं लेकिन कुछ भी नहीं; ऑब्जेक्ट अपारदर्शी और सफेद होता है जब यह इंजेक्शन वाले शेडर्स के बिना लगभग पारदर्शी होता है, और #pragma transparent निर्देश को इसे पारदर्शी बनाना चाहिए।

यह स्पष्ट करने के लिए, मैं यहां प्राप्त करने की कोशिश कर रहा हूं जिसमें एक दृश्य में 3 डी लेंस है जिसे आप देख सकते हैं और दूसरी तरफ जो भी हो, की अपवर्तित छवि देख सकते हैं।

किसी भी मदद की बहुत सराहना की जाएगी!

+0

क्या आप मुझे वांछित आउटपुट की छवियां दिखा सकते हैं? ग्लेन्स को प्रदान किया गया लिंक सिर्फ सैद्धांतिक है। मैं दृश्य हूँ – Confused

+0

आप वास्तव में प्रति नोड तकनीक नहीं कर सकते हैं, लेकिन हो सकता है कि आप "सामान्य" और अपवर्तन वाले लोगों को प्रस्तुत करने के लिए नोड को फ़िल्टर करने के लिए नोड श्रेणी बिटमैस्क का उपयोग कर सकें। इसलिए पास होने के कारण: [ड्रॉसेन (अपवर्तित ऑब्जेक्ट को छोड़कर), ड्रॉसेन (केवल अपवर्तित ऑब्जेक्ट + अपवर्तन के लिए कस्टम शेडर)] – Toyos

+0

@ कॉन्फ्यूज्ड यदि आप ग्लेन पेपर की सेक्शन 6 देखते हैं तो ऐसी चीज की कुछ छवियां हैं I मैं टीआईएम में प्रस्तुत करने की कोशिश कर रहा हूँ। लिंक संपादित किया गया है, इसलिए इसे सीधे आपको कागज के पीडीएफ में ले जाना चाहिए। – Cruthe93

उत्तर

2

यदि आप सीनकेट डिफ़ॉल्ट शेडर प्रोग्राम की बजाय अपने स्वयं के वर्टेक्स और खंड शेडर का उपयोग करना चाहते हैं, तो आपने SCNShaderModifierEntryPoint के बजाय एससीएनप्रोग्राम का भी उपयोग किया है।

एससीएनशैडरमोडिफायर एंटर्री पॉइंट्स केवल स्विफ्ट के डिफ़ॉल्ट शेडर प्रोग्राम को संशोधित करने की अनुमति दे रहे हैं।

let material = SCNMaterial() 
      let program:SCNProgram = SCNProgram() 
      do { 
       program.vertexShader = try String(contentsOfFile: Bundle.main.path(forResource: "fisheye", ofType: "vsh")!, encoding: String.Encoding.utf8) 
      } catch let error { 
       print("shaderReadingError:\(error)") 
      } 
      do { 
       program.fragmentShader = try String(contentsOfFile: Bundle.main.path(forResource: "fisheye", ofType: "fsh")!, encoding: String.Encoding.utf8) 
      } catch let error { 
       print("shaderReadingError:\(error)") 
      } 

    // and also your vertex shader has lack. 
    // You have to add some geometry source and transformation matrix to the vertex shader first with setSemantic method. 

      program.setSemantic(SCNGeometrySource.Semantic.vertex.rawValue, forSymbol: "vPosition", options: nil) 
      program.setSemantic(SCNGeometrySource.Semantic.texcoord.rawValue, forSymbol: "uv", options: nil) 
      program.setSemantic(SCNModelViewProjectionTransform, forSymbol: "uMVPMatrix", options: nil) 





    // and also your fragment shader expect some realtime data like 
    // colorSampler, rg, uv2, d, xy, Vertex_UV 
    // you have to use handleBinding block to update this values before rendering the object. 
      material.handleBinding(ofSymbol: "resolution", handler: { (programId:UInt32, location:UInt32, node:SCNNode?, renderer:SCNRenderer) in 


      }) 


      material.program = program 
      yourNode.geometry.firstMaterial = material 
संबंधित मुद्दे