SCNBox разного цвета или текстуры на каждой стороне

Я новичок в разработке iOS, и я зашел в тупик. Я пытаюсь визуализировать куб с помощью SceneKit, который имеет разные цвета для каждой грани.

Это то, что у меня есть до сих пор:

func sceneSetup() {
    // 1
    let scene = SCNScene()

    // 2
    let BoxGeometry = SCNBox(width: 0.9, height: 0.9, length: 0.9, chamferRadius: 0.0)

    BoxGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
    let cube = SCNNode(geometry: BoxGeometry)
    cube.position = SCNVector3(x: 0, y: 0, z: -1)
    scene.rootNode.addChildNode(cube)

    // 3
    sceneView.scene = scene
    sceneView.autoenablesDefaultLighting = true
    sceneView.allowsCameraControl = true

Но я бы хотел, чтобы у каждого лица был свой цвет. Как я могу это сделать?


person may19c19    schedule 16.12.2014    source источник


Ответы (3)


Коробка состоит из шести различных элементов (по одному с каждой стороны). Вы также могли заметить, что объект геометрии имеет одно свойство для первого материала, а также свойство для массива материалов.

Объект с несколькими элементами и несколькими материалами будет выбирать приращение материала (и обертки) для каждого элемента.

Например 4 элемента и 1 материал

Element   1  2  3  4
Material  1  1  1  1

или 4 элемента и 2 материала

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

Например 4 элемента и 7 материалов

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

В случае коробки это означает, что вы можете использовать массив из шести материалов, чтобы иметь уникальный материал на каждой стороне коробки. У меня есть пример этого в пример кода для одной из глав моей книги Scene Kit (в 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];
person David Rönnqvist    schedule 16.12.2014
comment
Отлично сделано, сэр! Стоит отметить еще одну вещь: со многими геометриями вы можете определить, сколько материалов она поддерживает, запросив ее geometryElementCount. Однако это не работает для SCNBox... он автоматически воссоздает свой набор элементов геометрии в зависимости от того, сколько материалов вы назначаете (таким образом, ему не нужно шесть вызовов отрисовки для рендеринга, если у него нет шести материалов). - person rickster; 16.12.2014
comment
Какая сторона какая (передняя, ​​правая, задняя, ​​левая, верхняя, нижняя)? - person Erik Aigner; 03.04.2016
comment
Я также хотел бы знать это ^ Хотя я также не уверен, как бы вы определили передний/правый/задний/левый/верхний/нижний... - person Ruben Martinez Jr.; 04.07.2017
comment
Дополнение к моему предыдущему комментарию: я никогда не говорил, что происходит, когда вы назначаете менее шести материалов. И у меня нет подробностей для каждого числа под рукой, но суть в том, что вы получаете примерно разумное распределение повторяющихся лиц. Например, если вы назначите три материала, вы получите материал для каждой пары противоположных граней. Два материала получают по три грани каждый. - person rickster; 02.08.2017
comment
@РубенМартинесДжр. Порядок массива определяет, какое лицо какое. Порядок должен быть таким же, как при указании карты куба для SCNMaterialProperty.contents: +х, -х, +у, -у, +з, -з. (Относительно зрителя в ориентации по умолчанию, это справа, слева, сверху, снизу, далеко, близко.) - person rickster; 02.08.2017
comment
Быстро преобразованный код для простоты: gist.github.com/mattrobmattrob/e934d664ef0fc8d45b7837d9eb797255 - person Matt Robinson; 31.08.2017
comment
@DavidRonnqvist Спасибо, что поделились этим! Это определенно лучше, чем создавать статические изображения текстур, когда все, что я хочу, это раскрасить стороны! - person Justin Ngan; 23.08.2020

Вот ответ Swift 4.

    let colors = [UIColor.green, // front
                  UIColor.red, // right
                  UIColor.blue, // back
                  UIColor.yellow, // left
                  UIColor.purple, // top
                  UIColor.gray] // bottom

    let sideMaterials = colors.map { color -> SCNMaterial in
        let material = SCNMaterial()
        material.diffuse.contents = color
        material.locksAmbientWithDiffuse = true
        return material
    }

    materials = sideMaterials

Чтобы изменить передний материал, просто возьмите материал и измените его содержимое.

let frontMaterial = materials[0]
frontMaterial.diffuse.contents = UIColor.white
person David    schedule 01.08.2017

спасибо за быструю помощь. я использовал код, который вы представили, но не смог использовать NSColor, поэтому я попробовал uicolor, но все, что я получил, это черный куб, поэтому я попробовал это, и у меня все заработало

    let BoxGeometry = SCNBox(width: 0.95, height: 0.95, length: 0.95, chamferRadius: 0.0)

    let greenMaterial = SCNMaterial()
    greenMaterial.diffuse.contents = UIImage(named: "g")
    greenMaterial.locksAmbientWithDiffuse = true;

    let redMaterial = SCNMaterial()
    redMaterial.diffuse.contents = UIImage(named: "r")
    redMaterial.locksAmbientWithDiffuse = true;


    let blueMaterial  = SCNMaterial()
    blueMaterial.diffuse.contents = UIImage(named: "b")
    blueMaterial.locksAmbientWithDiffuse = true;


    let yellowMaterial = SCNMaterial()
    yellowMaterial.diffuse.contents = UIImage(named: "y")
    yellowMaterial.locksAmbientWithDiffuse = true;


    let purpleMaterial = SCNMaterial()
    purpleMaterial.diffuse.contents = UIImage(named: "p")
    purpleMaterial.locksAmbientWithDiffuse = true;


    let WhiteMaterial = SCNMaterial()
    WhiteMaterial.diffuse.contents = UIImage(named: "w")
    WhiteMaterial.locksAmbientWithDiffuse   = true;


    BoxGeometry.materials =  [greenMaterial,  redMaterial,    blueMaterial,
    yellowMaterial, purpleMaterial, WhiteMaterial];

g - это jpeg зеленого цвета и так далее, и теперь это работает.

person may19c19    schedule 17.12.2014