diff options
-rw-r--r-- | source/blender/gpu/GPU_material.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 63 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 4 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_geometry.c | 2 |
4 files changed, 64 insertions, 8 deletions
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index ab55b9c61e7..c8f66e33202 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -112,7 +112,8 @@ typedef enum GPUBuiltin { GPU_OBJECT_INFO = (1 << 15), GPU_VOLUME_DENSITY = (1 << 16), GPU_VOLUME_FLAME = (1 << 17), - GPU_VOLUME_TEMPERATURE = (1 << 18) + GPU_VOLUME_TEMPERATURE = (1 << 18), + GPU_BARYCENTRIC_TEXCO = (1 << 19), } GPUBuiltin; typedef enum GPUMatType { diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 98f9e22cbc1..d4bba0a39c7 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -505,6 +505,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin) return "sampflame"; else if (builtin == GPU_VOLUME_TEMPERATURE) return "unftemperature"; + else if (builtin == GPU_BARYCENTRIC_TEXCO) + return "unfbarycentrictex"; else return ""; } @@ -724,6 +726,8 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final BLI_dynstr_append(ds, "viewmat"); else if (input->builtin == GPU_CAMERA_TEXCO_FACTORS) BLI_dynstr_append(ds, "camtexfac"); + else if (input->builtin == GPU_BARYCENTRIC_TEXCO) + BLI_dynstr_append(ds, "barytexco"); else if (input->builtin == GPU_OBJECT_MATRIX) BLI_dynstr_append(ds, "objmat"); else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX) @@ -783,13 +787,22 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO codegen_set_unique_ids(nodes); builtins = codegen_process_uniforms_functions(material, ds, nodes); -#if 0 - if (G.debug & G_DEBUG) - BLI_dynstr_appendf(ds, "/* %s */\n", name); -#endif + + if (builtins & GPU_BARYCENTRIC_TEXCO) + BLI_dynstr_append(ds, "\tin vec2 barycentricTexCo;\n"); BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n"); + if (builtins & GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); + BLI_dynstr_append(ds, "\tvec2 barytexco = vec2((fract(barycentricTexCo.y) != 0.0)\n" + "\t ? barycentricTexCo.x\n" + "\t : 1.0 - barycentricTexCo.x,\n" + "\t 0.0);\n"); + BLI_dynstr_append(ds, "#else\n"); + BLI_dynstr_append(ds, "\tvec2 barytexco = barycentricTexCo;\n"); + BLI_dynstr_append(ds, "#endif\n"); + } /* TODO(fclem) get rid of that. */ if (builtins & GPU_VIEW_MATRIX) BLI_dynstr_append(ds, "\tmat4 viewmat = ViewMatrix;\n"); @@ -894,6 +907,13 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u for (node = nodes->first; node; node = node->next) { for (input = node->inputs.first; input; input = input->next) { + if (input->source == GPU_SOURCE_BUILTIN) { + if (input->builtin == GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_appendf( + ds, "out vec2 barycentricTexCo%s;\n", + use_geom ? "g" : ""); + } + } if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { /* XXX FIXME : see notes in mesh_render_data_create() */ /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ @@ -949,6 +969,7 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u "vec3 hair_get_customdata_vec3(const samplerBuffer);\n" "vec4 hair_get_customdata_vec4(const samplerBuffer);\n" "vec3 hair_get_strand_pos(void);\n" + "int hair_get_base_id(void);\n" "\n" ); @@ -958,6 +979,21 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u for (node = nodes->first; node; node = node->next) { for (input = node->inputs.first; input; input = input->next) { + if (input->source == GPU_SOURCE_BUILTIN) { + if (input->builtin == GPU_BARYCENTRIC_TEXCO) { + /* To match cycles without breaking into individual segment we encode if we need to invert + * the first component into the second component. We invert if the barycentricTexCo.y + * is NOT 0.0 or 1.0. */ + BLI_dynstr_appendf( + ds, "\tint _base_id = hair_get_base_id();\n"); + BLI_dynstr_appendf( + ds, "\tbarycentricTexCo%s.x = float((_base_id %% 2) == 1);\n", + use_geom ? "g" : ""); + BLI_dynstr_appendf( + ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n", + use_geom ? "g" : ""); + } + } if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_TANGENT) { /* Not supported by hairs */ @@ -983,6 +1019,16 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u for (node = nodes->first; node; node = node->next) { for (input = node->inputs.first; input; input = input->next) { + if (input->source == GPU_SOURCE_BUILTIN) { + if (input->builtin == 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" : ""); + } + } if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_TANGENT) { /* silly exception */ BLI_dynstr_appendf( @@ -1049,6 +1095,10 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code) /* Generate varying declarations. */ for (node = nodes->first; node; node = node->next) { for (input = node->inputs.first; input; input = input->next) { + if (input->source == GPU_SOURCE_BUILTIN && input->builtin == GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_appendf(ds, "in vec2 barycentricTexCog[];\n"); + BLI_dynstr_appendf(ds, "out vec2 barycentricTexCo[];\n"); + } if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { BLI_dynstr_appendf( ds, "in %s var%dg[];\n", @@ -1066,6 +1116,11 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code) BLI_dynstr_appendf(ds, "void pass_attrib(in int vert) {\n"); for (node = nodes->first; node; node = node->next) { for (input = node->inputs.first; input; input = input->next) { + if (input->source == GPU_SOURCE_BUILTIN) { + if (input->builtin == GPU_BARYCENTRIC_TEXCO) { + BLI_dynstr_appendf(ds, "\tbarycentricTexCo = barycentricTexCog;\n"); + } + } if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { /* TODO let shader choose what to do depending on what the attrib is. */ BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", input->attribid, input->attribid); diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 40aba1cc004..f3dea3afaf4 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1705,7 +1705,7 @@ void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T) } void node_geometry( - vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld, + vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld, vec2 barycentric, out vec3 position, out vec3 normal, out vec3 tangent, out vec3 true_normal, out vec3 incoming, out vec3 parametric, out float backfacing, out float pointiness) @@ -1720,7 +1720,7 @@ void node_geometry( vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); incoming = -(toworld * vec4(I_view, 0.0)).xyz; - parametric = vec3(0.0); + parametric = vec3(barycentric, 0.0); backfacing = (gl_FrontFacing) ? 0.0 : 1.0; pointiness = 0.5; } diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c index dfeebcea305..d004e0e80a1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geometry.c +++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c @@ -46,7 +46,7 @@ static int node_shader_gpu_geometry(GPUMaterial *mat, bNode *node, bNodeExecData 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_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_BARYCENTRIC_TEXCO)); } /* node type definition */ |