SceneKit, flip direction of SCNMaterial

狂风中的少年 提交于 2019-12-05 05:02:51
Toyos

Instead of scaling the node (which may break your lighting) you can flip the mapping using SCNMaterialProperty's contentsTransform property:

material.diffuse.contentsTransform = SCNMatrix4MakeScale(1,-1,1)
material.diffuse.wrapT = SCNWrapModeRepeat // or translate contentsTransform by (0,1,0)

To flip the image horizontally:

material.diffuse.contentsTransform = SCNMatrix4Translate(SCNMatrix4MakeScale(-1, 1, 1), 1, 0, 0)

to flip it vertically:

material.diffuse.contentsTransform = SCNMatrix4Translate(SCNMatrix4MakeScale(1, -1, 1), 0, 1, 0)

this worked for me, flipping the normal of the geometry by scaling the node it's attached to:

sphereNode.scale = SCNVector3Make(-1, 1, 1)

The accepted answer will not work, guaranteed. Following is how to flip an image that is assigned as the value of the [material].diffuse.contents property; it assumes that two cubes in the scene, side-by-side:

// Define the matrices that perform the two orientation variants
SCNMatrix4 flip_horizontal;
flip_horizontal = SCNMatrix4Translate(SCNMatrix4MakeScale(-1, 1, 1), 1, 0, 0);
SCNMatrix4 flip_vertical;
flip_vertical = SCNMatrix4Translate(SCNMatrix4MakeScale(1, -1, 1), 0, 1, 0);

// Create the material objects for each cube, and assign an image as the contents
self.source_material = [SCNMaterial material];
self.source_material.diffuse.contents = [UIImage imageNamed:@"towelface.png"];
self.mirror_material = [SCNMaterial material];
self.mirror_material.diffuse.contents = self.source_material.diffuse.contents;

Pick only one of the following sections (as defined by the comments):

// PortraitOpposingDown
    [self.mirror_material.diffuse setContentsTransform:SCNMatrix4Mult(self.source_material.diffuse.contentsTransform, flip_vertical)];
        [self.source_material.diffuse setContentsTransform:SCNMatrix4Mult(self.mirror_material.diffuse.contentsTransform, flip_horizontal)]; 

// PortraitFacingDown
    [self.source_material.diffuse setContentsTransform:SCNMatrix4Mult(self.source_material.diffuse.contentsTransform, flip_vertical)];
    [self.mirror_material.diffuse setContentsTransform:SCNMatrix4Mult(self.source_material.diffuse.contentsTransform, flip_horizontal)];

// PortraitOpposingUp
    [self.source_material.diffuse setContentsTransform:SCNMatrix4Mult(self.source_material.diffuse.contentsTransform, flip_horizontal)];

// PortraitFacingUp
    [self.mirror_material.diffuse setContentsTransform:SCNMatrix4Mult(self.source_material.diffuse.contentsTransform, flip_horizontal)];

Insert the material at the desired index:

[cube[0] insertMaterial:self.source_material atIndex:0];
[cube[1] insertMaterial:self.mirror_material atIndex:0];

By the way, to insert a new image (such as for live video), simply replace the material at the index specified by the insertMaterial:atIndex method; do not reorient the contentsTransform. The following code shows you how; it assumes that your video camera is configured to output a sample buffer for each frame it captures to an AVCaptureVideoDataOutputSampleBufferDelegate, and the requisite code (CreateCGImageFromCVPixelBuffer) to create a CGImage from a CVPixelBuffer:

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CGImageRef cgImage;
    CreateCGImageFromCVPixelBuffer(pixelBuffer, &cgImage);
    UIImage *image = [UIImage imageWithCGImage:cgImage];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.source_material.diffuse.contents = image;
        [cube[0] replaceMaterialAtIndex:0 withMaterial:self.source_material];
        self.mirror_material.diffuse.contents = self.source_material.diffuse.contents;
        [cube[1] replaceMaterialAtIndex:0 withMaterial:self.mirror_material];
        });
        CGImageRelease(cgImage);
}

If you'd like actual code instead of my assumptions of code on your end, please ask. Here's a short video showing this code in action, but with live video instead of a static image.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!