[Bf-blender-cvs] [1f6437b] opensubdiv-modifier: OpenSubdiv: Proper lighting when in textured shading mode

Sergey Sharybin noreply at git.blender.org
Tue Jul 22 14:58:06 CEST 2014


Commit: 1f6437bdf52d4275682910040a3935eb7a103ccd
Author: Sergey Sharybin
Date:   Tue Jul 22 16:47:37 2014 +0600
Branches: opensubdiv-modifier
https://developer.blender.org/rB1f6437bdf52d4275682910040a3935eb7a103ccd

OpenSubdiv: Proper lighting when in textured shading mode

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

M	intern/opensubdiv/gpu_shader_opensubd_display.glsl
M	intern/opensubdiv/opensubdiv_gpu_capi.cc
M	source/blender/blenkernel/intern/subsurf_ccg.c

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

diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index 8b191b7..609d1c4 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -187,6 +187,7 @@ void main()
 /* ***** Fragment shader ***** */
 #ifdef FRAGMENT_SHADER
 
+#define MAX_LIGHTS 8
 #define NUM_SOLID_LIGHTS 3
 
 struct LightSource {
@@ -194,19 +195,26 @@ struct LightSource {
 	vec4 ambient;
 	vec4 diffuse;
 	vec4 specular;
+	vec4 spotDirection;
+	float constantAttenuation;
+	float linearAttenuation;
+	float quadraticAttenuation;
+	float spotCutoff;
+	float spotExponent;
+	float spotCosCutoff;
 };
 
 uniform Lighting {
-	LightSource lightSource[NUM_SOLID_LIGHTS];
+	LightSource lightSource[MAX_LIGHTS];
+	int num_enabled_lights;
 };
 
 uniform vec4 diffuse;
 uniform vec4 specular;
 uniform float shininess;
 
-#ifdef USE_TEXTURE
 uniform sampler2D texture_buffer;
-#endif
+uniform bool use_color_material;
 
 in block {
 	VertexData v;
@@ -226,27 +234,81 @@ void main()
 	vec3 L_diffuse = vec3(0.0);
 	vec3 L_specular = vec3(0.0);
 
-	/* Assume NUM_SOLID_LIGHTS directional lights. */
-	for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
-		vec3 light_direction = lightSource[i].position.xyz;
-
-		/* Diffuse light. */
-		vec3 light_diffuse = lightSource[i].diffuse.rgb;
-		float diffuse_bsdf = max(dot(N, light_direction), 0.0);
-		L_diffuse += light_diffuse * diffuse_bsdf;
-
-		vec4 Plight = lightSource[i].position;
-		vec3 l = (Plight.w == 0.0)
-			? normalize(Plight.xyz) : normalize(Plight.xyz -
-			                                    inpt.v.position.xyz);
-
-		/* Specular light. */
-		vec3 light_specular = lightSource[i].specular.rgb;
-		vec3 H = normalize(l + vec3(0,0,1));
-
-		float specular_bsdf = pow(max(dot(N, H), 0.0),
-		                          shininess);
-		L_specular += light_specular * specular_bsdf;
+	if (use_color_material == false) {
+		/* Assume NUM_SOLID_LIGHTS directional lights. */
+		for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
+			vec3 light_direction = lightSource[i].position.xyz;
+
+			/* Diffuse light. */
+			vec3 light_diffuse = lightSource[i].diffuse.rgb;
+			float diffuse_bsdf = max(dot(N, light_direction), 0.0);
+			L_diffuse += light_diffuse * diffuse_bsdf;
+
+			vec4 Plight = lightSource[i].position;
+			vec3 l = (Plight.w == 0.0)
+				? normalize(Plight.xyz) : normalize(Plight.xyz -
+				                                    inpt.v.position.xyz);
+
+			/* Specular light. */
+			vec3 light_specular = lightSource[i].specular.rgb;
+			vec3 H = normalize(l + vec3(0,0,1));
+
+			float specular_bsdf = pow(max(dot(N, H), 0.0),
+			                          shininess);
+			L_specular += light_specular * specular_bsdf;
+		}
+	}
+	else {
+		vec3 varying_position = inpt.v.position.xyz;
+		vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ?
+			normalize(varying_position): vec3(0.0, 0.0, -1.0);
+		for (int i = 0; i < num_enabled_lights; i++) {
+			/* todo: this is a slow check for disabled lights */
+			if (lightSource[i].specular.a == 0.0)
+				continue;
+
+			float intensity = 1.0;
+			vec3 light_direction;
+
+			if (lightSource[i].position.w == 0.0) {
+				/* directional light */
+				light_direction = lightSource[i].position.xyz;
+			}
+			else {
+				/* point light */
+				vec3 d = lightSource[i].position.xyz - varying_position;
+				light_direction = normalize(d);
+
+				/* spot light cone */
+				if (lightSource[i].spotCutoff < 90.0) {
+					float cosine = max(dot(light_direction,
+					                       -lightSource[i].spotDirection.xyz),
+					                   0.0);
+					intensity = pow(cosine, lightSource[i].spotExponent);
+					intensity *= step(lightSource[i].spotCosCutoff, cosine);
+				}
+
+				/* falloff */
+				float distance = length(d);
+
+				intensity /= lightSource[i].constantAttenuation +
+					lightSource[i].linearAttenuation * distance +
+					lightSource[i].quadraticAttenuation * distance * distance;
+			}
+
+			/* diffuse light */
+			vec3 light_diffuse = lightSource[i].diffuse.rgb;
+			float diffuse_bsdf = max(dot(N, light_direction), 0.0);
+			L_diffuse += light_diffuse*diffuse_bsdf*intensity;
+
+			/* specular light */
+			vec3 light_specular = lightSource[i].specular.rgb;
+			vec3 H = normalize(light_direction - V);
+
+			float specular_bsdf = pow(max(dot(N, H), 0.0),
+			                          gl_FrontMaterial.shininess);
+			L_specular += light_specular*specular_bsdf * intensity;
+		}
 	}
 
 	/* Compute diffuse color. */
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 2620489..c7ead60 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -61,16 +61,26 @@ using OpenSubdiv::PartitionedGLMeshInterface;
 
 extern "C" char datatoc_gpu_shader_opensubd_display_glsl[];
 
-#define NUM_SOLID_LIGHTS 3
+#define MAX_LIGHTS 8
 typedef struct Light {
 	float position[4];
 	float ambient[4];
 	float diffuse[4];
 	float specular[4];
+	float spot_direction[4];
+	float constant_attenuation;
+	float linear_attenuation;
+	float quadratic_attenuation;
+	float spot_cutoff;
+	float spot_exponent;
+	float spot_cos_cutoff;
+	float pad[2];
 } Light;
 
 typedef struct Lighting {
-	Light lights[NUM_SOLID_LIGHTS];
+	Light lights[MAX_LIGHTS];
+	int num_enabled;
+	int pad[3];
 } Lighting;
 
 typedef struct Transform {
@@ -321,8 +331,12 @@ void bindProgram(PartitionedGLMeshInterface *mesh,
 	glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
 
 	/* Color */
-	GLboolean use_lighting;
+	GLboolean use_lighting, use_color_material;
 	glGetBooleanv(GL_LIGHTING, &use_lighting);
+	glGetBooleanv(GL_COLOR_MATERIAL, &use_color_material);
+
+	glUniform1i(glGetUniformLocation(program, "use_color_material"),
+	            use_color_material);
 
 	if (use_lighting) {
 		float color[4];
@@ -402,7 +416,14 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl)
 	transpose_m3((float (*)[3])g_transform.normal_matrix);
 
 	/* Update OpenGL lights positions, colors etc. */
-	for (int i = 0; i < NUM_SOLID_LIGHTS; ++i) {
+	g_lighting_data.num_enabled = 0;
+	for (int i = 0; i < MAX_LIGHTS; ++i) {
+		GLboolean enabled;
+		glGetBooleanv(GL_LIGHT0 + i, &enabled);
+		if (enabled) {
+			g_lighting_data.num_enabled++;
+		}
+
 		glGetLightfv(GL_LIGHT0 + i,
 		             GL_POSITION,
 		             g_lighting_data.lights[i].position);
@@ -415,6 +436,26 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl)
 		glGetLightfv(GL_LIGHT0 + i,
 		             GL_SPECULAR,
 		             g_lighting_data.lights[i].specular);
+		glGetLightfv(GL_LIGHT0 + i,
+		             GL_SPOT_DIRECTION,
+		             g_lighting_data.lights[i].spot_direction);
+		glGetLightfv(GL_LIGHT0 + i,
+		             GL_CONSTANT_ATTENUATION,
+		             &g_lighting_data.lights[i].constant_attenuation);
+		glGetLightfv(GL_LIGHT0 + i,
+		             GL_LINEAR_ATTENUATION,
+		             &g_lighting_data.lights[i].linear_attenuation);
+		glGetLightfv(GL_LIGHT0 + i,
+		             GL_QUADRATIC_ATTENUATION,
+		             &g_lighting_data.lights[i].quadratic_attenuation);
+		glGetLightfv(GL_LIGHT0 + i,
+		             GL_SPOT_CUTOFF,
+		             &g_lighting_data.lights[i].spot_cutoff);
+		glGetLightfv(GL_LIGHT0 + i,
+		             GL_SPOT_EXPONENT,
+		             &g_lighting_data.lights[i].spot_exponent);
+		g_lighting_data.lights[i].spot_cos_cutoff =
+			cos(g_lighting_data.lights[i].spot_cutoff);
 	}
 }
 
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 3704f90..e80bfa0 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2459,6 +2459,8 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
 			mat_nr = 0;
 		}
 
+		glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
+
 		tmp_tf.tpage = G.main->image.first;
 		if (drawParams != NULL)
 			drawParams(&tmp_tf, (mcol != NULL), mat_nr);




More information about the Bf-blender-cvs mailing list