आप सामग्री के लिए एक 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);
}
स्रोत
2013-09-06 07:48:19
वाह, बहुत बहुत धन्यवाद! – simonfi
अंत में इसके साथ खेलने का कुछ समय था, और बस आपको धन्यवाद देना चाहता था! एक छोटे टाइपो (एटेक्टेक्शंस वर्टेक्स शेडर में समन्वय) को छोड़कर यह पूरी तरह से काम करता है, और मेरे पिछले कार्यान्वयन की तुलना में बहुत तेज़ है जो हर समय एक नए एनएसआईमेज का उपयोग करके बनावट को बदलता रहता है। बस एक छोटा सा सवाल; आपने इसे कैसे समझ लिया? SceneKit के लिए प्रलेखन अब तक बहुत सीमित लगता है। – simonfi