android opengl分屏,OpenGL ES分屏滤镜-静态分屏

news/2024/11/25 16:52:13/

静态分屏是指每一个屏幕的图像都完全一样。

分屏滤镜实现原理是在片元着色器中修改纹理坐标和纹理的对应关系。分屏之后,每个屏内纹理的对应关系都不一样。

这里我们用一种通用的方式来实现分屏滤镜,将屏数交由外部来控制。

预备知识

首先,我们来了解等一下会使用到的 GLSL 运算和函数。vec2 是二维向量类型,它支持下面的各种运算。

向量与向量的加减乘除(两个向量需要保证维数相同)

下面以乘法为例,其他类似。

vec2 a, b, c;

c = a * b;

复制代码

等价于

c.x = a.x * b.x;

c.y = a.y * b.y;

复制代码

向量与标量的加减乘除

下面以加法为例,其他类似。

vec2 a, b;

float c;

b = a + c;

复制代码

等价于

b.x = a.x + c;

b.y = a.y + c;

复制代码

向量与向量的 mod 运算(两个向量需要保证维数相同)

vec2 a, b, c;

c = mod(a, b);

复制代码

等价于

c.x = mod(a.x, b.x);

c.y = mod(a.y, b.y);

复制代码

向量与标量的 mod 运算

vec2 a, b;

float c;

b = mod(a, c);

复制代码

等价于

b.x = mod(a.x, c);

b.y = mod(a.y, c);

复制代码

着色器实现

有了上面的 GLSL 运算知识,来看下我们最终实现的片元着色器。

precision highp float;

uniform sampler2D inputImageTexture;

varying vec2 textureCoordinate;

uniform float horizontal; // (1)

uniform float vertical;

void main (void){

float horizontalCount = max(horizontal, 1.0); // (2)

float verticalCount = max(vertical, 1.0);

float ratio = verticalCount / horizontalCount; // (3)

vec2 originSize = vec2(1.0, 1.0);

vec2 newSize = originSize;

if (ratio > 1.0) {

newSize.y = 1.0 / ratio;

} else {

newSize.x = ratio;

}

vec2 offset = (originSize - newSize) / 2.0; // (4)

vec2 position = offset + mod(textureCoordinate * min(horizontalCount, verticalCount), newSize); // (5)

gl_FragColor = texture2D(inputImageTexture, position); // (6)

}

复制代码

(1) 我们最终暴露的接口,通过 uniform 变量的形式,从着色器外部传入横向分屏数 horizontal 和纵向分屏数 vertical 。

(2) 开始运算前,做了最小分屏数的限制,避免小于 1.0 的分屏数出现。

(3) 从这一行开始,是为了计算分屏之后,每一屏的新尺寸。比如分成 2 : 2,则 newSize 仍然是 (1.0, 1.0),因为每一屏都能显示完整的图像;而分成 3 : 2(横向 3 屏,纵向 2 屏),则 newSize 将会是 (2.0 / 3.0, 1.0),因为每一屏的纵向能显示完整的图像,而横向只能显示 2 / 3 的图像。

(4) 计算新的图像在原始图像中的偏移量。因为我们的图像要居中裁剪,所以要计算出裁剪后的偏移。比如 (2.0 / 3.0, 1.0) 的图像,对应的 offset 是 (1.0 / 6.0, 0.0) 。

(5) 这一行是这个着色器的精华所在,可能不太好理解。我们将原始的纹理坐标,乘上 horizontalCount 和 verticalCount 的较小者,然后对新的尺寸进行求模运算。这样,当原始纹理坐标在 0 ~ 1 的范围内增长时,可以让新的纹理坐标在 newSize 的范围内循环多次。另外,计算的结果加上 offset,可以让新的纹理坐标偏移到居中的位置。

下面简单演示一下每一步计算的效果,帮助理解:

31f61278ebfd7213bb02ef91b20fa057.png

(6) 通过新的计算出来的纹理坐标,从纹理中读出相应的颜色值输出。


http://www.ppmy.cn/news/334531.html

相关文章

电脑分屏没有声音_电脑分屏声音怎么分

首先,电脑无音看似简单,其实有时问题比较复杂,既涉及到硬件方面的问题又涉及到软件方面的问题 因此,要先查明原因,看是软件还是硬件出了故障,然后针对问题对症下药 千万不能原因不明,就乱捣一气,搞不好会把系统弄瘫痪,麻烦就大了 1、检查声卡、连接线,以及音箱等设备…

cmder 分屏

cmder 分成四屏 * -cur_console:ns1T50H -cur_console:C:"D:\Program Files\cmder_mini\icons\cmder.ico" "C:\WINDOWS\SYSTEM32\cmd.exe" /k ""%ConEmuDir%\..\init.bat" " >* -cur_console:ns2T50H -cur_console:C:"D:\P…

android6.0分屏插件,xposed分屏模块安卓6.0下载

安卓6.0系统分屏软件(xposed分屏插件)是一款支持分屏多任务软件,具有多窗口/双窗口功能,在众多智能分屏app中算是比较好用的啦,推荐给有需要的用户下载使用! 安卓6.0多窗口分屏软件简介 XHFW3在6.0下能用,很多以前的xp…

UISplitViewController 分屏控制器

为什么80%的码农都做不了架构师?>>> UIStoryboard(name: "Main", bundle: nil) 得到故事版文件对象 其中参数name是故事版的名字,可以中info.plist中查找或者就是Main.storyboard文件 1、建一个工程(single view appli…

VIM分屏的操作

在用vim编辑的时候,难免会涉及到分屏,分屏的主要操作如下 场景一: 同时打开两个文件,进行编辑 1. 同时打开两个文件 vim -o slam.py readme.md效果 2. 怎么把操作符从一个文件挪到另一个文件呢? ctrl w j/l 直…

vim编辑器---分屏操作

分屏操作 分屏操作: sp: 上下分屏,后可跟⽂件名 vsp: 左右分屏,后可跟⽂件名 Ctrww: 在多个窗⼝切换 启动分屏:使⽤⼤写O参数进⾏垂直分屏 $ vim -On file1 file2 …使⽤⼩写o参数进⾏⽔平分屏 $ vim -on file1 file2 … 注: n是数字,表示分屏的数量,n要⼤于等于⽂…

linux tmux 详细教程,Linux下的神器介绍之Tmux分屏器

前言 我们为什么需要分屏器呢? 对于这个问题,我想大家肯定都有自己的看法。 主流的观点是这样的,对于生活在Linux下的人(开发人员、运维人员、普通爱好者)都不可避免的使用终端模拟器(比如,gnome-terminal)去执行一些命令或者脚本…

vim编辑器-分屏

vim分屏显示 分屏启动vim使用大写的O来垂直分屏启动vim(n代表分为几个屏幕) vim -On file1 file2 使用小写的o来水平分屏启动vim(n代表分为几个屏幕) vim -on file1 file2 分屏上下分割打开当前的文件(同一个文件) ctrlw s &…