canvas+webgl实现三维无底圆柱体内部凹凸不平穿越动画效果代码

代码语言:html

所属分类:三维

代码描述:canvas+webgl实现三维无底圆柱体内部凹凸不平穿越动画效果代码

代码标签: canvas webgl 三维 无底 圆柱体 内部 凹凸 不平 穿越 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

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

<head>
  <meta charset="UTF-8">

  
  
<style>
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");

body, html {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #001;
}
canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

#controls {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 100;
  display: flex;
  align-items: center;
  z-index: 1;
}
button {
  background-color: #4CAF50;
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  border-radius: 10px;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  transition: background-color 0.3s;
  &:hover {
    background-color: #25902950;
  }
  &:active {
    background-color: #00FFFFCC;
  }
}
.btn {
  background-color: rgba(0, 0, 0, 0.4);
  border: none;
  color: rgba(255, 255, 255, 0.4);
  padding: 10px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 2px 2px;
  cursor: pointer;
  border-radius: 5px;
  transition: background-color 0.3s;
}
.btn:hover {
  background-color: rgba(255, 255, 255, 0.2);
  color: rgba(255, 255, 0, 1);
}
#fullscreenBtn {
  font-size: 20px;
}

.container {
  margin: 0 auto;
  padding: 2rem;
  position: absolute;
  width: 100%;
  font-family: "Roboto", sans-serif;
  text-shadow: 0 0 5px #000, 0 0 10px #000;
  color: #fff;
  filter: drop-shadow(0 0 10px rgba(0, 0, 50, 0.7))
		drop-shadow(0 0 15px rgba(0, 0, 0, 0.5))
		drop-shadow(0 0 20px rgba(0, 0, 0, 0.3));
  z-index: 2;
}
</style>

  
</head>

<body translate="no">
  <canvas id="glCanvas"></canvas>

<div class="container">
  <h1>Animated Shader: Oldschool Tube</h1>
  Lorem ipsum dolor sit amet, at labitur complectitur mei. Tota eloquentiam an sea, nostro electram mea et. Debitis accusata forensibus sed in, no omnium evertitur prodesset eam. Hendrerit torquatos deterruisset no per, eirmod equidem omnesque per ne. Vix appetere percipit cu.
  <p><button id="fullscreenBtn">⤢ Toggle Fullscreen</button>
</div>

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gl-matrix-min.js"></script>
  
      <script  >
/*
Old School Tube
https://www.shadertoy.com/view/Mly3WV
*/

const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl2');
if (!gl) {
  console.error('WebGL 2 not supported');
  document.body.innerHTML = 'WebGL 2 is not supported in your browser.';
}

const vertexShaderSource = `#version 300 es
in vec4 aPosition;
void main() {
    gl_Position = aPosition;
}`;

