前一節(jié)分析了一部分官方項目瞧哟,包括如何引入Filament庫、如何使用Filament庫和Filament的渲染過程三個部分枪向。
Filament分析-從Android官方項目分析1
接下來接續(xù)分析Android中使用Filament勤揩。
一、初始化
//編舞者
choreographer = Choreographer.getInstance()
//利用UiHelper初始化渲染窗口
setupSurfaceView()
//初始化Filament秘蛔,包括engine/renderer/view/scene/camera
setupFilament()
//初始化view(filament的view陨亡,不是android的view)
setupView()
//初始化scene
setupScene()
初始化scene。
//加載渲染材質(zhì)
loadMaterial()
//設(shè)置渲染材質(zhì)
setupMaterial()
//初始化mesh
createMesh()
//生成材質(zhì)類深员,
private fun loadMaterial() {
readUncompressedAsset("materials/lit.filamat").let {
material = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
//由材質(zhì)類生成材質(zhì)實例
private fun setupMaterial() {
materialInstance = material.createInstance()
materialInstance.setParameter("baseColor", Colors.RgbType.SRGB, 1.0f, 0.85f, 0.57f)
materialInstance.setParameter("roughness", 0.3f)
}
在readUncompressedAsset()方法中负蠕,將生成的材質(zhì)文件lit.filamat轉(zhuǎn)換為ByteBuffer,傳遞給native層倦畅,native層又調(diào)用了NioUtils.h里的方法遮糖,將ByteBuffer轉(zhuǎn)換為byte[],而轉(zhuǎn)換方式又調(diào)用了java層的NioUtils類提供的方法叠赐。
設(shè)置材質(zhì)時欲账,提供了幾個參數(shù):
materialInstance = material.createInstance()
materialInstance.setParameter("baseColor", Colors.RgbType.SRGB, 1.0f, 0.85f, 0.57f)
materialInstance.setParameter("roughness", 0.3f)
其中baseColor和roughness是在lit.mat里設(shè)定的。
// List of parameters exposed by this material
parameters : [
// The color must be passed in linear space, not sRGB
{
type : float3,
name : baseColor
},
{
type : float,
name : roughness
},
{
type : samplerExternal,
name : videoTexture
},
{
type : mat4,
name : textureTransform
}
],
關(guān)于材質(zhì)之后會單獨分析芭概。
二赛不、Mesh
分析創(chuàng)建網(wǎng)格化的代碼:
private fun createMesh() {
val floatSize = 4
val shortSize = 2
// A vertex is a position + a tangent frame:
// 3 floats for XYZ position, 4 floats for normal+tangents (quaternion)
val vertexSize = 3 * floatSize + 4 * floatSize
....
}
filament的頂點由2個部分組成,位置和正切值(法線+正切組成的四元數(shù))谈山。
位置:x/y/z 三個float
正切:四元數(shù)俄删,4個float
為此,建立了一個頂點類Vertex奏路,并增加了ByteBuffer的臨時方法畴椰,存放頂點數(shù)據(jù)。
// Define a vertex and a function to put a vertex in a ByteBuffer
@Suppress("ArrayInDataClass")
data class Vertex(val x: Float, val y: Float, val z: Float, val tangents: FloatArray)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
v.tangents.forEach { putFloat(it) }
return this
}
為什么用法線+正切組成的四元數(shù)存儲頂點呢鸽粉?
這是用于切線空間Tangent Space用的斜脂,可以參考一下文章:
切線空間
法線紋理
接下來有多個api調(diào)用,包括VertexBuffer触机、IndexBuffer帚戳,都是渲染引擎里的概念玷或,可以參考OpenGL里的概念。
除了渲染材質(zhì)RenderableManager外片任,還用上了光照LightManager偏友、轉(zhuǎn)換TransformManager。
TransformManager is used to add transform components to entities.
LightManager allows to create a light source in the scene, such as a sun or street lights.