美文网首页
Google Filament学习-从Android官方项目分析

Google Filament学习-从Android官方项目分析

作者: Lucky胡 | 来源:发表于2019-11-25 16:07 被阅读0次

    前一节分析了一部分官方项目,包括如何引入Filament库、如何使用Filament库和Filament的渲染过程三个部分。
    Filament分析-从Android官方项目分析1

    接下来接续分析Android中使用Filament。

    一、初始化

    //编舞者
            choreographer = Choreographer.getInstance()
    //利用UiHelper初始化渲染窗口
            setupSurfaceView()
    //初始化Filament,包括engine/renderer/view/scene/camera
            setupFilament()
    //初始化view(filament的view,不是android的view)
            setupView()
    //初始化scene
            setupScene()
    

    初始化scene。

    //加载渲染材质
            loadMaterial()
    //设置渲染材质
            setupMaterial()
    //初始化mesh
            createMesh()
    
    //生成材质类,
        private fun loadMaterial() {
            readUncompressedAsset("materials/lit.filamat").let {
                material = Material.Builder().payload(it, it.remaining()).build(engine)
            }
        }
    
    //由材质类生成材质实例
        private fun setupMaterial() {
            materialInstance = material.createInstance()
            materialInstance.setParameter("baseColor", Colors.RgbType.SRGB, 1.0f, 0.85f, 0.57f)
            materialInstance.setParameter("roughness", 0.3f)
        }
    

    在readUncompressedAsset()方法中,将生成的材质文件lit.filamat转换为ByteBuffer,传递给native层,native层又调用了NioUtils.h里的方法,将ByteBuffer转换为byte[],而转换方式又调用了java层的NioUtils类提供的方法。

    设置材质时,提供了几个参数:

    materialInstance = material.createInstance()
    materialInstance.setParameter("baseColor", Colors.RgbType.SRGB, 1.0f, 0.85f, 0.57f)
    materialInstance.setParameter("roughness", 0.3f)
    

    其中baseColor和roughness是在lit.mat里设定的。

        // 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
            }
        ],
    

    关于材质之后会单独分析。

    二、Mesh

    分析创建网格化的代码:

        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个部分组成,位置和正切值(法线+正切组成的四元数)。
    位置:x/y/z 三个float
    正切:四元数,4个float

    为此,建立了一个顶点类Vertex,并增加了ByteBuffer的临时方法,存放顶点数据。

            // 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
            }
    

    为什么用法线+正切组成的四元数存储顶点呢?
    这是用于切线空间Tangent Space用的,可以参考一下文章:
    切线空间
    法线纹理

    接下来有多个api调用,包括VertexBuffer、IndexBuffer,都是渲染引擎里的概念,可以参考OpenGL里的概念。
    除了渲染材质RenderableManager外,还用上了光照LightManager、转换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.
    

    相关文章

      网友评论

          本文标题:Google Filament学习-从Android官方项目分析

          本文链接:https://www.haomeiwen.com/subject/pfrjwctx.html