three+webgl实现晶莹剔透的茶杯旋转效果代码
代码语言:html
所属分类:三维
代码描述:three+webgl实现晶莹剔透的茶杯旋转效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { margin: 0; padding: 0; } #container { position: fixed; touch-action: none; } </style> </head> <body > <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.88.js"></script> <script id="vertexShader" type="x-shader/x-vertex"> void main() { gl_Position = vec4( position, 1.0 ); } </script> <script id="fragmentShader" type="x-shader/x-fragment"> uniform vec2 u_resolution; uniform float u_time; uniform vec2 u_mouse; uniform sampler2D u_noise; const int octaves = 2; const float seed = 43758.5453123; const float seed2 = 73156.8473192; // Epsilon value const float eps = 0.05; const vec3 ambientLight = 0.99 * vec3(1.0, 1.0, 1.0); const vec3 light1Pos = vec3(10., 5.0, -25.0); const vec3 light1Intensity = vec3(0.35); const vec3 light2Pos = vec3(-20., -25.0, 85.0); const vec3 light2Intensity = vec3(0.2); // movement variables vec3 movement = vec3(.0); // Gloable variables for the raymarching algorithm. const int maxIterations = 256; const int maxIterationsShad = 16; const float stepScale = .7; const float stopThreshold = 0.001; vec3 hash33(vec3 p){ return texture2D(u_noise, p.xy * p.z * 256.).rgb; } float pn( in vec3 p ) { vec3 i = floor(p); p -= i; p *= p*(3. - 2.*p); p.xy = texture2D(u_noise, (p.xy + i.xy + vec2(37, 17)*i.z + .5)/256., -100.).yx; return mix(p.x, p.y, p.z); } // Thanks to Shane for this one. // Basic low quality noise consisting of three layers of rotated, mutated // trigonometric functions. Needs work, but sufficient for this example. float trigNoise3D(in vec3 p){ float res = 0., sum = 0.; // IQ's cheap, texture-lookup noise function. Very efficient, but still // a little too processor intensive for multiple layer usage in a largish // "for loop" setup. Therefore, just one layer is being used here. float n = pn(p*8. + u_time*.5); // Two sinusoidal layers. I'm pretty sure you could get rid of one of // the swizzles (I have a feeling the GPU doesn't like them as much), // which I'll try to do later. vec3 t = sin(p.yzx*3.14159265 + cos(p.zxy*3.14159265+1.57/2.))*0.5 + 0.5; p = p*1.5 + (t - 1.5); // + u_time*0.1 res += (dot(t, vec3(0.333))); t = sin(p.yzx*3.14159265 + cos(p.zxy*3.14159265+1.57/2.))*0.5 + 0.5; res += (dot(t, vec3(0.333)))*0.7071; return ((res/1.7071))*0.85 + n*0.15; } mat4 rotationMatrix(vec3 axis, float angle) { axis = normalize(axis); float s = sin(angle); float c = cos(angle); float oc = 1.0 - c; return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0); } float length2( vec2 p ) { return sqrt( p.x*p.x + p.y*p.y ); } float length6( vec2 p ) { p = p*p*p; p = p*p; return pow( p.x + p.y, 1.0/6.0 ); } float length8( vec2 p ) { p = p*p; p = p*p; p = p*p; return pow( p.x + p.y, 1.0/8.0 ); } // Distance function primitives // Reference: http://iquilezles.org/www/articles/distfunctions/distfunctions.htm float sdBox( vec3 p, vec3 b ) { vec3 d = abs(p) - b; return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); } float udBox( vec3 p, vec3 b ) { return length(max(abs(p)-b,0.0)); } float udRoundBox( vec3 p, vec3 b, float r ) { return length(max(abs(p)-b,0.0))-r; } float sdSphere( vec3 p, float s ) { return length(p)-s; } float sdCylinder( vec3 p, vec3 c ) { return length(p.xz-c.xy)-c.z; } float sdCappedCylinder( vec3 p, vec2 h ) { vec2 d = abs(vec2(length(p.xz),p.y)) - h; return min(max(d.x,d.y),0.0) + length(max(d,0.0)); } float sdTorus82( vec3 p, vec2 t ) { vec2 q = vec2(length2(p.xz)-t.x,p.y); return length8(q)-t.y; } float sdPlane( vec3 p) { return p.y; } float sdTorus( vec3 p, vec2 t ) { vec2 q = vec2(length(p.xz)-t.x,p.y); return length(q)-t.y; } // smooth min // reference: http://iquilezles.org/www/articles/smin/smin.htm float smin(float a, float b, float k) { float res = exp(-k*a) + exp(-k*b); return -log(res)/k; } float smax(float a,float b, float k) { return -smin(-a,-b,k); } vec3 random3( vec3 p ) { return fract(sin(vec3(dot(p,vec3(127.1,311.7,319.8)),dot(p,vec3(269.5,183.3, 415.2)),dot(p,vec3(362.9,201.5,134.7))))*43758.5453); } vec2 random2( vec2 p ) { return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453); } float tri( float x ){ return abs( fract(x) - .5 ); } vec3 tri3( vec3 p ){ return vec3( tri( p.z + tri( p.y * 1. ) ), tri( p.z + tri( p.x * 1. ) ), tri( p.y + tri( p.x * 1. ) ) ); } float triNoise3D( vec3 p, float spd , float time){ float z = 1.4; float rz = 0.; vec3 bp = p; for( float i = 0.; i <= 3.; i++ ){ vec3 dg = tri3( bp * 2. ); p += ( dg + time * .1 * spd ); bp *= 1.8; z *= 1.5; p *= 1.2; float t = tri( p.z + tri( p.x + tri( p.y ))); rz += t / z; bp += 0.14; } return rz; } mat4 rotmat; // The world! float world_sdf(in vec3 p, inout int id) { float world = 10.; p = (vec4(p, 1.) * rotmat).xyz; vec3 _p = p; _p.y *= .8; float ctime = cos(u_time*.5); _p.xz += sin(p.y * 25. + 5.5 + ctime * 4.) * p.xz * .05; _p.xz += smoothstep(-.5, .2, _p.y) * p.xz * .5; float ymod = sin(p.y * 80. + ctime * 10.) * .002; _p += ymod + sin(p.x * 50.) * .2 * sin(p.z * 20.) * ymod; // p.xz *= 1. + sin(p.y * 1.5 + .1) * 5.; world = sdSphere(_p, .5); world = smax(p.y - .5, world, 10.); world = smax(-sdSphere(_p - vec3(0., .2, 0.), .33), world, 10.); world = max(-p.y - .5, world); float table = sdCappedCylinder(p+vec3(0., .53, 0.), vec2(.7, .03)); if(table < world) { id = 2; return table; } else { id = 1; return world; } return world; } float world_sdf(in vec3 p) { int id; return world_sdf(p, id); } // Fuck yeah, normals! vec3 calculate_normal(in vec3 p) { const vec3 small_step = vec3(0.0001, 0.0, 0.0); float gradient_x = world_sdf(vec3(p.x + eps, p.y, p.z)) - world_sdf(vec3(p.x - eps, p.y, p.z)); float gradient_y = world_sdf(vec3(p.x, p.y + eps, p.z)) - world_sdf(vec3(p.x, p.y - eps, p.z)); float gradient_z = world_sdf(vec3(p.x, p.y, p.z + eps)) - world_sdf(vec3(p.x, p.y, p.z - eps)); vec3 normal = vec3(gradient_x, gradient_y, gradient_z); return normalize(normal); } // Raymarching. float rayMarching( vec3 origin, vec3 dir, float start, float end, inout float field, inout int id ) { float sceneDist = 1e4; float rayDepth = start; for ( int i = 0; i < maxIterations; i++ ) { sceneDist = world_sdf( origin + dir * rayDepth, id ); // Distance from the point along the ray to the nearest surface point in the scene. if (( sceneDist < stopThreshold ) || (rayDepth >= end)) { break; } // We haven't hit anything, so increase the depth by a scaled factor of the minimum scene distance. rayDepth += sceneDist * stepScale; } if ( sceneDist >= stopThreshold ) rayDepth = end; else rayDepth += sceneDist; // We've used up our maximum iterations. Return the maximum distance. return rayDepth; } // Shadows // Reference at: http://www.iquilezles.org/www/articles/rmshadows/rmshadows.htm float softShadow(vec3 ro, vec3 lightPos, float start, float k){ vec3 rd = lightPos - ro; float end = length(rd); float shade = 1.0; float dist = start; .........完整代码请登录后点击上方下载按钮下载查看
网友评论0