EEVEE: Use half float in some part of the pipeline #5

Closed
Clément Foucault wants to merge 1 commits from eevee-half-opti into eevee-small-type-opti

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
23 changed files with 160 additions and 120 deletions

View File

@ -55,7 +55,7 @@ LightProbeRay bxdf_diffuse_lightprobe(vec3 N)
ClosureLight bxdf_diffuse_light(ClosureUndetermined cl)
{
ClosureLight light;
light.ltc_mat = vec4(1.0, 0.0, 0.0, 1.0); /* No transform, just plain cosine distribution. */
light.ltc_mat = half4(1.0, 0.0, 0.0, 1.0); /* No transform, just plain cosine distribution. */
light.N = cl.N;
light.type = LIGHT_DIFFUSE;
return light;
@ -144,7 +144,7 @@ ClosureLight bxdf_translucent_light(ClosureUndetermined cl, vec3 V, float thickn
* only focusing the light a tiny bit. Using the flipped normal is good enough approximation.
*/
ClosureLight light;
light.ltc_mat = vec4(1.0, 0.0, 0.0, 1.0); /* No transform, just plain cosine distribution. */
light.ltc_mat = half4(1.0, 0.0, 0.0, 1.0); /* No transform, just plain cosine distribution. */
light.N = -cl.N;
light.type = (thickness > 0.0) ? LIGHT_TRANSLUCENT_WITH_THICKNESS : LIGHT_DIFFUSE;
return light;

View File

@ -13,7 +13,7 @@
#include "gpu_shader_utildefines_lib.glsl"
struct BsdfSample {
packed_float3 direction;
float3 direction;
float pdf;
};
@ -26,14 +26,14 @@ struct BsdfEval {
struct ClosureLight {
/* LTC matrix. */
packed_float4 ltc_mat;
half4 ltc_mat;
/* Shading normal. */
packed_float3 N;
/* Enum used as index to fetch which light intensity to use [0..3]. */
LightingType type;
/* Output both shadowed and unshadowed for shadow denoising. */
packed_float3 light_shadowed;
packed_float3 light_unshadowed;
half3 light_shadowed;
half3 light_unshadowed;
};
/* Represent an approximation of a bunch of rays from a BSDF. */
@ -49,9 +49,9 @@ struct LightProbeRay {
/* General purpose 3D ray. */
struct Ray {
packed_float3 direction;
float max_time;
packed_float3 origin;
float max_time;
float3 direction;
};
/* -------------------------------------------------------------------- */

View File

@ -396,7 +396,8 @@ ClosureLight bxdf_ggx_light_reflection(ClosureReflection cl, vec3 V)
{
float cos_theta = dot(cl.N, V);
ClosureLight light;
light.ltc_mat = utility_tx_sample_lut(utility_tx, cos_theta, cl.roughness, UTIL_LTC_MAT_LAYER);
light.ltc_mat = half4(
utility_tx_sample_lut(utility_tx, cos_theta, cl.roughness, UTIL_LTC_MAT_LAYER));
light.N = cl.N;
light.type = LIGHT_SPECULAR;
return light;
@ -417,8 +418,8 @@ ClosureLight bxdf_ggx_light_transmission(ClosureRefraction cl, vec3 V, float thi
float cos_theta = dot(-cl.N, R);
ClosureLight light;
light.ltc_mat = utility_tx_sample_lut(
utility_tx, cos_theta, perceptual_roughness, UTIL_LTC_MAT_LAYER);
light.ltc_mat = half4(
utility_tx_sample_lut(utility_tx, cos_theta, perceptual_roughness, UTIL_LTC_MAT_LAYER));
light.N = -cl.N;
light.type = LIGHT_TRANSMISSION;
return light;

View File

@ -118,8 +118,8 @@ ClosureLight closure_light_new_ex(ClosureUndetermined cl,
break;
}
}
cl_light.light_shadowed = vec3(0.0);
cl_light.light_unshadowed = vec3(0.0);
cl_light.light_shadowed = half3(0.0);
cl_light.light_unshadowed = half3(0.0);
return cl_light;
}

View File

@ -64,20 +64,21 @@ void main()
uchar receiver_light_set = gbuffer_light_link_receiver_unpack(gbuf.header);
light_eval_reflection(stack, P, Ng, V, vPz, receiver_light_set);
vec3 radiance_front = stack.cl[0].light_shadowed;
half3 radiance_front = stack.cl[0].light_shadowed;
stack.cl[0] = closure_light_new(cl_transmit, V, gbuf.thickness);
light_eval_transmission(stack, P, Ng, V, vPz, gbuf.thickness, receiver_light_set);
vec3 radiance_back = stack.cl[0].light_shadowed;
half3 radiance_back = stack.cl[0].light_shadowed;
/* Indirect light. */
/* Can only load irradiance to avoid dependency loop with the reflection probe. */
SphericalHarmonicL1 sh = lightprobe_volume_sample(P, V, Ng);
radiance_front += spherical_harmonics_evaluate_lambert(Ng, sh);
radiance_front += half3(spherical_harmonics_evaluate_lambert(Ng, sh));
/* TODO(fclem): Correct transmission eval. */
radiance_back += spherical_harmonics_evaluate_lambert(-Ng, sh);
radiance_back += half3(spherical_harmonics_evaluate_lambert(-Ng, sh));
out_radiance = vec4(radiance_front * albedo_front + radiance_back * albedo_back, 0.0);
out_radiance = vec4(
vec3(radiance_front * half3(albedo_front) + radiance_back * half3(albedo_back)), 0.0);
}

View File

@ -76,7 +76,7 @@ void main()
if (use_transmission) {
ClosureUndetermined cl_transmit = gbuffer_closure_get(gbuf, 0);
#if 1 /* TODO Limit to SSS. */
vec3 sss_reflect_shadowed, sss_reflect_unshadowed;
half3 sss_reflect_shadowed, sss_reflect_unshadowed;
if (cl_transmit.type == CLOSURE_BSSRDF_BURLEY_ID) {
sss_reflect_shadowed = stack.cl[0].light_shadowed;
sss_reflect_unshadowed = stack.cl[0].light_unshadowed;
@ -91,7 +91,7 @@ void main()
#if 1 /* TODO Limit to SSS. */
if (cl_transmit.type == CLOSURE_BSSRDF_BURLEY_ID) {
/* Apply transmission profile onto transmitted light and sum with reflected light. */
vec3 sss_profile = subsurface_transmission(to_closure_subsurface(cl_transmit).sss_radius,
half3 sss_profile = subsurface_transmission(to_closure_subsurface(cl_transmit).sss_radius,
abs(gbuf.thickness));
stack.cl[0].light_shadowed *= sss_profile;
stack.cl[0].light_unshadowed *= sss_profile;
@ -102,13 +102,13 @@ void main()
}
if (render_pass_shadow_id != -1) {
vec3 radiance_shadowed = vec3(0);
vec3 radiance_unshadowed = vec3(0);
half3 radiance_shadowed = half3(0);
half3 radiance_unshadowed = half3(0);
for (int i = 0; i < LIGHT_CLOSURE_EVAL_COUNT && i < gbuf.closure_count; i++) {
radiance_shadowed += closure_light_get(stack, i).light_shadowed;
radiance_unshadowed += closure_light_get(stack, i).light_unshadowed;
}
vec3 shadows = radiance_shadowed * safe_rcp(radiance_unshadowed);
half3 shadows = radiance_shadowed * safe_rcp(radiance_unshadowed);
output_renderpass_value(render_pass_shadow_id, average(shadows));
}
@ -120,24 +120,24 @@ void main()
for (int i = 0; i < LIGHT_CLOSURE_EVAL_COUNT && i < gbuf.closure_count; i++) {
ClosureUndetermined cl = gbuffer_closure_get(gbuf, i);
vec3 indirect_light = lightprobe_eval(samp, cl, P, V, gbuf.thickness);
half3 indirect_light = lightprobe_eval(samp, cl, P, V, gbuf.thickness);
int layer_index = gbuffer_closure_get_bin_index(gbuf, i);
vec3 direct_light = closure_light_get(stack, i).light_shadowed;
half3 direct_light = closure_light_get(stack, i).light_shadowed;
if (use_split_indirect) {
write_radiance_indirect(layer_index, texel, indirect_light);
write_radiance_direct(layer_index, texel, direct_light);
write_radiance_indirect(layer_index, texel, vec3(indirect_light));
write_radiance_direct(layer_index, texel, vec3(direct_light));
}
else {
write_radiance_direct(layer_index, texel, direct_light + indirect_light);
write_radiance_direct(layer_index, texel, vec3(direct_light + indirect_light));
}
}
}
else {
for (int i = 0; i < LIGHT_CLOSURE_EVAL_COUNT && i < gbuf.closure_count; i++) {
int layer_index = gbuffer_closure_get_bin_index(gbuf, i);
vec3 direct_light = closure_light_get(stack, i).light_shadowed;
write_radiance_direct(layer_index, texel, direct_light);
half3 direct_light = closure_light_get(stack, i).light_shadowed;
write_radiance_direct(layer_index, texel, vec3(direct_light));
}
}
}

View File

@ -19,8 +19,8 @@ void main()
GBufferReader gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_normal_tx, texel);
vec3 albedo_front = vec3(0.0);
vec3 albedo_back = vec3(0.0);
half3 albedo_front = half3(0.0);
half3 albedo_back = half3(0.0);
for (int i = 0; i < GBUFFER_LAYER_MAX && i < gbuf.closure_count; i++) {
ClosureUndetermined cl = gbuffer_closure_get(gbuf, i);
@ -28,11 +28,11 @@ void main()
case CLOSURE_BSSRDF_BURLEY_ID:
case CLOSURE_BSDF_DIFFUSE_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFLECTION_ID:
albedo_front += cl.color;
albedo_front += half3(cl.color);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
albedo_back += (gbuf.thickness != 0.0) ? square(cl.color) : cl.color;
albedo_back += half3((gbuf.thickness != 0.0) ? square(cl.color) : cl.color);
break;
case CLOSURE_NONE_ID:
/* TODO(fclem): Assert. */
@ -59,18 +59,18 @@ void main()
uchar receiver_light_set = gbuffer_light_link_receiver_unpack(gbuf.header);
light_eval_reflection(stack, P, Ng, V, vPz, receiver_light_set);
vec3 radiance_front = stack.cl[0].light_shadowed;
half3 radiance_front = stack.cl[0].light_shadowed;
stack.cl[0] = closure_light_new(cl_transmit, V, gbuf.thickness);
light_eval_transmission(stack, P, Ng, V, vPz, gbuf.thickness, receiver_light_set);
vec3 radiance_back = stack.cl[0].light_shadowed;
half3 radiance_back = stack.cl[0].light_shadowed;
/* Indirect light. */
SphericalHarmonicL1 sh = lightprobe_volume_sample(P, V, Ng);
radiance_front += spherical_harmonics_evaluate_lambert(Ng, sh);
radiance_back += spherical_harmonics_evaluate_lambert(-Ng, sh);
radiance_front += half3(spherical_harmonics_evaluate_lambert(Ng, sh));
radiance_back += half3(spherical_harmonics_evaluate_lambert(-Ng, sh));
out_radiance = vec4(radiance_front * albedo_front + radiance_back * albedo_back, 0.0);
out_radiance = vec4(vec3(radiance_front * albedo_front + radiance_back * albedo_back), 0.0);
}

View File

@ -16,7 +16,7 @@ void main()
vec3 R = -reflect(V, probe_normal);
SphereProbeUvArea world_atlas_coord = reinterpret_as_atlas_coord(world_coord_packed);
out_color = lightprobe_spheres_sample(R, 0.0, world_atlas_coord);
out_color = vec4(lightprobe_spheres_sample(R, 0.0, world_atlas_coord));
}
else {
out_color = texture(planar_radiance_tx, vec3(uv, probe_index));

View File

@ -20,6 +20,7 @@ void main()
vec3 V = drw_world_incident_vector(P);
vec3 L = reflect(-V, N);
out_color = lightprobe_spheres_sample(L, 0, lightprobe_sphere_buf[probe_index].atlas_coord);
out_color = vec4(
lightprobe_spheres_sample(L, 0, lightprobe_sphere_buf[probe_index].atlas_coord));
out_color.a = 0.0;
}

View File

@ -81,11 +81,11 @@ struct GBufferReader {
/* Additional object information if any closure needs it. */
float thickness;
/* Number of valid closure encoded in the gbuffer. */
int closure_count;
uchar closure_count;
/* Only used for book-keeping when reading. */
int data_len;
uchar data_len;
/* Only used for debugging and testing. */
int normal_len;
uchar normal_len;
};
ClosureType gbuffer_mode_to_closure_type(uint mode)
@ -126,7 +126,7 @@ uint fetchGBuffer(usampler2D tx, ivec2 texel)
{
return texelFetch(tx, texel, 0).r;
}
vec4 fetchGBuffer(sampler2DArray tx, ivec2 texel, int layer)
vec4 fetchGBuffer(sampler2DArray tx, ivec2 texel, uchar layer)
{
return texelFetch(tx, ivec3(texel, layer), 0);
}
@ -142,11 +142,11 @@ uint fetchGBuffer(samplerGBufferHeader tx, ivec2 texel)
{
return uint(0);
}
vec4 fetchGBuffer(samplerGBufferClosure tx, ivec2 texel, int layer)
vec4 fetchGBuffer(samplerGBufferClosure tx, ivec2 texel, uchar layer)
{
return vec4(0.0);
}
vec4 fetchGBuffer(samplerGBufferNormal tx, ivec2 texel, int layer)
vec4 fetchGBuffer(samplerGBufferNormal tx, ivec2 texel, uchar layer)
{
return vec4(0.0);
}
@ -159,11 +159,11 @@ uint fetchGBuffer(samplerGBufferHeader tx, ivec2 texel)
{
return g_data_packed.header;
}
vec4 fetchGBuffer(samplerGBufferClosure tx, ivec2 texel, int layer)
vec4 fetchGBuffer(samplerGBufferClosure tx, ivec2 texel, uchar layer)
{
return g_data_packed.data[layer];
}
vec4 fetchGBuffer(samplerGBufferNormal tx, ivec2 texel, int layer)
vec4 fetchGBuffer(samplerGBufferNormal tx, ivec2 texel, uchar layer)
{
return g_data_packed.N[layer].xyyy;
}
@ -557,8 +557,8 @@ void gbuffer_closure_diffuse_skip(inout GBufferReader gbuf)
gbuffer_skip_normal(gbuf);
}
void gbuffer_closure_diffuse_load(inout GBufferReader gbuf,
int layer,
int bin_index,
uchar layer,
uchar bin_index,
samplerGBufferClosure closure_tx,
samplerGBufferNormal normal_tx)
{
@ -584,8 +584,8 @@ void gbuffer_closure_translucent_skip(inout GBufferReader gbuf)
gbuffer_skip_normal(gbuf);
}
void gbuffer_closure_translucent_load(inout GBufferReader gbuf,
int layer,
int bin_index,
uchar layer,
uchar bin_index,
samplerGBufferClosure closure_tx,
samplerGBufferNormal normal_tx)
{
@ -613,8 +613,8 @@ void gbuffer_closure_subsurface_skip(inout GBufferReader gbuf)
gbuffer_skip_normal(gbuf);
}
void gbuffer_closure_subsurface_load(inout GBufferReader gbuf,
int layer,
int bin_index,
uchar layer,
uchar bin_index,
samplerGBufferClosure closure_tx,
samplerGBufferNormal normal_tx)
{
@ -644,8 +644,8 @@ void gbuffer_closure_reflection_skip(inout GBufferReader gbuf)
gbuffer_skip_normal(gbuf);
}
void gbuffer_closure_reflection_load(inout GBufferReader gbuf,
int layer,
int bin_index,
uchar layer,
uchar bin_index,
samplerGBufferClosure closure_tx,
samplerGBufferNormal normal_tx)
{
@ -675,8 +675,8 @@ void gbuffer_closure_refraction_skip(inout GBufferReader gbuf)
gbuffer_skip_normal(gbuf);
}
void gbuffer_closure_refraction_load(inout GBufferReader gbuf,
int layer,
int bin_index,
uchar layer,
uchar bin_index,
samplerGBufferClosure closure_tx,
samplerGBufferNormal normal_tx)
{
@ -714,8 +714,8 @@ void gbuffer_closure_reflection_colorless_skip(inout GBufferReader gbuf)
gbuffer_skip_normal(gbuf);
}
void gbuffer_closure_reflection_colorless_load(inout GBufferReader gbuf,
int layer,
int bin_index,
uchar layer,
uchar bin_index,
samplerGBufferClosure closure_tx,
samplerGBufferNormal normal_tx)
{
@ -744,8 +744,8 @@ void gbuffer_closure_refraction_colorless_skip(inout GBufferReader gbuf)
gbuffer_skip_normal(gbuf);
}
void gbuffer_closure_refraction_colorless_load(inout GBufferReader gbuf,
int layer,
int bin_index,
uchar layer,
uchar bin_index,
samplerGBufferClosure closure_tx,
samplerGBufferNormal normal_tx)
{
@ -931,7 +931,7 @@ ClosureType gbuffer_closure_type_get_by_bin(uint header, int bin_index)
int gbuffer_closure_get_bin_index(GBufferReader gbuf, int layer_index)
{
int layer = 0;
for (int bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
for (uchar bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
GBufferMode mode = gbuffer_header_unpack(gbuf.header, bin);
/* Gbuffer header can have holes. Skip GBUF_NONE. */
if (mode != GBUF_NONE) {
@ -948,7 +948,7 @@ int gbuffer_closure_get_bin_index(GBufferReader gbuf, int layer_index)
ClosureUndetermined gbuffer_closure_get_by_bin(GBufferReader gbuf, int bin_index)
{
int layer_index = 0;
for (int bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
for (uchar bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
GBufferMode mode = gbuffer_header_unpack(gbuf.header, bin);
if (bin == bin_index) {
return gbuffer_closure_get(gbuf, layer_index);
@ -977,7 +977,7 @@ GBufferReader gbuffer_read(samplerGBufferHeader header_tx,
gbuf.data_len = 0;
gbuf.normal_len = 0;
gbuf.surface_N = vec3(0.0);
for (int bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
for (uchar bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
gbuffer_register_closure(gbuf, closure_new(CLOSURE_NONE_ID), bin);
}
@ -991,7 +991,7 @@ GBufferReader gbuffer_read(samplerGBufferHeader header_tx,
gbuf.surface_N = gbuffer_normal_unpack(fetchGBuffer(normal_tx, texel, 0).xy);
bool has_additional_data = false;
for (int bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
for (uchar bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
GBufferMode mode = gbuffer_header_unpack(gbuf.header, bin);
switch (mode) {
default:
@ -1060,7 +1060,7 @@ ClosureUndetermined gbuffer_read_bin(uint header,
}
GBufferMode mode;
for (int bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
for (uchar bin = 0; bin < GBUFFER_LAYER_MAX; bin++) {
mode = gbuffer_header_unpack(gbuf.header, bin);
if (bin >= bin_index) {

View File

@ -97,17 +97,17 @@ void light_eval_single_closure(LightData light,
LightVector lv,
inout ClosureLight cl,
vec3 V,
float attenuation,
float shadow,
half attenuation,
half shadow,
const bool is_transmission)
{
attenuation *= light_power_get(light, cl.type);
if (attenuation < 1e-30) {
return;
}
float ltc_result = light_ltc(utility_tx, light, cl.N, V, lv, cl.ltc_mat);
vec3 out_radiance = light.color * ltc_result;
float visibility = shadow * attenuation;
float ltc_result = light_ltc(utility_tx, light, cl.N, V, lv, vec4(cl.ltc_mat));
half3 out_radiance = half3(light.color * ltc_result);
half visibility = shadow * attenuation;
cl.light_shadowed += visibility * out_radiance;
cl.light_unshadowed += attenuation * out_radiance;
}
@ -148,7 +148,7 @@ void light_eval_single(uint l_idx,
return;
}
float shadow = 1.0;
half shadow = 1.0;
if (light.tilemap_index != LIGHT_NO_SHADOW) {
shadow = shadow_eval(light,
is_directional,

View File

@ -67,7 +67,7 @@ vec3 lightprobe_sphere_parallax(SphereProbeData probe, vec3 P, vec3 L)
* Return spherical sample normalized by irradiance at sample position.
* This avoid most of light leaking and reduce the need for many local probes.
*/
vec3 lightprobe_spherical_sample_normalized_with_parallax(LightProbeSample samp,
half3 lightprobe_spherical_sample_normalized_with_parallax(LightProbeSample samp,
vec3 P,
vec3 L,
float lod)
@ -87,36 +87,35 @@ float pdf_to_lod(float inv_pdf)
return blur_pdf * 2.0;
}
vec3 lightprobe_eval_direction(LightProbeSample samp, vec3 P, vec3 L, float inv_pdf)
half3 lightprobe_eval_direction(LightProbeSample samp, vec3 P, vec3 L, float inv_pdf)
{
vec3 radiance_sh = lightprobe_spherical_sample_normalized_with_parallax(
samp, P, L, pdf_to_lod(inv_pdf));
return radiance_sh;
return lightprobe_spherical_sample_normalized_with_parallax(samp, P, L, pdf_to_lod(inv_pdf));
}
# ifdef EEVEE_UTILITY_TX
/* TODO: Port that inside a BSSDF file. */
vec3 lightprobe_eval(LightProbeSample samp, ClosureSubsurface cl, vec3 P, vec3 V, float thickness)
half3 lightprobe_eval(LightProbeSample samp, ClosureSubsurface cl, vec3 P, vec3 V, float thickness)
{
vec3 sss_profile = subsurface_transmission(cl.sss_radius, abs(thickness));
vec3 radiance_sh = spherical_harmonics_evaluate_lambert(cl.N, samp.volume_irradiance);
radiance_sh += spherical_harmonics_evaluate_lambert(-cl.N, samp.volume_irradiance) * sss_profile;
half3 sss_profile = subsurface_transmission(cl.sss_radius, abs(thickness));
half3 radiance_sh = half3(spherical_harmonics_evaluate_lambert(cl.N, samp.volume_irradiance));
radiance_sh += half3(spherical_harmonics_evaluate_lambert(-cl.N, samp.volume_irradiance)) *
sss_profile;
return radiance_sh;
}
vec3 lightprobe_eval(
half3 lightprobe_eval(
LightProbeSample samp, ClosureUndetermined cl, vec3 P, vec3 V, float thickness)
{
LightProbeRay ray = bxdf_lightprobe_ray(cl, P, V, thickness);
float lod = sphere_probe_roughness_to_lod(ray.perceptual_roughness);
float fac = sphere_probe_roughness_to_mix_fac(ray.perceptual_roughness);
half fac = sphere_probe_roughness_to_mix_fac(ray.perceptual_roughness);
vec3 radiance_cube = lightprobe_spherical_sample_normalized_with_parallax(
half3 radiance_cube = lightprobe_spherical_sample_normalized_with_parallax(
samp, P, ray.dominant_direction, lod);
vec3 radiance_sh = spherical_harmonics_evaluate_lambert(ray.dominant_direction,
samp.volume_irradiance);
half3 radiance_sh = half3(
spherical_harmonics_evaluate_lambert(ray.dominant_direction, samp.volume_irradiance));
return mix(radiance_cube, radiance_sh, fac);
}
# endif

View File

@ -10,17 +10,18 @@
#include "gpu_shader_math_vector_lib.glsl"
#ifdef SPHERE_PROBE
vec4 lightprobe_spheres_sample(vec3 L, float lod, SphereProbeUvArea uv_area)
half4 lightprobe_spheres_sample(vec3 L, float lod, SphereProbeUvArea uv_area)
{
float lod_min = floor(lod);
float lod_max = ceil(lod);
float mix_fac = lod - lod_min;
half mix_fac = half(lod - lod_min);
vec2 altas_uv_min, altas_uv_max;
sphere_probe_direction_to_uv(L, lod_min, lod_max, uv_area, altas_uv_min, altas_uv_max);
vec4 color_min = textureLod(lightprobe_spheres_tx, vec3(altas_uv_min, uv_area.layer), lod_min);
vec4 color_max = textureLod(lightprobe_spheres_tx, vec3(altas_uv_max, uv_area.layer), lod_max);
half4 color_min, color_max;
color_min = half4(textureLod(lightprobe_spheres_tx, vec3(altas_uv_min, uv_area.layer), lod_min));
color_max = half4(textureLod(lightprobe_spheres_tx, vec3(altas_uv_max, uv_area.layer), lod_max));
return mix(color_min, color_max, mix_fac);
}
#endif

View File

@ -68,7 +68,7 @@ void irradiance_capture_world(vec3 L, inout SphericalHarmonicL1 sh)
if (capture_info_buf.capture_world_direct) {
SphereProbeUvArea atlas_coord = capture_info_buf.world_atlas_coord;
radiance = lightprobe_spheres_sample(L, 0.0, atlas_coord).rgb;
radiance = vec3(lightprobe_spheres_sample(L, 0.0, atlas_coord).rgb);
/* Clamped brightness. */
float luma = max(1e-8, reduce_max(radiance));

View File

@ -70,7 +70,7 @@ void main()
float clamp_indirect = uniform_buf.clamp.surface_indirect;
samp.volume_irradiance = spherical_harmonics_clamp(samp.volume_irradiance, clamp_indirect);
vec3 radiance = lightprobe_eval_direction(samp, ray.origin, ray.direction, ray_pdf_inv);
vec3 radiance = vec3(lightprobe_eval_direction(samp, ray.origin, ray.direction, ray_pdf_inv));
/* Set point really far for correct reprojection of background. */
float hit_time = 1000.0;

View File

@ -101,7 +101,7 @@ void main()
vec3 Ng = ray.direction;
/* Fallback to nearest light-probe. */
LightProbeSample samp = lightprobe_load(P, Ng, V);
radiance = lightprobe_eval_direction(samp, P, ray.direction, ray_pdf_inv);
radiance = vec3(lightprobe_eval_direction(samp, P, ray.direction, ray_pdf_inv));
/* Set point really far for correct reprojection of background. */
hit.time = 10000.0;
}

View File

@ -141,7 +141,7 @@ void main()
float clamp_indirect = uniform_buf.clamp.surface_indirect;
samp.volume_irradiance = spherical_harmonics_clamp(samp.volume_irradiance, clamp_indirect);
radiance = lightprobe_eval_direction(samp, ray.origin, ray.direction, ray_pdf_inv);
radiance = vec3(lightprobe_eval_direction(samp, ray.origin, ray.direction, ray_pdf_inv));
/* Set point really far for correct reprojection of background. */
hit.time = 10000.0;
}

View File

@ -409,7 +409,7 @@ float shadow_normal_offset(vec3 Ng, vec3 L)
* Evaluate shadowing by casting rays toward the light direction.
* Returns light visibility.
*/
float shadow_eval(LightData light,
half shadow_eval(LightData light,
const bool is_directional,
const bool is_transmission,
bool is_translucent_with_thickness,
@ -474,7 +474,7 @@ float shadow_eval(LightData light,
/* Don't do a any horizon clipping in this case as the closure is lit from both sides. */
lNg = (is_transmission && is_translucent_with_thickness) ? vec3(0.0) : lNg;
float surface_hit = 0.0;
half surface_hit = 0.0;
for (int ray_index = 0; ray_index < ray_count && ray_index < SHADOW_MAX_RAY; ray_index++) {
vec2 random_ray_2d = fract(hammersley_2d(ray_index, ray_count) + random_shadow_3d.xy);
@ -489,10 +489,10 @@ float shadow_eval(LightData light,
has_hit = shadow_map_trace(clip_ray, ray_step_count, random_shadow_3d.z);
}
surface_hit += float(has_hit);
surface_hit += half(has_hit);
}
/* Average samples. */
return saturate(1.0 - surface_hit / float(ray_count));
return saturate(1.0 - surface_hit / half(ray_count));
}
/** \} */

View File

@ -15,20 +15,20 @@
#ifdef EEVEE_UTILITY_TX
float subsurface_transmittance_profile(float u)
half subsurface_transmittance_profile(float u)
{
return utility_tx_sample(utility_tx, vec2(u, 0.0), UTIL_SSS_TRANSMITTANCE_PROFILE_LAYER).r;
return half(utility_tx_sample(utility_tx, vec2(u, 0.0), UTIL_SSS_TRANSMITTANCE_PROFILE_LAYER).r);
}
/**
* Returns the amount of light that can travels through a uniform medium and exit at the backface.
*/
vec3 subsurface_transmission(vec3 sss_radii, float thickness)
half3 subsurface_transmission(vec3 sss_radii, float thickness)
{
sss_radii *= SSS_TRANSMIT_LUT_RADIUS;
vec3 channels_co = saturate(thickness / sss_radii) * SSS_TRANSMIT_LUT_SCALE +
SSS_TRANSMIT_LUT_BIAS;
vec3 translucency;
half3 translucency;
translucency.x = (sss_radii.x > 0.0) ? subsurface_transmittance_profile(channels_co.x) : 0.0;
translucency.y = (sss_radii.y > 0.0) ? subsurface_transmittance_profile(channels_co.y) : 0.0;
translucency.z = (sss_radii.z > 0.0) ? subsurface_transmittance_profile(channels_co.z) : 0.0;

View File

@ -46,7 +46,7 @@ void main()
float lod = max(1.0, base_lod);
float mix_factor = min(1.0, base_lod);
SphereProbeUvArea world_atlas_coord = reinterpret_as_atlas_coord(world_coord_packed);
vec4 probe_color = lightprobe_spheres_sample(-g_data.N, lod, world_atlas_coord);
vec4 probe_color = vec4(lightprobe_spheres_sample(-g_data.N, lod, world_atlas_coord));
out_background.rgb = mix(out_background.rgb, probe_color.rgb, mix_factor);
SphericalHarmonicL1 volume_irradiance = lightprobe_volume_sample(

View File

@ -35,7 +35,7 @@ void main()
light_eval_reflection(stack, P, Ng, V, 0.0, surfel.receiver_light_set);
if (capture_info_buf.capture_indirect) {
surfel_buf[index].radiance_direct.front.rgb += stack.cl[0].light_shadowed *
surfel_buf[index].radiance_direct.front.rgb += vec3(stack.cl[0].light_shadowed) *
surfel.albedo_front;
}
@ -46,6 +46,7 @@ void main()
light_eval_reflection(stack, P, -Ng, -V, 0.0, surfel.receiver_light_set);
if (capture_info_buf.capture_indirect) {
surfel_buf[index].radiance_direct.back.rgb += stack.cl[0].light_shadowed * surfel.albedo_back;
surfel_buf[index].radiance_direct.back.rgb += vec3(stack.cl[0].light_shadowed) *
surfel.albedo_back;
}
}

View File

@ -89,7 +89,7 @@ void radiance_transfer_world(inout Surfel receiver, vec3 L)
if (capture_info_buf.capture_world_indirect) {
SphereProbeUvArea atlas_coord = capture_info_buf.world_atlas_coord;
radiance = lightprobe_spheres_sample(L, 0.0, atlas_coord).rgb;
radiance = vec3(lightprobe_spheres_sample(L, 0.0, atlas_coord).rgb);
}
if (capture_info_buf.capture_visibility_indirect) {

View File

@ -576,6 +576,18 @@ vec4 safe_rcp(vec4 a)
{
return select(vec4(0.0), (1.0 / a), notEqual(a, vec4(0.0)));
}
half2 safe_rcp(half2 a)
{
return select(half2(0.0), (1.0 / a), notEqual(a, half2(0.0)));
}
half3 safe_rcp(half3 a)
{
return select(half3(0.0), (1.0 / a), notEqual(a, half3(0.0)));
}
half4 safe_rcp(half4 a)
{
return select(half4(0.0), (1.0 / a), notEqual(a, half4(0.0)));
}
vec2 interpolate(vec2 a, vec2 b, float t)
{
@ -706,6 +718,18 @@ float reduce_add(vec4 a)
{
return a.x + a.y + a.z + a.w;
}
half reduce_add(half2 a)
{
return a.x + a.y;
}
half reduce_add(half3 a)
{
return a.x + a.y + a.z;
}
half reduce_add(half4 a)
{
return a.x + a.y + a.z + a.w;
}
int reduce_add(ivec2 a)
{
return a.x + a.y;
@ -756,6 +780,18 @@ float average(vec4 a)
{
return reduce_add(a) * (1.0 / 4.0);
}
float average(half2 a)
{
return reduce_add(a) * (1.0 / 2.0);
}
float average(half3 a)
{
return reduce_add(a) * (1.0 / 3.0);
}
float average(half4 a)
{
return reduce_add(a) * (1.0 / 4.0);
}
# define ASSERT_UNIT_EPSILON 0.0002