Scenekit Some Textures Have a Red Hue

SCNBox different colour or texture on each face

The box is composed out of six different elements (one for each side). You may also have noticed that a geometry object has one property for the first material but also a property for an array of materials.

An object with multiple elements and multiple materials will pick the increment the material (and wrap) for each element.

For example 4 elements and 1 material

Element   1  2  3  4
Material 1 1 1 1

or 4 elements and 2 materials

Element   1  2  3  4
Material 1 2 1 2 // note that they are repeating

For example 4 elements and 7 materials

Element   1  2  3  4
Material 1 2 3 4 // (5, 6, 7) is unused

In the case of the box this means that you can use an array of six materials to have a unique material on each side of the box. I have an example of this in the sample code for one of the chapters for my Scene Kit book (in Objective-C):

// Each side of the box has its own color
// --------------------------------------
// All have the same diffuse and ambient colors to show the
// effect of the ambient light, even with these materials.

SCNMaterial *greenMaterial = [SCNMaterial material];
greenMaterial.diffuse.contents = [NSColor greenColor];
greenMaterial.locksAmbientWithDiffuse = YES;

SCNMaterial *redMaterial = [SCNMaterial material];
redMaterial.diffuse.contents = [NSColor redColor];
redMaterial.locksAmbientWithDiffuse = YES;

SCNMaterial *blueMaterial = [SCNMaterial material];
blueMaterial.diffuse.contents = [NSColor blueColor];
blueMaterial.locksAmbientWithDiffuse = YES;

SCNMaterial *yellowMaterial = [SCNMaterial material];
yellowMaterial.diffuse.contents = [NSColor yellowColor];
yellowMaterial.locksAmbientWithDiffuse = YES;

SCNMaterial *purpleMaterial = [SCNMaterial material];
purpleMaterial.diffuse.contents = [NSColor purpleColor];
purpleMaterial.locksAmbientWithDiffuse = YES;

SCNMaterial *magentaMaterial = [SCNMaterial material];
magentaMaterial.diffuse.contents = [NSColor magentaColor];
magentaMaterial.locksAmbientWithDiffuse = YES;


box.materials = @[greenMaterial, redMaterial, blueMaterial,
yellowMaterial, purpleMaterial, magentaMaterial];

Image is shown as black and red colors only in ARKit

I solved it just using .jpg images. Yes just using jpg image instead of png.
I also reported this to Apple as a bug. They answered as that is a problem in 11.2 only with grayscale images with transparency. They fixed it in 11.3.

Image texture in SCNMaterial is always grey. How to apply color?

For future reference, here is what i found out:
Images shall not have the same name, even when saved in different groups or folders. I was using the name of the image as reference to load an overlay. When i changed the name and got the reference manually (by switch/case) everything works just fine.

Textures get a pink hue but only when displayed far away, or at some angle

This is a MipMap Bleeding issue, this usually happens in atlassed textures, when the textures in the atlas are too close to each other thus creating mipmap artefacts. This issue is usually sorted by adding some padding/dilation when creating an atlass.

Is there a way to use compressed textures with SceneKit background CubeMaps?

I found the solution. For anyone interested:

You can assign a Model IO texture to scnScene.background.contents
You can load a cube map Model IO texture using the function textureCubeWithImagesNamed:(Array of paths to 6 PVRTC compressed textures)

NSURL* posx = [artworkUrl URLByAppendingPathComponent:@"posx.pvr"]; 
NSURL* negx = [artworkUrl URLByAppendingPathComponent:@"negx.pvr"];
NSURL* posy = [artworkUrl URLByAppendingPathComponent:@"posy.pvr"];
NSURL* negy = [artworkUrl URLByAppendingPathComponent:@"negy.pvr"];
NSURL* posz = [artworkUrl URLByAppendingPathComponent:@"posz.pvr"];
NSURL* negz = [artworkUrl URLByAppendingPathComponent:@"negz.pvr"];

MDLTexture* cubeTexture = [MDLTexture textureCubeWithImagesNamed:@[posx.path,negx.path,posy.path,negy.path,posz.path,negz.path] ];
scnScene.background.contents = cubeTexture;

SceneKit issues applying texture to custom geometry

A single vertex can't have more than one texture coordinate. Since each vertex in a cube appears in a corner and is part of three different faces, you'll need to repeat the vertex data three times and match that up with the texture coordinates and then reference those with your indices.

Another way to look at it is that the same index that you're using to reference the vertex is also used to reference a texture coordinate, so since you only have 8 vertices, you'll only be able to reference the first 8 texture coordinates.

In one of the chapters from my book on SceneKit I create a custom cube geometry. Its texture coordinates display the complete texture on each face — so you'll have to change that part — but its indices should work for your cube as well:

