[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