EEVEE-Next: Split curve attributes to their own interface

This avoid poluting shader interfaces which might not be
optimized by the compilers.
This commit is contained in:
Clément Foucault 2023-10-03 15:56:41 +02:00
parent fb38327e6a
commit 23e4cbc86a
4 changed files with 49 additions and 54 deletions

View File

@ -187,7 +187,7 @@ int g_curves_attr_id = 0;
* based on the attribute scope (point or spline). */
int curves_attribute_element_id()
{
int id = interp_flat.curves_strand_id;
int id = curve_interp_flat.strand_id;
if (drw_curves.is_point_attribute[g_curves_attr_id][0] != 0u) {
# ifdef COMMON_HAIR_LIB
id = hair_get_base_id();
@ -205,11 +205,11 @@ vec4 attr_load_tangent(samplerBuffer cd_buf)
}
vec3 attr_load_uv(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, interp_flat.curves_strand_id).rgb;
return texelFetch(cd_buf, curve_interp_flat.strand_id).rgb;
}
vec4 attr_load_color(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, interp_flat.curves_strand_id).rgba;
return texelFetch(cd_buf, curve_interp_flat.strand_id).rgba;
}
vec4 attr_load_vec4(samplerBuffer cd_buf)
{

View File

@ -25,15 +25,15 @@ void main()
ViewMatrixInverse[3].xyz,
ViewMatrixInverse[2].xyz,
interp.P,
interp.curves_tangent,
interp.curves_binormal,
interp.curves_time,
interp.curves_thickness,
interp.curves_time_width);
curve_interp.tangent,
curve_interp.binormal,
curve_interp.time,
curve_interp.thickness,
curve_interp.time_width);
interp.N = cross(interp.curves_tangent, interp.curves_binormal);
interp_flat.curves_strand_id = hair_get_strand_id();
interp.barycentric_coords = hair_get_barycentric();
interp.N = cross(curve_interp.tangent, curve_interp.binormal);
curve_interp_flat.strand_id = hair_get_strand_id();
curve_interp.barycentric_coords = hair_get_barycentric();
#ifdef MAT_VELOCITY
/* Due to the screen space nature of the vertex positioning, we compute only the motion of curve
* strand, not its cylinder. Otherwise we would add the rotation velocity. */

View File

@ -41,35 +41,37 @@ void init_globals_mesh()
void init_globals_curves()
{
#if defined(MAT_GEOM_CURVES)
/* Shade as a cylinder. */
float cos_theta = interp.curves_time_width / interp.curves_thickness;
#if defined(GPU_FRAGMENT_SHADER) && defined(MAT_GEOM_CURVES)
float cos_theta = curve_interp.time_width / curve_interp.thickness;
# if defined(GPU_FRAGMENT_SHADER)
if (hairThicknessRes == 1) {
/* Random cosine normal distribution on the hair surface. */
float noise = utility_tx_fetch(utility_tx, gl_FragCoord.xy, UTIL_BLUE_NOISE_LAYER).x;
# ifdef EEVEE_SAMPLING_DATA
# ifdef EEVEE_SAMPLING_DATA
/* Needs to check for SAMPLING_DATA,
* otherwise Surfel and World (?!?!) shader validation fails. */
noise = fract(noise + sampling_rng_1D_get(SAMPLING_CURVES_U));
# endif
# endif
cos_theta = noise * 2.0 - 1.0;
}
#endif
# endif
float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
g_data.N = g_data.Ni = normalize(interp.N * sin_theta + interp.curves_binormal * cos_theta);
g_data.N = g_data.Ni = normalize(interp.N * sin_theta + curve_interp.binormal * cos_theta);
/* Costly, but follows cycles per pixel tangent space (not following curve shape). */
vec3 V = cameraVec(g_data.P);
g_data.curve_T = -interp.curves_tangent;
g_data.curve_T = -curve_interp.tangent;
g_data.curve_B = cross(V, g_data.curve_T);
g_data.curve_N = safe_normalize(cross(g_data.curve_T, g_data.curve_B));
g_data.is_strand = true;
g_data.hair_time = interp.curves_time;
g_data.hair_thickness = interp.curves_thickness;
g_data.hair_strand_id = interp_flat.curves_strand_id;
#if defined(USE_BARYCENTRICS) && defined(GPU_FRAGMENT_SHADER) && defined(MAT_GEOM_CURVES)
g_data.barycentric_coords = hair_resolve_barycentric(interp.barycentric_coords);
g_data.hair_time = curve_interp.time;
g_data.hair_thickness = curve_interp.thickness;
g_data.hair_strand_id = curve_interp_flat.strand_id;
# if defined(USE_BARYCENTRICS) && defined(GPU_FRAGMENT_SHADER)
g_data.barycentric_coords = hair_resolve_barycentric(curve_interp.barycentric_coords);
# endif
#endif
}
@ -117,13 +119,6 @@ void init_interface()
#ifdef GPU_VERTEX_SHADER
interp.P = vec3(0.0);
interp.N = vec3(0.0);
interp.barycentric_coords = vec2(0.0);
interp.curves_tangent = vec3(0.0);
interp.curves_binormal = vec3(0.0);
interp.curves_time = 0.0;
interp.curves_time_width = 0.0;
interp.curves_thickness = 0.0;
interp_flat.curves_strand_id = 0;
drw_ResourceID_iface.resource_index = resource_id;
#endif
}

