Fix T62021: Wireframe input node doesn't work properly
This fixes the general case. It is still not supported for hairs. Added a hack in the geometry node to avoid unnecessary geometry shader usage.
This commit is contained in:
parent
d68484a60f
commit
d7d180bd3d
Notes:
blender-bot
2023-02-14 11:28:39 +01:00
Referenced by issue #62104, VertexGroup.add() doesn't push depsgraph update for the mesh. Referenced by issue #62090, Eevee shader compilation error: C1503: undefined variable "att1_is_srgb" Referenced by issue #62065, Edge quality of uv export Referenced by issue #62021, Wireframe input node doesn't work properly
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue