2015-12-05 9 views
11

मैं SceneKit में गड़बड़ करने की कोशिश कर रहा हूं और खुद को सिखाता हूं। असल में, मैं 3 आयताकार पक्षों और 1 ढलान वाली स्लाइड के साथ एक ट्रैक्टर बना रहा हूं।कस्टम शेडर एससीएनप्रोग्राम आईओएस 9 सीनेट

मैं चाहता हूं कि सतह पर फैलाएं और विकृत हो जाएं।

कुछ सामान ऑनलाइन पढ़ना, ऐसा लगता है कि मुझे प्रभाव प्राप्त करने के लिए कस्टम वर्टेक्स और खंड शेडर्स के साथ SCNProgram बनाना होगा। लेकिन, मुझे सतह पर फैलाने के लिए बनावट प्रतीत नहीं हो रही है। कृपया मदद की ज़रूरत है। (मैं ग्राफिक्स प्रोग्रामिंग के लिए नया हूं इसलिए इसे खुद को सिखाने की कोशिश कर रहा हूं)।

मेरे स्विफ्ट कोड ज्यामिति और बनावट बनाने के लिए इसका इस प्रकार है:

func geometryCreate() -> SCNNode { 

    let verticesPosition = [ 
     SCNVector3Make(0.0, 0.0, 0.0), 
     SCNVector3Make(5.0, 0.0, 0.0), 
     SCNVector3Make(5.0, 5.0, 0.0), 
     SCNVector3Make(0.0, 3.0, 0.0) 
    ] 
    let textureCord = [CGPoint (x: 0.0,y: 0.0), CGPoint(x: 1.0,y: 0.0), CGPoint(x: 1.0,y: 1.0), CGPoint(x: 0.0,y: 1.0)] 

    let indices: [CInt] = [ 
    0, 2, 3, 
    0, 1, 2 
    ] 

    let vertexSource = SCNGeometrySource(vertices: verticesPosition, count: 4) 
    let srcTex = SCNGeometrySource(textureCoordinates: textureCord, count: 4) 
    let date = NSData(bytes: indices, length: sizeof(CInt) * indices.count) 

    let scngeometry = SCNGeometryElement(data: date, primitiveType: SCNGeometryPrimitiveType.Triangles, primitiveCount: 2, bytesPerIndex: sizeof(CInt)) 

    let geometry = SCNGeometry(sources: [vertexSource,srcTex], elements: [scngeometry]) 
    let program = SCNProgram() 

    if let filepath = NSBundle.mainBundle().pathForResource("vertexshadertry", ofType: "vert") { 
     do { 
      let contents = try NSString(contentsOfFile: filepath, encoding: NSUTF8StringEncoding) as String 
      program.vertexShader = contents 
     } catch { 
      print("**** happened loading vertex shader") 
     } 
    } 


    if let fragmentShaderPath = NSBundle.mainBundle().pathForResource("fragshadertry", ofType:"frag") 
    { 
     do { 
     let fragmentShaderAsAString = try NSString(contentsOfFile: fragmentShaderPath, encoding: NSUTF8StringEncoding) 
     program.fragmentShader = fragmentShaderAsAString as String 
     } catch { 
      print("**** happened loading frag shader") 
     } 
    } 
    program.setSemantic(SCNGeometrySourceSemanticVertex, forSymbol: "position", options: nil) 
    program.setSemantic(SCNGeometrySourceSemanticTexcoord, forSymbol: "textureCoordinate", options: nil) 
    program.setSemantic(SCNModelViewProjectionTransform, forSymbol: "modelViewProjection", options: nil) 
    do { 
     let texture = try GLKTextureLoader.textureWithCGImage(UIImage(named: "stripes")!.CGImage!, options: nil) 

     geometry.firstMaterial?.handleBindingOfSymbol("yourTexture", usingBlock: { (programId:UInt32, location:UInt32, node:SCNNode!, renderer:SCNRenderer!) -> Void in 
       glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), Float(GL_CLAMP_TO_EDGE)) 
       glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), Float(GL_CLAMP_TO_EDGE)) 
       glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), Float(GL_LINEAR)) 
       glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), Float(GL_LINEAR)) 
       glBindTexture(GLenum(GL_TEXTURE_2D), texture.name) 
     }) 
    } catch { 
     print("Texture not loaded") 
    } 

    geometry.firstMaterial?.program = program 
    let scnnode = SCNNode(geometry: geometry) 
    return scnnode 

} 

