顶点着色器的妙用,轻松实现WebGL2.0计算效果

2026-03-05 0 633

顶点着色器能让手机游戏画面实现过去想都不敢想的效果,比如让一面静态的旗帜变得像被风吹动一样自然,或者让水面产生逼真的波浪起伏。这种技术在ES 1.x时代几乎无法高效实现,而现在只需要几段巧妙的代码就能完成。

波浪运动的核心原理

要实现旗帜飘扬的效果,首先得把旗帜的模型做细。不能像以前那样只用两个三角形拼成一个矩形,而是要用大量的小三角形组成网格。这样顶点数量多了,才能通过改变每个顶点的位置来模拟飘动。

具体计算时采用正弦曲线来控制顶点位置。假设旗帜面向z轴正方向,原始状态下所有顶点的z坐标都是0。顶点着色器会根据每个顶点的x坐标计算出新的z值,让顶点在z轴方向上下振动,从而形成波浪。

计算过程其实不复杂。先算出当前顶点离最左边顶点的水平距离,把这个距离乘上一个转换系数变成角度值,再加上一个随时间变化的基础角度,最后对这个角度求正弦就得到了z坐标的偏移量。

三种不同方向的波浪效果

案例中实现了三种不同风格的波浪效果,让旗帜的飘动方式更加多样化。第一种是沿x轴方向传播的波浪,看起来就像风吹过旗帜时产生的横向波纹,这是最基础也最直观的效果。

第二种是斜向下方向的波浪,计算时不仅考虑x坐标,还把y轴方向的因素也加了进去。这样波浪就会沿着斜线方向传播,视觉效果更加丰富,有点像旗帜被风吹得斜着飘起来。

顶点着色器的妙用,轻松实现WebGL2.0计算效果

第三种是x和y两个方向的波浪叠加效果。先分别算出x方向波浪和y方向波浪在当前顶点产生的z坐标,然后把两个值加在一起。这样旗帜表面就会出现纵横交错的波纹,看起来更加自然真实。

密度参数控制波浪形态

顶点着色器里有一个变量专门用来控制波浪的密度。这个值调得越大,波浪的数量就越多,旗帜表面的起伏也就越频繁。开发者可以根据需要灵活调整,实现从微波荡漾到大浪翻涌的各种效果。

比如在模拟旗帜飘扬时,密度值可以设置得小一些,让波浪看起来舒展自然。如果是模拟水面效果,密度值就可以适当加大,表现出水面的细碎波纹。这种参数化的设计大大提高了技术的适用性。

纹理矩形的数据传递

为了能让顶点着色器正常工作,需要在Java代码中把起始角度和角度总跨度这些数据传进去。这些数据每帧都会变化,比如让起始角度在0到2π之间连续循环,这样旗帜就能一直飘动下去。

顶点着色器的妙用,轻松实现WebGL2.0计算效果

纹理矩形类的代码大部分和之前的案例相同,主要就是增加了传递这些参数的部分。具体的实现细节在光盘的源代码里都有,读者可以直接参考,不需要重新编写重复的代码。

片元着色器的纹理采样

三套顶点着色器对应的片元着色器是完全一样的,都是采用普通的纹理采样方式。这部分代码在很多前面的案例中都已经出现过,就是根据纹理坐标从旗帜贴图上取出对应的颜色值。

这样设计的好处是顶点着色器专注于处理位置变化,片元着色器负责表面颜色,分工明确。开发者只需要换不同的顶点着色器组合,就能快速实现多种不同的波浪效果。

真机运行的实际体验

由于书中的插图是灰度印刷,而且画面是静态的,很难完全展示出波浪的动态效果。强烈建议读者把案例代码放到真机上运行,这样才能真正感受到旗帜飘扬的流畅动画。

      1    uniform mat4 uMVPMatrix;                  //总变换矩阵
      2    uniform float uStartAngle;                //本帧起始角度(即最左侧顶点的对应角度)
      3    uniform float uWidthSpan;                 //横向长度总跨度
      4    attribute vec3 aPosition;                 //顶点位置
      5    attribute vec2 aTexCoor;                  //顶点纹理坐标
      6    varying vec2 vTextureCoord;               //用于传递给片元着色器的纹理坐标
      7    void main(){
      8       float angleSpanH=4.0*3.14159265;       //横向角度总跨度,用于进行 x距离与角度的换算
      9       float startX=-uWidthSpan/2.0;           //起始 x坐标(即最左侧顶点的 x坐标)
      10      //根据横向角度总跨度、横向长度总跨度及当前点 x坐标折算出当前顶点 x坐标对应的角度
      11      float currAngle=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
      12      float tz=sin(currAngle)*0.1;            //通过正弦函数求出当前点的 Z坐标
      13      //根据总变换矩阵计算此次绘制此顶点位置
      14      gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tz,1);
      15      vTextureCoord = aTexCoor;               //将接收的纹理坐标传递给片元着色器
      16   }

从左到右切换三种波浪模式,可以清楚看到x方向波浪的规整、斜向下波浪的变化以及双向波浪的复杂。这种动态效果在ES 1.x时代需要大量CPU计算才能勉强实现,现在用顶点着色器轻松搞定。

看了这三种波浪效果,你觉得在实际游戏开发中,哪种更适合用来表现水面,哪种更适合表现旗帜?欢迎在评论区分享你的看法,点赞转发让更多开发者看到这个实用的技术。

      1    uniform mat4 uMVPMatrix;                  //总变换矩阵
      2    uniform float uStartAngle;                //本帧起始角度(即最左侧顶点的对应角度)
      3    uniform float uWidthSpan;                 //横向长度总跨度
      4    attribute vec3 aPosition;                 //顶点位置
      5    attribute vec2 aTexCoor;                  //顶点纹理坐标
      6    varying vec2 vTextureCoord;               //用于传递给片元着色器的纹理坐标
      7    void main(){
      8       float angleSpanH=4.0*3.14159265;       //横向角度总跨度,用于进行X距离与角度的换算
      9       float startX=-uWidthSpan/2.0;           //起始 x坐标(即最左侧顶点的 x坐标)
      10      //根据横向角度总跨度、横向长度总跨度及当前点 X坐标折算出当前顶点 x坐标对应的角度
      11      float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
      13      float angleSpanZ=4.0*3.14159265;       //纵向角度总跨度,用于进行Y距离与角度的换算
      14      float uHeightSpan=0.75*uWidthSpan;     //纵向长度总跨度
      15      float startY=-uHeightSpan/2.0;          //起始 y坐标(即最上侧顶点的 y坐标)
      16      //根据纵向角度总跨度、纵向长度总跨度及当前点 y坐标折算出当前顶点 y坐标对应的角度
      17      float currAngleZ=((aPosition.y-startY)/uHeightSpan)*angleSpanZ;
      18      float tzH=sin(currAngleH-currAngleZ)*0.1;     //通过正弦函数求出当前点的 z坐标
      19      //根据总变换矩阵计算此次绘制此顶点的位置
      20      gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH,1);
      21      vTextureCoord = aTexCoor;                      //将接收的纹理坐标传递给片元着色器
      22   }

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

七爪网 行业资讯 顶点着色器的妙用,轻松实现WebGL2.0计算效果 https://www.7claw.com/2826470.html

七爪网源码交易平台

相关文章