The problem background

I now want to write a 600m by 600m floor with SceneKit, the floor texture is as follows:

However, I ran into a problem that caused serious distortion if I assigned the texture directly as follows:

let geo = SCNPlane.init(width: 600, height: 600) geo.firstMaterial? .diffuse.contents = UIImage.init(named:"rustediron-streaks-albedo.png")Copy the code

After the above code runs, the floor will look like the Mosaic shown below:

solution

Because sceneKit related materials are few on the Internet, I directly read the official documents here, and found the following document after browsing:

After reading the official document, I have locked three attributes :1. Contentstransform 2, wrapT 3, and wrapS

At first, I thought it was very simple. I directly assigned wrapT and wrapS to reapeat mode, and then I found that the assignment did not work. Then I carefully observed the document and found a sentence: If you use the contentsTransform property to shrink a texture relative to the surface of a geometry, This means that winding only works if you use the ContentStransForm.

Contentstransform attribute

From the above figure, we can see that this matrix represents the mapping matrix of the texture map. We can change this matrix according to the size of the geometry to achieve the effect of matching the texture.

Going back to the problem I met earlier: I created a 600m plane, but the texture actually only fits the 6m floor, I can reduce the scope of the texture by 100 times, and then change wrapT and wrapS to repeat mode. Corresponding code:

geo.firstMaterial? .diffuse.contents = UIImage.init(named:"rustediron-streaks-albedo.png") let mat = SCNMatrix4Scale(SCNMatrix4Identity, 100, 100, 100) geo.firstMaterial? .diffuse.contentsTransform = mat geo.firstMaterial? .diffuse. WrapS =. Repeat // Must use geo. FirstMaterial with Content Transform? .diffuse.wrapT = .repeatCopy the code

Problem solving

After running the above code, you get something like this:

Contrast the floor of Mosaic form that just began, the effect was much better.

conclusion

You can use the ContentStransForm property of SCNMaterialProperty to do a lot of things, such as mirror inversion, texture rotation, etc. With the mode of wrapT and wrapS, you can solve a lot of 3D texture adaptation problems.