मेरे वर्टेक्स शेडर है:

attribute vec4 position; 
attribute vec2 textureCoordinate; 
uniform mat4 modelViewProjection; 
varying highp vec2 pos; 
varying vec2 texCoord; 
void main() { 
    texCoord = vec2(textureCoordinate.s, 1.0 - textureCoordinate.t) ; 
    gl_Position = modelViewProjection * position; 
    pos = vec2(position.x, 1.0 - position.y); 
} 

मेरे टुकड़ा शेडर है:

precision highp float; 
uniform sampler2D yourTexture; 
varying highp vec2 texCoord; 
varying highp vec2 pos; 
void main() { 
    gl_FragColor = texture2D(yourTexture, vec2(pos.x, pos.y)); 
} 

मैं बस सतह पर फैले नीचे बाईं ओर बनावट बना नहीं लग रहा है। क्या आप मदद कर सकतें है?

This is what is rendered when I run the code

कुछ मैनुअल शीर्ष और frag शेडर करतब दिखाने करना, मैं परिणाम प्राप्त कर सकते हैं लेकिन यह बहुत असजीला लगता है और मैं बहुत यकीन है कि यह इस तरह विशिष्ट कोड लिखने नहीं होना चाहिए हूँ।

attribute vec4 position; 
attribute vec2 textureCoordinate; 
uniform mat4 modelViewProjection; 
varying highp vec2 pos; 

varying vec2 texCoord; 

void main() { 
    // Pass along to the fragment shader 
    texCoord = vec2(textureCoordinate.s, 1.0 - textureCoordinate.t) ; 

    // output the projected position 
    gl_Position = modelViewProjection * position; 
    pos = vec2(position.x, position.y); 
} 

टुकड़ा शेडर में किए गए परिवर्तन (जहां 0.4 ट्रैक्टर के शीर्ष की ढलान):

precision highp float; 
uniform sampler2D yourTexture; 
varying highp vec2 texCoord; 
varying highp vec2 pos; 


void main() { 

    gl_FragColor = texture2D(yourTexture, vec2(pos.x/5.0, 1.0 - pos.y/(3.0+0.4*pos.x))); 
// gl_FragColor = vec4 (0.0, pos.y/5.0, 0.0, 1.0); 
} 

कौन सा मुझे देता है मैं वास्तव में क्या देख रहा हूँ, लेकिन यह काम करने के बहुत गलत तरीके से लगता है ।

enter image description here

