Skip to content

Commit

Permalink
Update GameEngine_PathTracer_Fragment.glsl
Browse files Browse the repository at this point in the history
  • Loading branch information
erichlof authored Sep 12, 2024
1 parent 4affd0f commit 2096621
Showing 1 changed file with 77 additions and 67 deletions.
144 changes: 77 additions & 67 deletions shaders/GameEngine_PathTracer_Fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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; };
Expand Down Expand Up @@ -86,6 +86,8 @@ float SceneIntersect(out int finalIsRayExiting)
{
vec3 rObjOrigin, rObjDirection;
vec3 n;
vec3 hitPos;
float q;
float d, dt;
float t = INFINITY;
int isRayExiting = FALSE;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -307,73 +311,82 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o
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 < 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.01; // maximum sharpness for dynamic scenes
}

if (diffuseCount == 0)
if (isReflectionTime == TRUE && bounceIsSpecular == TRUE)
{
objectNormal = nl;
objectColor = hitColor;
//objectColor = hitColor;
objectID = hitObjectID;
}


if (bounceIsSpecular == TRUE || sampleLight == TRUE)
accumCol += mask * hitEmission;

Expand All @@ -386,7 +399,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
Expand All @@ -407,7 +420,7 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o
willNeedReflectionRay = FALSE;
bounceIsSpecular = TRUE;
sampleLight = FALSE;
diffuseCount = 0;
isReflectionTime = TRUE;
continue;
}

Expand All @@ -417,34 +430,25 @@ 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;

bounceIsSpecular = FALSE;

if (diffuseCount == 1 && rand() < 0.4)
if (diffuseCount == 1 && rand() < 0.5)
{
mask /= 0.4;
mask *= 2.0;
// choose random Diffuse sample vector
rayDirection = randomCosWeightedDirectionInHemisphere(nl);
rayOrigin = x + nl * uEPS_intersect;
continue;
}

dirToLight = sampleSphereLight(x, nl, lightChoice, weight);
mask /= diffuseCount == 1 ? 0.6 : 1.0;
mask *= diffuseCount == 1 ? 2.0 : 1.0;
mask *= weight * N_LIGHTS;

rayDirection = dirToLight;
Expand All @@ -470,31 +474,26 @@ vec3 CalculateRadiance( out vec3 objectNormal, out vec3 objectColor, out float o

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
Expand All @@ -511,8 +510,7 @@ 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)
Expand All @@ -527,25 +525,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;
Expand Down Expand Up @@ -576,7 +573,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);
Expand All @@ -598,7 +595,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( sin(mod(uTime * 0.3, TWO_PI)) * 80.0, 25, cos(mod(uTime * 0.1, TWO_PI)) * 80.0 ), z, vec3(1.0, 1.0, 1.0), REFR);//Glass sphere

Expand All @@ -608,7 +605,7 @@ void SetupScene(void)

openCylinders[0] = OpenCylinder( 15.0, 30.0, vec3( cos(mod(uTime * 0.1, TWO_PI)) * 100.0, 10, sin(mod(uTime * 0.4, TWO_PI)) * 100.0 ), z, vec3(0.9,0.01,0.01), REFR);//red glass open Cylinder

cappedCylinders[0] = CappedCylinder( 14.0, vec3(-60,0,20), vec3(-60,14,20), z, vec3(0.05,0.05,0.05), COAT);//dark gray capped Cylinder
cappedCylinders[0] = CappedCylinder( 14.0, vec3(-60,0,20), vec3(-60,14,20), z, vec3(0.04,0.04,0.04), COAT);//dark gray capped Cylinder

cones[0] = Cone( vec3(1,20,-12), 15.0, vec3(1,0,-12), 0.0, z, vec3(0.01,0.1,0.5), REFR);//blue Cone

Expand Down Expand Up @@ -645,8 +642,9 @@ void main( void )
randNumber = 0.0; // the final randomly-generated number (range: 0.0 to 1.0)
blueNoise = texelFetch(tBlueNoiseTexture, ivec2(mod(floor(gl_FragCoord.xy), 128.0)), 0).r;

vec2 pixelOffset = vec2( tentFilter(rand()), tentFilter(rand()) ) * 0.5;

vec2 pixelOffset = vec2( tentFilter(rand()), tentFilter(rand()) );
pixelOffset *= 0.5;//uCameraIsMoving ? 0.5 : 0.75;

// we must map pixelPos into the range -1.0 to +1.0
vec2 pixelPos = ((gl_FragCoord.xy + vec2(0.5) + pixelOffset) / uResolution) * 2.0 - 1.0;

Expand Down Expand Up @@ -721,20 +719,32 @@ void main( void )
currentPixel.rgb *= 0.5;
}


if (colorDifference >= 1.0 || normalDifference >= 1.0 || objectDifference >= 1.0)
pixelSharpness = 1.01;

currentPixel.a = pixelSharpness;

// makes sharp edges more stable
// check for all edges that are not light sources
if (pixelSharpness < 1.01 && (colorDifference >= 1.0 || normalDifference >= 1.0 || objectDifference >= 1.0)) // all other edges
currentPixel.a = pixelSharpness = 1.0;

// makes light source edges (shape boundaries) more stable
if (previousPixel.a == 1.01)
currentPixel.a = 1.01;
{
if (pixelSharpness > 0.0)
currentPixel.a = 1.01;
else currentPixel.a = 1.0;
}

// makes sharp edges more stable
if (!uCameraIsMoving && previousPixel.a == 1.0)
{
if (pixelSharpness > 0.0)
currentPixel.a = 1.01;
else currentPixel.a = 1.0;
}

// for dynamic scenes (to clear out old, dark, sharp pixel trails left behind from moving objects)
if (previousPixel.a == 1.01 && rng() < 0.05)
currentPixel.a = 1.0;
if (previousPixel.a == 1.0 && rng() < 0.05)
currentPixel.a = 0.0;


pc_fragColor = vec4(previousPixel.rgb + currentPixel.rgb, currentPixel.a);
}

0 comments on commit 2096621

Please sign in to comment.