Skip to content

Commit

Permalink
WIP(gi): use medium stack
Browse files Browse the repository at this point in the history
  • Loading branch information
pablode committed May 26, 2024
1 parent 3a2c098 commit 7b2a46d
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 19 deletions.
83 changes: 64 additions & 19 deletions src/gi/shaders/rp_main.chit
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ void main()
{
/* 1. Get hit info. */
vec2 hit_bc = baryCoord;
float hit_t = gl_HitTEXT;
BlasPayload payload = blas_payloads[gl_InstanceCustomIndexEXT];

/* 2. Set up shading state. */
Expand All @@ -150,8 +149,7 @@ void main()
vec3 throughput = vec3(rayPayload.throughput);
vec3 radiance = vec3(rayPayload.radiance);

uint bounce = (rayPayload.bitfield & SHADE_RAY_PAYLOAD_BOUNCES_MASK);
bool inside = shadeRayPayloadGetMediumIdx(rayPayload) > 0;
uint mediumIdx = shadeRayPayloadGetMediumIdx(rayPayload);
bool doubleSided = bool(payload.bitfield & BLAS_PAYLOAD_BITFLAG_IS_DOUBLE_SIDED);

bool thinWalled = doubleSided;
Expand All @@ -162,9 +160,6 @@ void main()
}
#endif

const float iorCurrent = (inside && !thinWalled) ? BSDF_USE_MATERIAL_IOR : 1.0;
const float iorOther = (inside && !thinWalled) ? 1.0 : BSDF_USE_MATERIAL_IOR;

#if AOV_ID == AOV_ID_DEBUG_OPACITY
#ifndef HAS_CUTOUT_TRANSPARENCY
rayPayload.radiance = vec3(1.0, 0.0, 0.0); // Distinct from viridis heatmap
Expand Down Expand Up @@ -216,14 +211,30 @@ void main()
#endif

/* 3. Apply volume attenuation */
#ifdef HAS_VOLUME_ABSORPTION_COEFF
if (inside && !thinWalled)
vec3 mediumIor = vec3(1.0);
vec3 prevMediumIor = vec3(1.0);

if (mediumIdx > 0)
{
vec3 abs_coeff = mdl_volume_absorption_coefficient(shading_state);
throughput *= exp(-abs_coeff * hit_t);
}
#if MEDIUM_STACK_SIZE == 0
vec3 sigma_a = mdl_volume_absorption_coefficient(shading_state);
#else
Medium m = rayPayload.media[mediumIdx - 1];
vec3 sigma_a = m.sigma_t - m.sigma_s;

mediumIor = m.ior;
if (mediumIdx > 1)
{
prevMediumIor = rayPayload.media[mediumIdx - 2].ior;
}
#endif

throughput *= exp(-sigma_a * gl_HitTEXT);
}

const vec3 iorCurrent = (!is_backface || thinWalled) ? mediumIor : vec3(BSDF_USE_MATERIAL_IOR);
const vec3 iorOther = (!is_backface || thinWalled) ? vec3(BSDF_USE_MATERIAL_IOR) : prevMediumIor;

/* 4. Add Emission */
#ifdef IS_EMISSIVE
{
Expand Down Expand Up @@ -311,6 +322,8 @@ void main()
rayPayload.ray_dir = bsdf_sample_data.k2;
}

bool isTransmissionEvent = (eventType & BSDF_EVENT_TRANSMISSION) != 0;

/* 6. NEE light sampling */
#ifdef NEXT_EVENT_ESTIMATION
if ((eventType & (BSDF_EVENT_DIFFUSE | BSDF_EVENT_GLOSSY)) != 0)
Expand Down Expand Up @@ -364,23 +377,55 @@ void main()
}
#endif

// Update rest of path state
if (eventType == BSDF_EVENT_ABSORB)
// Modify medium stack
if (!thinWalled && isTransmissionEvent)
{
rayPayload.bitfield |= SHADE_RAY_PAYLOAD_TERMINATE_FLAG;
#if MEDIUM_STACK_SIZE > 0
if (!is_backface) // push
{
mediumIdx++;

if (mediumIdx <= MEDIUM_STACK_SIZE)
{
vec3 sigma_a = mdl_volume_absorption_coefficient(shading_state);
vec3 sigma_s = mdl_volume_scattering_coefficient(shading_state);
vec3 sigma_t = sigma_a + sigma_s;

Medium m;
m.ior = mdl_ior(shading_state);
m.sigma_s = sigma_s;
m.sigma_t = sigma_t;
m.bias = MEDIUM_DIRECTIONAL_BIAS;
rayPayload.media[mediumIdx - 1] = m;

rayPayload.sigma_t = sigma_t;
}
}
else if (mediumIdx > 0) // pop
{
mediumIdx--;
}

shadeRayPayloadSetMediumIdx(rayPayload, mediumIdx);

// medium changes -- reset walk
rayPayload.bitfield &= ~SHADE_RAY_PAYLOAD_WALK_MASK;
#else
mediumIdx = (1 - mediumIdx); // toggle between inside and outside
#endif

shadeRayPayloadSetMediumIdx(rayPayload, mediumIdx);
}

bool isTransmissionEvent = (eventType & BSDF_EVENT_TRANSMISSION) != 0;
if (isTransmissionEvent && !thinWalled)
// Update rest of path state
if (eventType == BSDF_EVENT_ABSORB)
{
inside = !inside;
rayPayload.bitfield |= SHADE_RAY_PAYLOAD_TERMINATE_FLAG;
}

vec3 geomNormal = shading_state.geom_normal * (isTransmissionEvent ? -1.0 /* undo flip */ : 1.0);
rayPayload.ray_origin = offset_ray_origin(shading_state.position, geomNormal);

shadeRayPayloadSetMediumIdx(rayPayload, inside ? 1 : 0);

rayPayload.throughput = throughput;
rayPayload.radiance = radiance;
}
14 changes: 14 additions & 0 deletions src/gi/shaders/rp_main_payload.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
#define SHADE_RAY_PAYLOAD_WALK_OFFSET 12
#define SHADE_RAY_PAYLOAD_BOUNCES_MASK 0x00000fffu

struct Medium
{
vec3 ior;
vec3 sigma_s;
vec3 sigma_t; // sigma_a + sigma_s
float bias;
};

struct ShadeRayPayload
{
/* inout */ vec3 throughput;
Expand All @@ -19,7 +27,13 @@ struct ShadeRayPayload
/* inout */ uint bitfield;

/* inout */ vec3 radiance;

/* inout */ RNG_STATE_TYPE rng_state;

#if MEDIUM_STACK_SIZE > 0
/* inout */ Medium media[MEDIUM_STACK_SIZE];
#endif

/* out */ vec3 ray_origin;
/* out */ vec3 ray_dir;
/* out */ vec3 neeToLight;
Expand Down

0 comments on commit 7b2a46d

Please sign in to comment.