demo.html
HTML source for Cathedral, 169 lines. Raw file
<html>
<title>WebGL Fragment Shader Canvas</title>
<script src="webgl_fragment_framework.js?download"></script>
<script id="shader" type="x-shader/x-fragment">
#ifdef GL_ES
precision mediump float;
#endif
varying vec3 vPosition;
uniform float uTime;
uniform vec2 uMousePos;
//ifs
float fu; //fractal_spheresubstract
float fd; //fractal_distancemult
vec3 cs; //fractal_csize
float fs; //fractal_size
vec3 fc; //fractal_c
vec2 rs; //resolution
//camera
vec3 cp; //camera position
mat3 cr; //camera rotation
float dE(vec3 p) {
float dEfactor=1.;
//int fractal_iterations = 12;
for(int i=0;i<12;i++){
//box folding
p=2.*clamp(p, -cs, cs)-p;
//inversion
float k=max(fs/dot(p,p),1.);
p*=k;
dEfactor*=k;
//julia seed
p+=fc;
}
//call basic shape and scale its DE
//need to adjust fractal_distancemult with non zero julia seed
float rxy=length(p.xy)-fu;
//distance from pos to the pseudo kleinian basic shape ...
return (fd*max(rxy,abs(length(p.xy)*p.z)/sqrt(dot(p,p)))/abs(dEfactor));
}
float rd(vec2 fragment_coordinates) {
//calculate ray direction from fragment coordinates ...
vec2 ray_position = fragment_coordinates;//(0.5*rs-fragment_coordinates)/vec2(rs.x,-rs.y);
ray_position.x *= (rs.x/rs.y); //aspect_ratio
vec3 ray_direction = normalize(cr * vec3(ray_position.x * vec3(1, 0, 0) + ray_position.y * vec3(0, 1, 0) - .9 * vec3(0, 0, 1)));
//sphere tracing initialization ...
float ray_length = 0.0;
vec3 ray = cp+ray_length*ray_direction;
float epsilon = 0.0000006;
float calculated_distance;
int tracingsteps = 0;
bool hit = false;
ray = cp+ray_length*ray_direction;
//magic :) DO NOT TOUCH!
float eps_factor = 2.0*0.743294*(1.0/rs.y)*.6;
//actual sphere tracing ...
//#define tracingsteps_max 200
for (int i=0; i<20; i++) {
tracingsteps = i;
calculated_distance = dE(ray);
//small stepback to remove 'fuzzel'-structures near inside shooting range
//#define raylength_max 10000.0
if (hit && calculated_distance<epsilon || ray_length>10000.) {
tracingsteps--;
break;
}
hit = false;
ray_length += calculated_distance;
ray = cp+ray_length*ray_direction;
epsilon = ray_length * eps_factor;
if (calculated_distance<epsilon) {
hit = true;
}
}
//---
//intersects ?
//#define tracingsteps_max 200
// return float(tracingsteps)/float(40);
/*
float epsilon_normal = 1.5e-7;
vec3 normal = normalize(vec3(
dE(ray+vec3(epsilon_normal, 0, 0))-dE(ray-vec3(epsilon_normal, 0, 0)),
dE(ray+vec3(0, epsilon_normal, 0))-dE(ray-vec3(0, epsilon_normal, 0)),
dE(ray+vec3(0, 0, epsilon_normal))-dE(ray-vec3(0, 0, epsilon_normal)))
);
*/
return ray_length * 40.2;// + 0.1 + 0.1 * dot( normal, vec3( 0.707, 0.0, 0.707 ) );
}
//return rotation matrix for rotating around vector v by angle
mat3 mr(vec3 v, float angle) {
float c = cos(radians(angle));
float s = sin(radians(angle));
return mat3(c+(1.0-c)*v.x*v.x , (1.0-c)*v.x*v.y-s*v.z , (1.0-c)*v.x*v.z+s*v.y,
(1.0-c)*v.x*v.y+s*v.z, c+(1.0-c)*v.y*v.y , (1.0-c)*v.y*v.z-s*v.x,
(1.0-c)*v.x*v.z-s*v.y, (1.0 - c)*v.y*v.z+s*v.x, c+(1.0-c)*v.z*v.z);
}
void main(void)
{
float camera_roll = 0.;
float camera_pitch = 90.;
float camera_yaw = 0.;
vec2 custom_glFragCoord = gl_FragCoord.xy;
float temp_scenetimer = uTime;
fu = 10.0;
fd = 0.763;
cs = vec3(0.80800,0.80800,1.16700);
fs = 1.0;
fc = vec3(0.0);
rs = vec2( 300.0, 300.0 );
camera_pitch = 23.9;
cp = vec3(0.8,-1.16339+16.0-uTime*0.395,-1.80153);
cs.y = 0.58000;
fu = 1.01000;
cp = vec3(0.0007,0.02000,0.10000-temp_scenetimer*0.00028);
camera_pitch = 0.0;
camera_yaw = temp_scenetimer*0.009*180.0;
cs.x = 0.90000;
cr = mat3( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
cr = mr(vec3(0, 1, 0), 180.0 - camera_yaw) * mr(vec3(1, 0, 0), -camera_pitch) * mr(vec3(0, 0, 1), camera_roll);
float a = rd( vec2( vPosition.x, vPosition.y ) );
gl_FragColor = vec4( a, a, a, 1.0 );
}
</script>
<body onload="webgl_init( 'canvas', 'shader', 'status' )" bgcolor="#000000">
<table cellspacing="0" cellpadding="0" border="0" width="100%" aheight="100%"><tr><td align="center" valign="middle">
<table cellspacing="0" cellpadding="0" border="0" width="200">
<tr>
<td style="padding:8px;background:#555555;color:#FFFFFF;font-family:arial;font-size:11px;font-weight:bold">
<div>WebGL GLSL Raycaster</div>
</td>
</tr>
<tr>
<td><canvas id="canvas" width="300" height="300" style="border:5px solid #FFFFFF"></canvas></td>
</tr><tr>
<td style="padding:8px;background:#555555;color:#FFFFFF;font-family:arial;font-size:11px;font-weight:bold">
<div id="status"> </div>
</td>
</tr>
</table>
</td></tr></table>
</body>
</html>