diff options
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 32 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_geometry.c | 5 |
2 files changed, 25 insertions, 12 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index e85a2c62172..a2c25a9ffb4 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -902,9 +902,11 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u } if (builtins & GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); BLI_dynstr_appendf( ds, "out vec2 barycentricTexCo%s;\n", use_geom ? "g" : ""); + BLI_dynstr_append(ds, "#endif\n"); } if (builtins & GPU_BARYCENTRIC_DIST) { @@ -986,14 +988,9 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u BLI_dynstr_append(ds, "#else /* MESH_SHADER */\n"); - if (builtins & GPU_BARYCENTRIC_TEXCO) { - BLI_dynstr_appendf( - ds, "\tbarycentricTexCo%s.x = float((gl_VertexID %% 3) == 0);\n", - use_geom ? "g" : ""); - BLI_dynstr_appendf( - ds, "\tbarycentricTexCo%s.y = float((gl_VertexID %% 3) == 1);\n", - use_geom ? "g" : ""); - } + /* GPU_BARYCENTRIC_TEXCO cannot be computed based on gl_VertexID + * for MESH_SHADER because of indexed drawing. In this case a + * geometry shader is needed. */ if (builtins & GPU_BARYCENTRIC_DIST) { BLI_dynstr_appendf(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n"); @@ -1071,7 +1068,7 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u return code; } -static char *code_generate_geometry(ListBase *nodes, const char *geom_code) +static char *code_generate_geometry(ListBase *nodes, const char *geom_code, const char *defines) { DynStr *ds = BLI_dynstr_new(); GPUNode *node; @@ -1079,6 +1076,9 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code) char *code; int builtins = 0; + /* XXX we should not make specific eevee cases here. */ + bool is_hair_shader = (strstr(defines, "HAIR_SHADER") != NULL); + /* Create prototype because attributes cannot be declared before layout. */ BLI_dynstr_appendf(ds, "void pass_attr(in int vert);\n"); BLI_dynstr_appendf(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2);\n"); @@ -1104,7 +1104,10 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code) } if (builtins & GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_appendf(ds, "#ifdef HAIR_SHADER\n"); BLI_dynstr_appendf(ds, "in vec2 barycentricTexCog[];\n"); + BLI_dynstr_appendf(ds, "#endif\n"); + BLI_dynstr_appendf(ds, "out vec2 barycentricTexCo;\n"); } @@ -1114,7 +1117,9 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code) } if (geom_code == NULL) { - if ((builtins & GPU_BARYCENTRIC_DIST) == 0) { + /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used. + * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */ + if ((builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0 || is_hair_shader) { /* Early out */ BLI_dynstr_free(ds); return NULL; @@ -1189,7 +1194,12 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code) } if (builtins & GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_appendf(ds, "#ifdef HAIR_SHADER\n"); BLI_dynstr_appendf(ds, "\tbarycentricTexCo = barycentricTexCog[vert];\n"); + BLI_dynstr_appendf(ds, "#else\n"); + BLI_dynstr_appendf(ds, "\tbarycentricTexCo.x = float((vert %% 3) == 0);\n"); + BLI_dynstr_appendf(ds, "\tbarycentricTexCo.y = float((vert %% 3) == 1);\n"); + BLI_dynstr_appendf(ds, "#endif\n"); } for (node = nodes->first; node; node = node->next) { @@ -1817,7 +1827,7 @@ GPUPass *GPU_generate_pass( * continue generating the shader strings. */ char *tmp = BLI_strdupcat(frag_lib, glsl_material_library); - geometrycode = code_generate_geometry(nodes, geom_code); + geometrycode = code_generate_geometry(nodes, geom_code, defines); vertexcode = code_generate_vertex(nodes, vert_code, (geometrycode != NULL)); fragmentcode = BLI_strdupcat(tmp, fragmentgen); diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c index 241b6b863e4..4c4ad7c4cc9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geometry.c +++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c @@ -35,10 +35,13 @@ static bNodeSocketTemplate sh_node_geometry_out[] = { static int node_shader_gpu_geometry(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { + /* HACK: Don't request GPU_BARYCENTRIC_TEXCO if not used because it will + * trigger the use of geometry shader (and the performance penalty it implies). */ + eGPUBuiltin bary_builtin = (out[7].type == GPU_NONE) ? GPU_VIEW_NORMAL : GPU_BARYCENTRIC_TEXCO; return GPU_stack_link(mat, node, "node_geometry", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), GPU_attribute(CD_ORCO, ""), GPU_builtin(GPU_OBJECT_MATRIX), - GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_BARYCENTRIC_TEXCO)); + GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(bary_builtin)); } /* node type definition */ |