【EQ-R】在安卓中使用filament(sceneform)材质(二)

这篇具有很好参考价值的文章主要介绍了【EQ-R】在安卓中使用filament(sceneform)材质(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

EQ-R

简介

EQ-Renderer是EQ基于sceneform(filament)扩展的一个用于安卓端的三维AR渲染器。

主要功能

它包含sceneform_v1.16.0中九成接口(剔除了如sfb资源加载等已弃用的内容),扩展了视频背景视图、解决了sceneform模型加载的内存泄漏问题、集成了AREngine和ORB-SLAM3、添加了场景坐标与地理坐标系(CGCS-2000)的转换方法。

注:由于精力有限,文档和示例都不完善。sceneform相关请直接参考谷歌官方文档,扩展部分接口说明请移步git联系。

相关链接

Git仓库
  • EQ-Renderer的示例工程
码云
  • EQ-Renderer的示例工程
EQ-R相关文档
  • 文档目录

Filament材质

注:本节内容源于filament材质文档,更多详情请转至原链接查看。

相关文档

  • filament官方文档

  • sceneform自定义材质文档

  • 中文文档(Jerkwin译)

概述

Filament是一个基于物理的渲染(PBR)引擎, 用于Android. Filament提供了一个可定制的材质系统, 你可以用它来创建简单材质和复杂材质. 本文档介绍材质支持的所有功能以及如何创建自己的材质.

核心概念

材质: 材质定义了表面的视觉外观. 为完整描述和渲染表面, 材质提供以下信息:

  • 材质模型
  • 一组用户可控制的命名参数
  • 光栅状态(混合模式, 背面剔除等)
  • 顶点着色器代码
  • 片段着色器代码

材质模型: 也称 着色模型 或 光照模型, 材质模型定义表面的内在特性. 这些特性直接影响光照的计算方式, 从而影响表面的外观.

材质定义: 描述材质所需的所有信息的文本文件. 这是你可以直接编写以创建新材质的文件.

材质包: 在运行时, 从 材质包 中加载材质, 材质包是使用matc工具根据材质的定义编译得到的. 材质包含了描述材质所需的所有信息, 以及为目标运行时平台生成的着色器. 这是必要的, 因为不同的平台(Android, macOS, Linux等)使用不同的图形API, 或相似图形API的不同变体(例如OpenGL与OpenGL ES).

材质实例: 一个材质实例是对材质的引用, 以及对应该材质的不同参数的一组值. 本文档不包括材质实例, 因为可以直接使用Filament代码创建和操控它们。

材质模型

Filament支持以下材质模型:

  • 光亮(或标准)
  • 次表面
  • 布料
  • 无光亮
  • 镜面光泽(用于以前的模型)

材质定义

一个材质定义是描述材质所需的所有信息的一个文本文件:

  • 名称
  • 用户参数
  • 材质模型
  • 必需属性
  • 插值(称为 变量)
  • 光栅状态(混合模式等)
  • 着色器代码(片段着色器, 可选的顶点着色器)

材质编译

matc工具

可以使用名为matc的命令行工具从材质定义编译材质包. 使用matc的最简单的方法是, 指定一个输入材质定义(下面示例中的car_paint.mat)和一个输出材质包(下面示例中的car_paint.filamat):

matc.exe工具编译过程请参考在安卓中使用filament(sceneform)材质(一)。

matc -o ./materials/bin/car_paint.filamat ./materials/src/car_paint.mat
批量编译
  1. 在window电脑创建一个"genfilamat.bat"文件,使用编辑器打开,输入以下内容。
@echo off
if not exist out mkdir out
for /R %%G in (*.mat) do matc --optimize-size --platform=mobile -o "out\%%~nG.filamat" "%%G"

@echo off
echo success!
pause

  1. 将多个材质文件(*.mat) 拷贝至 “genfilamat.bat” 的同级目录。
  2. 运行 “genfilamat.bat” ,输出结果在同级目录的/out文件夹中。

材质调用

下文将通过一个材质示例,来讲述如何在【EQ-R】中调用filament材质实现法线贴图

编写材质

现要创建一个支持法线贴图的材质文件,步骤如下:

  1. 创建名为“eq_opaque_mat.mat”的文件
  2. 通过编辑器(记事本)打开mat文件,填写如下内容。
material {
    name : "EQ Opaque Mat",

    parameters : [
        {
           type : sampler2d,
           name : texture
        },
        {
           type : sampler2d,
           name : normalMap
        },
        {
           type : float,
           name : metallic
        },
        {
            type : float,
            name : roughness
        },
        {
            type : float,
            name : reflectance
        },
        {
            type : float4,
            name : emissive
        }
    ],
    requires : [
        position,
        uv0
    ],
    shadingModel : lit,
    blending : opaque
}
fragment {
    void material(inout MaterialInputs material) {
        // 获取切线空间中的法线,normal属性必须在prepareMaterial()前调用
        vec3 normal = texture(materialParams_normalMap, getUV0()).xyz;
        material.normal = normal * 2.0 - 1.0;
        prepareMaterial(material);
        //基色
        material.baseColor = texture(materialParams_texture, getUV0());
        //金属度
        material.metallic = materialParams.metallic;
        //粗糙度
        material.roughness = materialParams.roughness;
        //反射率
        material.reflectance = materialParams.reflectance;
        //自发光
        material.emissive = materialParams.emissive;
    }
}

上述的文本内容可以根据filament材质文档做修改,标准模型的材质参数范围和类型如下:

baseColor 基色 float4 [0…1] 预乘的线性RGB
metallic 金属度 float [0…1] 应为0或1
roughness 粗糙度 float [0…1]
reflectance 反射率 float [0…1] 首选值 > 0.35
clearCoat 涂层 float [0…1] 应为0或1
clearCoatRoughness 涂层粗糙度 float [0…1] 重新映射到[0…0.6]
anisotropy 各向异性度 float [−1…1] 当此值为正时, 各向异性位于切线方向
anisotropyDirection 各向异性方向 float3 [0…1] 线性RGB, 编码切线空间中的方向向量
ambientOcclusion 环境光遮蔽 float [0…1]
normal 法线 float3 [0…1] 线性RGB, 编码切线空间中的方向向量
clearCoatNormal 涂层法线 float3 [0…1] 线性RGB, 编码切线空间中的方向向量
emissive 自发光 float4 rgb=[0…1], a=[-n…n] Alpha为是曝光补偿
postLightingColor 后处理光照颜色 float4 [0…1] 预乘的线性RGB

编译材质

通过matc工具编译得到(“eq_opaque_mat.filamat”)文件

调用材质

以下内容均在AndroidStudio中操作,使用Java接口

  1. 将“eq_opaque_mat.filamat“文件拷贝至项目模块的/res/raw目录下(这里我在res目录下创建了名为raw的文件夹,创建其它名称也可,只要能通过资源ID找到这个文件即可)
  2. 编写代码调用材质。
        Bitmap normalMap = loadBitmapFromAsstes("MATERIALS/org_fur/normal.png");
        Bitmap srcBm = loadBitmapFromAsstes("MATERIALS/org_fur/basecolor.png");

        Material.builder()
                .setSource(context, LoadHelper.rawResourceNameToIdentifier(context, "eq_opaque_mat"))
                .build().thenAccept(new Consumer<Material>() {
                    @Override
                    public void accept(Material mat) {
                        material = mat;
                        material.setFloat("reflectance",0.1f);
                        material.setFloat("roughness",0.6f);
                        material.setFloat("metallic",0.0f);
                        Texture.builder()
                                .setSource(normalMap)
                                .build().thenAccept(new Consumer<Texture>() {
                                    @Override
                                    public void accept(Texture normalMapTexture) {
                                        material.setTexture("normalMap", normalMapTexture);
                                    }
                                });
                        Texture.builder()
                                .setSource(srcBm)
                                .build().thenAccept(new Consumer<Texture>() {
                                    @Override
                                    public void accept(Texture srcMapTexture) {
                                        material.setTexture("texture",srcMapTexture);
                                    }
                                });
                    }
                });

此外,之前的“eq_opaque_mat.filamat“文件也可以放于其它能访问到的路径。

通过以下方式进行访问。

Material.builder().setSource(this,Uri.fromFile(new File(path)));
  1. 修改材质参数

​ 在材质build之后,可以通过material.setXX相关方法动态地对参数进行修改。参数名为“编写材质”步骤中的“parameters”对应的name文章来源地址https://www.toymoban.com/news/detail-838710.html

材质示例

Opaque Colored

material {
    "name" : "Opaque Colored",

    "parameters" : [
        {
           "type" : "float3",
           "name" : "color"
        },
        {
           "type" : "float",
           "name" : "metallic"
        },
        {
            "type" : "float",
            "name" : "roughness"
        },
        {
            "type" : "float",
            "name" : "reflectance"
        },
        {
            "type" : "float4",
            "name" : "emissive"
        }
    ],
    "requires" : [
        "position",
        "uv0"
    ],
    "shadingModel" : "lit",
    "blending" : "opaque",
    doubleSided : true
}
fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor.rgb = materialParams.color;
        material.metallic = materialParams.metallic;
        material.roughness = materialParams.roughness;
        material.reflectance = materialParams.reflectance;
        material.emissive = materialParams.emissive;
    }
}

