Fix T93179: geonodes UVs and Vertex colors do not work in EEVEE

Overwriting UV map or vertex color data in Geometry nodes will move the
layers to another CustomData channel, and as such, will make attribute
lookup fail from the UVMap and Vertex Color nodes in EEVEE as the
CustomDataType will also be modified (i.e. no longer `CD_MTFACE` or
`CD_MCOL`).

As discussed in T93179, the solution is to use `CD_PROP_AUTO_FROM_NAME`
so that the render engine is able to find the attributes. This also makes
EEVEE emulate Cycles behaviour in this regard. `attr_load_uv` and
`attr_load_color` are also removed in favor of the generic attribute
API in the various GLSL shaders.

Although `CD_PROP_AUTO_FROM_NAME` is now used even for UV maps, the
active UV map is still used in case the attribute name is empty, to
preserve the old behavior.

Differential Revision: https://developer.blender.org/D13730
This commit is contained in:
Kévin Dietrich 2022-05-03 22:45:27 +02:00
parent 94205e1d02
commit 281bcc1c1d
Notes: blender-bot 2023-02-14 00:29:15 +01:00
Referenced by commit d86d7c935e, Fix T97827: material preview not displaying textures
Referenced by issue #98825, Regression: Eevee shader compilation error
Referenced by issue #97827, Regression: Material Preview Not Displaying Textures
Referenced by issue #93179, Eevee Attribute Rendering Has Some Left Out Nodes Comparing with Cycles
15 changed files with 21 additions and 112 deletions

View File

@ -71,16 +71,6 @@ vec4 attr_load_tangent(samplerBuffer cd_buf)
return vec4(0.0, 0.0, 0.0, 1.0);
}
vec3 attr_load_uv(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, hairStrandID).rgb;
}
vec4 attr_load_color(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, hairStrandID).rgba;
}
vec4 attr_load_vec4(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, hairStrandID).rgba;
@ -135,14 +125,6 @@ vec2 attr_load_float(vec2 attr)
{
return attr;
}
vec4 attr_load_color(vec4 attr)
{
return attr;
}
vec3 attr_load_uv(vec3 attr)
{
return attr;
}
#endif
/* Passthrough. */

View File

@ -171,14 +171,6 @@ vec2 attr_load_vec2(vec2 attr)
{
return vec2(0);
}
vec4 attr_load_color(vec4 attr)
{
return vec4(0);
}
vec3 attr_load_uv(vec3 attr)
{
return vec3(0);
}
/* Passthrough. */
float attr_load_temperature_post(float attr)

View File

