Vulkan_顶点着色器特效6(二维扭曲)

47 篇文章 9 订阅
20 篇文章 6 订阅

前面几个案例都是在 3D 空间中对顶点位置进行的变换,但本次将给出一个在 2D 空间中基于顶点位置变换进行二维扭曲的案例。
在这里插入图片描述

一、基本原理

介绍本节案例的具体开发之前,首先需要了解二维扭曲的基本情况,如图所示。
在这里插入图片描述

从图中可以看出,左侧的原始三角形经过扭曲处理后产生了右侧奇异的形状,犹如一个风车。同时从图中可以看出,要想对原始三角形实现扭曲处理,必须将大三角形切分为很多小三角形。下面简单介绍扭曲的计算思路,具体步骤如下。
在这里插入图片描述

  • (1) 设扭动的中心点为点 O,其坐标为(X0,Y0);绕中心点被扭动的点为 D,其坐标为(X1,Y1)。
  • (2)设 D 点在 X 方向上的偏移为 XSpan, Y 方向上的偏移为 YSpan,则有以下结论。

在这里插入图片描述

  • (3)接着就可以求出 OD 与 X 轴正方向的夹角θ,具体情况如下。

  • 如果 XSpan=0,并且 YSpan 大于 0,那么θ = π /2。

  • 如果 XSpan=0,并且 YSpan 小于 0,那么θ =3 π /2。

  • 如果 XSpan 不等于 0,那么θ =atan(YSpan/ XSpan)。

  • (4)然后计算旋转后的 D 点与 X 轴正方向的夹角θ '。

在这里插入图片描述
其中 ratio 表示与当前总体旋转角度线性相关的一个系数,用于将距离转化为当前考察点的旋转角度(本案例中为-3.0~5.0,需自行根据项目设置)。

  • (5)计算出旋转后的夹角后,就可以求出旋转后点的 X、 Y 坐标了。

在这里插入图片描述

二、开发步骤

项目基础为之前的布料模拟项目,故着色器中的代码可能有些冗余,但主要部分已经标出:

顶点着色器如下:

#version 450

layout (location = 0) in vec3 inPos;
layout (location = 1) in vec2 inUV;
layout (location = 2) in vec3 inNormal;

layout (location = 0) out vec2 outUV;
layout (location = 1) out vec3 outNormal;
layout (location = 2) out vec3 outViewVec;
layout (location = 3) out vec3 outLightVec;


layout (binding = 0) uniform UBO 
{
	mat4 projection;
	mat4 modelview;
	vec4 lightPos;
	float ratio;//扭曲系数
	float centerX;//顶圆心x位置
	float centerY;//顶圆心y位置
} ubo;

out gl_PerVertex
{
	vec4 gl_Position;
};

void main () 
{
	
	float ratio = ubo.ratio;
	float pi = 3.1415926; //圆周率
	float centerX = ubo.centerX;//中心点的X坐标
	float centerY = ubo.centerY;//中心点的Y坐标
	float currX = inPos.x;//当前点的x坐标
	float currY = inPos.y;//当前点的y坐标
	float spanX = currX - centerX;//当前x偏移量
	float spanY = currY - centerY;//当前y偏移量
	float currRadius = sqrt(spanX * spanX + spanY * spanY);//计算距离
	float currRadians;//当前点与x轴正方向的夹角
	if(spanX != 0.0)
	{//一般情况
		currRadians = atan(spanY , spanX);
	}
	else
	{
		currRadians = spanY > 0.0 ? pi/2.0 : 3.0*pi/2.0; 
	}
	float resultRadians = currRadians + ratio*currRadius;//计算出扭曲后的角度
	float resultX = centerX + currRadius * cos(resultRadians);//计算结果点的x坐标
	float resultY = centerY + currRadius * sin(resultRadians);//计算结果点的y坐标
	//构造结果点,并根据总变换矩阵计算此次绘制此顶点的位置
	vec4 eyePos = ubo.modelview * vec4(resultX, resultY, inPos.z, 1.0); 
	

	outUV = inUV;
	outNormal = inNormal.xyz;
	gl_Position = ubo.projection * eyePos;
	vec4 pos = vec4(inPos, 1.0);
	vec3 lPos = ubo.lightPos.xyz;
	outLightVec = lPos - pos.xyz;
	outViewVec = -pos.xyz;		
}

我们也可以动态把圆心移动到布料一角,旋转可见如下效果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值