【Shader特效5】扭曲效果顶点着色器的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ModestBean/article/details/79171289

扭曲效果的实现

说在开始:

最近使用顶点着色器开发了一个扭曲的例子,在这里进行总结一些算法和开发过程。我都将我的代码放到了我的github上https://github.com/ModestBean/ShaderSample。本人的知识有限,如果本节内容有错误和不合理之处,还请朋友们多多指出,我会虚心接受每一个建议。
#####参考内容:

  • 《OpenGL ES 3.X 游戏开发 下卷》

运行效果

这里写图片描述
##基本原理
这里写图片描述
####前提:中心点坐标已知。
1、计算DF和OF,根据atan函数计算当前OD与X轴形成的角度θ。当θ为90度或者270度时还应该特殊处理,此时的tan值是无限大或者无限小的。
2、然后计算旋转后的角度,θ‘=θ+ratioOD。此时的ratio代表一个中间值,将OD的长度转换为距离。
3、最后计算旋转后的角度。对OD‘进行分解,X新=X原+OD
cos(θ);Y新=Y原+OD*sin(θ)
##代码部分

#version 400
#extension GL_ARB_separate_shader_objects : enable //开启separate_shader_objects
#extension GL_ARB_shading_language_420pack : enable //开启shading_language_420pack
layout (push_constant) uniform constantVals { //推送常量块
    mat4 mvp; //总变换矩阵
} myConstantVals;
layout (std140,set = 0, binding = 0) uniform bufferVals { //一致块
    float ratio; //旋转系数(整体扭动角度因子)
} myBufferVals;
layout (location = 0) in vec3 aPosition; //输入的顶点位置
layout (location = 1) in vec2 inTexCoor; //输入的纹理坐标
layout (location = 0) out vec2 outTexCoor; //输出到片元着色器的纹理坐标
out gl_PerVertex { //输出接口块
    vec4 gl_Position; //内建变量gl_Position
};
void main() {
    float pi = 3.1415926; //圆周率近似值
    float centerX=0.0; //中心点的X 坐标
    float centerY=-15; //中心点的Y 坐标
    float currX = aPosition.x; //当前点的X 坐标
    float currY = aPosition.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 + myBufferVals.ratio*currRadius; //计算出扭曲后的角度
    float resultX = centerX + currRadius * cos(resultRadians); //计算结果点的X 坐标
    float resultY = centerY + currRadius * sin(resultRadians); //计算结果点的Y 坐标
    outTexCoor = inTexCoor; //传输到片元着色器的纹理坐标
    gl_Position = myConstantVals.mvp * vec4(resultX,resultY,0.0,1.0); //计算顶点最终位置
}

当然,ratio的值是需要在适当的范围内变化的,我设置的变换范围为0–0.2~0.2,这个范围根据自己的需要去修改。
##最后:
本人的知识有限,如果本节内容有错误和不合理之处,还请朋友们多多指出,我会虚心接受每一个建议。

猜你喜欢

转载自blog.csdn.net/ModestBean/article/details/79171289
今日推荐