View File

@ -32,12 +32,20 @@ GPU_SHADER_CREATE_INFO(eevee_utility_texture)
/** \name Surface Mesh Type
* \{ */
/* Common interface */
GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp")
/* World Position. */
.smooth(Type::VEC3, "P")
/* World Normal. */
.smooth(Type::VEC3, "N");
GPU_SHADER_CREATE_INFO(eevee_geom_mesh)
.additional_info("eevee_shared")
.define("MAT_GEOM_MESH")
.vertex_in(0, Type::VEC3, "pos")
.vertex_in(1, Type::VEC3, "nor")
.vertex_source("eevee_geom_mesh_vert.glsl")
.vertex_out(eevee_surf_iface)
.additional_info("draw_modelmat_new", "draw_resource_id_varying", "draw_view");
GPU_SHADER_INTERFACE_INFO(eevee_surf_point_cloud_iface, "point_cloud_interp")
@ -50,6 +58,7 @@ GPU_SHADER_CREATE_INFO(eevee_geom_point_cloud)
.additional_info("eevee_shared")
.define("MAT_GEOM_POINT_CLOUD")
.vertex_source("eevee_geom_point_cloud_vert.glsl")
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_point_cloud_iface)
.vertex_out(eevee_surf_point_cloud_flat_iface)
/* TODO(Miguel Pozo): Remove once we get rid of old EEVEE. */
@ -65,12 +74,26 @@ GPU_SHADER_CREATE_INFO(eevee_geom_gpencil)
.additional_info("eevee_shared")
.define("MAT_GEOM_GPENCIL")
.vertex_source("eevee_geom_gpencil_vert.glsl")
.vertex_out(eevee_surf_iface)
.additional_info("draw_gpencil_new", "draw_resource_id_varying", "draw_resource_id_new");
GPU_SHADER_INTERFACE_INFO(eevee_surf_curve_iface, "curve_interp")
.smooth(Type::VEC2, "barycentric_coords")
.smooth(Type::VEC3, "tangent")
.smooth(Type::VEC3, "binormal")
.smooth(Type::FLOAT, "time")
.smooth(Type::FLOAT, "time_width")
.smooth(Type::FLOAT, "thickness");
GPU_SHADER_INTERFACE_INFO(eevee_surf_curve_flat_iface, "curve_interp_flat")
.flat(Type::INT, "strand_id");
GPU_SHADER_CREATE_INFO(eevee_geom_curves)
.additional_info("eevee_shared")
.define("MAT_GEOM_CURVES")
.vertex_source("eevee_geom_curves_vert.glsl")
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_curve_iface)
.vertex_out(eevee_surf_curve_flat_iface)
.additional_info("draw_modelmat_new",
"draw_resource_id_varying",
"draw_view",
@ -82,6 +105,7 @@ GPU_SHADER_CREATE_INFO(eevee_geom_world)
.define("MAT_GEOM_WORLD")
.builtins(BuiltinBits::VERTEX_ID)
.vertex_source("eevee_geom_world_vert.glsl")
.vertex_out(eevee_surf_iface)
.additional_info("draw_modelmat_new", "draw_resource_id_varying", "draw_view");
/** \} */
@ -90,18 +114,6 @@ GPU_SHADER_CREATE_INFO(eevee_geom_world)
/** \name Surface
* \{ */
GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp")
.smooth(Type::VEC3, "P")
.smooth(Type::VEC3, "N")
.smooth(Type::VEC2, "barycentric_coords")
.smooth(Type::VEC3, "curves_tangent")
.smooth(Type::VEC3, "curves_binormal")
.smooth(Type::FLOAT, "curves_time")
.smooth(Type::FLOAT, "curves_time_width")
.smooth(Type::FLOAT, "curves_thickness");
GPU_SHADER_INTERFACE_INFO(eevee_surf_flat_iface, "interp_flat")
.flat(Type::INT, "curves_strand_id");
#define image_out(slot, qualifier, format, name) \
image(slot, format, qualifier, ImageType::FLOAT_2D, name, Frequency::PASS)
#define image_array_out(slot, qualifier, format, name) \
@ -118,8 +130,6 @@ GPU_SHADER_CREATE_INFO(eevee_cryptomatte_out)
.image_out(RBUFS_CRYPTOMATTE_SLOT, Qualifier::WRITE, GPU_RGBA32F, "rp_cryptomatte_img");
GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_flat_iface)
/* NOTE: This removes the possibility of using gl_FragDepth. */
.early_fragment_test(true)
/* Direct output. (Emissive, Holdout) */
@ -140,8 +150,6 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
"eevee_cryptomatte_out");
GPU_SHADER_CREATE_INFO(eevee_surf_forward)
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_flat_iface)
/* Early fragment test is needed for render passes support for forward surfaces. */
/* NOTE: This removes the possibility of using gl_FragDepth. */
.early_fragment_test(true)
@ -161,8 +169,6 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
);
GPU_SHADER_CREATE_INFO(eevee_surf_capture)
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_flat_iface)
.define("MAT_CAPTURE")
.storage_buf(SURFEL_BUF_SLOT, Qualifier::WRITE, "Surfel", "surfel_buf[]")
.storage_buf(CAPTURE_BUF_SLOT, Qualifier::READ_WRITE, "CaptureInfoData", "capture_info_buf")
@ -171,14 +177,10 @@ GPU_SHADER_CREATE_INFO(eevee_surf_capture)
GPU_SHADER_CREATE_INFO(eevee_surf_depth)
.define("MAT_DEPTH")
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_flat_iface)
.fragment_source("eevee_surf_depth_frag.glsl")
.additional_info("eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture");
GPU_SHADER_CREATE_INFO(eevee_surf_world)
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_flat_iface)
.push_constant(Type::FLOAT, "world_opacity_fade")
.fragment_out(0, Type::VEC4, "out_background")
.fragment_source("eevee_surf_world_frag.glsl")
@ -194,8 +196,6 @@ GPU_SHADER_CREATE_INFO(eevee_surf_shadow)
.builtins(BuiltinBits::VIEWPORT_INDEX)
.builtins(BuiltinBits::LAYER)
.builtins(BuiltinBits::TEXTURE_ATOMIC)
.vertex_out(eevee_surf_iface)
.vertex_out(eevee_surf_flat_iface)
.storage_buf(SHADOW_RENDER_MAP_BUF_SLOT,
Qualifier::READ,
"uint",