@ -77,16 +77,6 @@ vec4 attr_load_tangent(samplerBuffer cd_buf)
return vec4(hairTangent, 1.0);
}
vec3 attr_load_uv(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, hairStrandID).rgb;
}
vec4 attr_load_color(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, hairStrandID).rgba;
}
vec4 attr_load_vec4(samplerBuffer cd_buf)
{
return texelFetch(cd_buf, hairStrandID).rgba;
@ -148,14 +138,6 @@ float attr_load_float(float attr)
{
return attr;
}
vec4 attr_load_color(vec4 attr)
{
return attr;
}
vec3 attr_load_uv(vec3 attr)
{
return attr;
}
#endif
/* Passthrough. */

View File

@ -155,15 +155,6 @@ float attr_load_float(sampler3D tex)
{
return texture(tex, grid_coordinates()).r;
}
vec4 attr_load_color(sampler3D tex)
{
return texture(tex, grid_coordinates());
}
vec3 attr_load_uv(sampler3D attr)
{
attr_id += 1;
return vec3(0);
}
/* TODO(@fclem): These implementation details should concern the DRWManager and not be a fix on
* the engine side. But as of now, the engines are reponsible for loading the attributes. */

View File

@ -875,14 +875,13 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit
GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
int n = 0;
BLI_snprintf(cache->uv_layer_names[i][n++], MAX_LAYER_NAME_LEN, "u%s", attr_safe_name);
BLI_snprintf(cache->uv_layer_names[i][n++], MAX_LAYER_NAME_LEN, "a%s", attr_safe_name);
if (i == active_uv) {
BLI_strncpy(cache->uv_layer_names[i][n++], "au", MAX_LAYER_NAME_LEN);
}
if (i == render_uv) {
BLI_strncpy(cache->uv_layer_names[i][n++], "u", MAX_LAYER_NAME_LEN);
BLI_strncpy(cache->uv_layer_names[i][n++], "a", MAX_LAYER_NAME_LEN);
}
}
/* Vertex colors */
@ -896,12 +895,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit
GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
int n = 0;
BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "c%s", attr_safe_name);
/* We only do vcols auto name that are not overridden by uvs */
if (CustomData_get_named_layer_index(&psmd->mesh_final->ldata, CD_MLOOPUV, name) == -1) {
BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "a%s", attr_safe_name);
}
BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "a%s", attr_safe_name);
if (i == active_col) {
BLI_strncpy(cache->col_layer_names[i][n++], "ac", MAX_LAYER_NAME_LEN);
@ -1186,11 +1180,11 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i);
GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
BLI_snprintf(uuid, sizeof(uuid), "u%s", attr_safe_name);
BLI_snprintf(uuid, sizeof(uuid), "a%s", attr_safe_name);
uv_id[i] = GPU_vertformat_attr_add(&format, uuid, GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (i == active_uv) {
GPU_vertformat_alias_add(&format, "u");
GPU_vertformat_alias_add(&format, "a");
}
}
@ -1200,7 +1194,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR, i);
GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
BLI_snprintf(uuid, sizeof(uuid), "c%s", attr_safe_name);
BLI_snprintf(uuid, sizeof(uuid), "a%s", attr_safe_name);
col_id[i] = GPU_vertformat_attr_add(&format, uuid, GPU_COMP_U16, 4, GPU_FETCH_FLOAT);
if (i == active_col) {

View File

@ -44,14 +44,11 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
/* UV layer name. */
BLI_snprintf(attr_name, sizeof(attr_name), "u%s", attr_safe_name);
GPU_vertformat_attr_add(format, attr_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* Auto layer name. */
BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
GPU_vertformat_alias_add(format, attr_name);
GPU_vertformat_attr_add(format, attr_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* Active render layer name. */
if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) {
GPU_vertformat_alias_add(format, "u");
GPU_vertformat_alias_add(format, "a");
}
/* Active display layer name. */
if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) {

View File

@ -90,7 +90,7 @@ static void init_vcol_format(GPUVertFormat *format,
GPU_vertformat_safe_attr_name(ref.layer->name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
/* VCol layer name. */
BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
GPU_vertformat_attr_add(format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
/* Active layer name. */
@ -102,16 +102,6 @@ static void init_vcol_format(GPUVertFormat *format,
if (ref.layer == render) {
GPU_vertformat_alias_add(format, "c");
}
/* Gather number of auto layers. */
/* We only do `vcols` that are not overridden by `uvs`. */
bool bad = ref.domain == ATTR_DOMAIN_CORNER;
bad = bad && CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, ref.layer->name) != -1;
if (!bad) {
BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
GPU_vertformat_alias_add(format, attr_name);
}
}
}

View File

@ -4,8 +4,6 @@
vec3 attr_load_orco(vec4 orco);
vec4 attr_load_tangent(vec4 tangent);
vec3 attr_load_uv(vec3 uv);
vec4 attr_load_color(vec4 color);
vec4 attr_load_vec4(vec4 attr);
vec3 attr_load_vec3(vec3 attr);
vec2 attr_load_vec2(vec2 attr);
@ -13,8 +11,6 @@ float attr_load_float(float attr);
vec3 attr_load_orco(samplerBuffer orco);
vec4 attr_load_tangent(samplerBuffer tangent);
vec3 attr_load_uv(samplerBuffer uv);
vec4 attr_load_color(samplerBuffer color);
vec4 attr_load_vec4(samplerBuffer attr);
vec3 attr_load_vec3(samplerBuffer attr);
vec2 attr_load_vec2(samplerBuffer attr);
@ -22,8 +18,6 @@ float attr_load_float(samplerBuffer attr);
vec3 attr_load_orco(sampler3D orco);
vec4 attr_load_tangent(sampler3D tangent);
vec3 attr_load_uv(sampler3D attr);
vec4 attr_load_color(sampler3D tex);
vec4 attr_load_vec4(sampler3D tex);
vec3 attr_load_vec3(sampler3D tex);
vec2 attr_load_vec2(sampler3D tex);

View File

@ -326,14 +326,6 @@ void GPUCodegen::generate_attribs()
iface_type = input_type = GPU_VEC4;
load_ss << " = attr_load_tangent(" << attr_name << ");\n";
break;
case CD_MTFACE:
iface_type = input_type = GPU_VEC3;
load_ss << " = attr_load_uv(" << attr_name << ");\n";
break;
case CD_MCOL:
iface_type = input_type = GPU_VEC4;
load_ss << " = attr_load_color(" << attr_name << ");\n";
break;
default:
iface_type = input_type = GPU_VEC4;
load_ss << " = attr_load_" << input_type << "(" << attr_name << ");\n";

View File

@ -331,15 +331,8 @@ void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph)
static char attr_prefix_get(CustomDataType type)
{
switch (type) {
case CD_MTFACE:
return 'u';
case CD_TANGENT:
return 't';
case CD_MCOL:
case CD_PROP_BYTE_COLOR:
return 'c';
case CD_PROP_COLOR:
return 'c';
case CD_AUTO_FROM_NAME:
return 'a';
case CD_HAIRLENGTH:
@ -372,11 +365,6 @@ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph,
CustomDataType type,
const char *name)
{
/* Fall back to the UV layer, which matches old behavior. */
if (type == CD_AUTO_FROM_NAME && name[0] == '\0') {
type = CD_MTFACE;
}
/* Find existing attribute. */
int num_attributes = 0;
GPUMaterialAttribute *attr = graph->attributes.first;

View File

@ -1,4 +1,4 @@
void node_uvmap(vec3 attr_uv, out vec3 outvec)
void node_uvmap(vec4 attr_uv, out vec3 outvec)
{
outvec = attr_uv;
outvec = attr_uv.xyz;
}

View File

@ -44,7 +44,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
/* Opti: don't request orco if not needed. */
float4 zero(0.0f);
GPUNodeLink *orco = (!out[0].hasoutput) ? GPU_constant(zero) : GPU_attribute(mat, CD_ORCO, "");
GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, "");
GPUNodeLink *mtface = GPU_attribute(mat, CD_AUTO_FROM_NAME, "");
GPU_stack_link(mat, node, "node_tex_coord", in, out, inv_obmat, orco, mtface);

View File

@ -44,7 +44,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPUNodeLink **texco = &in[0].link;
if (!*texco) {
*texco = GPU_attribute(mat, CD_MTFACE, "");
*texco = GPU_attribute(mat, CD_AUTO_FROM_NAME, "");
node_shader_gpu_bump_tex_coord(mat, node, texco);
}

View File

@ -44,7 +44,11 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderUVMap *attr = static_cast<NodeShaderUVMap *>(node->storage);
GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, attr->uv_map);
/* NOTE: using CD_AUTO_FROM_NAME instead of CD_MTFACE as geometry nodes may overwrite data which
* will also change the CustomDataType. This will also make EEVEE and Cycles consistent. See
* T93179. */
GPUNodeLink *mtface = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->uv_map);
GPU_stack_link(mat, node, "node_uvmap", in, out, mtface);

View File

@ -42,7 +42,10 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_PROP_COLOR, vertexColor->layer_name);
/* NOTE: using CD_AUTO_FROM_NAME instead of CD_MCOL or CD_PROP_COLOR as geometry nodes may
* overwrite data which will also change the CustomDataType. This will also make EEVEE and Cycles
* consistent. See T93179. */
GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_AUTO_FROM_NAME, vertexColor->layer_name);
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
}