大家好,又见面了,我是你们的朋友全栈君。
目的:
我的2D游戏,需要一个有特定感觉的“漩涡shader”。
上一节里,我简单实现了这个:
但转动有些乏味,它的转动动作是类似这样的:
(网图)
接下来想让它动起来更加深邃,恐怖。本文先搞了2种效果:
(图3,扩散瞳孔)(图4,深渊)
抽象分析:
前篇的Shader效果之所以看起来乏味,是因为在旋转的时候,像素点的极长(以方块中心为原点极坐标系)并没有改变,只是越接近中心,
点的旋转量越小而已。
(旋转前后点都在同心圆上)
如果我想要深渊有“吃人”的感觉,那么内部的点就要往外转,有种瞳孔扩大的感觉
(图6,期望效果)
数学分析:
之前说过,涉及旋转,极坐标/复数往往比线代好,下面用复数推导。
设原先点在(u0,v0),复数为,程序旋转缩放的变幻为(顺时针转),当前点位置
有
可得:
由于我们写到shader,输入是u,v,s1,theta1,输出是u0,v0。所以比较方便的是theta0就推导到这步,然后代入:
其中
Shader代码:
uniform sampler2D tex;
uniform float maxScale;
varying vec2 texCoord2D;
void main()
{
float pi = 3.1415926f;
float u = texCoord2D.x-0.5f;
float v = texCoord2D.y-0.5f;
float s = sqrt(u*u+v*v);
float scale = mix(1.0f,maxScale,s/0.707f);
//float scale = mix(maxScale,1.0f,s/0.707f);
float s0=s/scale;
float a = pi;
float u0 = s0*(u/s*cos(a)-v/s*sin(a));
float v0 = s0*(v/s*cos(a)+u/s*sin(a));
if(abs(u0)>0.5||abs(v0)>0.5)
{
discard;
}
vec2 uv0 = vec2(u0+0.5,v0+0.5);
gl_FragColor = texture(tex, uv0);
}
计算scale的时候,被注释的那行是图3,也就是上述“瞳孔方法”效果的算法,即越接近中心的点,越被发散到外面去。
我尝试互换了一下mix中的x,y值,让越远的点放得越大,出现了图4″深渊”的效果,可惜的是这种算法最后深渊底部总是会变黑,因为图片中心部分的像素有限。
结语
下次看看能否调整图片大小,或其他办法,让整个临场恐怖感加深。
使用复数在本篇里仅仅是符号简洁,易于推导,完全可以用极坐标。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/151188.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...