const fragmentShaderSource = `#version 300 es
precision highp float;

uniform vec3 iResolution;
uniform float iTime;
uniform vec4 iMouse;
out vec4 fragColor;

/*--- BEGIN OF SHADERTOY ---*/

/*

	Oldschool Tube
	--------------

	An oldschool tube effect, with a few extra lines to bump it and light it up. Virtually no 
	different in concept to the more compact, minimal character versions.

	Aiekick asked about cylindrically wrapping a pattern - like Voronoi - onto a cyclinder, so 
	I thought I'd put a simple example together and post it privately... However, I got a little 
	carried away adding window dressing. It's still not particularly interesting, but I liked
	the simple rendering style, so thought I'd release it publicly.

	Having said that, one minor point of interest is that the edging is done in the bump routine.
	Most edging examples are raymarched and involved normal-based edge calculations, but this
	shows that you can have edging on the bump mapped part of the scene too. There are much more
	interesting applications, and I'll give an example at a later date.


	Created in repsonse to the following:

    Voro Tri Tunnel - aiekick
    https://www.shadertoy.com/view/XtGGWy

	A rough explanation of the oldschool tunnel effect:

	Traced Minkowski Tube - Shane
    https://www.shadertoy.com/view/4lSXzh

    // Another example.
	Luminescent Tiles - Shane
	https://www.shadertoy.com/view/MtSXRm

*/

// 2D rotation. Always handy. Angle vector, courtesy of Fabrice.
mat2 rot( float th ){ vec2 a = sin(vec2(1.5707963, 0) + th); return mat2(a, -a.y, a.x); }


// Compact, self-contained version of IQ's 3D value noise function. I have a transparent noise
// example that explains it, if you require it.
float n3D(vec3 p){
    
	const vec3 s = vec3(7, 157, 113);
	vec3 ip = floor(p); p -= ip; 
    vec4 h = vec4(0., s.yz, s.y + s.z) + dot(ip, s);
    p = p*p*(3. - 2.*p); //p *= p*p*(p*(p * 6. - 15.) + 10.);
    h = mix(fract(sin(h)*43758.5453), fract(sin(h + s.x)*43758.5453), p.x);
    h.xy = mix(h.xz, h.yw, p.y);
    return mix(h.x, h.y, p.z); // Range: [0, 1].
}

// vec2 to vec2 hash.
vec2 hash22(vec2 p, float w) { 

    // The Voronoi pattern needs to be repeatable. Hence the "mod" line below.
    p = mod(p, w);
    // Faster, but doesn't disperse things quite as nicely. However, when framerate
    // is an issue, and it often is, this is a good one to use. Basically, it's a tweaked 
    // amalgamation I put together, based on a couple of other random algorithms I've 
    // seen around... so use it with caution, because I make a tonne of mistakes. :)
    float n = sin(dot(p, vec2(41, 289)));
    return fract(vec2(262144, 32768)*n)*.9 + .1; 
    
    // Animated.
    //p = fract(vec2(262144, 32768)*n); 
    // Note the ".45," insted of ".5" that you'd expect to see. When edging, it can open 
    // up the cells ever so slightly for a more even spread. In fact, lower numbers work 
    // even better, but then the random movement would become too restricted. Zero would 
    // give you square cells.
    //return sin( p*6.2831853 + iTime )*.45 + .5; 
    
}


float vx;
// 2D 2nd-order Voronoi: Obviously, this is just a rehash of IQ's original. I've tidied
// up those if-statements. Since there's less writing, it should go faster. That's how 
// it works, right? :)
//
float Voronoi(in vec2 p, float w){
    
    
	vec2 g = floor(p), o; p -= g;
	
	vec3 d = vec3(1.4142); // 1.4, etc. "d.z" holds the distance comparison value.
    
	for(int y=-1; y<=1; y++){
		for(int x=-1; x<=1; x++){
            
			o = vec2(x, y);
            o += hash22(g + o, w) - p;
            
			d.z = length(o);//(dot(o, o)); 
            
            // More distance metrics.
            //o = abs(o);
            //d.z = mix(max(abs(o.x)*.866025 + o.y*.5, -o.y), dot(o, o), .2);//
            //d.z = max(abs(o.x)*.866025 - o.y*.5, o.y);
            //d.z = max(abs(o.x) + o.y*.5, -(o.y)*.8660254);
            //d.z = max(o.x, o.y);
            //d.z = (o.x*.7 + o.y*.7);
            
            d.y = max(d.x, min(d.y, d.z));
            d.x = min(d.x, d.z); 
                       
		}
	}
 					 
	d/=1.4142;
    
    vx = d.x;
    
    d = smoothstep(0., 1., d);

    
    return max(d.y/1.333 - d.x, 0.)*1.333;
    
   
    //return d.y - d.x;
    
}

float objID;

// The bump mapping function.
float bumpFunction(in vec3 p){
    
    // Stock standard cylindrical mapping. This line here is pretty much
    // where all the oldschool tunnel examples stem from.
    vec2 uv = vec2(atan(p.y, p.x)/6.2832, p.z/8.);
    
    float c = Voronoi(uv*16., 16.);

    objID = 0.;

    // The web section. Comment it out, if you're not sure what it does.
    if(c<.15) { c = abs(max(c, 0.01) - .3), objID = 1.; }
    
    return c;
   
}


// Standard function-based bump mapping function, with some edging added to the mix.
vec3 doBumpMap(in vec3 p, in vec3 n, float bumpfactor, inout float edge){
    
    vec2 e = vec2(2.5/iResolution.y, 0);
    
    float f = bumpFunction(p); 
    
    // Samples about the hit point in each of the axial directions.
    float fx = bumpFunction(p - e.xyy); // Same for the nearby sample in the X-direction.
    float fy = bumpFunction(p - e.yxy); // Same for the nearby sample in the Y-direction.
    float fz = bumpFunction(p - e.yyx); // Same for the nearby sample in the Y-direction.

    // Samples from the other side.
    float fx2 = bumpFunction(p + e.xyy); // Same for the nearby sample in the X-direction.
    float fy2 = bumpFunction(p + e.yxy); // Same for the nearby sample in the Y-direction.
    float fz2 = bumpFunction(p + e.yyx); // Same for the nearby sample in the Y-direction.
    
    // We made three extra function calls, so we may as well use them. Taking measurements
    // from either side of the hit point has a slight antialiasing effect.
    vec3 grad = (vec3(fx - fx2, fy - fy2, fz .........完整代码请登录后点击上方下载按钮下载查看

网友评论0