之前光照demo的玻璃盒子边缘感觉太锐利了,于是想看看能不能让面的边缘逐渐变黑,这样应该会更接近于真实的拼接效果。
首先,玻璃盒子每个面的纹理采样坐标设定如下:
已知采样坐标范围是(0,0)~(1,1)这个矩形范围,现在我想把这个矩形范围的边缘弄成渐变黑色,换个说法可以变换为:构造一个比采样范围举行更小的矩形,例如宽高均为0.8,两个矩形同心,两个矩形之间的位置填充渐变的黑色。
但显然上图形式的向量实现起来没那么方便,如果向量的起点都在矩形的中心,那实现这个想法就方便得多。于是我把所有的向量都减去最大向量(1,1)的一半,即(0.5, 0.5),这样就可以将向量变换为:
那么内部的矩形叠加到上图就是如下所示:
从向量的角度来看,可以理解为每个向量从长度80%的位置开始逐渐填充为黑色即可。
具体逻辑,实际代码我换成从向量长度百分之90开始变黑,缩小一些黑边:
首先已知向量在遍历这个矩形的过程,要么x不变,y变化。要么y不变,x变化。因此:
0、将当前采样向量减去(0.5, 0.5),让它从中心开始发散。
1、首先通过normalize获取向量的方向,然后用1去除以它,分量中较小的那个值作为系数,去乘以normalize后的结果,即可得到同方向的、其中一分量为1的向量,再乘以0.5(因为实际变换后的向量最长长度只有0.5)。
2、再将当前采样向量长度 / 步骤1所得向量长度,判断是否已达90%位置,是的话通过smoothstep系数的作用,从0开始逐步接近1,再用1去减前述结果。
这样就实现了获取当前采样向量,并判断其是否到达同方向最大长度向量的90%,如达到后就逐步衰减颜色浓淡系数的目的。
具体代码如下:
vec2 fragVTexCoordInCenter = fragVTexCoord - vec2(0.5, 0.5); //采样点变换为以点(0,0)为原点
vec2 fragVTexCoordInCenterNor = normalize(fragVTexCoordInCenter); //当前采样变量的方向特征向量
vec2 times = abs(1.0 / fragVTexCoordInCenterNor); //求出如果让x要为单位1.0,要让fragVTexCoordInCenterNor.x乘以多少系数
vec2 uvInCenterMaxLen = min(times[0], times[1]) * fragVTexCoordInCenterNor * 0.5;
vec2 uvInCenter = fragVTexCoord - vec2(0.5, 0.5);
float edgeColorX = 1.0 - smoothstep(0.9, 1.0, distance(uvInCenter, vec2(0.0, 0.0)) / distance(uvInCenterMaxLen, vec2(0.0, 0.0)));
color = vec4(color.rgb * edgeColorX, color.a);
最后效果如图:
视频如下:
【OpenGL 毛玻璃盒子_通过片元shader的向量处理添加黑边】 OpenGL 毛玻璃盒子_通过片元shader的向量处理添加黑边_哔哩哔哩_bilibili