【Sceneform-EQR】scenefrom-eqr中的几种背景实现(不仅用于AR、三维场景,在图片、视频播放器中也适用)

本文主要是介绍【Sceneform-EQR】scenefrom-eqr中的几种背景实现(不仅用于AR、三维场景,在图片、视频播放器中也适用),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Sceneform-EQR

简介

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

相关链接

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

几种背景实现方式

示例工程

Sceneform-EQR

实现透明背景

代码样例

示例地址:Sceneform-EQR中BaseSceneActivity.java

安卓布局文件:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#1E4670"tools:context=".BaseSceneActivity"><TextViewandroid:textColor="#fff"android:textSize="24dp"android:layout_marginTop="20dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="EQ-Renderer"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><com.eqgis.eqr.layout.SceneLayoutandroid:id="@+id/base_scene_layout"android:layout_width="match_parent"android:layout_height="match_parent"/></androidx.constraintlayout.widget.ConstraintLayout>

Java接口调用:

外部直接调用setTransparent(true);即可实现背景透明

        sceneLayout = findViewById(R.id.base_scene_layout);sceneLayout.setTransparent(true);
注意事项

SurfaceView的问题

由于当前SceneView继承SurfaceView,而在SurfaceView中常见的设置透明背景会有的层级问题。这里也会存在。

使用setTransparent(true)后,SceneView被置顶

解决思路

SceneView修改为继承TextureView,可以规避SurfaceView的问题(PS:这里考虑性能,主版本代码已修改回SurfaceView)。

参考代码提交日志:

由于性能,改回使用surfaceView

使用扩展背景

这里需要时用ExSceneView类,参考如下即可实现,暂不放效果截图了。

最初的需求

之前有实现视频背景、图片背景的需求,曾在sceneview的discussions中提过我的实现思路。(链接)

当时,我创建了一个ExSceneView的类,实现扩展背景的功能。(现已集成至Sceneform-EQR)

图片背景样例
  1. 获取Externaltexture
ExSceneView sceneView = (ExSceneView) scene.getView();
externalTexture = sceneView.getExternalTexture();
  1. 在canvas中绘制Bitmap

如下,那么同理可以在cavans绘制其他内容,而不仅仅是绘制一张图片。

    private void loadStaticBackground(Bitmap bitmap) {int width = bitmap.getWidth();int height = bitmap.getHeight();externalTexture.getSurfaceTexture().setDefaultBufferSize(width,height);if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {Canvas canvas = externalTexture.getSurface().lockHardwareCanvas();canvas.drawBitmap(bitmap,new Matrix(),new Paint());externalTexture.getSurface().unlockCanvasAndPost(canvas);}bitmap.recycle();}
视频背景样例

通过上一个样例可知。我们还可以绘制其他内容。那么同理我们也可以获取externalTexture的surface,配合MediaPlayer,那么我们就可以实现播放视频背景。

  1. 获取Externaltexture
ExSceneView sceneView = (ExSceneView) scene.getView();
backgroundTexture = sceneView.getExternalTexture();
  1. 配合MediaPlayer使用

关键:mediaPlayer.setSurface(backgroundTexture.getSurface());

private void loadDynamicBackground() {ExSceneView sceneView = (ExSceneView) scene.getView();ExternalTexture backgroundTexture = sceneView.getExternalTexture();mediaPlayer = MediaPlayer.create(sceneView.getContext(),R.raw.bg_video);mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {@Overridepublic void onVideoSizeChanged(MediaPlayer mediaPlayer, int w, int h) {if (backgroundTexture != null) {backgroundTexture.getSurfaceTexture().setDefaultBufferSize(w,h);}}});mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mediaPlayer) {mediaPlayer.setSurface(backgroundTexture.getSurface());mediaPlayer.setLooping(true);mediaPlayer.start();}});}
颜色剔除

通过颜色剔除,我们可以在显示时过滤指定颜色值,从而达到类似抠图的效果。

  • 实现这个需要重写材质文件并编译。(之前写过材质使用的文档,这里不赘述。)

下面材质中samplerExternal类型,对应sceneform中的ExternalTexture类。keyColor属性名称对应的颜色即为要剔除的颜色值。

material {name : "Material",parameters : [{// 扩展纹理type : samplerExternal,name : texture},{// 要剔除的颜色值type : float4,name : keyColor}],requires : [ uv0 ],shadingModel : unlit,doubleSided : true,blending : masked
}fragment {vec3 desaturate(vec3 color, float amount) {vec3 gray = vec3(dot(vec3(0.2126, 0.7152, 0.0722), color));return vec3(mix(color, gray, amount));}void material(inout MaterialInputs material) {prepareMaterial(material);vec2 uv = getUV0();if (!gl_FrontFacing) {uv.x = 1.0 - uv.x;}vec4 color = texture(materialParams_texture, uv).rgba;vec3 keyColor = materialParams.keyColor.rgb;float threshold = 0.675;float slope = 0.2;float distance = abs(length(abs(keyColor - color.rgb)));float edge0 = threshold * (1.0 - slope);float alpha = smoothstep(edge0, threshold, distance);color.rgb = desaturate(color.rgb, 1.0 - (alpha * alpha * alpha));material.baseColor.a = alpha;material.baseColor.rgb = inverseTonemapSRGB(color.rgb);material.baseColor.rgb *= material.baseColor.a;}
}
颜色混合

通过颜色剔除,我们可以在显示时叠加某个颜色值(或者纹理),从而达到类似滤镜的效果。

material {name : "EQ Blend Mat for Camera",shadingModel : unlit,blending : opaque,parameters : [{type : samplerExternal,name : cameraTexture},{type : float4x4,name : uvTransform},{// 用于混合背景的颜色type : float4,name : blendColor}],requires : [uv0]
}fragment {void material(inout MaterialInputs material) {prepareMaterial(material);vec4 color = texture(materialParams_cameraTexture, getUV0()).rgba;vec4 bColor = materialParams.blendColor.rgba;color = mix(color, bColor, 0.2);material.baseColor.rgb = inverseTonemapSRGB(color.rgb);material.baseColor.a = 1.f;}
}vertex {void materialVertex(inout MaterialVertexInputs material) {material.uv0 = mulMat4x4Float3(materialParams.uvTransform, vec3(material.uv0.x, material.uv0.y, 0.f)).xy;vec4 clip = getPosition();clip.z = 0.99999f;material.worldPosition = mulMat4x4Float3(getWorldFromClipMatrix(), clip.xyz);}
} 

这篇关于【Sceneform-EQR】scenefrom-eqr中的几种背景实现(不仅用于AR、三维场景,在图片、视频播放器中也适用)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111667

相关文章

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont