2015-12-05 23 views
11

SceneKit ürününü karıştırmaya çalışıyorum ve kendime öğretiyorum. Temel olarak, 3 dikdörtgen kenarlı ve 1 eğimli kızağı olan bir dörtlü yaratıyorum.Özel Gölgelendirici SCNProgram iOS 9 Scenekit

Üzerine dokularımın yüzey boyunca gerilmesini ve çözülmesini/deforme olmasını istiyorum.

Bazı şeyleri çevrimiçi ortamda okumak, efekt almak için özel köşe ve parça gölgelendiricileri olan bir SCNProgram yapmam gerekiyor gibi görünüyor. Ancak, yüzeye yayılacak bir doku elde edemiyorum. Yardıma ihtiyacın var. (Bu yüzden grafik programlamada yeniyim, bunu kendime öğretmeye çalışıyorum). aşağıdaki gibi

My Swift kodu o geometri ve doku oluşturmak için:

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 

} 

My Vertex Shader:

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); 
} 

My parça gölgelendirici olup:

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)); 
} 

I Sadece alt soldaki doku yüzey boyunca yayılmış gibi görünmüyor. Lütfen yardım eder misiniz? bazı manuel köşe ve frag gölgelendirici jonglörlüğü yapmak

This is what is rendered when I run the code

, ben sonuç alabilir ama çok çirkin hissediyor ve bunun böyle spesifik kod yazarken edilmemelidir eminim. Ben arıyorum ama şeyler yapmanın çok yanlış şekilde hisseden tam olarak ne

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); 
} 

bana verir: (0.4 dörtlü üst eğimi olan) parça gölgelendirici

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); 
} 

Değişiklikler .

enter image description here

DÜZENLEME: texCoord olarak yerine texCoord ait pos değişken kullanıyorum :(Gerçekten anlayamıyorum cehennem sonuçları olarak bana garip veriyor

Ben değiştirmeye olsaydı aman. enter image description here

: aşağıda pic gibi bir şey olsun

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); 
} 

: parça gölgelendirici olarak

Doku koordine tanımımda yanlış bir şey olduğunu bana söylüyor ama ne olduğunu anlayamıyorum?

EDIT2: Tamam ilerleme. Şimdi

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

benim frag gölgelendiricideki texCoord kullandığınızda bana böyle bir sonuç verir:

enter image description here

Kilit altında yöntem kullanılarak benim UV'lerinizi yeniden ilgili parçacığı üzerinde verdi bir cevap dayanarak

Yukarıdaki dokuda gördüğüm kavisli deformasyonlar kadar iyi değil. Ama ilerlemesi.Herhangi bir fikir bu Massive soruda pic 2 gibi nasıl pürüzsüz hale getirebilirim?

Lütfen yardım edin.

+1

Güzel çalışma @AdiTheExplorer. Sadece sol üst doku koordinatını ayarlamanız gerekiyor, 0,1 yerine deformasyonu durdurmak için 0,0,6 (3/5) olacak. FWIW, doku koordinatlarını oluştururken kullandığınız kodda neyin yanlış olduğunu göremiyorum, ama açıkçası bununla ilgili bir şey doğru değildi. – lock

+1

Teşekkürler @lock. Ama aslında bu iplikteki 2 no.lu resimdeki gibi deforme olmasını ve dokuya girmesini istiyorum. 2 üçgen boyunca eşit olarak deforme olduğunda. Bu arada harika bir yardım aldınız. Onsuz yapamadım :) – AdiTheExplorer

+1

Yeterince adil. Bu durumda, muhtemelen çimdiklemek istediğiniz en üst sağ koordinattır, bu da bu y koordinatının daha da gerilmesini sağlar. Muhtemelen hala şekil 2'de gördüğünüz deformasyona sahip olmayacak, bu da doku koordinatlarını hesaplamak için sahip olduğunuz yaratıcı bir denklem. Muhtemelen uv'leri kullanarak bunu çoğaltabilirsiniz, şimdi tamamdırlar ('gl_FragColor = texture2D (SizinTexture, vec2 (texCoord.x, texCoord.y/(0.4 * texCoord.x)));' belki ...). AMA, genellikle doku görüntüsünüzde standart gölgelendiricilerin kullanımına izin veren deformasyon olur. – lock

cevap

7

parça gölgelendiricisinde, pos yerine texCoord kullanmak zorunda kalıyorsunuz.

Ayrıca, rasgele bir geometriyi biçimlendirmek için bir programa ihtiyacınız olmadığını unutmayın. Özel geometriler için düzenli malzeme kullanabilirsiniz. Düzenli bir malzemeyle mümkün olmayan bir şey yapmak isterseniz, gölgelendirici düzenleyicilere de bakabilirsiniz, programlardan daha kolaydır ve örneğin ışıkları elle tutmanızı gerektirmez.

+1

Bunu kullandım ama bana garip sonuçlar veriyor ... pos değişkeni daha iyi çalışıyor gibi görünüyor. TexCoord başlangıçta kod yazdı ve başarısız oldu :( – AdiTheExplorer

+2

Hala bu üzerinde sıkışmış :( – AdiTheExplorer