2013-09-05 5 views
6

ऐप्पल के दस्तावेज़ीकरण के अनुसार आप एसएसएनएमटेरियलप्रोपर्टी को बनावट प्रदान करने के लिए एनएससीओलर, एनएसआईमेज और कैलियर का उपयोग कर सकते हैं। SCNMaterialPropertyदृश्य के साथ मौजूदा ओपनजी बनावट का उपयोग

हालांकि मैं सोच रहा हूं कि मौजूदा ओपनजीएल बनावट प्रदान करने का कोई तरीका है, जिसे glGenTextures के साथ बनाया गया है और अलग से प्रस्तुत किया गया है।

मैं निश्चित रूप से बनावट के बफर, सेटअप एक NSImage पढ़ा है, और SCNMaterialProperty है कि एक प्रदान कर सकते हैं; लेकिन प्रदर्शन कारणों के लिए जो स्पष्ट रूप से इष्टतम नहीं है।

यह समझ बनाने के सामग्री मुझे लगता है की शेडर कार्यक्रम (रों) अधिभावी द्वारा ऊपर लागू करने के लिए होगा, लेकिन ऐसा करने के लिए दस्तावेज़ न के बराबर हो रहा है।

उत्तर

8

आप सामग्री के लिए एक SCNProgram बताए बनाकर शेडर कार्यक्रमों ओवरराइड कर सकते हैं। फिर SCNProgramDelegate के लिए प्रतिनिधि विधियों में से एक में आप बनावट (और अन्य वर्दी) के लिए अपने मूल्यों को बांध सकते हैं। हालांकि आप अपने खुद के शेडर्स लिखेंगे।

सेटअप का एक छोटा सा है, अगर आप ऑब्जेक्टिव-सी करने के लिए उपयोग किया जाता है लेकिन यह वास्तव में इतना जब आप इसी ओपन कोड के बारे में सोच नहीं है।

निम्नलिखित उदाहरण शेडर प्रोग्राम है जो एक ज्यामिति ऑब्जेक्ट की सतह पर बनावट को बांधता है। सादगी के लिए यह मानक और प्रकाश स्रोतों के साथ कोई छायांकन नहीं करता है।

ध्यान दें कि मैं नहीं जानता कि कैसे आप ऐसा कोड में अपने विशिष्ट बनावट बाँध नीचे मैं GLKit का उपयोग कर एक png पढ़ सकते हैं और है कि बनावट का उपयोग करना चाहते।

// Create a material 
SCNMaterial *material = [SCNMaterial material]; 

// Create a program 
SCNProgram *program = [SCNProgram program]; 

// Read the shader files from your bundle 
NSURL *vertexShaderURL = [[NSBundle mainBundle] URLForResource:@"yourShader" withExtension:@"vert"]; 
NSURL *fragmentShaderURL = [[NSBundle mainBundle] URLForResource:@"yourShader" withExtension:@"frag"]; 
NSString *vertexShader = [[NSString alloc] initWithContentsOfURL:vertexShaderURL 
                 encoding:NSUTF8StringEncoding 
                  error:NULL]; 
NSString *fragmentShader = [[NSString alloc] initWithContentsOfURL:fragmentShaderURL 
                  encoding:NSUTF8StringEncoding 
                  error:NULL]; 
// Assign the shades 
program.vertexShader = vertexShader; 
program.fragmentShader = fragmentShader; 

// Bind the position of the geometry and the model view projection 
// you would do the same for other geometry properties like normals 
// and other geometry properties/transforms. 
// 
// The attributes and uniforms in the shaders are defined as: 
// attribute vec4 position; 
// attribute vec2 textureCoordinate; 
// uniform mat4 modelViewProjection;  
[program setSemantic:SCNGeometrySourceSemanticVertex 
      forSymbol:@"position" 
      options:nil]; 
[program setSemantic:SCNGeometrySourceSemanticTexcoord 
      forSymbol:@"textureCoordinate" 
      options:nil]; 
[program setSemantic:SCNModelViewProjectionTransform 
      forSymbol:@"modelViewProjection" 
      options:nil]; 


