EEVEE-Next: Light: Add light evaluation support

This is the same implementation as the old one.
This commit is contained in:
Clément Foucault 2022-08-14 14:27:08 +02:00
parent 67d7792503
commit 659b63751d
Notes: blender-bot 2023-10-25 12:23:53 +02:00
Referenced by issue #100846, Problems with materials nodes in Alpha Trees
Referenced by issue #98946, Crash choice asset library
Referenced by issue #114141, Crash when extrude with E key
4 changed files with 53 additions and 40 deletions

View File

@ -102,11 +102,13 @@ DRWShadingGroup *ForwardPipeline::material_opaque_add(::Material *blender_mat, G
RenderBuffers &rbufs = inst_.render_buffers;
DRWPass *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ? opaque_culled_ps_ : opaque_ps_;
LightModule &lights = inst_.lights;
Sampling &sampling = inst_.sampling;
// LightProbeModule &lightprobes = inst_.lightprobes;
// RaytracingModule &raytracing = inst_.raytracing;
// eGPUSamplerState no_interp = GPU_SAMPLER_DEFAULT;
DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, pass);
lights.bind_resources(grp);
sampling.bind_resources(grp);
// DRW_shgroup_uniform_block(grp, "sampling_buf", inst_.sampling.ubo_get());
// DRW_shgroup_uniform_block(grp, "grids_buf", lightprobes.grid_ubo_get());
// DRW_shgroup_uniform_block(grp, "cubes_buf", lightprobes.cube_ubo_get());
@ -164,18 +166,20 @@ DRWShadingGroup *ForwardPipeline::material_transparent_add(::Material *blender_m
{
RenderBuffers &rbufs = inst_.render_buffers;
LightModule &lights = inst_.lights;
Sampling &sampling = inst_.sampling;
// LightProbeModule &lightprobes = inst_.lightprobes;
// RaytracingModule &raytracing = inst_.raytracing;
// eGPUSamplerState no_interp = GPU_SAMPLER_DEFAULT;
DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, transparent_ps_);
lights.bind_resources(grp);
sampling.bind_resources(grp);
// DRW_shgroup_uniform_block(grp, "sampling_buf", inst_.sampling.ubo_get());
// DRW_shgroup_uniform_block(grp, "grids_buf", lightprobes.grid_ubo_get());
// DRW_shgroup_uniform_block(grp, "cubes_buf", lightprobes.cube_ubo_get());
// DRW_shgroup_uniform_block(grp, "probes_buf", lightprobes.info_ubo_get());
// DRW_shgroup_uniform_texture_ref(grp, "lightprobe_grid_tx", lightprobes.grid_tx_ref_get());
// DRW_shgroup_uniform_texture_ref(grp, "lightprobe_cube_tx", lightprobes.cube_tx_ref_get());
// DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx);
DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx);
/* TODO(fclem): Make this only needed if material uses it ... somehow. */
// if (true) {
// DRW_shgroup_uniform_texture_ref(

View File

@ -39,6 +39,8 @@ bool closure_select(float weight, inout float total_weight, inout float r)
destination = candidate; \
}
float g_closure_rand;
void closure_weights_reset()
{
g_diffuse_data.weight = 0.0;
@ -58,18 +60,8 @@ void closure_weights_reset()
g_refraction_data.roughness = 0.0;
g_refraction_data.ior = 0.0;
/* TEMP */
#define P(x) ((x + 0.5) / 16.0)
const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)),
vec4(P(12.0), P(4.0), P(14.0), P(6.0)),
vec4(P(3.0), P(11.0), P(1.0), P(9.0)),
vec4(P(15.0), P(7.0), P(13.0), P(5.0)));
#undef P
#if defined(GPU_FRAGMENT_SHADER)
ivec2 pix = ivec2(gl_FragCoord.xy) % ivec2(4);
g_diffuse_rand = dither_mat4x4[pix.x][pix.y];
g_reflection_rand = dither_mat4x4[pix.x][pix.y];
g_refraction_rand = dither_mat4x4[pix.x][pix.y];
g_diffuse_rand = g_reflection_rand = g_refraction_rand = g_closure_rand;
#else
g_diffuse_rand = 0.0;
g_reflection_rand = 0.0;

View File

@ -5,35 +5,36 @@
* This is used by alpha blended materials and materials using Shader to RGB nodes.
**/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
float spec_light(ClosureReflection ref)
{
float gloss = saturate(1.0 - ref.roughness);
float shininess = exp2(10.0 * gloss + 1.0);
vec3 N = ref.N;
vec3 L = vec3(0.0, 0.0, 1.0);
vec3 H = normalize(L + cameraVec(g_data.P));
float spec_angle = saturate(dot(N, H));
float normalization_factor = shininess * 0.125 + 1.0;
float spec_light = pow(spec_angle, shininess) * saturate(dot(N, L)) * normalization_factor;
return spec_light;
}
vec4 closure_to_rgba(Closure cl)
{
vec3 diffuse_light = vec3(0.0);
vec3 reflection_light = vec3(0.0);
vec3 refraction_light = vec3(0.0);
float vP_z = dot(cameraForward, g_data.P) - dot(cameraForward, cameraPos);
light_eval(g_diffuse_data,
g_reflection_data,
g_data.P,
cameraVec(g_data.P),
vP_z,
0.01 /* TODO(fclem) thickness. */,
diffuse_light,
reflection_light);
vec4 out_color;
out_color.rgb = g_emission;
out_color.rgb += g_diffuse_data.color * g_diffuse_data.weight *
saturate(g_diffuse_data.N.z * 0.5 + 0.5);
out_color.rgb += g_reflection_data.color * g_reflection_data.weight *
spec_light(g_reflection_data);
out_color.rgb += g_refraction_data.color * g_refraction_data.weight *
saturate(g_refraction_data.N.z * 0.5 + 0.5);
out_color.rgb += g_diffuse_data.color * g_diffuse_data.weight * diffuse_light;
out_color.rgb += g_reflection_data.color * g_reflection_data.weight * reflection_light;
out_color.rgb += g_refraction_data.color * g_refraction_data.weight * refraction_light;
out_color.a = saturate(1.0 - avg(g_transmittance));
@ -47,15 +48,29 @@ void main()
{
init_globals();
float noise = utility_tx_fetch(utility_tx, gl_FragCoord.xy, UTIL_BLUE_NOISE_LAYER).r;
g_closure_rand = fract(noise + sampling_rng_1D_get(SAMPLING_CLOSURE));
fragment_displacement();
nodetree_surface();
g_holdout = saturate(g_holdout);
vec3 diffuse_light = vec3(saturate(g_diffuse_data.N.z * 0.5 + 0.5));
vec3 reflection_light = vec3(spec_light(g_reflection_data));
vec3 refraction_light = vec3(saturate(g_refraction_data.N.z * 0.5 + 0.5));
vec3 diffuse_light = vec3(0.0);
vec3 reflection_light = vec3(0.0);
vec3 refraction_light = vec3(0.0);
float vP_z = dot(cameraForward, g_data.P) - dot(cameraForward, cameraPos);
light_eval(g_diffuse_data,
g_reflection_data,
g_data.P,
cameraVec(g_data.P),
vP_z,
0.01 /* TODO(fclem) thickness. */,
diffuse_light,
reflection_light);
g_diffuse_data.color *= g_diffuse_data.weight;
g_reflection_data.color *= g_reflection_data.weight;

View File

@ -16,6 +16,8 @@ GPU_SHADER_CREATE_INFO(eevee_sampling_data)
.additional_info("eevee_shared")
.storage_buf(14, Qualifier::READ, "SamplingData", "sampling_buf");
GPU_SHADER_CREATE_INFO(eevee_utility_texture).sampler(8, ImageType::FLOAT_2D_ARRAY, "utility_tx");
/** \} */
/* -------------------------------------------------------------------- */
@ -116,14 +118,14 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
.image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_light_img")
.image_out(4, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
.image_out(5, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img")
.additional_info("eevee_aov_out"
// "eevee_sampling_data",
.additional_info("eevee_aov_out",
"eevee_light_data",
"eevee_utility_texture",
"eevee_sampling_data"
// "eevee_lightprobe_data",
/* Optionally added depending on the material. */
// "eevee_raytrace_data",
// "eevee_transmittance_data",
// "eevee_utility_texture",
// "eevee_light_data",
// "eevee_shadow_data"
);