利用shader来实现飘扬的旗帜,同样可以实现水面起伏的效果.
说多无益,来看一张实现的美图,蔚蓝的天,还有那阵阵微风,水浪徐徐波动,动人心悸.
float ReturnY( VS_INPUT In ) { // --------------------- shader 1 ----------------------- // 设置比较点, float3 fZero = float3( 0.0 ,0.0 , 0.0 ); //振动值 float fScale = sin(1.40*distance(In.Position, fZero) - g_fTime * 5) + 1.5; //随距离衰减 float fY = -1.0 * exp( - fScale ) +1.0 ; //; return max( fY , -4.0 ); } VS_OUTPUT RenderSceneVS( VS_INPUT In ) { VS_OUTPUT Out = ( VS_OUTPUT )0; In.Position.y = ReturnY( In ); float4x4 matWorldView = mul( g_matWorld ,g_matView ); float4x4 matWorldViewProject = mul( matWorldView ,g_matProject ); Out.Position = mul( In.Position , matWorldViewProject ); Out.TextureUV = In.TextureUV; return Out; }
uniform mat4 uMVPMatrix; //总变换矩阵 uniform float uStartAngle;//本帧起始角度 uniform float uWidthSpan;//横向长度总跨度 attribute vec3 aPosition; //顶点位置 attribute vec2 aTexCoor; //顶点纹理坐标 varying vec2 vTextureCoord; //用于传递给片元着色器的变量 void main() { //计算X向角度 float angleSpanH=40.0*3.14159265;//横向角度总跨度,对波纹的X轴幅度有影响 float startX=0.0;//起始X坐标 //根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度 float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH; //计算出随z向发展起始角度的扰动值 float startZ=0.0;//起始z坐标 //根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度 float currAngleZ=((aPosition.z-startZ)/uWidthSpan)*angleSpanH; //计算斜向波浪 float tzH=sin(currAngleH-currAngleZ)*0.7; //根据总变换矩阵计算此次绘制此顶点位置 gl_Position = uMVPMatrix * vec4(aPosition.x,tzH,aPosition.z,1); // gl_Position = uMVPMatrix * vec4(aPosition,1); vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器 }