这是一款基于HTML5的3D水波动画特效,它的效果非常逼真的,我们可以按“ G”键来让水池中的石头上下浮动,按“ L”键添加灯光效果,设计相当完美。同时说明一下,这款3D水波动画是基于WebGL渲染技术的,大家可以了解一下WebGL。
在线预览 原始码下载
HTML代码
XML / HTML代码将内容复制到文本
< img id = “ tiles” src = “ tiles.jpg” >
< img id = “ xneg” src = “ xneg.jpg” >
< img id = “ xpos” src = “ xpos.jpg” >
< img id = “ ypos” src = “ ypos.jpg” >
< img id = “ zneg” src = “ zneg.jpg” >
< img id = “ zpos” src = “ zpos.jpg” >
JavaScript代码
JavaScript代码将内容复制到
函数 Water(){
var vertexShader = '/
变化的vec2坐标; /
void main(){/
坐标= gl_Vertex.xy * 0.5 + 0.5; /
gl_Position = vec4(gl_Vertex.xyz,1.0); /
} /
' ;
这个.plane = GL.Mesh.plane();
如果 (!GL.Texture.canUseFloatingPointTextures()){
抛出新的 错误(“此演示需要OES_texture_float扩展名” );
}
var filter = GL.Texture.canUseFloatingPointLinearFiltering()吗?gl.LINEAR:gl.NEAREST;
这个.textureA = 新的 GL.Texture(256,256,{类型:gl.FLOAT,过滤器:过滤器});
这个.textureB = 新的 GL.Texture(256,256,{类型:gl.FLOAT,过滤器:过滤器});
这个.dropShader = new GL.Shader(vertexShader, '/
const float PI = 3.141592653589793; /
均匀的sampler2D纹理; /
统一的vec2中心; /
均匀的浮动半径; /
均匀的浮力; /
变化的vec2坐标; /
void main(){/
/ *获取顶点信息* //
vec4信息= texture2D(纹理,坐标); /
/
/ *将下落添加到高度* //
浮动落差= max(0.0,1.0-长度(中心* 0.5 + 0.5-坐标)/半径); /
下降= 0.5-cos(下降* PI)* 0.5; /
info.r + =下降*强度; /
/
gl_FragColor = info; /
} /
' );
这个.updateShader = new GL.Shader(vertexShader, '/
均匀的sampler2D纹理; /
统一的vec2增量; /
变化的vec2坐标; /
void main(){/
/ *获取顶点信息* //
vec4信息= texture2D(纹理,坐标); /
/
/ *计算平均邻居身高* //
vec2 dx = vec2(delta.x,0.0); /
vec2 dy = vec2(0.0,delta.y); /
浮动平均值=(/
texture2D(纹理,坐标-dx).r + /
texture2D(纹理,坐标-dy).r + /
texture2D(纹理,坐标+ dx).r + /
texture2D(纹理,坐标+ dy).r /
)* 0.25; /
/
/ *更改速度以移向平均值* //
info.g + =(平均值-info.r)* 2.0; /
/
/ *稍微减弱速度,所以波浪不会永远持续* //
info.g * = 0.995; /
/
/ *沿速度移动顶点* //
info.r + = info.g; /
/
gl_FragColor = info; /
} /
' );
这个.normalShader = new GL.Shader(vertexShader, '/
均匀的sampler2D纹理; /
统一的vec2增量; /
变化的vec2坐标; /
void main(){/
/ *获取顶点信息* //
vec4信息= texture2D(纹理,坐标); /
/
/ *更新常规* //
vec3 dx = vec3(delta.x,texture2D(texture,vec2(coord.x + delta.x,coord.y))。r-info.r,0.0); /
vec3 dy = vec3(0.0,texture2D(纹理,vec2(coord.x,coord.y + delta.y))。r-info.r,delta.y); /
info.ba = normalize(cross(dy,dx))。xz; /
/
gl_FragColor = info; /
} /
' );
这个.sphereShader = new GL.Shader(vertexShader, '/
均匀的sampler2D纹理; /
统一的vec3 oldCenter; /
统一的vec3 newCenter; /
均匀的浮动半径; /
变化的vec2坐标; /
/
float volumeInSphere(vec3 center){/
vec3到Center = vec3(coord.x * 2.0-1.0,0.0,coord.y * 2.0-1.0)-中心; /
浮点t =长度(到中心)/半径; /
浮点dy = exp(-pow(t * 1.5,6.0)); /
浮点ymin = min(0.0,center.y-dy); /
浮点ymax = min(max(0.0,center.y + dy),ymin + 2.0 * dy); /
回报率(ymax-ymin)* 0.1; /
} /
/
void main(){/
/ *获取顶点信息* //
vec4信息= texture2D(纹理,坐标); /
/
/ *添加旧卷* //
info.r + = volumeInSphere(oldCenter); /
/
/ *减去新音量* //
info.r-= volumeInSphere(newCenter); /
/
gl_FragColor = info; /
} /
' );
}
Water.prototype.addDrop = 函数(x,y,半径,强度){
var this_ = this ;
这个.textureB.drawTo(function (){
this_.textureA.bind();
this_.dropShader.uniforms({
中心:[x,y],
半径:半径,
实力:实力
})。draw(this_.plane);
});
this .textureB.swapWith(this .textureA);
};
Water.prototype.moveSphere = 函数(旧中心,新中心,半径){
var this_ = this ;
这个.textureB.drawTo(function (){
this_.textureA.bind();
this_.sphereShader.uniforms({
oldCenter:oldCenter,
newCenter:newCenter,
半径:半径
})。draw(this_.plane);
});
this .textureB.swapWith(this .textureA);
};
Water.prototype.stepSimulation = function (){
var this_ = this ;
这个.textureB.drawTo(function (){
this_.textureA.bind();
this_.updateShader.uniforms({
增量:[1 / / this_.textureA.width,1 / / this_.textureA.height]
})。draw(this_.plane);
});
this .textureB.swapWith(this .textureA);
};
Water.prototype.updateNormals = function (){
var this_ = this ;
这个.textureB.drawTo(function (){
this_.textureA.bind();
this_.normalShader.uniforms({
增量:[1 / / this_.textureA.width,1 / / this_.textureA.height]
})。draw(this_.plane);
});
this .textureB.swapWith(this .textureA);
};
以上就是本文的全部内容,希望对大家的学习有所帮助。