2017-03-09 77 views
3

我有一個從Blender導出的動畫模型(collada)。根據我的理解,着色器會在動畫過程中嘗試插入法線,並且我想防止發生這種情況。我的模型很笨重,但Scenekit使它像Apple產品一樣平滑。我希望它看起來像我的世界。Scenekit Shader - 關閉平滑着色和任何正常插值

回答

3

我假設你正在尋找一種類似於左下方所示的扁平陰影低聚類外觀。

Flat and smooth shaded

這個例子使用SCNSphere作爲幾何源,但它也應該在你從DAE文件中加載的幾何工作。

您加載的模型以及默認的SCNSphere由多個面組成。在光滑模型的情況下,頂點通常在面間共享,每個頂點只能有一個法線。我們需要做的是確保每個面不與相鄰面共享頂點,並且每個頂點上使用的法線僅根據面的法線方向計算。

SceneKit本身沒有任何本地功能,但是另一個Apple的框架不會...... ModelIO。

您需要導入ModelIO。

import ModelIO 
import SceneKit.ModelIO 

我用來生成上面兩個球體的代碼如下所示。

let geom = SCNSphere(radius: 0.5) 

// convert SceneKit geometry to ModelIO mesh object 
let modelMesh = MDLMesh(scnGeometry: geom) 
// ensure vertices are not shared with neighbouring faces 
modelMesh.makeVerticesUnique() 
// replace existing 'smooth' normal definition with an 'non-smoothed' normal 
modelMesh.addNormals(withAttributeNamed: "normal", creaseThreshold: 1.0) 

// create SceneKit geometry from ModelIO mesh object 
let flattenedGeom = SCNGeometry(mdlMesh: modelMesh) 
let flattenedNode = SCNNode(geometry: flattenedGeom) 
scene.rootNode.addChildNode(flattenedNode) 

// smooth sphere for comparison only 
let sphereNodeSmooth = SCNNode(geometry: SCNSphere(radius: 0.5)) 
sphereNodeSmooth.position = SCNVector3Make(0, 1.2, 0) 
scene.rootNode.addChildNode(sphereNodeSmooth) 

當然,我可能會建議您修改Blender的模型以這種方式出口的(唯一的頂點,非平滑法線)。這會使您的應用程序不必在加載資源時執行比所需更多的處理。不幸的是,我的Blender知識缺乏一些。

+1

如果希望每個面都是平坦的表面,這是一個很好的簡單方法,但請注意,如果您想要不是三角形的多邊形曲面,此方法雖然看起來很好,但也會生成比頂點更多的頂點它需要。此外,SceneKit有支持此功能的方法,但它需要使用GeometrySource進行法線處理,程序員需要做更多的工作。我會舉一個例子,如果我得到第二個。另請注意,如果您的幾何圖形具有常規來源,則將其轉換爲MDLMesh也將使用這些法線,並且您可能會丟失銳利邊緣。 – Ash