0
点赞
收藏
分享

微信扫一扫

HTML+CSS+JS实现 ❤️3D洞穴无限延伸动画特效❤️



???? 作者主页:​​Java李杨勇 ​​

???? 简介:Java领域优质创作者????、【java李杨勇】公号作者✌  简历模板、学习资料、面试题库、技术互助【关注我,都给你】

???? 欢迎点赞 ???? 收藏 ⭐留言 ????   



效果演示: 文末获取源码



 代码目录:


HTML+CSS+JS实现 ❤️3D洞穴无限延伸动画特效❤️_3D洞穴无限延伸动画_02


主要代码实现:


CSS样式:

body {
margin: 0;
}

canvas {
height: 100vh !important;
position: fixed;
width: 100vw !important;
}

HTML代码 :

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>CodePen - Control 2</title>
<link rel="stylesheet" href="css/style.css">

</head>

<body>
<!-- partial:index.partial.html -->
<canvas id="webgl" width="500" height="1758"></canvas>

<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_position; uniform mat4 u_modelViewMatrix; uniform mat4 u_projectionMatrix; void main() { gl_Position = a_position; }
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision highp float; precision highp int; uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; uniform sampler2D u_noise; // movement variables vec3 movement = vec3(.0); const int maxIterations = 256; const float stopThreshold = 0.002;
const float stepScale = .5; const float eps = 0.002; const vec3 clipColour = vec3(1.); const vec3 fogColour = vec3(1.); const vec3 light1_position = vec3(0, 1., -1.); const vec3 light1_colour = vec3(.8, .8, .85); struct Surface { int object_id;
float distance; vec3 position; vec3 onsurface_position; vec3 colour; float steps; float ambient; float spec; float fog; }; // Distance function copyright Inigo Quilez float opExtrusion( in vec3 p, in float primitive, in float h ) { float d = primitive;
vec2 w = vec2( d, abs(p.z) - h ); return min(max(w.x,w.y),0.0) + length(max(w,0.0)); } float sdBox( in vec2 p, in vec2 b ) { vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } vec3 path(float z) { // return vec3(0,0,0.); return
vec3(sin(z * .1) * 4., sin(z * .05) * 10., z); } float getBlock(vec3 position, inout int object_id, inout vec3 p) { // position.z = fract(position.z) - .5; // object_id = int(id); float id = float(object_id); float r = sin(id * .3 + u_time) *
.5; r = sin(texture2D(u_noise, vec2((id*2.)/255.)).x * 2. + u_time - id) * .25; float rw = texture2D(u_noise, vec2((id*2.)/255.)).x - .5; // // position.xy += r; float s = sin(r); float c = cos(r); position.xy *= mat2(c, -s, s, c); p = position;
float box = sdBox(position.xy, vec2(1.5 + rw, 1.)) * -1.; float world = opExtrusion(position, box, .45) - .005; // world += smoothstep(.04, 0., abs(sin(p.x * 4.))) * .01; // world += smoothstep(.02, 0., abs(sin(p.y * 2.))) * .01; return world;
} // This function describes the world in distances from any given 3 dimensional point in space float world(in vec3 position, inout int object_id, inout vec3 p) { position.xy -= path(position.z).xy; float id = floor(position.z); position.z = fract(position.z)
- .5; int oid1 = int(id); vec3 p1; float block1 = getBlock(position, oid1, p1); int oid2 = int(id+1.); vec3 p2; float block2 = getBlock(position + vec3(0,0,-1), oid2, p2); object_id = oid1; p = p1; if(block2
< block1) { block1=b lock2;
object_id=o id2; p=p 2; } return block1; } float world(in vec3 position, inout int object_id) { vec3 p; return world(position, object_id, p); } float world(in vec3 position) { int dummy=0 ; return world(position, dummy); } Surface getSurface(int
object_id, float rayDepth, vec3 sp, float steps, vec3 onsurface_pos, float fog) { return Surface( object_id, rayDepth, sp, onsurface_pos, vec3(1.), steps, .5, 1000., fog); } // The raymarch loop Surface rayMarch(vec3 ro, vec3 rd, float start,
float end) { float sceneDist=1 e4; float rayDepth=s tart; int object_id=0 ; float steps=0 .; float fog=0 .; vec3 p; for(int i=0 ; i < maxIterations; i++) { sceneDist=w orld(ro + rd * rayDepth, object_id, p); rd +=( texture2D(u_noise, (p.xy)*255.).rgb-.5)*.0005;
steps++; fog +=m ax(sceneDist, 0.); if(sceneDist < stopThreshold || rayDepth> end) { break; } rayDepth += sceneDist * stepScale; } return getSurface(object_id, rayDepth, ro + rd * rayDepth, steps, p, fog); } // Calculated the normal of any given point in space. Intended to be cast from the point of a surface vec3 calculate_normal(in
vec3 position) { vec3 grad = vec3( world(vec3(position.x + eps, position.y, position.z)) - world(vec3(position.x - eps, position.y, position.z)), world(vec3(position.x, position.y + eps, position.z)) - world(vec3(position.x, position.y - eps,
position.z)), world(vec3(position.x, position.y, position.z + eps)) - world(vec3(position.x, position.y, position.z - eps)) ); return normalize(grad); } vec3 lighting(Surface surface_object, vec3 cam) { // start with black vec3 sceneColour
= vec3(0); // Surface normal vec3 normal = calculate_normal(surface_object.position); normal += smoothstep(.02, 0., abs(sin(surface_object.onsurface_position.x * 4.))) * .5; normal += smoothstep(.01, 0., abs(sin(surface_object.onsurface_position.y
* 2.))) * .5; // Light position vec3 lp = path(u_time*3.+15.); // Light direction vec3 ld = lp - surface_object.position; // light attenuation // For brightly lit scenes or global illumination (like sunlit), this can be limited to just normalizing
the ld float len = length( ld ); ld = normalize(ld); float lightAtten = min( 1.0 / ( 0.15*len ), 1.0 ); lightAtten = 1.; // The surface's light reflection normal vec3 reflection_normal = reflect(-ld, normal); // Ambient Occlusion float ao
= (surface_object.steps*.01*(1./(surface_object.fog*.07))); ao *= ao*2.; ao = clamp( ((1.-ao)+.3) , 0., 1.); // ao -= surface_object.steps*.005; // Object surface properties float diffuse = max(0., dot(normal, ld)); float specular = max(0.,
dot( reflection_normal, normalize(cam - surface_object.position) )); // Bringing all of the lighting components together vec3 tp = surface_object.onsurface_position * 2.; vec3 c = texture2D(u_noise, tp.xy + tp.zx).rrr + texture2D(u_noise,
tp.zy + tp.yx).rrr; tp = surface_object.onsurface_position * vec3(.8, .8, 1.); c += texture2D(u_noise, tp.xy + tp.zx).rrr + texture2D(u_noise, tp.zy + tp.yx).rrr; tp = surface_object.onsurface_position * vec3(1., .4, .4); c += texture2D(u_noise,
tp.xy + tp.zx).rrr + texture2D(u_noise, tp.zy + tp.yx).rrr; c *= .125; c *= .5 + .5; c *= vec3(1,.98,.90); sceneColour += ( c * (diffuse + specular )) * light1_colour * lightAtten * ao; // adding fog float fogl = surface_object.fog*.04; fogl
*= smoothstep(-.5, 1.8, fogl); sceneColour = mix( sceneColour, fogColour, fogl ); return sceneColour; } void main() { vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / min(u_resolution.y, u_resolution.x); float t = u_time * 3.; // movement
movement = path(t); // Camera and look-at vec3 cam = vec3(0,0,-2); vec3 lookAt = vec3(0,-.5,-2.); // add movement lookAt = path(t+3.); cam = movement; // cam.y += abs(sin(u_time*20.)*.02); // Unit vectors vec3 forward = normalize(lookAt -
cam); vec3 right = normalize(vec3(forward.z, 0., -forward.x)); vec3 up = normalize(cross(forward, right)); // FOV float FOV = 1.4; // Ray origin and ray direction vec3 ro = cam; vec3 rd = normalize(forward + FOV * uv.x * right + FOV * uv.y
* up); rd.y -= (movement.y - lookAt.y) * .04; // Ray marching const float clipNear = 0.; const float clipFar = 20.; Surface objectSurface = rayMarch(ro, rd, clipNear, clipFar); if(objectSurface.distance > clipFar) { gl_FragColor = vec4(clipColour,
1.); return; } vec3 sceneColour = lighting(objectSurface, cam); gl_FragColor = vec4(sceneColour, 1.); // gl_FragColor += vec4(vec3(objectSurface.fog*.01), 1.); }

</script>
<!-- partial -->
<script src="js/script.js"></script>

</body>

</html>


源码获取

打卡 文章 更新 48  /  100天


举报

相关推荐

HTML+CSS+JS的3D进度条

0 条评论