[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53573] branches/ge_harmony/source: Adding support for spot lights when using inferred lighting.

Daniel Stokes kupomail at gmail.com
Sat Jan 5 08:39:21 CET 2013


Revision: 53573
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53573
Author:   kupoman
Date:     2013-01-05 07:39:14 +0000 (Sat, 05 Jan 2013)
Log Message:
-----------
Adding support for spot lights when using inferred lighting. Square spot lights are not yet supported. Furthermore there appears to be an offsetting problem unrelated to spot lights that is easy to notice on spot lights.

Modified Paths:
--------------
    branches/ge_harmony/source/blender/gpu/shaders/gpu_shader_light_frag.glsl
    branches/ge_harmony/source/gameengine/Ketsji/KX_Light.cpp
    branches/ge_harmony/source/gameengine/Rasterizer/RAS_LightObject.h
    branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
    branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h

Modified: branches/ge_harmony/source/blender/gpu/shaders/gpu_shader_light_frag.glsl
===================================================================
--- branches/ge_harmony/source/blender/gpu/shaders/gpu_shader_light_frag.glsl	2013-01-05 07:30:52 UTC (rev 53572)
+++ branches/ge_harmony/source/blender/gpu/shaders/gpu_shader_light_frag.glsl	2013-01-05 07:39:14 UTC (rev 53573)
@@ -34,6 +34,8 @@
 	float dist;
 	vec3 position;
 	vec3 vector;
+	float spotsize;
+	float spotblend;
 };
 
 //varying vec3 varposition;
@@ -91,7 +93,15 @@
 		
 		attenuation *= max((light.dist - dist), 0.0)/light.dist;
 	}
+	L = normalize(L);
 	
+	if (light.type == SPOT) {
+		float inpr;
+		lamp_visibility_spot_circle(light.vector, L, inpr);
+		lamp_visibility_spot(light.spotsize, light.spotblend, inpr, attenuation, attenuation);
+	}
+	
+	attenuation = (attenuation < 0.001) ? 0.0 : attenuation;
 	int matid = int(gbuffer.a*65535);
 	int diff_shader = matid / 16;
 	int spec_shader = matid - (diff_shader*16);
@@ -100,7 +110,6 @@
 	float diff_term = 0.0;
 	float diff_param1 = mbuffer.r * 10.0;
 	float diff_param2 = mbuffer.g * 10.0;
-	L = normalize(L);
 	float lambert = max(dot(N, L), 0.0);
 	if (light.type == HEMI)
 		diff_term = 0.5*lambert + 0.5;
@@ -138,7 +147,7 @@
 	// Factor in light properties
 	vec3 diff = light.color * light.energy * diff_term * attenuation;
 	float spec = length(light.energy) * spec_term * attenuation;
-	
+	// diff = mix(diff, vec3(0.5, 1.0, 0.0), 0.01);
 	gl_FragData[0] = vec4(diff, spec);
 }
 

Modified: branches/ge_harmony/source/gameengine/Ketsji/KX_Light.cpp
===================================================================
--- branches/ge_harmony/source/gameengine/Ketsji/KX_Light.cpp	2013-01-05 07:30:52 UTC (rev 53572)
+++ branches/ge_harmony/source/gameengine/Ketsji/KX_Light.cpp	2013-01-05 07:39:14 UTC (rev 53573)
@@ -210,6 +210,7 @@
 
 		memcpy(m_lightobj.m_position, &obmat[3], sizeof(float)*4);
 		memcpy(m_lightobj.m_vector, &obmat[2], sizeof(float)*3);
+		memcpy(m_lightobj.m_obmat, obmat, sizeof(float)*16);
 
 		GPU_lamp_update(lamp, m_lightobj.m_layer, 0, obmat);
 		GPU_lamp_update_colors(lamp, m_lightobj.m_red, m_lightobj.m_green, 

Modified: branches/ge_harmony/source/gameengine/Rasterizer/RAS_LightObject.h
===================================================================
--- branches/ge_harmony/source/gameengine/Rasterizer/RAS_LightObject.h	2013-01-05 07:30:52 UTC (rev 53572)
+++ branches/ge_harmony/source/gameengine/Rasterizer/RAS_LightObject.h	2013-01-05 07:39:14 UTC (rev 53573)
@@ -74,6 +74,7 @@
 
 	float	m_position[4];
 	float	m_vector[3];
+	float	m_obmat[4][4];
 };
 
 #endif  /* __RAS_LIGHTOBJECT_H__ */

Modified: branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
===================================================================
--- branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp	2013-01-05 07:30:52 UTC (rev 53572)
+++ branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp	2013-01-05 07:39:14 UTC (rev 53573)
@@ -210,6 +210,7 @@
 		m_light_shader_default = GPU_shader_get_builtin_shader(GPU_SHADER_LIGHT);
 		m_prepass_shader_default = GPU_shader_get_builtin_shader(GPU_SHADER_PREPASS);
 		init_sphere();
+		m_cone_size = 0;
 	}
 
 	m_light_shader = m_light_shader_default;
@@ -275,7 +276,53 @@
 	std::copy(i_tmp, i_tmp+60, &m_sphere_indices[0]);
 }
 
+void RAS_OpenGLRasterizer::init_cone(float angle)
+{
+	int edges = 8;
+	int distance = 1.1;
 
+	/* Only need half the angle */
+	float theta = M_PI * angle / 360;
+	float r = 1.5 * distance * sinf(theta);
+	float d = distance * cosf(theta);
+	float s = M_PI * 2 / edges;
+	
+	if (m_cone_size == 0) {
+		m_cone_size = 2 * edges * 3;
+		m_cone_vertices = new float[(edges+2)*3];
+		m_cone_indices = new unsigned short[m_cone_size];
+	}
+
+	m_cone_vertices[0] = 0;
+	m_cone_vertices[1] = 0;
+	m_cone_vertices[2] = 0;
+	m_cone_vertices[3] = 0;
+	m_cone_vertices[4] = 0;
+	m_cone_vertices[5] = -distance;
+
+	for (int i = 2; i < edges+2; i++){
+		m_cone_vertices[3 * i + 0] = r * cosf(i*s);
+		m_cone_vertices[3 * i + 1] = r * sinf(i*s);
+		m_cone_vertices[3 * i + 2] = -d;
+	}
+
+	m_cone_indices[0] = 0;
+	m_cone_indices[1] = edges;
+	m_cone_indices[2] = 2;
+	m_cone_indices[3] = 1;
+	m_cone_indices[4] = 2;
+	m_cone_indices[5] = edges;
+
+	for (int i = 0; i < edges-1; i++) {
+		m_cone_indices[6 * i + 0] = 0;
+		m_cone_indices[6 * i + 1] = 2+i;
+		m_cone_indices[6 * i + 2] = 3+i;
+		m_cone_indices[6 * i + 3] = 1;
+		m_cone_indices[6 * i + 4] = 3+i;
+		m_cone_indices[6 * i + 5] = 2+i;
+	}
+}
+
 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
 {
 	m_ambr = red;
@@ -417,8 +464,14 @@
 	if (m_technique == KX_TECH_INFERRED)
 	{
 		glDeleteTextures(m_prepass_count+1, m_prepass_target);
-		delete m_sphere_vertices;
-		delete m_sphere_indices;
+		delete[] m_sphere_vertices;
+		delete[] m_sphere_indices;
+
+		if (m_cone_size != 0)
+		{
+			 delete[] m_cone_vertices;
+			 delete[] m_cone_indices;
+		}
 	}
 	
 	EndFrame();
@@ -755,7 +808,7 @@
 
 			// Update light target
 			glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(m_light_target));
-			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_width, m_height, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
@@ -1427,19 +1480,37 @@
 	bind = GPU_shader_get_uniform(m_light_shader, "light.vector");
 	GPU_shader_uniform_vector(m_light_shader, bind, 3, 1, fvec);
 
+	float spotsi = cosf((float)M_PI * light->m_spotsize/360.0f);
+	bind = GPU_shader_get_uniform(m_light_shader, "light.spotsize");
+	GPU_shader_uniform_vector(m_light_shader, bind, 1, 1, &spotsi);
+
+	float spotbl = (1.0f - spotsi/2.0f) * light->m_spotblend;
+	bind = GPU_shader_get_uniform(m_light_shader, "light.spotblend");
+	GPU_shader_uniform_vector(m_light_shader, bind, 1, 1, &spotbl);
+
 	if (light->m_type == RAS_LightObject::LIGHT_NORMAL) {
 		glMatrixMode(GL_MODELVIEW);
 		glPushMatrix();
-		glLoadIdentity();
+		glMultMatrixf((GLfloat*)light->m_obmat);
 
-		glTranslatef(fpos[0], fpos[1], fpos[2]);
-		glScalef(light->m_distance, light->m_distance, light->m_distance);
 		glEnableClientState(GL_VERTEX_ARRAY);
 		glVertexPointer(3, GL_FLOAT, 0, m_sphere_vertices);
 		glDrawElements(GL_TRIANGLES, m_sphere_size, GL_UNSIGNED_SHORT, m_sphere_indices);
 
 		glPopMatrix();
 	}
+	else if (light->m_type == RAS_LightObject::LIGHT_SPOT) {
+		glMatrixMode(GL_MODELVIEW);
+		glPushMatrix();
+		glMultMatrixf((GLfloat*)light->m_obmat);
+
+		this->init_cone(light->m_spotsize);
+		glEnableClientState(GL_VERTEX_ARRAY);
+		glVertexPointer(3, GL_FLOAT, 0, m_cone_vertices);
+		glDrawElements(GL_TRIANGLES, m_cone_size, GL_UNSIGNED_SHORT, m_cone_indices);
+
+		glPopMatrix();
+	}
 	else {
 		glMatrixMode(GL_MODELVIEW);
 		glPushMatrix();

Modified: branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
===================================================================
--- branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h	2013-01-05 07:30:52 UTC (rev 53572)
+++ branches/ge_harmony/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h	2013-01-05 07:39:14 UTC (rev 53573)
@@ -145,6 +145,10 @@
 	float*			m_sphere_vertices;
 	unsigned short*	m_sphere_indices;
 	int				m_sphere_size;
+	void init_cone(float angle);
+	float*			m_cone_vertices;
+	unsigned short*	m_cone_indices;
+	int				m_cone_size;
 
 	/** Stores the caching information for the last material activated. */
 	RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;




More information about the Bf-blender-cvs mailing list