[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