संपादित करें: मैं texCoord रूप texCoord के बजाय pos चर का उपयोग कर रहा मुझे नरक परिणाम जो मैं वास्तव में समझ में नहीं कर सकते, क्योंकि :(अजीब दे रहा है

अगर मैं संशोधित करने के लिए था मेरी। टुकड़ा शेडर के रूप में: enter image description here

:

precision highp float; 
uniform sampler2D yourTexture; 
varying highp vec2 texCoord; 
varying highp vec2 pos; 

void main() { 

// gl_FragColor = texture2D(yourTexture, vec2(pos.x/5.0, 1.0 - pos.y/(3.0+0.4*pos.x))); 
    gl_FragColor = texture2D(yourTexture, texCoord); 

// gl_FragColor = vec4 (0.0, pos.y/5.0, 0.0, 1.0); 
} 

मैं नीचे तस्वीर की तरह कुछ मिलता है

जो मुझसे कहता है कि मेरे बनावट में कुछ गड़बड़ है परिभाषा को निर्देशित करता है लेकिन मुझे पता नहीं लगा सकता कि क्या?

EDIT2: ठीक प्रगति।

let uvSource = SCNGeometrySource(data: uvData, 
      semantic: SCNGeometrySourceSemanticTexcoord, 
      vectorCount: textureCord.count, 
      floatComponents: true, 
      componentsPerVector: 3, 
      bytesPerComponent: sizeof(Float), 
      dataOffset: 0, 
      dataStride: sizeof(vector_float2)) 

अब जब मैं अपने frag शेडर में texCoord का उपयोग यह मुझे इस तरह एक परिणाम देता है::

enter image description here

एक जवाब है कि लॉक एक संबंधित धागा मैं अपने uvs नए सिरे से परिभाषित पर दिया नीचे विधि का उपयोग कर के आधार पर

यह ऊपर की बनावट में घुमावदार विकृतियों के रूप में महान नहीं है। लेकिन इसकी प्रगति।किसी भी विचार से मैं इस विशाल प्रश्न में तस्वीर 2 की तरह कैसे सुगम हो सकता हूं?

कृपया मदद करते हैं।

+1

अच्छा काम @AdiTheExplorer। विरूपण को रोकने के लिए आपको 0,1.6 (3/5) पर होने के बजाय, शीर्ष बाएं बनावट समन्वय को समायोजित करने की आवश्यकता है। एफडब्ल्यूआईडब्ल्यू, मुझे नहीं लगता कि आपके पास बनावट निर्देशांक उत्पन्न करने के लिए कोड के साथ क्या गलत है, लेकिन स्पष्ट रूप से कुछ इसके साथ बिल्कुल सही नहीं था। – lock

+1

धन्यवाद @lock। लेकिन मैं वास्तव में यह चाहता हूं कि यह थ्रेड में तस्वीर 2 में विकृत हो जाए ताकि यह वक्र बनावट में जा सके? जहां यह 2 त्रिकोणों में समान रूप से विकृत हो रहा है। आप रास्ते से एक बड़ी मदद कर चुके हैं। इसके बिना इसे नहीं किया जा सका :) – AdiTheExplorer

+1

पर्याप्त मेला। उस स्थिति में यह शायद शीर्ष दाएं समन्वय है जिसे आप ट्विक करना चाहते हैं, जिससे यह y समन्वय कम हो जाएगा। यह संभवतः आपको चित्र 2 में दिखाई देने वाली विरूपण नहीं देगा, यह एक रचनात्मक समीकरण है जिसे आपने बनावट निर्देशांक की गणना के लिए प्राप्त किया है। आप शायद यूवी के उपयोग से इसे दोहराना कर सकते हैं, अब वे ठीक हैं ('gl_FragColor = texture2D (yourTexture, vec2 (texCoord.x, texCoord.y/(0.4 * texCoord.x));' शायद ...)। लेकिन, आम तौर पर आपकी बनावट छवि में मानक शेडर्स के उपयोग की इजाजत देकर विरूपण होता है। – lock

उत्तर

7

खंड शतरंज में आपको के बजाय texCoord का उपयोग अपने बनावट का नमूना देने के लिए करना है।

यह भी ध्यान रखें कि आपको एक मनमानी ज्यामिति बनाने के लिए प्रोग्राम की आवश्यकता नहीं है। आप कस्टम ज्यामिति के लिए भी नियमित सामग्री का उपयोग कर सकते हैं। यदि आप नियमित सामग्री के साथ ऐसा कुछ नहीं करना चाहते हैं, तो आप शेडर संशोधक को भी देख सकते हैं, वे प्रोग्रामों से उपयोग करना आसान हैं और उदाहरण के लिए आपको मैन्युअल रूप से रोशनी को संभालने की आवश्यकता नहीं है।

+1

मैंने इसका इस्तेमाल किया लेकिन यह मुझे अजीब परिणाम देता है ... pos variable बेहतर काम करता प्रतीत होता है। TexCoord तब से है जब मैंने प्रारंभ में कोड लिखा और असफल रहा :( – AdiTheExplorer

+2

अभी भी इस पर अटक गया है :( – AdiTheExplorer