Unity 3D: 实现可交互液晶屏幕

最近翻出了最初学习Unity的项目,似乎我当时在研究像素屏幕,但表现的效果很有限。现将其重新实现,并添加新的功能。


在开始之前,我先给出本文章的实现效果:

屏幕视差深度、凸面屏幕
视差
像素级缩放
在这里插入图片描述
自定义分辨率像素采样 图片大小限制,使用较低的GIF质量
像素化采样
RGB像素形状、LCD最低背光亮度、像素偏移

亮度、形状 像素偏移
背光 偏移

荧幕自发光亮度调整
自发光亮度
用户交互

交互 细节
在这里插入图片描述 画面交互


像素化采样

首先实现像素化采样,这是让屏幕从近距离看起来像液晶屏幕的基础。
我们需要提供两个参数:width/height分别表示横纵分辨率。
考虑一种极端情况,假设预期分辨率为2x2,也就是只有四个像素:
极端采样
方块内的每一个片段(片段着色器所渲染的单位),都应该显示本方块采样点的颜色(图中的红点)。
则每一个片段都需要知道自己的方块位于哪一个位置,进而根据方块位置计算采样点位置。如下图所示:
在这里插入图片描述
根据图中的逻辑,在连连看中实现采样点UV的计算方法
计算采样

输出
之后根据这个坐标,即可直接进行图像采样:

采样 输出
在这里插入图片描述 风景图

单像素边缘裁切

仔细观察输出结果,发现在方块边缘处会出现错误的颜色
错误颜色
首先需要明确,像素的显示时机是在显示三原色之前,因此每个像素之间需要存在一定间隙,这也是现实生活中的现象:
像素点间隙
因此我们不会去解决边缘错色的问题,取而代之的是直接裁切每个像素的边缘,使其相互间隔一段距离,而不是连接在一起。
首先我们计算每个像素方块到边缘处的距离,即边缘的SDF:
在这里插入图片描述
其算法是:
计算方式
首先使用减法和绝对值组合,使范围从(0,1)映射到(0.5,0)(0,0.5)
之后一个减法将范围从(0.5,0)(0,0.5)映射到(0,0.5)(0.5,0),使其恰好反映出到边缘的距离。
之后使用step函数,让最接近边缘的片段输出为1,其他部分输出为0

为了绘制出最细的线段,使用DDXY来实现标记最靠近边缘的片段
计算
效果

如果你对DDXY在这里的用法感到疑惑,在上一篇文章中,我解释了使用DDXY绘制单像素抗锯齿网格的原理_CNDS。通俗的讲,DDXY在这里的作用是获取每一个片段所占据的UV宽度。由此来裁切掉最靠近边缘的片段,同时确保了结果不会失真。
你可以按照上一篇文章的内容,将step换为smooth,以消除边缘锯齿,代价是牺牲部分性能。
在这里插入图片描述
消除锯齿

将结果的01值,对像素颜色使用乘法可以做到裁切像素的效果
裁切

动态裁切像素边缘

本节开始出现容易混淆的名词,在此先强调:
”屏幕像素“指的是真实的像素,是实体显示器上显示出来的像素。
“仿真像素”指的是我们模拟出来的虚假的仿真像素,是由多个屏幕像素组合而成。
”片段“指的是在Shader中,片段着色器的基本单位
没有开启多重抗锯齿时,片段屏幕像素是大小相等,一一对应的,本文建立在此基础之上。

现在存在一个问题:如果仿真像素分辨率极大,或摄像机距离较远,会导致大部分片段被当作仿真像素的边缘而裁切(因为最靠近边缘的片段始终被裁切,而整个仿真像素的宽度可能才只有3个片段)。
裁切
为了防止这类情况,需要在恰当时机显示边缘,而不是总是裁切。
我们希望当画面上的仿真像素屏幕像素更大时显示边缘,反之则裁切。

为了做到这一点,我们需要将仿真像素的UV宽度,与屏幕像素的UV宽度比较,并以此为权重显示对应的内容。

注意:不要试图使用摄像机位置作为影响因子来管理这一过程。因为摄像机位置无法反应出焦距、UV视差深度的变化。

计算因数

注意DDXY计算的结果是相较于前一个片段的差值,将其乘以二用于大致估算此片段的完整UV宽度。一个并不准确的示意图(此图仅为示意):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值