Chango的数学Shader世界(二十三)漩涡Shader-复数分析(深渊)

23 篇文章 10 订阅
4 篇文章 0 订阅

目的:

我的2D游戏,需要一个有特定感觉的“漩涡shader”。

上一节里,我简单实现了这个:

但转动有些乏味,它的转动动作是类似这样的:

(网图)

接下来想让它动起来更加深邃,恐怖。本文先搞了2种效果:

(图3,扩散瞳孔)(图4,深渊)

抽象分析:

前篇的Shader效果之所以看起来乏味,是因为在旋转的时候,像素点的极长(以方块中心为原点极坐标系)并没有改变,只是越接近中心,

点的旋转量越小而已。

(旋转前后点都在同心圆上)

如果我想要深渊有“吃人”的感觉,那么内部的点就要往外转,有种瞳孔扩大的感觉

(图6,期望效果)

数学分析:

之前说过,涉及旋转,极坐标/复数往往比线代好,下面用复数推导。

设原先点在(u0,v0),复数为s_{0}e^{\theta _{0}},程序旋转缩放的变幻为s_{1}e^{-\theta _{1}}(顺时针转),当前点位置se^{\theta }

s_{0}e^{\theta _{0}} \cdot s_{1}e^{-\theta _{1}} = se^{\theta _}

可得:

s_{0} = \frac{s}{s1}=\frac{\sqrt{u^{2}+v^{2}}}{s1}

\theta _{0} = \theta +\theta _{1}

由于我们写到shader,输入是u,v,s1,theta1,输出是u0,v0。所以比较方便的是theta0就推导到这步,然后代入:

u_{0} =s_{0}\cdot cos(\theta_{0} )=s_{0}\cdot cos(\theta +\theta_{1} )=s_{0}\cdot (u/s\cdot cos(\theta _{1})-v/s\cdot sin(\theta _{1}))

v_{0} =s_{0}\cdot sin(\theta_{0} )=s_{0}\cdot sin(\theta +\theta_{1} )=s_{0}\cdot (v/s\cdot cos(\theta _{1})+u/s\cdot sin(\theta _{1}))

其中s = \sqrt{u^{2}+v^{2}}

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"深渊"的效果,可惜的是这种算法最后深渊底部总是会变黑,因为图片中心部分的像素有限。

 

结语

下次看看能否调整图片大小,或其他办法,让整个临场恐怖感加深。

使用复数在本篇里仅仅是符号简洁,易于推导,完全可以用极坐标。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值