The Code Therapy

my raytrace

this is a raytracer that i am making

Created by purplejragon on Thu, 09 Mar 2023 15:07:56 GMT.


#version 300 es
precision highp float;

uniform vec2 resolution;
uniform float time;
out vec4 fragColor;
uniform sampler2D prgm1Texture;

void main(void) {
  vec4 tex = texture(prgm1Texture, gl_FragCoord.xy / resolution);
  fragColor = vec4(tex.xyz / tex.w, 1.0);
}

#version 300 es
precision highp float;

uniform vec2 resolution;
uniform float time;
out vec4 fragColor;
uniform sampler2D prgm1Texture;
vec3 aces(vec3 x) {
  const float a = 2.51;
  const float b = 0.03;
  const float c = 2.43;
  const float d = 0.59;
  const float e = 0.14;
  return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);
}
vec3 reinhard(vec3 x) {
  return x / (x + 1.0);
}
mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
 vec3 rr = vec3(sin(roll), cos(roll), 0.0);
 vec3 ww = normalize(target - origin);
 vec3 uu = normalize(cross(ww, rr));
 vec3 vv = normalize(cross(uu, ww));
 return mat3(uu, vv, ww);
}
vec3 palette(float t) {
  vec3 a = vec3(0.5, 0.5, 0.5);
  vec3 b = vec3(0.5, 0.5, 0.5);
  vec3 c = vec3(1.0, 1.0, 0.5);
  vec3 d = vec3(0.80, 0.90, 0.30);
  return a + b * cos(6.28318*(c*t+d));
}
uint base_hash(uvec2 p) {
  p = 1103515245U*((p >> 1U)^(p.yx));
  uint h32 = 1103515245U*((p.x)^(p.y>>3U));
  return h32^(h32 >> 16);
}
float g_seed = 0.;
vec2 hash2(inout float seed) {
  uint n = base_hash(floatBitsToUint(vec2(seed+=.1,seed+=.1)));
  uvec2 rz = uvec2(n, n*48271U);
  return vec2(rz.xy & uvec2(0x7fffffffU))/float(0x7fffffff);
}
vec3 hash3(inout float seed) {
  uint n = base_hash(floatBitsToUint(vec2(seed+=.1,seed+=.1)));
  uvec3 rz = uvec3(n, n*16807U, n*48271U);
  return vec3(rz & uvec3(0x7fffffffU))/float(0x7fffffff);
}
float iSphere(vec3 ro, vec3 rd, vec3 ce, float ra) {
  vec3 oc = ro - ce;
  float b = dot(oc, rd);
  float c = dot(oc, oc) - ra * ra;
  float h = b * b - c;
  if(h < 0.0) return -1.0;
  h = sqrt(h);
  return -b - h;
}
vec3 nSphere(vec3 p, vec4 s) {
  return (p - s.xyz) / s.w;
}
float iPlane(vec3 ro, vec3 rd, vec4 p) {
  return -(dot(ro,p.xyz)+p.w)/dot(rd,p.xyz);
}
const int numSpheres = 25;
const vec4 spheres[numSpheres] = vec4[](
  vec4(-0.36660654093250233, 0.4810051779075237, 4.0582166281008, 0.4810051779075237),
vec4(0.521231691042181, 0.757207009221915, -0.557816893265084, 0.757207009221915),
vec4(-0.40080925266423595, 0.4058643452165143, -4.112902788720031, 0.4058643452165143),
vec4(-0.4121365439967972, 0.7697890374478957, 1.8430600789763654, 0.7697890374478957),
vec4(0.2502733742857135, 0.33647212707003205, -4.685633062982894, 0.33647212707003205),
vec4(0.8167705545563084, 0.3311226388150169, -3.5034755501910597, 0.3311226388150169),
vec4(-0.7598735568019643, 0.5727583894206782, 0.3584147381529643, 0.5727583894206782),
vec4(0.7404326972326567, 0.5159643753149772, 2.5848576377583186, 0.5159643753149772),
vec4(-0.47805673862040976, 0.651293010370205, -2.146204386807269, 0.651293010370205),
vec4(-0.7208223110337499, 0.30497953508248316, -1.229065945343637, 0.30497953508248316),
vec4(0.702683624947583, 0.3512271868587096, -2.231423108443006, 0.3512271868587096),
vec4(0.47649746625461376, 0.3682419909501204, 0.7098580471899734, 0.3682419909501204),
vec4(-0.24333331534202696, 0.35675962874402195, 3.2203811292920523, 0.35675962874402195),
vec4(-0.04586411577434468, 0.33691206669653767, 4.844348635897296, 0.33691206669653767),
vec4(0.7324917627333107, 0.3877275760581087, 4.105576417624642, 0.3877275760581087),
vec4(0.8142768099575015, 0.3703983298792686, 4.9240917931373644, 0.3703983298792686),
vec4(-0.673161582726614, 0.34009759836735004, -4.984317924682228, 0.34009759836735004),
vec4(0.7455662661888152, 0.332145907120081, -4.2302172897676, 0.332145907120081),
vec4(-0.39515341352844846, 0.37392780538735154, -3.2099644226990187, 0.37392780538735154),
vec4(0.8587826390764572, 0.3805379583841979, 1.5951397478717269, 0.3805379583841979),
vec4(-0.7950474325838179, 0.3218585197465875, -0.5825592294935857, 0.3218585197465875),
vec4(0.3433121539311852, 0.3883042947150447, -2.8864372825682674, 0.3883042947150447),
vec4(0.3824731367455927, 0.3238372357594674, -1.5978591060350498, 0.3238372357594674),
vec4(-0.8471778492166102, 0.3096693802720418, 2.9204053805327748, 0.3096693802720418),
vec4(-0.9311663985751686, 0.31732049103175325, 4.642701792539025, 0.31732049103175325)
);
bool intersect(vec3 ro, vec3 rd, out vec2 hit, out vec3 nor) {
  float t = 1000.0;
  float d;
  float m = -1.0;

  vec4 p = vec4(normalize(vec3(0, 1, 0)), 0.0);
  d = iPlane(ro, rd, p); if (d > 0.0 && d < t) { t = d; m = 1.0; nor = p.xyz; }

  float seed = 2.0;

  for (int i = 0; i < numSpheres; i++) {
    vec4 s = spheres[i];
    d = iSphere(ro, rd, s.xyz, s.w); if (d > 0.0 && d < t) { t = d; m = float(i+2); nor = nSphere(ro+rd*t, s); }
  }
  hit = vec2(t, m);
  return m > 0.0;
}
void material(float m, vec3 pos, vec3 nor, out vec3 color, out vec3 emission) {
  emission = vec3(0);
  if (int(m) % 5 == 0) {
    emission = vec3(20) * palette(m * 60000.0);
  }
  if (m == 1.0) {
    color = vec3(0.6);
  }
  else {
    color = palette(m*60000.0);
  }
}
vec3 raytrace(in vec3 ro, in vec3 rd) {
  vec3 scol = vec3(1.0);
  vec3 fcol = vec3(0);
  vec2 hit;
  vec3 nor;
  for (int i = 0; i < 4; i++) {
    if (intersect(ro, rd, hit, nor)) {
      vec3 p = ro + rd * hit.x;

      ro = p + nor * 0.001;
      vec3 target = ro+nor + (hash3(g_seed)*2.-1.);
      rd = normalize(target - ro);

      float cosTheta = max(0., dot(rd, nor));
      vec3 emission, color;
      material(hit.y, p, nor, color, emission);
      scol *= color * cosTheta * 2.0;
      fcol += emission;
    } else {
      //scol *= mix(vec3(0.0), vec3(0.04, 0.08, 0.4), rd.y * 0.5 + 0.5);
      scol *= vec3(0.04, 0.05, 0.06);
      fcol += scol;
      break;
    }
  }
  return fcol;
}
void main(void) {
  g_seed = float(base_hash(floatBitsToUint(gl_FragCoord.xy))) / float(0xffffffff)+time*10000.;
  vec4 prev = texture(prgm1Texture, gl_FragCoord.xy / resolution);
  vec3 ro = vec3(1, 4, -3);
  mat3 la = calcLookAtMatrix(ro, vec3(0.0, 0.5, 0), 0.0);
  vec3 rd = normalize(la * vec3(((gl_FragCoord.xy + hash2(g_seed)) - 0.5 * resolution) / resolution.y, 1.0));
  vec3 color = raytrace(ro, rd);
  color = sqrt(aces(color));
  fragColor = vec4(color, 1.0) + prev;
}