2

Our app lets users upload custom images to serve as materials for SCNNodes, as you can see from the screenshots and code below.

Screenshot 1 shows SCNNodes when the materials use a scale of 1.

Screenshot 2 shows the same nodes with a scale of 2.

While using a scale of 2 sharpens the texture/materials noticeably, it also repeats the image because of the wrapS and wrapT properties. Using Mirror or Clamp for these properties instead of Repeat did not help.

In SceneKit or UIKit, you supply an image of higher resolution and scale down to improve sharpness for different devices. For instance, for a 50x50 button, you supply a 100x100 image. You can see the contrast between UIKit sharpness and SceneKit sharpness for the same image by viewing the sharpness of the same images when rendered in UIKit components at the bottom.

1) How do you apply the same principle to SceneKit?

2) More importantly, how can you achieve the texture/material sharpness of screenshot 2 while avoiding the repeating behavior?

Code:

// Create box geometry
let box = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.0)
box.firstMaterial!.diffuse.contents = style.getContents() // This returns a UIImage
box.firstMaterial!.specular.contents = UIColor.whiteColor()

// Increase resolution for image styles
let scale = Float(2)
if style.type == .Image {
    box.firstMaterial!.diffuse.contentsTransform = SCNMatrix4MakeScale(scale, scale, scale)
    //box.firstMaterial!.locksAmbientWithDiffuse = true
    box.firstMaterial!.diffuse.wrapS = .Repeat
    box.firstMaterial!.diffuse.wrapT = .Repeat
    box.firstMaterial!.diffuse.mipFilter = .Linear
}

Textures:

enter image description here enter image description here enter image description here

Screenshot 1: enter image description here

Screenshot 2: enter image description here

Crashalot
  • 33,605
  • 61
  • 269
  • 439
  • Are you adding these images to the faces of geometry? eg are they the side of a cube or something similar? – Confused Sep 17 '16 at 13:21
  • Yes, the code is in the question. Will clarify the question, but the contents are getting set to a UIImage. – Crashalot Sep 17 '16 at 17:27
  • @Confused Also added the textures if you want to reproduce the boxes. – Crashalot Sep 17 '16 at 17:30
  • I think you need much bigger textures. No other way to get the sharpness, that I can think of. – Confused Sep 17 '16 at 17:58
  • @Confused Thanks. What size do we need? With SpriteKit and UIKit, it's easy to estimate the texture size because it relates to the size of the component (e.g., 100px image for 50px button for 2x resolution). – Crashalot Sep 17 '16 at 18:21
  • @Confused so a scale value of 1 is correct? Also could you post all this as an answer? – Crashalot Sep 17 '16 at 18:21
  • Sorry, have never used textures in geometry of SceneKit. How do you load them and apply them to your cubes? – Confused Sep 17 '16 at 19:02

1 Answers1

2

You'll need to think in terms of the actual pixels your images are going to take up on the screen, at the closest position to the camera, and with the greatest degree of perspective distortion.

So, by way of example, a cube close to the camera, on the left of the scene, might have an edge very near the "lens" of the camera, and be taking up (for example) much of the y axis (height) of the screen. If this is a common scenario, in your game, then aiming at guessing this size in (real) pixels will give you an idea of how big you need your texture for sharpness.

This is one of the reasons LOD (Level of Detail) functionality exists in 3D engines, so that not all the objects in a scene need to have the best, biggest quality texture on them all the time, nor the greatest number of polygons to express their shape.

There's also different types of texture processing algorithms in most 3D engines, for smoothing. Turning these off, if they exist in SceneKit, will be a big plus to getting sharp(er) textures, too.

Geometry Level of Detail

(not directly applicable to your request, but shows how this works)

https://developer.apple.com/reference/scenekit/scnlevelofdetail

Texture "Scaling" (mip mapping)

This is more applicable. This "trick" is really old, I remember it from the first 3D cards. It renders your texture smaller:

https://developer.apple.com/reference/scenekit/scnmaterialproperty/1395398-mipfilter

I read this as being wonderfully automatic, on second look:

From the above page:

"SceneKit automatically creates several mipmap levels for the material property’s image contents, each at a fraction of the original image’s size. When rendering, SceneKit automatically samples texels from the mipmap level closest to the size being rendered."

Confused
  • 6,048
  • 6
  • 34
  • 75
  • thanks so much! so does this mean we should not use Linear for the mipfilter since you said smoother textures will help yield sharper textures? so smoother is not a good thing for textures? – Crashalot Sep 17 '16 at 22:39
  • my reading of it tends to make me think you should have it on linear, but I don't know. Try it. Most things in Scene Kit work the way I expect them to. Some are completely confusing. – Confused Sep 17 '16 at 22:45
  • OK will try. Could you elaborate on you meant when you implied there is a negative relationship between smoothness and sharpness? – Crashalot Sep 17 '16 at 22:46
  • Also it doesn't seem like we misused the scale property, right (i.e., the repeating effect with scale of 2 is expected behavior)? If true, it means a scale of 1 should be used, at least for SCNBoxes. – Crashalot Sep 17 '16 at 23:14
  • smoothness (for pixels) will usually soften things, reducing sharpness. But I'm not sure we're talking about the same thing. On scaling, yes, 2 works right, but not something to use. Just leave it at 1. It's not the same as 2x and 3x graphics in 2D/UIKit etc. – Confused Sep 18 '16 at 07:35
  • OK cool. Could you please update the answer with this last comment (i.e., smoothness vs sharpness, scaling of 2 *will* cause repeating and is not a byproduct of incorrect configuration elsewhere) to help future readers? – Crashalot Sep 18 '16 at 21:39