이것은 HTML5를 기반으로 한 3D 물결 애니메이션 특수 효과입니다. 그 효과는 매우 사실적입니다. "G" 키를 누르면 수영장의 돌이 위아래로 뜨고, "L" 키를 누르면 됩니다. 조명 효과를 추가하세요. 디자인이 아주 완벽해요. 동시에 이 3D 물결 애니메이션은 WebGL 렌더링 기술을 기반으로 하므로 WebGL에 대해 배울 수 있습니다.
JavaScript 코드클립보드에 콘텐츠 복사
-
기능 물() {
-
var vertexShader = '
-
다양한 vec2 좌표;
-
void main() {
-
coord = gl_Vertex.xy * 0.5 0.5;
-
gl_Position = vec4(gl_Vertex.xyz, 1.0);
-
}
-
';
-
이것.plane = GL.Mesh.plane();
-
if (!GL.Texture.canUseFloatingPointTextures()) {
-
throw new 오류('이 데모에는 OES_texture_float 확장 프로그램이 필요합니다');
-
}
-
var 필터 = GL.Texture.canUseFloatingPointLinearFiltering() ? gl.LINEAR : gl.NEAREST;
-
이.textureA = new GL.Texture(256, 256, { 유형: gl.FLOAT, 필터: 필터 });
-
이것.textureB = new GL.Texture(256, 256, { 유형: gl.FLOAT, 필터: 필터 });
-
이.dropShader = new GL.Shader(vertexShader, '
-
const float PI = 3.141592653589793;
-
균일한 샘플러2D 텍스처;
-
유니폼 vec2 센터;
-
균일한 플로트 반경;
-
균일한 플로트 강도;
-
다양한 vec2 좌표;
-
void main() {
-
/* 정점 정보 가져오기 */
-
vec4 정보 = texture2D(texture, coord);
-
-
/* 높이에 드롭 추가 */
-
float drop = max(0.0, 1.0 - length(center * 0.5 0.5 - coord) / radius);
-
drop = 0.5 - cos(drop * PI) * 0.5;
-
info.r = 드롭 * 강도;
-
-
gl_FragColor = 정보;
-
}
-
');
-
이.updateShader = new GL.Shader(vertexShader, '
-
균일한 샘플러2D 텍스처;
-
균일한 vec2 델타;
-
다양한 vec2 좌표;
-
void main() {
-
/* 정점 정보 가져오기 */
-
vec4 정보 = texture2D(texture, coord);
-
-
/* 평균 이웃 높이 계산 */
-
vec2 dx = vec2(delta.x, 0.0);
-
vec2 dy = vec2(0.0, delta.y);
-
부동평균 = (
-
texture2D(texture, coord - dx).r
-
texture2D(texture, coord - dy).r
-
texture2D(texture, coord dx).r
-
texture2D(texture, coord dy).r
-
) * 0.25;
-
-
/* 평균을 향해 이동하도록 속도를 변경합니다.*/
-
info.g = (평균 - info.r) * 2.0;
-
-
/* 속도를 약간 약화시켜 파도가 영원히 지속되지 않도록 합니다.*/
-
info.g *= 0.995;
-
-
/* 속도에 따라 꼭지점 이동 */
-
info.r = info.g;
-
-
gl_FragColor = 정보;
-
}
-
');
-
이.normalShader = new GL.Shader(vertexShader, '
-
균일한 샘플러2D 텍스처;
-
균일한 vec2 델타;
-
다양한 vec2 좌표;
-
void main() {
-
/* 정점 정보 가져오기 */
-
vec4 정보 = texture2D(texture, coord);
-
-
/* 정상적으로 업데이트 */
-
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(texture, vec2(coord.x, coord.y delta.y)).r - info.r, delta.y);
-
info.ba = normalize(cross(dy, dx)).xz;
-
-
gl_FragColor = 정보;
-
}
-
');
-
이.sphereShader = new GL.Shader(vertexShader, '
-
균일한 샘플러2D 텍스처;
-
uniform vec3 oldCenter;
-
uniform vec3 newCenter;
-
균일한 플로트 반경;
-
다양한 vec2 좌표;
-
-
float volumeInSphere(vec3 center) {
-
vec3 toCenter = vec3(coord.x * 2.0 - 1.0, 0.0, coord.y * 2.0 - 1.0) - center;
-
float t = 길이(중심까지) / 반경;
-
float dy = exp(-pow(t * 1.5, 6.0));
-
float ymin = min(0.0, center.y - dy);
-
float ymax = min(max(0.0, center.y dy), ymin 2.0 * dy);
-
반품(ymax - ymin) * 0.1;
-
}
-
-
void main() {
-
/* 정점 정보 가져오기 */
-
vec4 정보 = texture2D(texture, coord);
-
-
/* 이전 볼륨 추가 */
-
info.r = volumeInSphere(oldCenter);
-
-
/* 새 볼륨 빼기 */
-
info.r -= volumeInSphere(newCenter);
-
-
gl_FragColor = 정보;
-
}
-
');
-
}
-
-
Water.prototype.addDrop = 함수(x, y, 반경, 강도) {
-
var this_ = this;
-
이.textureB.drawTo(함수() {
-
this_.textureA.bind();
-
this_.dropShader.uniforms({
-
중앙: [x, y],
-
반경: 반경,
-
강도: 강도
-
}).draw(this_.plane);
-
});
-
이것.textureB.swapWith(이것.textureA);
-
};
-
-
Water.prototype.moveSphere = 함수(oldCenter, newCenter, radius) {
-
var this_ = this;
-
이.textureB.drawTo(함수() {
-
this_.textureA.bind();
-
this_.sphereShader.uniforms({
-
oldCenter: oldCenter,
-
newCenter: newCenter,
-
반경: 반경
-
}).draw(this_.plane);
-
});
-
이것.textureB.swapWith(이것.textureA);
-
};
-
-
Water.prototype.stepSimulation = 함수() {
-
var this_ = this;
-
이.textureB.drawTo(함수() {
-
this_.textureA.bind();
-
this_.updateShader.uniforms({
-
델타: [1 / this_.textureA.width, 1 / this_.textureA.height]
-
}).draw(this_.plane);
-
});
-
이것.textureB.swapWith(이것.textureA);
-
};
-
-
Water.prototype.updateNormals = 함수() {
-
var this_ = this;
-
이.textureB.drawTo(함수() {
-
this_.textureA.bind();
-
this_.normalShader.uniforms({
-
델타: [1 / this_.textureA.width, 1 / this_.textureA.height]
-
}).draw(this_.plane);
-
});
-
이것.textureB.swapWith(이것.textureA);
-
};
以上就是本文의 전체 부서는 内容, 希望对大家의 학교입니다.