// Become the program delegate so that you get the binding callback 
program.delegate = self; 

// Set program on geometry 
material.program = program; 
yourGeometry.materials = @[material]; 

इस उदाहरण में shaders अंत में ...bindValueForSymbol:... विधि के लिए कार्यान्वयन "yourTexture" वर्दी के लिए एक बनावट बाध्य करने के लिए के रूप में

// yourShader.vert 
attribute vec4 position; 
attribute vec2 textureCoordinate; 
uniform mat4 modelViewProjection; 

varying vec2 texCoord; 

void main(void) { 
    // Pass along to the fragment shader 
    texCoord = textureCoordinate; 

    // output the projected position 
    gl_Position = modelViewProjection * position; 
} 

और

// yourShader.frag 
uniform sampler2D yourTexture; 
varying vec2 texCoord; 

void main(void) { 
    gl_FragColor = texture2D(yourTexture, texCoord); 
} 

लिखा जाता है।

- (BOOL) program:(SCNProgram *)program 
bindValueForSymbol:(NSString *)symbol 
     atLocation:(unsigned int)location 
      programID:(unsigned int)programID 
      renderer:(SCNRenderer *)renderer 
{ 
    if ([symbol isEqualToString:@"yourTexture"]) { 
     // I'm loading a png with GLKit but you can do your very own thing 
     // here to bind your own texture. 
     NSError *error = nil; 
     NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"sampleImage" ofType:@"png"]; 
     GLKTextureInfo *texture = [GLKTextureLoader textureWithContentsOfFile:imagePath options:nil error:&error]; 
     if(!texture) { 
      NSLog(@"Error loading file: %@", [error localizedDescription]); 
     } 

     glBindTexture(GL_TEXTURE_2D, texture.name); 

     return YES; // indicate that the symbol was bound successfully. 
    } 

    return NO; // no symbol was bound. 
} 

इसके अलावा, डीबगिंग उद्देश्यों के लिए यह बहुत ही program:handleError: लागू करने के लिए किसी भी शेडर संकलन त्रुटियों

- (void)program:(SCNProgram*)program handleError:(NSError*)error { 
    // Log the shader compilation error 
    NSLog(@"%@", error); 
} 
+0

वाह, बहुत बहुत धन्यवाद! – simonfi

+2

अंत में इसके साथ खेलने का कुछ समय था, और बस आपको धन्यवाद देना चाहता था! एक छोटे टाइपो (एटेक्टेक्शंस वर्टेक्स शेडर में समन्वय) को छोड़कर यह पूरी तरह से काम करता है, और मेरे पिछले कार्यान्वयन की तुलना में बहुत तेज़ है जो हर समय एक नए एनएसआईमेज का उपयोग करके बनावट को बदलता रहता है। बस एक छोटा सा सवाल; आपने इसे कैसे समझ लिया? SceneKit के लिए प्रलेखन अब तक बहुत सीमित लगता है। – simonfi

1

आप सीधे ओपन से निपटने और अपने कस्टम बनावट बाध्य करने के लिए की जरूरत है तो SCNProgram या SCNNode के प्रतिनिधि जाना (MountainLion या अधिक) तरीके हैं। यदि आपके पास ऐप्पल डेवलपर खाता है तो आपको यहां एक नमूना कोड मिलेगा: http://developer.apple.com/downloads/ "डब्ल्यूडब्ल्यूडीसी 2013 नमूना कोड" के तहत। "OS_X_SceneKit_Slides_WWDC2013" के लिए देखो

+0

बाहर मुद्रित करने के लिए उपयोगी है दुर्भाग्य से आप अपने खुद के shaders की आपूर्ति करनी होगी। इसके अलावा, अपने आप में सीनकेट माउंटेन शेर और उच्च है;) –

+0

@ टोयोस आपका ईमेल पता क्या है? यदि आपको कोई फर्क नहीं पड़ता है तो आपको एक परियोजना के बारे में ईमेल करना चाहते हैं। – Crashalot

संबंधित मुद्दे