Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct material{
- vec3 color;
- };
- struct sphere{
- vec3 pos;
- float radius;
- float radiussq;
- material material;
- };
- struct panel{
- vec3 pos;
- vec3 normal;
- float radius;
- vec3 uvn1; //normal for uv
- vec3 uvn2;
- material material;
- };
- struct rayresult{
- bool hit; //if hit
- vec3 N; //normal
- vec3 P; //hit pos
- vec3 o; //origin
- vec3 v; //direction
- float dist; //distance
- vec2 uv; //material texture uv pos
- material material;
- };
- struct light{
- vec3 pos;
- float brightness;
- vec3 color;
- };
- const int sphere_count=20;
- sphere spheres[sphere_count];
- const int panel_count=1;
- panel panels[panel_count];
- const int light_count=3;
- light lights[light_count];
- mat4 cam = mat4(
- 1,0,0,0,
- 0,1,0,0,
- 0,0,1,0,
- 0,0,0,1
- );
- mat4 addmv(mat4 mat, vec3 v){
- mat4 n = mat;
- n[3]=n[3]+vec4(v,0);
- return n;
- }
- mat4 mat4v(vec3 v){
- return mat4(
- 1,0,0,v.x,
- 0,1,0,v.y,
- 0,0,1,v.z,
- 0,0,0,1
- );
- }
- vec3 matpos(mat4 mat){
- return mat[3].xyz;
- }
- const float planedist = 1.;
- //float tick = iTime/5.0;
- bool raycheck(vec3 pos, vec3 dir){
- for (int i=0;i<sphere_count;i++){
- sphere c=spheres[i];
- vec3 L = c.pos-pos;
- float tca = dot(L,dir);
- if (tca>0.){
- float d2 = dot(L,L)-tca*tca;
- if (d2<c.radiussq){
- return true;
- }
- }
- }
- for (int i=0;i<panel_count;i++){
- panel p=panels[i];
- vec3 op=p.pos-pos;
- if (dot(p.normal,dir)<0.){
- float dist = dot(op,p.normal)/dot(dir,p.normal);
- vec3 P = pos+dist*dir;
- if (length(P-p.pos)<p.radius){
- return true;
- }
- }
- }
- return false;
- }
- rayresult ray(vec3 pos, vec3 dir){
- rayresult ray;
- float zbuffer = 9999999999.;
- ray.hit=false;
- ray.o=pos;
- ray.v=dir;
- for (int i=0;i<sphere_count;i++){
- sphere c=spheres[i];
- vec3 L = c.pos-pos;
- float tca = dot(L,dir);
- if (tca>0.){
- float d2 = dot(L,L)-tca*tca;
- if (d2<c.radiussq){
- float dist = tca-sqrt(c.radiussq-d2);
- if (dist<zbuffer){
- zbuffer=dist;
- ray.P = pos+dist*dir;
- ray.N = normalize(ray.P-c.pos);
- ray.material=c.material;
- ray.dist=dist;
- ray.hit=true;
- ray.uv=vec2(atan(ray.N.z,ray.N.x),acos(ray.N.y));
- }
- }
- }
- }
- for (int i=0;i<panel_count;i++){
- panel p=panels[i];
- vec3 op=p.pos-pos;
- if (dot(p.normal,dir)<0.){
- float dist = dot(op,p.normal)/dot(dir,p.normal);
- vec3 P = pos+dist*dir;
- if ( dist<zbuffer && length(P-p.pos)<p.radius){
- zbuffer = dist;
- ray.P = P;
- ray.N = p.normal;
- ray.material=p.material;
- ray.dist=dist;
- ray.hit=true;
- vec3 normop = normalize(p.pos-P);
- ray.uv=vec2(atan(dot(p.uvn1,normop),dot(p.uvn2,normop)),length(p.pos-P)/p.radius*2.);
- }
- }
- }
- return ray;
- }
- const float ambient = 0.05;
- vec3 doLight(rayresult o,float dit,bool next){//Returns color
- vec3 col = vec3(0,0,0);
- for (int i=0;i<light_count;i++){
- vec3 v = lights[i].pos-o.P;
- vec3 dir = normalize(v);
- v += dir*dit;
- if (!raycheck(o.P,dir)){
- col += texture(iChannel1,o.uv).xyz
- *o.material.color
- *lights[i].color
- *lights[i].brightness
- /length(v)/length(v)
- *dot(v,o.N);
- }
- }
- if (!next){
- col+=texture(iChannel0,reflect(o.v,o.N)).xyz*ambient*o.material.color;
- }
- return col;
- }
- const int maxrec = 5; //maximum recursion
- vec3 manager(rayresult o){
- vec3 col = vec3(0,0,0);
- bool en = true;
- float dit=0.;
- int rec = 1;
- while (en && maxrec>rec){
- col += doLight(o,dit,rec<=1)/float(rec);
- vec3 ndir = reflect(o.v,o.N);
- o = ray(o.P+ndir*0.1,ndir);
- en = o.hit;
- dit+=o.dist;
- rec++;
- }
- return col;
- }
- void updatescene(float tick){
- for (int i=0;i<sphere_count;i++){
- float ii = float(i);
- spheres[i].pos=vec3(cos(tick+ii)*29.,sin(tick*5.+ii)*12.,50.1+ii*2.9+sin(ii*4.4567));
- spheres[i].radius = cos(tick*2.+ii)*2.+5.;
- spheres[i].radiussq = spheres[i].radius*spheres[i].radius;
- spheres[i].material.color=vec3(1,sin(ii),cos(ii));
- }
- lights[0].pos = vec3(0,20,45);
- lights[0].brightness = 25.;
- lights[0].color = vec3(1,1,1);
- //lights[1].pos = vec3(0,-20,45);
- //lights[1].brightness = 25.;
- //lights[1].color = vec3(1,1,1);
- //lights[2].pos = vec3(10,10,25);
- //lights[2].brightness = 25.;
- //lights[2].color = vec3(1,1,1);
- //for (int i=1;i<light_count;i++){
- //}
- panels[0].pos = vec3(0,-30,80);
- panels[0].normal = vec3(0,1,0);
- panels[0].radius = 30.;
- panels[0].material.color = vec3(1,1,1);
- panels[0].uvn1 = cross(panels[0].normal,normalize(vec3(454,957,234)));
- panels[0].uvn2 = cross(panels[0].normal,panels[0].uvn1);
- }
- void mainImage( out vec4 fragColor, in vec2 fragCoord )
- {
- float tick = iTime/15.;
- updatescene(tick);
- vec2 mouseuv = (iMouse.xy-iResolution.xy/2.0)/iResolution.xx*2.;
- mat4 ncam = cam
- *build_transform(vec3(0,0,0),vec3(0,-mouseuv.x*3.1415928,0))
- *build_transform(vec3(0,0,0),vec3(-mouseuv.y*3.1415928,0,0))
- ;
- ncam = ncam
- *build_transform(vec3(0,0,-80),vec3(0,0,0))
- ;
- ncam[3].xyz = ncam[3].xyz + vec3(0,0,80);
- vec3 campos = matpos(ncam);
- vec2 uv = (fragCoord-iResolution.xy/2.0)/iResolution.xx*2.;
- vec3 v = normalize(uv.x*ncam[0].xyz+uv.y*ncam[1].xyz+ncam[2].xyz*planedist);
- vec3 col = vec3(0,0,0);
- rayresult o = ray(campos,v);
- if (o.hit){
- col += manager(o);
- }else{
- col = texture(iChannel0,o.v).xyz;
- }
- fragColor = vec4(col,1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement