From de818d81c3f9868ca78399fa7f106bed893e540f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 2 Sep 2022 13:48:55 +0200 Subject: [PATCH 1/4] Fix T98190: EEVEE: Very slow rendering on Intel HD Graphics 4400 This particular GPU driver does not constant fold all the way in order to discard the unused branches. To workaround that, we introduce a series of material flag that generates defines that only keep used branches. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D15852 --- release/scripts/addons | 2 +- source/blender/gpu/GPU_material.h | 8 +++++++ source/blender/gpu/intern/gpu_codegen.cc | 18 ++++++++++++++++ .../gpu_shader_material_principled.glsl | 12 +++++++++++ .../nodes/node_shader_bsdf_principled.cc | 21 +++++++++++++++++++ 5 files changed, 60 insertions(+), 1 deletion(-) diff --git a/release/scripts/addons b/release/scripts/addons index 7a8502871c3..67f1fbca148 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 7a8502871c34db0343cc7de52d6b49b15a84238a +Subproject commit 67f1fbca1482d9d9362a4001332e785c3fd5d230 diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3ca465fa57a..ddd8300bf0f 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -77,12 +77,20 @@ typedef enum eGPUMaterialFlag { GPU_MATFLAG_HOLDOUT = (1 << 6), GPU_MATFLAG_SHADER_TO_RGBA = (1 << 7), GPU_MATFLAG_AO = (1 << 8), + GPU_MATFLAG_CLEARCOAT = (1 << 9), GPU_MATFLAG_OBJECT_INFO = (1 << 10), GPU_MATFLAG_AOV = (1 << 11), GPU_MATFLAG_BARYCENTRIC = (1 << 20), + /* Optimization to only add the branches of the principled shader that are necessary. */ + GPU_MATFLAG_PRINCIPLED_CLEARCOAT = (1 << 21), + GPU_MATFLAG_PRINCIPLED_METALLIC = (1 << 22), + GPU_MATFLAG_PRINCIPLED_DIELECTRIC = (1 << 23), + GPU_MATFLAG_PRINCIPLED_GLASS = (1 << 24), + GPU_MATFLAG_PRINCIPLED_ANY = (1 << 25), + /* Tells the render engine the material was just compiled or updated. */ GPU_MATFLAG_UPDATED = (1 << 29), diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 82441c3c89c..a05bf51242f 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -351,6 +351,24 @@ void GPUCodegen::generate_resources() { GPUCodegenCreateInfo &info = *create_info; + /* Ref. T98190: Defines are optimizations for old compilers. + * Might become unecessary with EEVEE-Next. */ + if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_CLEARCOAT)) { + info.define("PRINCIPLED_CLEARCOAT"); + } + if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_METALLIC)) { + info.define("PRINCIPLED_METALLIC"); + } + if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_DIELECTRIC)) { + info.define("PRINCIPLED_DIELECTRIC"); + } + if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_GLASS)) { + info.define("PRINCIPLED_GLASS"); + } + if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_ANY)) { + info.define("PRINCIPLED_ANY"); + } + std::stringstream ss; /* Textures. */ diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index 2e695fa3e14..0d8f2272c10 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -149,25 +149,37 @@ void node_bsdf_principled(vec4 base_color, max(roughness, transmission_roughness); refraction_data.ior = ior; + /* Ref. T98190: Defines are optimizations for old compilers. + * Might become unecessary with EEVEE-Next. */ if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat != 0.0) { +#ifdef PRINCIPLED_CLEARCOAT /* Metallic & Clearcoat case. */ result = closure_eval(reflection_data, clearcoat_data); +#endif } else if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) { +#ifdef PRINCIPLED_METALLIC /* Metallic case. */ result = closure_eval(reflection_data); +#endif } else if (do_diffuse != 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) { +#ifdef PRINCIPLED_DIELECTRIC /* Dielectric case. */ result = closure_eval(diffuse_data, reflection_data); +#endif } else if (do_diffuse == 0.0 && do_refraction != 0.0 && do_clearcoat == 0.0) { +#ifdef PRINCIPLED_GLASS /* Glass case. */ result = closure_eval(reflection_data, refraction_data); +#endif } else { +#ifdef PRINCIPLED_ANY /* Un-optimized case. */ result = closure_eval(diffuse_data, reflection_data, clearcoat_data, refraction_data); +#endif } Closure emission_cl = closure_eval(emission_data); Closure transparency_cl = closure_eval(transparency_data); diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index a63c7aede04..2f75b7b533f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -167,6 +167,27 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, if (use_transparency) { flag |= GPU_MATFLAG_TRANSPARENT; } + if (use_clear) { + flag |= GPU_MATFLAG_CLEARCOAT; + } + + /* Ref. T98190: Defines are optimizations for old compilers. + * Might become unecessary with EEVEE-Next. */ + if (use_diffuse == false && use_refract == false && use_clear == true) { + flag |= GPU_MATFLAG_PRINCIPLED_CLEARCOAT; + } + else if (use_diffuse == false && use_refract == false && use_clear == false) { + flag |= GPU_MATFLAG_PRINCIPLED_METALLIC; + } + else if (use_diffuse == true && use_refract == false && use_clear == false) { + flag |= GPU_MATFLAG_PRINCIPLED_DIELECTRIC; + } + else if (use_diffuse == false && use_refract == true && use_clear == false) { + flag |= GPU_MATFLAG_PRINCIPLED_GLASS; + } + else { + flag |= GPU_MATFLAG_PRINCIPLED_ANY; + } if (use_subsurf) { bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2); From 874e9cbab9fbd65220794cebc195e5e28786ad78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 2 Sep 2022 18:08:59 +0200 Subject: [PATCH 2/4] Fix T99528: EEVEE: Regression: Faulty shaders when using Volume Info node Workaround the issue by adding an intermediate function. This is usually the case when working with attributes. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D15860 --- .../material/gpu_shader_material_attribute.glsl | 10 ++++++++++ .../nodes/shader/nodes/node_shader_volume_info.cc | 2 ++ 2 files changed, 12 insertions(+) diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl index 2ae53b35b3f..af4a511d627 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl @@ -12,6 +12,16 @@ void node_attribute_temperature(vec4 attr, out vec4 out_attr) out_attr.w = 1.0; } +void node_attribute_density(vec4 attr, out float out_attr) +{ + out_attr = attr.x; +} + +void node_attribute_flame(vec4 attr, out float out_attr) +{ + out_attr = attr.x; +} + void node_attribute( vec4 attr, out vec4 outcol, out vec3 outvec, out float outf, out float outalpha) { diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_info.cc b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc index a202312f8d8..1f31e9c605f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_volume_info.cc +++ b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc @@ -25,9 +25,11 @@ static int node_shader_gpu_volume_info(GPUMaterial *mat, } if (out[1].hasoutput) { out[1].link = GPU_attribute(mat, CD_AUTO_FROM_NAME, "density"); + GPU_link(mat, "node_attribute_density", out[1].link, &out[1].link); } if (out[2].hasoutput) { out[2].link = GPU_attribute(mat, CD_AUTO_FROM_NAME, "flame"); + GPU_link(mat, "node_attribute_flame", out[2].link, &out[2].link); } if (out[3].hasoutput) { out[3].link = GPU_attribute(mat, CD_AUTO_FROM_NAME, "temperature"); From 07cf3ce92fa257a0cac5565ca1ff857834ce67ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 2 Sep 2022 18:13:54 +0200 Subject: [PATCH 3/4] Fix T100377: EEVEE: Regression 3.2 normalmap node broken This was caused by un-wanted normalization. This is a requirement of the MikkTspace. The issue is that g_data.N is expected to be normalized by many other functions and overriden by bump displacement. Adding a new global variable containing the interpolated normal fixes the issue AND make it match cycles behavior better (mix between bump and interpolated normal). --- source/blender/draw/engines/eevee/shaders/surface_lib.glsl | 5 +++-- .../draw/engines/eevee_next/shaders/eevee_surf_lib.glsl | 3 ++- source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl | 4 +++- .../shaders/material/gpu_shader_material_normal_map.glsl | 6 +++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl index 488e229bff7..b984a6df7b3 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl @@ -98,10 +98,11 @@ GlobalData init_globals(void) # if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) surf.P = transform_direction(ViewMatrixInverse, -viewCameraVec(viewPosition)); - surf.N = surf.Ng = -surf.P; + surf.N = surf.Ng = surf.Ni = -surf.P; surf.ray_length = 0.0; # else surf.P = worldPosition; + surf.Ni = worldNormal; surf.N = safe_normalize(worldNormal); surf.Ng = safe_normalize(cross(dFdx(surf.P), dFdy(surf.P))); surf.ray_length = distance(surf.P, cameraPos); @@ -123,7 +124,7 @@ GlobalData init_globals(void) cos_theta = hairThickTime / hairThickness; } float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta)); - surf.N = safe_normalize(worldNormal * sin_theta + B * cos_theta); + surf.N = surf.Ni = safe_normalize(worldNormal * sin_theta + B * cos_theta); surf.curve_T = -hairTangent; /* Costly, but follows cycles per pixel tangent space (not following curve shape). */ surf.curve_B = cross(V, surf.curve_T); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl index 30b48edaa78..18e748596d5 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl @@ -40,7 +40,7 @@ void init_globals_curves() /* Shade as a cylinder. */ float cos_theta = interp.curves_time_width / interp.curves_thickness; float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta)); - g_data.N = normalize(interp.N * sin_theta + interp.curves_binormal * cos_theta); + g_data.N = g_data.Ni = normalize(interp.N * sin_theta + interp.curves_binormal * cos_theta); /* Costly, but follows cycles per pixel tangent space (not following curve shape). */ vec3 V = cameraVec(g_data.P); @@ -67,6 +67,7 @@ void init_globals() { /* Default values. */ g_data.P = interp.P; + g_data.Ni = interp.N; g_data.N = safe_normalize(interp.N); g_data.Ng = g_data.N; g_data.is_strand = false; diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl index 6091a5c834a..c0821085c8d 100644 --- a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl @@ -187,8 +187,10 @@ struct ClosureTransparency { struct GlobalData { /** World position. */ vec3 P; - /** Surface Normal. */ + /** Surface Normal. Normalized, overriden by bump displacement. */ vec3 N; + /** Raw interpolated normal (non-normalized) data. */ + vec3 Ni; /** Geometric Normal. */ vec3 Ng; /** Curve Tangent Space. */ diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl index a54dc59ddfe..3fc4992f7c4 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_normal_map.glsl @@ -3,13 +3,13 @@ void node_normal_map(vec4 tangent, vec3 texnormal, out vec3 outnormal) { if (all(equal(tangent, vec4(0.0, 0.0, 0.0, 1.0)))) { - outnormal = g_data.N; + outnormal = g_data.Ni; return; } tangent *= (FrontFacing ? 1.0 : -1.0); - vec3 B = tangent.w * cross(g_data.N, tangent.xyz) * sign(ObjectInfo.w); + vec3 B = tangent.w * cross(g_data.Ni, tangent.xyz) * sign(ObjectInfo.w); - outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * g_data.N; + outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * g_data.Ni; outnormal = normalize(outnormal); } #endif From e02e844f511528a0ff5d57ebbe35d129ae3fae69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 2 Sep 2022 18:20:24 +0200 Subject: [PATCH 4/4] Fix T100163: Eevee: Regression: Displacement maps affected by rotation This was an oversight as the matrix multiplication present in original code was reversed. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D15858 --- .../gpu/shaders/material/gpu_shader_material_displacement.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl index cdcdbe50917..52b4edf665f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_displacement.glsl @@ -1,6 +1,6 @@ void node_displacement_object(float height, float midlevel, float scale, vec3 N, out vec3 result) { - N = transform_direction(ModelMatrix, N); + N = transform_direction(ModelMatrixInverse, N); result = (height - midlevel) * scale * normalize(N); /* Apply object scale and orientation. */ result = transform_direction(ModelMatrix, result);