[Bf-blender-cvs] [e4ff110] opensubdiv-modifier: OpenSubdiv: Initial support of tanged spaced normal maps

Sergey Sharybin noreply at git.blender.org
Wed Jul 30 13:49:28 CEST 2014


Commit: e4ff11057713c9e115c22f1e901c96737eaec0f7
Author: Sergey Sharybin
Date:   Wed Jul 30 17:42:22 2014 +0600
Branches: opensubdiv-modifier
https://developer.blender.org/rBe4ff11057713c9e115c22f1e901c96737eaec0f7

OpenSubdiv: Initial support of tanged spaced normal maps

Made it so tnagent space is being calculated from GLSL
instead of using CD_TANGENT layer (which is missing for
the OSD meshes).

For now used real basic tangent space calculation, which
is _really_ average and only looks ok-ish with high
enough number of faces.

This is to be improved further with either using different
tangent space calculation or using some sort of evaluator
from OSD (seems they've got some code for this, but it's
not that trivial to hook up for tests because of the way
how our GLSL pipeline is constructed).

===================================================================

M	intern/opensubdiv/opensubdiv_gpu_capi.cc
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/shaders/gpu_shader_geometry.glsl

===================================================================

diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 465b54a..8378b5e 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -486,6 +486,12 @@ static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh,
 				if (location != -1) {
 					glUniform1i(location, mesh->GetFVarCount());
 				}
+
+				location = glGetUniformLocation(program, "osd_active_uv_offset");
+				if (location != -1) {
+					glUniform1i(location,
+					            g_active_uv_index * 2);
+				}
 			}
 
 		}
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 2c3cd5c..dfa336d 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -510,8 +510,19 @@ static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
 				}
 			}
 			else if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+#ifdef WITH_OPENSUBDIV
+				bool skip_opensubdiv = input->attribtype == CD_TANGENT;
+				if (skip_opensubdiv) {
+					BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
+				}
+#endif
 				BLI_dynstr_appendf(ds, "varying %s var%d;\n",
 					GPU_DATATYPE_STR[input->type], input->attribid);
+#ifdef WITH_OPENSUBDIV
+				if (skip_opensubdiv) {
+					BLI_dynstr_appendf(ds, "#endif\n");
+				}
+#endif
 			}
 		}
 	}
@@ -612,6 +623,11 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
 	char *code;
 	int builtins;
 
+#ifdef WITH_OPENSUBDIV
+	GPUNode *node;
+	GPUInput *input;
+#endif
+
 	/*BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);*/
 
 	codegen_set_unique_ids(nodes);
@@ -625,7 +641,34 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
 
 	if (builtins & GPU_VIEW_NORMAL)
 		BLI_dynstr_append(ds, "\tvec3 facingnormal = (gl_FrontFacing)? varnormal: -varnormal;\n");
-		
+
+	/* Calculate tangent space. */
+#ifdef WITH_OPENSUBDIV
+	{
+		bool has_tangent = false;
+		for (node = nodes->first; node; node = node->next) {
+			for (input = node->inputs.first; input; input = input->next) {
+				if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+					if (input->attribtype == CD_TANGENT) {
+						BLI_dynstr_appendf(ds, "#ifdef USE_OPENSUBDIV\n");
+						BLI_dynstr_appendf(ds, "\t%s var%d;\n",
+						                   GPU_DATATYPE_STR[input->type],
+						                   input->attribid);
+						if (has_tangent == false) {
+							BLI_dynstr_appendf(ds, "\tvec3 Q1 = dFdx(inpt.v.position.xyz);\n");
+							BLI_dynstr_appendf(ds, "\tvec3 Q2 = dFdy(inpt.v.position.xyz);\n");
+							BLI_dynstr_appendf(ds, "\tvec2 st1 = dFdx(inpt.v.uv);\n");
+							BLI_dynstr_appendf(ds, "\tvec2 st2 = dFdy(inpt.v.uv);\n");
+							BLI_dynstr_appendf(ds, "\tvec3 T = normalize(Q1 * st2.t - Q2 * st1.t);\n");
+						}
+						BLI_dynstr_appendf(ds, "\tvar%d = vec4(T, 1.0);\n", input->attribid);
+						BLI_dynstr_appendf(ds, "#endif\n");
+					}
+				}
+			}
+		}
+	}
+#endif
 
 	codegen_declare_tmps(ds, nodes);
 	codegen_call_functions(ds, nodes, output);
@@ -708,8 +751,8 @@ static char *code_generate_vertex(ListBase *nodes)
 		for (input=node->inputs.first; input; input=input->next) {
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
 #ifdef WITH_OPENSUBDIV
-				bool is_mtface = input->attribtype == CD_MTFACE;
-				if (is_mtface) {
+				bool skip_opensubdiv = ELEM(input->attribtype, CD_MTFACE, CD_TANGENT);
+				if (skip_opensubdiv) {
 					BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
 				}
 #endif
@@ -718,7 +761,7 @@ static char *code_generate_vertex(ListBase *nodes)
 				BLI_dynstr_appendf(ds, "varying %s var%d;\n",
 					GPU_DATATYPE_STR[input->type], input->attribid);
 #ifdef WITH_OPENSUBDIV
-				if (is_mtface) {
+				if (skip_opensubdiv) {
 					BLI_dynstr_appendf(ds, "#endif\n");
 				}
 #endif
@@ -733,8 +776,14 @@ static char *code_generate_vertex(ListBase *nodes)
 		for (input=node->inputs.first; input; input=input->next)
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
 				if (input->attribtype == CD_TANGENT) { /* silly exception */
+#ifdef WITH_OPENSUBDIV
+					BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
+#endif
 					BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize((gl_ModelViewMatrix * vec4(att%d.xyz, 0)).xyz);\n", input->attribid, input->attribid);
 					BLI_dynstr_appendf(ds, "\tvar%d.w = att%d.w;\n", input->attribid, input->attribid);
+#ifdef WITH_OPENSUBDIV
+					BLI_dynstr_appendf(ds, "#endif\n");
+#endif
 				}
 				else {
 #ifdef WITH_OPENSUBDIV
diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
index 4d76a09..a0ae96a 100644
--- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
@@ -1,4 +1,5 @@
 uniform int PrimitiveIdBase;
+uniform int osd_active_uv_offset;
 
 varying vec3 varnormal;
 varying vec3 varposition;
@@ -45,7 +46,7 @@ void emit_flat(int index, vec3 normal)
 	vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
 	vec2 st = quadst[index];
 
-	INTERP_FACE_VARYING_2(outpt.v.uv, 0, st);
+	INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
 
 	set_mtface_vertex_attrs(st);
 
@@ -66,7 +67,7 @@ void emit_smooth(int index)
 	vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
 	vec2 st = quadst[index];
 
-	INTERP_FACE_VARYING_2(outpt.v.uv, 0, st);
+	INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
 
 	set_mtface_vertex_attrs(st);




More information about the Bf-blender-cvs mailing list