diff --git a/shaders/Geometry_Showcase_Fragment.glsl b/shaders/Geometry_Showcase_Fragment.glsl index 1a9033d6..8a5ee73b 100644 --- a/shaders/Geometry_Showcase_Fragment.glsl +++ b/shaders/Geometry_Showcase_Fragment.glsl @@ -28,7 +28,7 @@ vec3 rayOrigin, rayDirection; // recorded intersection data: vec3 hitNormal, hitEmission, hitColor; vec2 hitUV; -float hitObjectID; +float hitObjectID = -INFINITY; int hitType = -100; struct Sphere { float radius; vec3 position; vec3 emission; vec3 color; int type; }; @@ -83,9 +83,11 @@ float SceneIntersect( out int finalIsRayExiting ) //------------------------------------------------------------------------------------------------------------------- { vec3 rObjOrigin, rObjDirection; + vec3 hitPos; vec3 n; float d, dt; float t = INFINITY; + float q; int isRayExiting = FALSE; int insideSphere = FALSE; int objectCount = 0; @@ -133,9 +135,11 @@ float SceneIntersect( out int finalIsRayExiting ) if (d < t) { t = d; - hitNormal = (rayOrigin + rayDirection * t) - spheres[3].position; + hitPos = rayOrigin + (rayDirection * t); + hitNormal = hitPos - spheres[3].position; hitEmission = spheres[3].emission; - hitColor = spheres[3].color; + q = clamp( mod( dot( floor(hitPos.xz * 0.04), vec2(1.0) ), 2.0 ) , 0.0, 1.0 ); + hitColor = mix(vec3(0.5), spheres[3].color, q); hitType = spheres[3].type; hitObjectID = float(objectCount); } @@ -305,72 +309,78 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o vec3 reflectionMask = vec3(1); vec3 reflectionRayOrigin = vec3(0); vec3 reflectionRayDirection = vec3(0); - vec3 checkCol0 = vec3(1); - vec3 checkCol1 = vec3(0.5); vec3 dirToLight; - vec3 tdir; vec3 x, n, nl; float t; float nc, nt, ratioIoR, Re, Tr; - //float P, RP, TP; float weight; float thickness = 0.1; + float previousObjectID; + int reflectionBounces = -1; int diffuseCount = 0; int previousIntersecType = -100; hitType = -100; - int coatTypeIntersected = FALSE; int bounceIsSpecular = TRUE; int sampleLight = FALSE; int isRayExiting; int willNeedReflectionRay = FALSE; + int isReflectionTime = FALSE; + int reflectionNeedsToBeSharp = FALSE; lightChoice = spheres[int(rand() * N_LIGHTS)]; - for (int bounces = 0; bounces < 7; bounces++) + for (int bounces = 0; bounces < 8; bounces++) { + if (isReflectionTime == TRUE) + reflectionBounces++; + previousIntersecType = hitType; + previousObjectID = hitObjectID; t = SceneIntersect(isRayExiting); - /* - //not used in this scene because we are inside a huge sphere - no rays can escape + // shouldn't happen because we are inside a huge checkered sphere, but just in case if (t == INFINITY) { break; } - */ - + // useful data n = normalize(hitNormal); nl = dot(n, rayDirection) < 0.0 ? n : -n; x = rayOrigin + rayDirection * t; if (bounces == 0) + { + objectID = hitObjectID; + } + if (isReflectionTime == FALSE && diffuseCount == 0 && hitObjectID != previousObjectID) { objectNormal = nl; objectColor = hitColor; - objectID = hitObjectID; } - if (bounces == 1 && diffuseCount == 0 && previousIntersecType == SPEC) + if (reflectionNeedsToBeSharp == TRUE && reflectionBounces == 0) { objectNormal = nl; + objectColor = hitColor; } + if (hitType == LIGHT) { - if (bounces == 0 || (bounces == 1 && previousIntersecType == SPEC)) - pixelSharpness = 1.01; + if (diffuseCount == 0 && isReflectionTime == FALSE) + pixelSharpness = 1.0; - if (diffuseCount == 0) + if (isReflectionTime == TRUE && bounceIsSpecular == TRUE) { objectNormal = nl; - objectColor = hitColor; + //objectColor = hitColor; objectID = hitObjectID; } @@ -386,7 +396,7 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o willNeedReflectionRay = FALSE; bounceIsSpecular = TRUE; sampleLight = FALSE; - diffuseCount = 0; + isReflectionTime = TRUE; continue; } // reached a light, so we can exit @@ -407,7 +417,7 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o willNeedReflectionRay = FALSE; bounceIsSpecular = TRUE; sampleLight = FALSE; - diffuseCount = 0; + isReflectionTime = TRUE; continue; } @@ -417,17 +427,9 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o - if (hitType == DIFF || hitType == CHECK) // Ideal DIFFUSE reflection + if (hitType == DIFF) // Ideal DIFFUSE reflection { - if( hitType == CHECK ) - { - float q = clamp( mod( dot( floor(x.xz * 0.04), vec2(1.0) ), 2.0 ) , 0.0, 1.0 ); - hitColor = checkCol0 * q + checkCol1 * (1.0 - q); - } - // must update objectColor because hitColor may have changed - if (bounces == 0 || (diffuseCount == 0 && coatTypeIntersected == FALSE && previousIntersecType == SPEC)) - objectColor = hitColor; - + diffuseCount++; mask *= hitColor; @@ -462,39 +464,34 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o rayDirection = reflect(rayDirection, nl); rayOrigin = x + nl * uEPS_intersect; - //if (diffuseCount == 1) - // bounceIsSpecular = TRUE; // turn on reflective mirror caustics + // if (diffuseCount == 1) + // bounceIsSpecular = TRUE; // turn on reflective mirror caustics continue; } if (hitType == REFR) // Ideal dielectric REFRACTION { - pixelSharpness = diffuseCount == 0 && coatTypeIntersected == FALSE ? -1.0 : pixelSharpness; - nc = 1.0; // IOR of Air nt = 1.5; // IOR of common Glass Re = calcFresnelReflectance(rayDirection, n, nc, nt, ratioIoR); Tr = 1.0 - Re; - if (bounces == 0 || (bounces == 1 && hitObjectID != objectID && bounceIsSpecular == TRUE)) + if (Re == 1.0) + { + rayDirection = reflect(rayDirection, nl); + rayOrigin = x + nl * uEPS_intersect; + continue; + } + + if (diffuseCount == 0 && hitObjectID != previousObjectID && n == nl) { reflectionMask = mask * Re; reflectionRayDirection = reflect(rayDirection, nl); // reflect ray from surface reflectionRayOrigin = x + nl * uEPS_intersect; willNeedReflectionRay = TRUE; - } - - if (Re == 1.0) - { - mask = reflectionMask; - rayOrigin = reflectionRayOrigin; - rayDirection = reflectionRayDirection; - - willNeedReflectionRay = FALSE; - bounceIsSpecular = TRUE; - sampleLight = FALSE; - continue; + if (bounces == 0 && hitColor == vec3(0.2,0.9,0.7) && isRayExiting == FALSE) + reflectionNeedsToBeSharp = TRUE; } // transmit ray through surface @@ -511,11 +508,10 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o mask *= Tr; - tdir = refract(rayDirection, nl, ratioIoR); - rayDirection = tdir; + rayDirection = refract(rayDirection, nl, ratioIoR); rayOrigin = x - nl * uEPS_intersect; - if (diffuseCount == 1) + if (diffuseCount == 1 && isReflectionTime == FALSE) bounceIsSpecular = TRUE; // turn on refracting caustics continue; @@ -524,25 +520,24 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o if (hitType == COAT) // Diffuse object underneath with ClearCoat on top { - coatTypeIntersected = TRUE; - nc = 1.0; // IOR of Air nt = 1.4; // IOR of Clear Coat Re = calcFresnelReflectance(rayDirection, nl, nc, nt, ratioIoR); Tr = 1.0 - Re; - if (bounces == 0 || (bounces == 1 && hitObjectID != objectID && bounceIsSpecular == TRUE)) + if (diffuseCount == 0 && hitObjectID != previousObjectID) { reflectionMask = mask * Re; reflectionRayDirection = reflect(rayDirection, nl); // reflect ray from surface reflectionRayOrigin = x + nl * uEPS_intersect; willNeedReflectionRay = TRUE; + if (bounces == 0 && hitColor == vec3(0.04,0.04,0.04)) + reflectionNeedsToBeSharp = TRUE; } diffuseCount++; - //if (bounces == 0) - mask *= Tr; + mask *= Tr; mask *= hitColor; bounceIsSpecular = FALSE; @@ -573,7 +568,7 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o } //end if (hitType == COAT) - } // end for (int bounces = 0; bounces < 6; bounces++) + } // end for (int bounces = 0; bounces < 8; bounces++) return max(vec3(0), accumCol); @@ -594,7 +589,7 @@ void SetupScene(void) spheres[1] = Sphere(100.0, vec3( 300, 400,-300), L2, z, LIGHT);//spherical yellow Light2 spheres[2] = Sphere( 50.0, vec3( 500, 250,-100), L3, z, LIGHT);//spherical blue Light3 - spheres[3] = Sphere(1000.0, vec3( 0.0, 1000.0, 0.0), z, vec3(1.0, 1.0, 1.0), CHECK);//Checkered Floor + spheres[3] = Sphere(1000.0, vec3( 0.0, 1000.0, 0.0), z, vec3(1.0, 1.0, 1.0), DIFF);//Checkered Floor spheres[4] = Sphere( 16.5, vec3(-26.0, 17.2, 5.0), z, vec3(0.95, 0.95, 0.95), SPEC);//Mirror sphere spheres[5] = Sphere( 15.0, vec3( 32.0, 16.1, 30.0), z, vec3(1.0, 1.0, 1.0), REFR);//Glass sphere