Opaque Textured

material {
    "name" : "Opaque Textured",

    "parameters" : [
        {
           "type" : "sampler2d",
           "name" : "texture"
        },
        {
           "type" : "float",
           "name" : "metallic"
        },
        {
            "type" : "float",
            "name" : "roughness"
        },
        {
            "type" : "float",
            "name" : "reflectance"
        },
        {
            "type" : "float4",
            "name" : "emissive"
        }
    ],
    "requires" : [
        "position",
        "uv0"
    ],
    "shadingModel" : "lit",
    "blending" : "opaque",
    doubleSided : true
}
fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor = texture(materialParams_texture, getUV0());
        material.metallic = materialParams.metallic;
        material.roughness = materialParams.roughness;
        material.reflectance = materialParams.reflectance;
        material.emissive = materialParams.emissive;
    }
}

Transparent Colored

material {
    "name" : "Transparent Colored",

    "parameters" : [
        {
           "type" : "float4",
           "name" : "color"
        },
        {
           "type" : "float",
           "name" : "metallic"
        },
        {
            "type" : "float",
            "name" : "roughness"
        },
        {
            "type" : "float",
            "name" : "reflectance"
        },
        {
            "type" : "float4",
            "name" : "emissive"
        }
    ],
    "requires" : [
        "position",
        "uv0"
    ],
    "shadingModel" : "lit",
    "blending" : "transparent"
}
fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor = materialParams.color;
        material.metallic = materialParams.metallic;
        material.roughness = materialParams.roughness;
        material.reflectance = materialParams.reflectance;
        material.emissive = materialParams.emissive;
    }
}

