webgl实现草原上的七星瓢虫三维爬行效果代码
代码语言:html
所属分类:三维
代码描述:webgl实现草原上的七星瓢虫三维爬行效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
html {
height: 100%;
}
body {
background: #286870;
background: -moz-linear-gradient(180deg, #286870 0%, #0b232b 62%, #588849 100%);
background: -webkit-linear-gradient(180deg, #286870 0%, #0b232b 62%, #588849 100%);
background: linear-gradient(180deg, #286870 0%, #0b232b 62%, #588849 100%);
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
min-height: 100vh;
display: flex;
align-items: center;
position: relative;
}
canvas {
box-sizing: border-box;
padding: 0;
margin: 0;
outline: none;
box-shadow: 2px 20px 13px rgba(0, 0, 0, 0.75);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 800px;
height: 450px;
z-index: 0;
}
</style>
</head>
<body >
<!-- VertexShader code here -->
<script id="vertexShader" type="x-shader/x-vertex">#version 300 es
precision highp float;
in vec4 vPosition;
void main() {
gl_Position = vPosition;
}
</script>
<!-- FragmentShader code here -->
<script id="fragmentShader" type="x-shader/x-fragment">#version 300 es
precision highp float;
out vec4 fragColor;
uniform vec4 mouse;
uniform vec2 resolution;
uniform float time;
#define R resolution
#define T time
#define M mouse
#define PI 3.14159265359
#define PI2 6.28318530718
#define MAX_DIST 120.
#define MIN_DIST .0005
float hash21(vec2 p) { return fract(sin(dot(p,vec2(23.86,48.32)))*4374.432); }
vec2 hash2( vec2 p) { return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453); }
vec3 hash3( vec2 p) {
vec3 q = vec3( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)), dot(p,vec2(419.2,371.9)) );
return fract(sin(q)*43758.5453);
}
mat2 rot(float a) { return mat2(cos(a),sin(a),-sin(a),cos(a)); }
vec3 noised( in vec2 x ){
vec2 f = fract(x);
vec2 u = f*f*(3.0-2.0*f);
vec2 p = vec2(floor(x));
float a = hash21( p+vec2(0,0) );
float b = hash21( p+vec2(1,0) );
float c = hash21( p+vec2(0,1) );
float d = hash21( p+vec2(1,1) );
return vec3(a+(b-a)*u.x+(c-a)*u.y+(a-b-c+d)*u.x*u.y,
6.0*f*(1.0-f)*(vec2(b-a,c-a)+(a-b-c+d)*u.yx));
}
float fbm( vec2 p, float freq ) {
float h = -1.,w = 2.6,m = .35;
for (float i = 0.; i < freq; i++) {
h += w * noised((p * m)).x;
w *= .5;
m *= 2.;
}
return h;
}
vec2 truchet(vec2 uv, float scale) {
uv *= scale;
vec2 grid = fract(uv)-.5;
vec2 id = floor(uv);
float hs = hash21(id);
if(hs>.5) grid.x*=-1.;
vec2 d2 = vec2(length(grid-.5), length(grid+.5));
vec2 gx = d2.x<d2.y? vec2(grid-.5) : vec2(grid+.5);
float circle = length(gx)-.5;
circle=abs(circle)-.095;
return vec2(clamp(circle,0.,1.),hs);
}
//@iq Voronoi Distances
//https://www.shadertoy.com/view/ldl3W8
vec4 voronoi( in vec2 x){
vec2 n = floor(x);
vec2 f = fract(x);
float ox = 0.;
float wave = 323.23123;
vec2 mg, mr;
float md = 8.;
for( float j=-1.; j<=1.; j++ )
for( float i=-1.; i<=1.; i++ )
{
vec2 g = vec2(i,j);
vec2 o = hash2( n + g );
o = .35 + .35 *sin(o * wave + PI2);
vec2 r = g + o - f;
float d = dot(r,r);
if( d<md ){
md = d;
mr = r;
mg = g;
}
}
md = 8.;
for( float j=-2.; j<=2.; j++ )
for( float i=-2.; i<=2.; i++ )
{
vec2 g = mg + vec2(i,j);
vec2 o = hash2( n + g );
ox = o.x;
o = .35 + .35 *sin(o * wave + PI2);
vec2 r = g + o - f;
if( dot(mr-r,mr-r)>.00001 )
md = min( md, dot( .5*(mr+r), normalize(r-mr) ) );
}
return vec4( md, mr, ox );
}
//globals
vec3 hitPoint,hit;
mat2 rotA,rotB,rotC;
float box(vec3 p,vec3 s) {
p=abs(p)-s; return max(p.x,max(p.y,p.z));
}
float box(vec2 p, vec2 b) {
vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
// Field created watching @nusans shader livestream
// with some improvisations on some things
float blade(vec3 p, float sc) {
p/=sc; p.y-=1.5;
p.zx+= abs(p.xz)*.1;
float wd = sin((p.y+1.5)*1.5)*.1;
float d = box(p,vec3(wd,1.5,wd));
return d*sc*.8;
}
vec2 field(vec3 p, float rp) {
vec2 res=vec2(1e5,0);
vec2 id=floor(p.xz/rp-.5);
float hs = hash21(id);
p.xz=(fract(p.xz/rp-.5)-.5)*rp;
p.xz*=rot(hs*PI2);
float fs = hash21(id+3.4);
float sc = .5+hs*.8;
float b = blade(p,sc);
if(b<res.x) res =vec2(b,1.);
if(fs>.9) {
float fb=length(p-vec3(0,sc*2.,0))-(sc*.075);
if(fb<res.x) res =vec2(fb,6.);
}
return res;
}
vec2 grass(vec3 p) {
vec2 res = vec2(1e5,0),d;
p.xz +=sin(p.zx*.15+p.y*.1+T*3.)*.3*max(0.,p.y)*.5;
d = field(p,1.75);
if(d.x<res.x) res = d;
p.xz*=rotA;
p.x+=45.35;
d = field(p,1.15);
if(d.x<res.x) res = d;
p.xz*=rotB;
p.x+=141.5;
d = field(p,.75);
if(d.x<res.x) res = d;
return res;
}
float specks(vec3 p,float rp) {
p.z+=T*5.+abs(sin(T*.5-p.z*.01))*10.;
p.xyz+=sin(p.zxy*vec3(.02,0,.07)+vec3(.1,.07,.05)*T)*5.5;
p = (fract(p/rp-.5)-.5)*rp;
return length(p)-.05;
}
float mst=0.;
float mist(vec3 p) {
vec3 q = p;
float d = specks(p,11.);
p.xz*=rotC;
p.yz*=rotB;
d = min(specks(p,7.),d);
d += max(.0,-(6.-q.y)*.025);
return d;
}
// The truchet path is something I made up, however I haven't
// found a good way of implimenting yet - tried some other
// multi-tap systems so prevent the cutoff but not smart enough
// mathwise to know what I'm trying to do.
// well its not perfect but looks ok if you squint.
float gid,sid;
vec2 map(vec3 p, float sd) {
vec2 res = vec2(1e5,0.);
p.x+=T;
vec3 pbk = p;
float gnd = fbm(p.xz*.15,.1)*1.95;
p.y+=gnd;
vec2 uv = p.xz*.05;
float py = p.y+.5;
vec2 tc = truchet(p.xz,.05);
float cc = tc.x;
vec2 dx = grass(p);
if(dx.x<res.x) {
if(cc<.03){
dx.x += max(.1,.15-cc*.25);
}
res = vec2(dx.x,dx.y);
hit=p;
}
float mt3 = mist(p);
if(mt3<res.x && sd>0.) {
res = vec2(mt3,3.);
mst +=clamp(.0025/(.00025+mt3*mt3) ,.0, max(.0, (gnd)*.015) );
//mst += .0025/(.00025+mt3*mt3);
}
vec2 id = floor(p.xz*.05);
vec2 guv= fract(p.xz*.05)-.5;
float hs .........完整代码请登录后点击上方下载按钮下载查看
网友评论0