Guest User

path tracer glsl shader

a guest
Aug 6th, 2025
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OpenGL Shading 20.57 KB | Software | 0 0
  1. #version 430 core
  2.  
  3. #define EPS .000002
  4. #define M_PI 3.1415926535897932384626433832795
  5. #define SQRT_TWO 1.41421356237
  6. #define spatialrand vec2
  7. //#define CULL_BACKFACE
  8.  
  9. out vec4 FragColor;
  10.  
  11. uniform vec2 screenRes;
  12.  
  13. uniform mat4 camMat;
  14. uniform vec3 camPos;
  15.  
  16. uniform sampler2D skyBox;
  17.  
  18. uniform int renderMode;
  19.  
  20. uniform int triTestThreshold;
  21. uniform int boxTestThreshold;
  22.  
  23. uniform int frameCount;
  24.  
  25. uniform float time;
  26.  
  27. uniform int maxBounces;
  28. uniform int raysPerPix;
  29.  
  30. uniform bool drawSkyBox;
  31. uniform float skyBoxBrightness;
  32. uniform bool dls;
  33.  
  34. uint triTests = 0;
  35. uint boxTests = 0;
  36.  
  37. float weights[100];
  38. float weightSum = 0;
  39.  
  40. bool singleRay = false;
  41.  
  42. vec3 aces(vec3 x)
  43. {
  44.   const float a = 2.51;
  45.   const float b = 0.03;
  46.   const float c = 2.43;
  47.   const float d = 0.59;
  48.   const float e = 0.14;
  49.   return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);
  50. }
  51.  
  52. vec3 acesInv(vec3 x) {
  53.     return (sqrt(-10127.*x*x + 13702.*x + 9.) + 59.*x - 3.) / (502. - 486.*x);
  54. }
  55.  
  56. float rand(inout uint state) {
  57.     state = state * uint(747796405) + uint(2891336453);
  58.     uint result = ((state >> ((state >> uint(28)) + uint(4))) ^ state) * uint(277803737);
  59.     result = (result >> 22) ^ result;
  60.     return result / 4294967295.0;
  61. }
  62.  
  63. float randNormDist(inout uint state) {
  64.     float theta = 2.0 * 3.1415926 * rand(state);
  65.     float rho = sqrt(-2.0 * log(rand(state)));
  66.     return abs(rho * cos(theta)) / 6;
  67. }
  68.  
  69. vec3 isotropic(float rp, float c) {
  70.   // sin(a) = sqrt(1.0 - cos(a)^2) , in the interval [0, PI/2] relevant for us
  71.   float p = M_PI * 2 * rp, s = sqrt(1.0 - c*c);
  72.   return vec3(cos(p) * s, sin(p) * s, c);
  73. }
  74.  
  75. vec3 ortho(vec3 v) {
  76.   return mix(vec3(-v.y, v.x, 0.0), vec3(0.0, -v.z, v.y), step(abs(v.x), abs(v.z)));
  77. }
  78.  
  79. vec3 around(vec3 v, vec3 z) {
  80.   vec3 t = ortho(z), b = cross(z, t);
  81.   return fma(t, vec3(v.x), fma(b, vec3(v.y), z * v.z));
  82. }
  83.  
  84. vec3 randomCosineWeightedHemispherePoint(vec3 n, inout uint state) {
  85.  
  86.   vec3 rand = vec3(rand(state), rand(state), rand(state));
  87.  
  88.   float c = sqrt(rand.y);
  89.   return vec3(around(isotropic(rand.x, c), n));
  90. }
  91.  
  92. float randRange(inout uint state, float minVal, float maxVal) {
  93.     return rand(state) * (maxVal - minVal) + minVal;
  94. }
  95.  
  96. struct Tri {
  97.     vec4 v1;
  98.     vec4 v2;
  99.     vec4 v3;
  100.     vec4 normal;
  101.     vec4 minPos;
  102.     vec4 maxPos;
  103.     float area;
  104.     float accumArea;
  105.     float padding1;
  106.     float padding2;
  107. };
  108.  
  109. struct BoundingBox {
  110.     vec4 minPos;
  111.     vec4 maxPos;
  112.     uint triIndex;
  113.     uint triCount;
  114.     uint childAIndex;
  115.     uint childBIndex;
  116. };
  117.  
  118. struct Ray {
  119.     vec3 origin;
  120.     vec3 dir;
  121.     vec3 inLight;
  122.     vec3 rayCol;
  123. };
  124.  
  125. struct RayHit {
  126.     bool hit;
  127.     vec3 hitPos;
  128.     vec3 normal;
  129.     float dst;
  130.     int modelIndex;
  131.     int triIndex;
  132.     bool internal;
  133. };
  134.  
  135. struct Sphere {
  136.     vec3 pos;
  137.     float rad;
  138. };
  139.  
  140. struct Material {
  141.     vec4 diffuseCol;
  142.     float roughness;
  143.     float brightness;
  144.     float padding1;
  145.     float padding2;
  146. };
  147.  
  148. struct Model {
  149.     mat4 worldToModel;
  150.     mat4 modelToWorld;
  151.     Material mat;
  152.     uint rootBoxIndex;
  153.     float totalArea;
  154.     float scale;
  155.     uint lightIndex;
  156. };
  157.  
  158. struct LightSelectResult {
  159.     uint i;
  160.     float weight;
  161.     float weightSum;
  162. };
  163.  
  164. layout (std430, binding = 0) buffer Triangles {
  165.     Tri tris[];
  166. };
  167.  
  168. layout (std430, binding = 1) buffer Boxes {
  169.     BoundingBox boxes[];
  170. };
  171.  
  172. layout (std430, binding = 2) buffer Models {
  173.     Model models[];
  174. };
  175.  
  176. layout (std430, binding = 3) buffer Colors {
  177.     vec4 colors[];
  178. };
  179.  
  180. layout (std430, binding = 4) buffer LightIdxs {
  181.     unsigned int lightIdxs[];
  182. };
  183.  
  184. /*layout (std430, binding = 2) buffer RootBoxIndexes {
  185.     uint rootBoxIndex[];
  186. };*/
  187.  
  188. Ray newRay(inout uint state, vec2 uv) {
  189.     Ray r;
  190.     //r.dir = normalize((vec4(uv, -1.0, 1.0) * camMat).xyz + vec3(randRange(state, 0.0, 0.1), randRange(state, 0.0, 0.1), 0.0));
  191.     r.dir = normalize((vec4(uv, -1.0, 1.0) * camMat).xyz);
  192.     r.dir += randomCosineWeightedHemispherePoint(r.dir, state) * 0.001;
  193.     r.origin = camPos;
  194.     r.rayCol = vec3(1.0);
  195.     r.inLight = vec3(0.0);
  196.     return r;
  197. };
  198.  
  199. RayHit newRayHit() {
  200.     RayHit r;
  201.     r.hit = false;
  202.     r.hitPos = vec3(0.0);
  203.     r.normal = vec3(0.0);
  204.     r.dst = 9999999.f;
  205.     r.modelIndex = -1;
  206.     r.triIndex = -1;
  207.     r.internal = false;
  208.     return r;
  209. };
  210.  
  211. Sphere newSphere(vec3 pos, float rad)
  212. {
  213.     Sphere s;
  214.     s.pos = pos;
  215.     s.rad = rad;
  216.     return s;
  217. }
  218.  
  219. BoundingBox growToInclude(BoundingBox b, Tri t)
  220. {
  221.     b.minPos = vec4(min(b.minPos.x, t.v1.x), min(b.minPos.y, t.v1.y), min(b.minPos.z, t.v1.z), 0.0);
  222.     b.maxPos = vec4(max(b.maxPos.x, t.v1.x), max(b.maxPos.y, t.v1.y), max(b.maxPos.z, t.v1.z), 0.0);
  223.  
  224.     b.minPos = vec4(min(b.minPos.x, t.v2.x), min(b.minPos.y, t.v2.y), min(b.minPos.z, t.v2.z), 0.0);
  225.     b.maxPos = vec4(max(b.maxPos.x, t.v2.x), max(b.maxPos.y, t.v2.y), max(b.maxPos.z, t.v2.z), 0.0);
  226.  
  227.     b.minPos = vec4(min(b.minPos.x, t.v3.x), min(b.minPos.y, t.v3.y), min(b.minPos.z, t.v3.z), 0.0);
  228.     b.maxPos = vec4(max(b.maxPos.x, t.v3.x), max(b.maxPos.y, t.v3.y), max(b.maxPos.z, t.v3.z), 0.0);
  229.  
  230.     return b;
  231. }
  232.  
  233. float boxCollide(Ray r, BoundingBox b)
  234. {
  235.     vec3 invDir = 1.f / r.dir;
  236.     vec3 tMin = (b.minPos.xyz - r.origin) * invDir;
  237.     vec3 tMax = (b.maxPos.xyz - r.origin) * invDir;
  238.     vec3 t1 = min(tMin, tMax);
  239.     vec3 t2 = max(tMin, tMax);
  240.  
  241.     float dstFar = min(min(t2.x, t2.y), t2.z);
  242.     float dstNear = max(max(t1.x, t1.y), t1.z);
  243.  
  244.     if (dstFar >= dstNear && dstFar > 0)
  245.     {
  246.         return dstNear;
  247.     }
  248.     ++boxTests;
  249.     return 9999999.0;
  250. }
  251.  
  252. RayHit triCollide(Ray ray, Tri tri)
  253. {
  254.     RayHit rHit = newRayHit();
  255.     vec3 e1 = tri.v2.xyz - tri.v1.xyz; vec3 e2 = tri.v3.xyz - tri.v1.xyz;
  256.     vec3 dxe2 = cross(ray.dir, e2);
  257.     float det = dot(dxe2, e1);
  258.     // ray parallel to triangle plane
  259.     if (abs(det) < EPS) return rHit;
  260.     if (det < EPS)
  261.     {
  262.         rHit.internal = true;
  263.     }
  264.     float invDet = 1. / det;
  265.     vec3 t = ray.origin - tri.v1.xyz;
  266.     float u = dot(dxe2, t) * invDet;
  267.     vec3 txe1 = cross(t, e1);
  268.     float v = dot(txe1, ray.dir) * invDet;
  269.     if (u < 0. || v < 0. || u + v > 1.) return rHit;
  270.     float d = dot(txe1, e2) * invDet;
  271.     //result = vec3(d, u, v);
  272.     if (d > 0.0)
  273.     {
  274.         rHit.hit = true;
  275.         if (rHit.internal)
  276.         {
  277.             rHit.normal = -tri.normal.xyz;
  278.         }
  279.         else
  280.         {
  281.             rHit.normal = tri.normal.xyz;
  282.         }
  283.         rHit.dst = d;
  284.         rHit.hitPos = ray.origin + ray.dir * d;
  285.     }
  286.     ++triTests;
  287.     return rHit;
  288. }
  289.  
  290. RayHit sphereCollide(Ray r, Sphere s) {
  291.     RayHit rHit = newRayHit();
  292.  
  293.     float a = dot(r.dir, r.dir);
  294.     vec3 s0_r0 = r.origin - s.pos;
  295.     float b = 2.0 * dot(r.dir, s0_r0);
  296.     float c = dot(s0_r0, s0_r0) - (s.rad * s.rad);
  297.     float dst = (-b - sqrt((b*b) - 4.0*a*c))/(2.0*a);
  298.     if (!(b*b - 4.0*a*c < 0.0) && dst > 0) {
  299.         rHit.hit = true;
  300.         rHit.dst = dst;
  301.         rHit.hitPos = r.origin + r.dir * rHit.dst;
  302.         rHit.normal = normalize(rHit.hitPos - s.pos);
  303.     }
  304.     return rHit;
  305. }
  306.  
  307. RayHit findHit(Ray r) {
  308.  
  309.     RayHit closest = newRayHit();
  310.  
  311.     closest.hitPos = r.dir;
  312.  
  313.     uint stack[64];
  314.     uint stackIndex = 0;
  315.  
  316.     Ray localRay = r;
  317.  
  318.     for (int modelIndex = 0; modelIndex < models.length(); ++modelIndex)
  319.     {
  320.         stack[stackIndex++] = models[modelIndex].rootBoxIndex;
  321.  
  322.         localRay.origin = (vec4(r.origin, 1.0) * models[modelIndex].worldToModel).xyz;
  323.         localRay.dir = (vec4(r.dir, 0.0) * models[modelIndex].worldToModel).xyz;
  324.  
  325.         while (stackIndex > 0)
  326.         {
  327.             BoundingBox box = boxes[stack[--stackIndex]];
  328.  
  329.             if (box.childAIndex == 0)
  330.             {
  331.                 for (uint i = box.triIndex; i < box.triIndex + box.triCount; ++i)
  332.                 {
  333.                     RayHit rHit = triCollide(localRay, tris[i]);
  334.                     //rHit.dst *= models[modelIndex].scale;
  335.  
  336.                     if (rHit.hit && rHit.dst < closest.dst)
  337.                     {
  338.                         closest = rHit;
  339.                         closest.normal = normalize((vec4(closest.normal, 0.0) * models[modelIndex].modelToWorld).xyz);
  340.                         closest.hitPos = (vec4(closest.hitPos, 1.0) * models[modelIndex].modelToWorld).xyz;
  341.                         closest.modelIndex = modelIndex;
  342.                         closest.triIndex = int(i);
  343.                     }
  344.                 }
  345.             }
  346.             else
  347.             {
  348.                 BoundingBox childA = boxes[box.childAIndex];
  349.                 BoundingBox childB = boxes[box.childBIndex];
  350.  
  351.                 float dstA = boxCollide(localRay, childA);
  352.                 float dstB = boxCollide(localRay, childB);
  353.  
  354.                 if (dstA > dstB)
  355.                 {
  356.                     if (dstA < closest.dst) stack[stackIndex++] = box.childAIndex;
  357.                     if (dstB < closest.dst) stack[stackIndex++] = box.childBIndex;
  358.                 }
  359.                 else
  360.                 {
  361.                     if (dstB < closest.dst) stack[stackIndex++] = box.childBIndex;
  362.                     if (dstA < closest.dst) stack[stackIndex++] = box.childAIndex;
  363.                 }  
  364.             }
  365.         }
  366.     }
  367.  
  368.     return closest;
  369. }
  370.  
  371. vec2 sphericalMap(vec3 p)
  372. {
  373.     float theta = atan(p.x, p.z);
  374.  
  375.     vec3 vec = vec3(p.x, p.y, p.z);
  376.     float radius = length(vec);
  377.     float phi = acos(p.y / radius);
  378.  
  379.     float raw_u = theta / (2 * M_PI);
  380.  
  381.     float u = 1 - (raw_u + 0.5);
  382.  
  383.     float v = 1 - phi / (M_PI);
  384.  
  385.     return vec2(u, v);
  386. }
  387.  
  388. /*void BRDF(inout Ray r, RayHit rH, inout uint state)
  389. {
  390.     if (models[rH.modelIndex].mat.brightness == 0)
  391.     {
  392.         r.dir = normalize((r.dir - 2.0 * (dot(r.dir, rH.normal)) * rH.normal) * (1 - models[rH.modelIndex].mat.roughness) + randomCosineWeightedHemispherePoint(rH.normal, state) * models[rH.modelIndex].mat.roughness);
  393.         r.origin = rH.hitPos + r.dir * 0.001;
  394.         r.rayCol = models[rH.modelIndex].mat.diffuseCol.xyz * r.rayCol;
  395.     }
  396.     else
  397.     {
  398.        
  399.     }
  400. }*/
  401.  
  402. uint sampleLightDistanceAreaWeighted(vec3 hitPos, inout uint state)
  403. {
  404.     //float weights[100];  // max 100 lights — adjust as needed
  405.     weightSum = 0.0;
  406.  
  407.     for (uint i = 0; i < lightIdxs.length(); ++i) {
  408.         vec3 lightPos = (vec4(0.0, 0.0, 0.0, 1.0) * models[lightIdxs[i]].modelToWorld).xyz;
  409.         float distSq = dot(lightPos - hitPos, lightPos - hitPos) + EPS;
  410.         weights[i] = models[lightIdxs[i]].mat.brightness * (models[lightIdxs[i]].totalArea * models[lightIdxs[i]].scale * models[lightIdxs[i]].scale) / distSq;
  411.         weightSum += weights[i];
  412.     }
  413.  
  414.     float cdf[100];
  415.     float accum = 0.0;
  416.     for (uint i = 0; i < lightIdxs.length(); ++i) {
  417.         accum += weights[i] / weightSum;
  418.         cdf[i] = accum;
  419.     }
  420.  
  421.     float xi = rand(state);
  422.     for (uint i = 0; i < lightIdxs.length(); ++i) {
  423.         if (xi < cdf[i]) {
  424.             return i;
  425.         }
  426.     }
  427.  
  428.     return uint(rand(state) * lightIdxs.length());
  429. }
  430.  
  431. uint lightSampleTriIdx(uint modelIdx, inout uint state)
  432. {
  433.     float r = rand(state); // Uniform in [0, 1]
  434.  
  435.     // Binary search over CDF
  436.     uint low = boxes[models[modelIdx].rootBoxIndex].triIndex;
  437.     uint high = boxes[models[modelIdx].rootBoxIndex].triIndex + boxes[models[modelIdx].rootBoxIndex].triCount;
  438.     while (low < high) {
  439.         uint mid = (low + high) / 2;
  440.         if (r < tris[mid].accumArea)
  441.             high = mid;
  442.         else
  443.             low = mid + 1;
  444.     }
  445.  
  446.     return low;
  447. }
  448.  
  449. vec3 directLightSample(Ray r, RayHit rH, inout uint state)
  450. {
  451.     vec3 col = vec3(0.0);
  452.  
  453.     RayHit lH = newRayHit();
  454.  
  455.     uint i = sampleLightDistanceAreaWeighted(rH.hitPos, state);
  456.     //uint i = uint(rand(state) * lightIdxs.length());;
  457.     uint triIndex = lightSampleTriIdx(lightIdxs[i], state);
  458.  
  459.     float u = rand(state);
  460.     float v = rand(state);
  461.  
  462.     if (u + v > 1.0f) {
  463.         u = 1.0f - u;
  464.         v = 1.0f - v;
  465.     }
  466.  
  467.     vec4 v1 = tris[triIndex].v1 * models[lightIdxs[i]].modelToWorld;
  468.     vec4 v2 = tris[triIndex].v2 * models[lightIdxs[i]].modelToWorld;
  469.     vec4 v3 = tris[triIndex].v3 * models[lightIdxs[i]].modelToWorld;
  470.  
  471.     vec3 triNormal = (tris[triIndex].normal * models[lightIdxs[i]].modelToWorld).xyz;
  472.     triNormal = normalize(triNormal);
  473.  
  474.     vec3 samplePoint = v1.xyz + u * (v2 - v1).xyz + v * (v3 - v1).xyz;
  475.  
  476.     vec3 toLight = samplePoint - rH.hitPos;
  477.     float dstToLight = length(toLight);
  478.     vec3 dir = normalize(toLight);
  479.  
  480.     float cos_surface = max(dot(rH.normal, dir), 0.0);
  481.     float cos_light = max(dot(-dir, triNormal), 0.0);
  482.  
  483.     float lightPickPdf = weights[i] / weightSum;
  484.     //float lightPickPdf = 1.0 / lightIdxs.length();
  485.  
  486.     float area =  models[lightIdxs[i]].totalArea / tris[triIndex].area;
  487.     float pdfArea = (area * models[lightIdxs[i]].scale * models[lightIdxs[i]].scale);
  488.     float pdfLight = ((dstToLight * dstToLight) / (cos_light * pdfArea)) * lightPickPdf;
  489.  
  490.     //pdfLight = 1.0;
  491.  
  492.     float pdfBRDF = max(dot(dir, rH.normal), 0.0) / M_PI;
  493.  
  494.     Ray r2 = r;
  495.     r2.dir = dir;
  496.  
  497.     r2.origin = rH.hitPos + r2.dir * 0.001;
  498.  
  499.     lH = findHit(r2);
  500.     if (lH.hit && lH.triIndex == triIndex && lH.modelIndex == lightIdxs[i])
  501.     {
  502.         vec3 emittedLight = models[lightIdxs[i]].mat.diffuseCol.xyz * models[lightIdxs[i]].mat.brightness;// Emission per triangle
  503.         vec3 brdf = models[rH.modelIndex].mat.diffuseCol.xyz / M_PI;
  504.  
  505.         vec3 contribution = (emittedLight * brdf * cos_surface) / (pdfLight);
  506.         //vec3 contribution = (emittedLight * brdf * cos_surface * cos_light) / (dstToLight * dstToLight * pdfLight);
  507.  
  508.         //float w = (pdfLight * pdfLight) / (pdfLight * pdfLight + pdfBRDF * pdfBRDF);
  509.         float w = pdfLight / (pdfLight + pdfBRDF);
  510.  
  511.         col += contribution * r.rayCol * w;
  512.     }
  513.     return col;
  514. }
  515.  
  516. vec4 trace(Ray r, inout uint state)
  517. {
  518.     RayHit rH = newRayHit();
  519.  
  520.     vec3 emittedLight = vec3(0.0);
  521.  
  522.     for (int bounces = 0; bounces < maxBounces; ++bounces)
  523.     {
  524.         rH = findHit(r);
  525.  
  526.         if (rH.hit)
  527.         {
  528.             if (models[rH.modelIndex].mat.brightness == 0)
  529.             {
  530.                 if (dls)
  531.                 {
  532.                     r.inLight += directLightSample(r, rH, state);
  533.                     //return vec4(directLightSample(r, rH, state), 1.0);
  534.                 }
  535.  
  536.                 r.dir = normalize((r.dir - 2.0 * (dot(r.dir, rH.normal)) * rH.normal) * (1 - models[rH.modelIndex].mat.roughness) + randomCosineWeightedHemispherePoint(rH.normal, state) * models[rH.modelIndex].mat.roughness);
  537.                 r.origin = rH.hitPos + r.dir * 0.001;
  538.                 r.rayCol = models[rH.modelIndex].mat.diffuseCol.xyz / M_PI * r.rayCol;
  539.  
  540.             }
  541.             else
  542.             {
  543.                 emittedLight = models[rH.modelIndex].mat.diffuseCol.xyz * models[rH.modelIndex].mat.brightness;
  544.                 if (bounces == 0)
  545.                 {
  546.                     singleRay = true;
  547.                     return vec4(emittedLight, 1.0);
  548.                     //return vec4(vec3(tris[rH.triIndex].accumArea), 1.0);
  549.                 }
  550.  
  551.                 if (dls)
  552.                 {
  553.                     float pdfBRDF = max(dot(r.dir, rH.normal), 0.0);
  554.  
  555.                     float cos_surface = max(dot(rH.normal, r.dir), 0.0);
  556.                     float cos_light = max(dot(-r.dir, tris[rH.triIndex].normal.xyz), 0.01); // clamp here!
  557.  
  558.                     uint light = models[rH.modelIndex].lightIndex;
  559.  
  560.                     float lightPickPdf = weights[light] / weightSum;
  561.                     //float pdfArea = 1.0 / (models[rH.modelIndex].totalArea * models[rH.modelIndex].scale * models[rH.modelIndex].scale);
  562.                     //float pdfLight = ((rH.dst * rH.dst) / cos_light) * pdfArea * lightPickPdf;
  563.                     float area =  models[rH.modelIndex].totalArea / tris[rH.triIndex].area;
  564.                     float pdfArea = (area * models[rH.modelIndex].scale * models[rH.modelIndex].scale);
  565.                     float pdfLight = ((rH.dst * rH.dst) / (cos_light * pdfArea)) * lightPickPdf;
  566.                     //float pdfLight = pdfArea * rH.dst * rH.dst / (cos_light + 0.000001);
  567.  
  568.                     //float w = (pdfBRDF * pdfBRDF) / (pdfLight * pdfLight + pdfBRDF * pdfBRDF);
  569.                     float w = pdfBRDF / (pdfLight + pdfBRDF);
  570.  
  571.                     r.inLight += w * emittedLight * r.rayCol;
  572.                 }
  573.                 else
  574.                 {
  575.                     r.inLight += emittedLight * r.rayCol;
  576.                 }
  577.                
  578.                 return vec4(r.inLight, 1.0);
  579.             }
  580.         }
  581.         else
  582.         {
  583.             if (bounces == 0)
  584.             {
  585.                 singleRay = true;
  586.                 if (drawSkyBox)
  587.                 {
  588.                     r.inLight += r.rayCol * acesInv(texture(skyBox, sphericalMap(-r.dir)).xyz * skyBoxBrightness);
  589.                     return vec4(r.inLight, 1.0);
  590.                 }
  591.                 return vec4(0.0);
  592.             }
  593.             else
  594.             {
  595.                 if (drawSkyBox)
  596.                 {
  597.                     r.inLight += r.rayCol * acesInv(texture(skyBox, sphericalMap(-r.dir)).xyz * skyBoxBrightness);
  598.                     return vec4(r.inLight, 1.0);
  599.                 }
  600.                 return vec4(r.inLight, 1.0);
  601.             }
  602.         }
  603.     }
  604.     return vec4(r.inLight, 1.0);
  605. }
  606.  
  607. void main()
  608. {
  609.     vec2 texUV = gl_FragCoord.xy / screenRes;
  610.     vec2 uv = ((texUV - 0.5) * 2) * vec2(screenRes.x / screenRes.y, 1.0);
  611.     uint pixelIndex = uint(gl_FragCoord.y * screenRes.x + gl_FragCoord.x);
  612.     uint rngState = pixelIndex + uint(time * 3000 * (2508 - time));
  613.  
  614.     Ray r = newRay(rngState, uv);
  615.  
  616.     switch (renderMode) {
  617.         case 0:
  618.             RayHit rHit = findHit(r);
  619.             //FragColor = vec4(0.0, 1.0, 0.0, 1.0);
  620.            
  621.             if (rHit.hit) {
  622.                 FragColor = models[rHit.modelIndex].mat.diffuseCol * (dot(rHit.normal, vec3(1.0)) + 1) * 0.5;
  623.             }
  624.             else {
  625.                 if (drawSkyBox) {
  626.                     FragColor = texture(skyBox, sphericalMap(-r.dir));
  627.                 }
  628.                 else {
  629.                     FragColor = vec4(0.0, 0.0, 0.0, 1.0);
  630.                 }
  631.             }
  632.            
  633.             break;
  634.         case 1:
  635.            
  636.             if (frameCount == 1)
  637.             {
  638.                 vec4 col = vec4(0.0);
  639.                 for (int i = 0; i < raysPerPix; ++i)
  640.                 {
  641.                     col += trace(r, rngState);
  642.                     if (singleRay)
  643.                     {
  644.                         col *= raysPerPix;
  645.                         break;
  646.                     }
  647.                 }
  648.                 colors[pixelIndex] = col;
  649.                 FragColor = vec4(aces(colors[pixelIndex].xyz / raysPerPix), 1.0);
  650.                 //FragColor = vec4(colors[pixelIndex].xyz, 1.0);
  651.                 //FragColor = vec4(vec3(a) / raysPerPix, 1.0);
  652.             }
  653.             else
  654.             {
  655.                 vec4 col = vec4(0.0);
  656.                 for (int i = 0; i < raysPerPix; ++i)
  657.                 {
  658.                     col += trace(r, rngState);
  659.                     if (singleRay)
  660.                     {
  661.                         col *= raysPerPix;
  662.                         break;
  663.                     }
  664.                 }
  665.                 colors[pixelIndex] += col;
  666.                 FragColor = vec4(aces(colors[pixelIndex].xyz / (raysPerPix * frameCount)), 1.0);
  667.                 //FragColor = vec4(colors[pixelIndex].xyz / frameCount, 1.0);
  668.                 //FragColor = vec4(vec3(a) / raysPerPix, 1.0);
  669.             }
  670.             break;
  671.  
  672.         case 2:
  673.             vec4 col1 = vec4(0.0);
  674.             for (int i = 0; i < raysPerPix; ++i)
  675.             {
  676.                 col1 += trace(r, rngState);
  677.                 if (singleRay)
  678.                 {
  679.                     break;
  680.                 }
  681.             }
  682.             if (triTests > triTestThreshold)
  683.             {
  684.                 FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  685.             }
  686.             else
  687.             {
  688.                 FragColor = vec4(vec3(float(triTests) / float(triTestThreshold)), 1.0);
  689.             }
  690.             break;
  691.  
  692.         case 3:
  693.             vec4 col2 = vec4(0.0);
  694.             for (int i = 0; i < raysPerPix; ++i)
  695.             {
  696.                 col2 += trace(r, rngState);
  697.                 if (singleRay)
  698.                 {
  699.                     break;
  700.                 }
  701.             }
  702.             if (boxTests > boxTestThreshold)
  703.             {
  704.                 FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  705.             }
  706.             else
  707.             {
  708.                 FragColor = vec4(vec3(float(boxTests) / float(boxTestThreshold)), 1.0);
  709.             }
  710.             break;
  711.     }
  712. }
Advertisement
Add Comment
Please, Sign In to add comment