diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-05-18 15:29:57 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-05-18 17:05:03 +0300 |
commit | 242a044bd1fd015f5424318f60fd7a4604970783 (patch) | |
tree | f32f2c2b46095f7cc24d01bfc692edfc184e161f /source/blender | |
parent | c55c2dbfbafb78a21d6a0cad85e8293a81c994a0 (diff) |
GPUMaterial: Add support for tangent node.
Diffstat (limited to 'source/blender')
5 files changed, 63 insertions, 2 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 841092f1c8d..999ce0a95e4 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1754,6 +1754,8 @@ static VertexBuffer *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata /* Tangent */ attrib_name = mesh_render_data_tangent_layer_uuid_get(rdata, i); + /* WATCH IT : only specifying 3 component instead of 4 (4th is sign). + * That may cause some problem but I could not make it to fail (fclem) */ #ifdef USE_COMP_MESH_DATA # if USE_10_10_10 && 0 /* Tangents need more precision than this */ tangent_id[i] = VertexFormat_add_attrib(format, attrib_name, COMP_I10, 3, NORMALIZE_INT_TO_FLOAT); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 33655396d88..734474465cd 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -626,6 +626,8 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final BLI_dynstr_append(ds, "viewinv"); else if (input->builtin == GPU_CAMERA_TEXCO_FACTORS) BLI_dynstr_append(ds, "camtexfac"); + else if (input->builtin == GPU_OBJECT_MATRIX) + BLI_dynstr_append(ds, "objmat"); else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX) BLI_dynstr_append(ds, "objinv"); else if (input->builtin == GPU_VIEW_POSITION) @@ -697,6 +699,8 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use if (use_new_shading) { if (builtins & GPU_CAMERA_TEXCO_FACTORS) BLI_dynstr_append(ds, "\tvec4 camtexfac = CameraTexCoFactors;\n"); + if (builtins & GPU_OBJECT_MATRIX) + BLI_dynstr_append(ds, "\tmat4 objmat = ModelMatrix;\n"); if (builtins & GPU_INVERSE_OBJECT_MATRIX) BLI_dynstr_append(ds, "\tmat4 objinv = ModelMatrixInverse;\n"); if (builtins & GPU_INVERSE_VIEW_MATRIX) @@ -709,6 +713,8 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, bool use else { if (builtins & GPU_CAMERA_TEXCO_FACTORS) BLI_dynstr_append(ds, "\tvec4 camtexfac = unfcameratexfactors;\n"); + if (builtins & GPU_OBJECT_MATRIX) + BLI_dynstr_append(ds, "\tmat4 objmat = unfobmat;\n"); if (builtins & GPU_INVERSE_OBJECT_MATRIX) BLI_dynstr_append(ds, "\tmat4 objinv = unfinvobmat;\n"); if (builtins & GPU_INVERSE_VIEW_MATRIX) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 5a1f48f1f83..f179d9da7bf 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -3,6 +3,7 @@ uniform mat4 ModelViewMatrix; #ifndef EEVEE_ENGINE uniform mat4 ProjectionMatrix; #endif +uniform mat4 ModelMatrix; uniform mat4 ModelMatrixInverse; uniform mat4 ModelViewMatrixInverse; uniform mat4 ViewMatrixInverse; @@ -2922,15 +2923,43 @@ void node_uvmap(vec3 attr_uv, out vec3 outvec) outvec = attr_uv; } +void tangent_orco_x(vec3 orco_in, out vec3 orco_out) +{ + orco_out = vec3(0.0, (orco_in.z - 0.5) * -0.5, (orco_in.y - 0.5) * 0.5); +} + +void tangent_orco_y(vec3 orco_in, out vec3 orco_out) +{ + orco_out = vec3((orco_in.z - 0.5) * -0.5, 0.0, (orco_in.x - 0.5) * 0.5); +} + +void tangent_orco_z(vec3 orco_in, out vec3 orco_out) +{ + orco_out = vec3((orco_in.y - 0.5) * -0.5, (orco_in.x - 0.5) * 0.5, 0.0); +} + +void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent) +{ + tangent = (toworld * vec4(attr_tangent.xyz, 0.0)).xyz; +} + +void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T) +{ + N = (toworld * vec4(N, 0.0)).xyz; + T = (objmat * vec4(orco, 0.0)).xyz; + T = cross(N, normalize(cross(T, N))); +} + void node_geometry( - vec3 I, vec3 N, mat4 toworld, + vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld, 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) { position = (toworld * vec4(I, 1.0)).xyz; normal = (toworld * vec4(N, 0.0)).xyz; - tangent = vec3(0.0); + tangent_orco_z(orco, orco); + node_tangent(N, orco, objmat, toworld, tangent); true_normal = normal; /* handle perspective/orthographic */ diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c index 553ea65154f..79833034498 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geometry.c +++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c @@ -45,6 +45,7 @@ static int node_shader_gpu_geometry(GPUMaterial *mat, bNode *UNUSED(node), bNode { return GPU_stack_link(mat, "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)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c index 7aa7fb43221..9c853f9d86f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tangent.c +++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c @@ -41,6 +41,28 @@ static void node_shader_init_tangent(bNodeTree *UNUSED(ntree), bNode *node) node->storage = attr; } +static int node_shader_gpu_tangent(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + NodeShaderTangent *attr = node->storage; + + if (attr->direction_type == SHD_TANGENT_UVMAP) { + return GPU_stack_link(mat, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, ""), GPU_builtin(GPU_INVERSE_VIEW_MATRIX)); + } + else { + GPUNodeLink *orco = GPU_attribute(CD_ORCO, ""); + + if (attr->axis == SHD_TANGENT_AXIS_X) + GPU_link(mat, "tangent_orco_x", orco, &orco); + else if (attr->axis == SHD_TANGENT_AXIS_Y) + GPU_link(mat, "tangent_orco_y", orco, &orco); + else + GPU_link(mat, "tangent_orco_z", orco, &orco); + + return GPU_stack_link(mat, "node_tangent", in, out, GPU_builtin(GPU_VIEW_NORMAL), orco, + GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX)); + } +} + /* node type definition */ void register_node_type_sh_tangent(void) { @@ -51,6 +73,7 @@ void register_node_type_sh_tangent(void) node_type_socket_templates(&ntype, NULL, sh_node_tangent_out); node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); node_type_init(&ntype, node_shader_init_tangent); + node_type_gpu(&ntype, node_shader_gpu_tangent); node_type_storage(&ntype, "NodeShaderTangent", node_free_standard_storage, node_copy_standard_storage); nodeRegisterType(&ntype); |