Transparent Textured

material {
    "name" : "Transparent Textured",

    "parameters" : [
        {
           "type" : "sampler2d",
           "name" : "texture"
        },
        {
           "type" : "float",
           "name" : "metallic"
        },
        {
            "type" : "float",
            "name" : "roughness"
        },
        {
            "type" : "float",
            "name" : "reflectance"
        },
        {
            "type" : "float4",
            "name" : "emissive"
        }
    ],
    "requires" : [
        "position",
        "uv0"
    ],
    "shadingModel" : "lit",
    "blending" : "transparent"
}
fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);
        material.baseColor = texture(materialParams_texture, getUV0());
        material.metallic = materialParams.metallic;
        material.roughness = materialParams.roughness;
        material.reflectance = materialParams.reflectance;
        material.emissive = materialParams.emissive;
    }
}

View

material {
    "name" : "View",
    "parameters" : [
        {
           "type" : "samplerExternal",
           "name" : "viewTexture"
        },
        {
            "type" : "float2",
            "name" : "offsetUv"
        },
        {
            "type" : "float4",
            "name" : "emissive"
        }
    ],
    "requires" : [
        "position",
        "uv0"
    ],
    "shadingModel" : "unlit",
    "blending" : "transparent",
    "doubleSided" : true
}

fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);

        vec2 uv = getUV0();

        if (!gl_FrontFacing) {
          uv.x = 1.0 - uv.x;
        }

        // Set offsetUv if we want to invert around an axis.
        // In front facing camera, set offsetUv.x to 1 and offsetUv.y to 0.
        uv.x = uv.x + materialParams.offsetUv.x * (1.0 - 2.0 * uv.x);
        uv.y = uv.y + materialParams.offsetUv.y * (1.0 - 2.0 * uv.y);

        material.baseColor = texture(materialParams_viewTexture, uv);
        material.baseColor.rgb = inverseTonemapSRGB(material.baseColor.rgb);
        material.emissive = materialParams.emissive;
    }
}

Camera

material {
    "name" : "Camera",

    "parameters" : [
        {
           "type" : "samplerExternal",
           "name" : "cameraTexture"
        }
    ],
    "requires" : [
        "uv0"
    ],
    "vertexDomain" : "device",
    "depthWrite" : false,
    "shadingModel" : "unlit",
    "doubleSided" : true
}
fragment {
    void material(inout MaterialInputs material) {
        prepareMaterial(material);

        vec4 color = texture(materialParams_cameraTexture, getUV0());
        material.baseColor.rgb = inverseTonemapSRGB(color.rgb);
    }
}

到了这里,关于【EQ-R】在安卓中使用filament(sceneform)材质(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 开发必备知识点及面试题汇总(Android+Java+算法+性能优化+四大组件……),腾讯安卓开发面试

    5.请介绍下 AsyncTask的内部实现,适用的场景是 AsyncTask 内部也是 Handler 机制来完成的,只不过 Android 提供了执行框架来提供线程池来 执行相应地任务,因为线程池的大小问题,所以 AsyncTask 只应该用来执行耗时时间较短的任务, 比如 HTTP 请求,大规模的下载和数据库的更改不

    2024年04月15日
    浏览(62)
  • 0003Java安卓程序设计-springboot基于Android的学习生活交流APP

    编程技术交流、源码分享、模板分享、网课教程 🐧裙:776871563 网络的广泛应用给生活带来了十分的便利。所以把学习生活交流管理与现在网络相结合,利用java技术建设学习生活交流APP,实现学习生活交流的信息化。则对于进一步提高学习生活交流管理发展,丰富学习生活交

    2024年02月05日
    浏览(48)
  • 使用WGCLOUD监测安卓(Android)设备的运行状态

    WGCLOUD是一款开源运维监控软件,除了能监控各种服务器、主机、进程应用、端口、接口、docker容器、日志、数据等资源 WGCLOUD还可以监测安卓设备,比如安卓手机、安卓设备等 我们只要下载对应的安卓客户端,部署运行即可,如下是下载链接 android(安卓)设备监测使用说明

    2024年02月15日
    浏览(37)
  • 使用ADB命令查询Android设备的安卓版本信息

    确保你已经安装了ADB并将其添加到系统的路径中。 连接你的Android设备到计算机,并确保启用了开发者选项和USB调试模式。你可以在设备的设置中找到这些选项。 打开终端(命令提示符或终端窗口)。 运行以下ADB命令来获取Android设备的安卓版本信息: 如果你希望获得更详细

    2024年02月08日
    浏览(41)
  • Android,ios,安卓app推送消息通知,java后台向手机推送app的通知教程

    个推是商用级的移动应用消息推送云服务供应商,客户端 SDK 支持 Android 和 iOS 两大平台,开发者集成 SDK 后,可以通过个推强大的 web 端及丰富的 API 开放接口,发送推送消息、统计分析推送效果。可有效提高 App 活跃度,增加用户留存率。 如果您还没有个推 账号,可在 个推

    2024年02月04日
    浏览(44)
  • QT搭建Android编译环境及使用安卓虚拟机调试

    QT是可以创建Android APP的,同时生成apk提供安装。 而为了编译和生成apk,就需要为QT添加对应的支持包。 一、Android环境支持包下载 1、JAVA SE8 JDK JAVA SE8 JDK是JAVA环境的支持包,Android APP通常使用JAVA区编写,但是使用QT可以直接用C/C++,其实是QT将C/C++自动转换为了JAVA,最后用的也

    2024年02月14日
    浏览(44)
  • 使用SSH远程连接安卓手机Termux - Android手机服务器

    转载自cpolar极点云的文章:公网SSH远程连接Termux – 电脑使用安卓Termux 「无需公网IP」 使用安卓机跑东西的时候,屏幕太小,有时候操作不习惯。不过我们可以开启ssh,使用电脑PC端SSH远程连接手机termux。 本次教程主要实现在安卓手机termux上安装SSH,在电脑上通过SSH远程连接

    2024年02月07日
    浏览(57)
  • Android Studio配置adb使用WIFI连接手机调试安卓程序

    安装adb参考:https://www.linmeimei.top/2023/03/02/flutter-adb 手机设置 打开开发者模式(用HUAWEI举例) 【设置】→【关于手机】→【版本号】→ 连续点击5次即可进入开发者模式 打开USB调试 【设置】→【系统和更新】→【开发人员选项】→开启【USB调试】开关→开启【\\\"仅充电\\\"模式下允许

    2024年02月04日
    浏览(52)
  • 公网使用SSH远程连接安卓手机Termux - Android手机服务器

    转载自cpolar极点云的文章:公网SSH远程连接Termux – 电脑使用安卓Termux 「无需公网IP」 使用安卓机跑东西的时候,屏幕太小,有时候操作不习惯。不过我们可以开启ssh,使用电脑PC端SSH远程连接手机termux。 本次教程主要实现在安卓手机termux上安装SSH,在电脑上通过SSH远程连接

    2024年02月07日
    浏览(45)
  • 在Android Studio上使用Monkey工具对安卓应用进行压力测试

    2–pct-trackball 调整轨迹事件的百分比(轨迹事件由一个或几个随机的移动组成,有时还伴随有点击)–(轨迹球) 3–pct-nav 调整“基本”导航事件的百分比(导航事件由来自方向输入设备的up/down/left/right组成) 4–pct-majornav 调整“主要”导航事件的百分比(这些导航事件通常引发图

    2024年04月15日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包