// Indices that turn the source data into triangles
// ------------------------------------------------

int indices[] = {
// bottom
0, 2, 1,
1, 2, 3,
// back
10, 14, 11, // 2, 6, 3, + 8
11, 14, 15, // 3, 6, 7, + 8
// left
16, 20, 18, // 0, 4, 2, + 16
18, 20, 22, // 2, 4, 6, + 16
// right
17, 19, 21, // 1, 3, 5, + 16
19, 23, 21, // 3, 7, 5, + 16
// front
8, 9, 12, // 0, 1, 4, + 8
9, 13, 12, // 1, 5, 4, + 8
// top
4, 5, 6,
5, 7, 6
};

// Custom geometry data for a cube
// -------------------------------

SCNVector3 vertices[] = {
SCNVector3Make(-halfSide, -halfSide, halfSide),
SCNVector3Make( halfSide, -halfSide, halfSide),
SCNVector3Make(-halfSide, -halfSide, -halfSide),
SCNVector3Make( halfSide, -halfSide, -halfSide),
SCNVector3Make(-halfSide, halfSide, halfSide),
SCNVector3Make( halfSide, halfSide, halfSide),
SCNVector3Make(-halfSide, halfSide, -halfSide),
SCNVector3Make( halfSide, halfSide, -halfSide),

// repeat exactly the same
SCNVector3Make(-halfSide, -halfSide, halfSide),
SCNVector3Make( halfSide, -halfSide, halfSide),
SCNVector3Make(-halfSide, -halfSide, -halfSide),
SCNVector3Make( halfSide, -halfSide, -halfSide),
SCNVector3Make(-halfSide, halfSide, halfSide),
SCNVector3Make( halfSide, halfSide, halfSide),
SCNVector3Make(-halfSide, halfSide, -halfSide),
SCNVector3Make( halfSide, halfSide, -halfSide),

// repeat exactly the same
SCNVector3Make(-halfSide, -halfSide, halfSide),
SCNVector3Make( halfSide, -halfSide, halfSide),
SCNVector3Make(-halfSide, -halfSide, -halfSide),
SCNVector3Make( halfSide, -halfSide, -halfSide),
SCNVector3Make(-halfSide, halfSide, halfSide),
SCNVector3Make( halfSide, halfSide, halfSide),
SCNVector3Make(-halfSide, halfSide, -halfSide),
SCNVector3Make( halfSide, halfSide, -halfSide)
};

SCNVector3 normals[] = {
// up and down
SCNVector3Make( 0, -1, 0),
SCNVector3Make( 0, -1, 0),
SCNVector3Make( 0, -1, 0),
SCNVector3Make( 0, -1, 0),

SCNVector3Make( 0, 1, 0),
SCNVector3Make( 0, 1, 0),
SCNVector3Make( 0, 1, 0),
SCNVector3Make( 0, 1, 0),

// back and front
SCNVector3Make( 0, 0, 1),
SCNVector3Make( 0, 0, 1),
SCNVector3Make( 0, 0, -1),
SCNVector3Make( 0, 0, -1),

SCNVector3Make( 0, 0, 1),
SCNVector3Make( 0, 0, 1),
SCNVector3Make( 0, 0, -1),
SCNVector3Make( 0, 0, -1),

// left and right
SCNVector3Make(-1, 0, 0),
SCNVector3Make( 1, 0, 0),
SCNVector3Make(-1, 0, 0),
SCNVector3Make( 1, 0, 0),

SCNVector3Make(-1, 0, 0),
SCNVector3Make( 1, 0, 0),
SCNVector3Make(-1, 0, 0),
SCNVector3Make( 1, 0, 0),
};

CGPoint UVs[] = {
CGPointMake(0, 0), // bottom
CGPointMake(1, 0), // bottom
CGPointMake(0, 1), // bottom
CGPointMake(1, 1), // bottom

CGPointMake(0, 1), // top
CGPointMake(1, 1), // top
CGPointMake(0, 0), // top
CGPointMake(1, 0), // top

CGPointMake(0, 1), // front
CGPointMake(1, 1), // front
CGPointMake(1, 1), // back
CGPointMake(0, 1), // back

CGPointMake(0, 0), // front
CGPointMake(1, 0), // front
CGPointMake(1, 0), // back
CGPointMake(0, 0), // back

CGPointMake(1, 1), // left
CGPointMake(0, 1), // right
CGPointMake(0, 1), // left
CGPointMake(1, 1), // right

CGPointMake(1, 0), // left
CGPointMake(0, 0), // right
CGPointMake(0, 0), // left
CGPointMake(1, 0), // right
};


Related Topics



Leave a reply



Submit