Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-08-04 11:49:32 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-08-04 11:52:50 +0300
commitabb976ae889985a973d322bd7f3a792495553ff3 (patch)
tree777dc6b66c868613ec6e8577ebcd662be3249bfc /intern
parentcff288cf3a0d71b610fa20875a321ea3b8db2388 (diff)
OpenSubdiv: Optimize drawing shader
The idea is to cut as much code as possible and use compile-time ifdefs rather than runtime if() statements. Gives about 2x speedup on catmark_car model from OpenSubdiv repository making our FPS much closer to what glViewer is capable of.
Diffstat (limited to 'intern')
-rw-r--r--intern/opensubdiv/gpu_shader_opensubd_display.glsl154
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc53
2 files changed, 106 insertions, 101 deletions
diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index 110898ad917..e343c952944 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -215,8 +215,6 @@ uniform vec4 specular;
uniform float shininess;
uniform sampler2D texture_buffer;
-uniform bool use_color_material;
-uniform bool use_texture_2d;
in block {
VertexData v;
@@ -236,99 +234,89 @@ void main()
vec3 L_diffuse = vec3(0.0);
vec3 L_specular = vec3(0.0);
- 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;
-
- /* Specular light. */
- vec4 Plight = lightSource[i].position;
- vec3 l = (Plight.w == 0.0)
- ? normalize(Plight.xyz) : normalize(Plight.xyz -
- inpt.v.position.xyz);
- 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;
- }
+#ifndef USE_COLOR_MATERIAL
+ /* Assume NUM_SOLID_LIGHTS directional lights. */
+ for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
+ vec4 Plight = lightSource[i].position;
+#ifdef USE_DIRECTIONAL_LIGHT
+ vec3 l = (Plight.w == 0.0)
+ ? normalize(Plight.xyz)
+ : normalize(inpt.v.position.xyz);
+#else /* USE_DIRECTIONAL_LIGHT */
+ /* TODO(sergey): We can normalize it outside of the shader. */
+ vec3 l = normalize(Plight.xyz);
+#endif /* USE_DIRECTIONAL_LIGHT */
+ vec3 h = normalize(l + vec3(0, 0, 1));
+ float d = max(0.0, dot(N, l));
+ float s = pow(max(0.0, dot(N, h)), 500.0f);
+ L_diffuse += d * lightSource[i].diffuse;
+ L_specular += s * lightSource[i].specular;
}
- 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;
+#else /* USE_COLOR_MATERIAL */
+ 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);
}
- /* 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;
+ /* falloff */
+ float distance = length(d);
- /* 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;
+ 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;
}
+#endif /* USE_COLOR_MATERIAL */
/* Compute diffuse color. */
- float alpha;
- if (use_texture_2d) {
- L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
- }
- else {
- L_diffuse *= diffuse.rgb;
- }
- alpha = diffuse.a;
+#ifdef USE_TEXTURE_2D
+ L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
+#else
+ L_diffuse *= diffuse.rgb;
+#endif
/* Sum lighting. */
- vec3 L = /*gl_FrontLightModelProduct.sceneColor.rgb +*/ L_diffuse;
- if (shininess != 0.0f) {
- L += L_specular * specular.rgb;
- }
+ vec3 L = L_diffuse + L_specular * specular.rgb;
/* Write out fragment color. */
- gl_FragColor = vec4(L, alpha);
+ gl_FragColor = vec4(L, diffuse.a);
#endif
}
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index d46211f3668..9498f936b6b 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -86,8 +86,10 @@ typedef struct Transform {
static bool g_use_osd_glsl = false;
static int g_active_uv_index = -1;
-static GLuint g_flat_fill_program = 0;
-static GLuint g_smooth_fill_program = 0;
+static GLuint g_flat_fill_solid_program = 0;
+static GLuint g_flat_fill_texture2d_program = 0;
+static GLuint g_smooth_fill_solid_program = 0;
+static GLuint g_smooth_fill_texture2d_program = 0;
static GLuint g_wireframe_program = 0;
static GLuint g_lighting_ub = 0;
@@ -324,15 +326,8 @@ void bindProgram(PartitionedGLMeshInterface * /*mesh*/,
glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
/* Color */
- GLboolean use_lighting, use_color_material, use_texture_2d;
+ GLboolean use_lighting;
glGetBooleanv(GL_LIGHTING, &use_lighting);
- glGetBooleanv(GL_COLOR_MATERIAL, &use_color_material);
- glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
-
- glUniform1i(glGetUniformLocation(program, "use_color_material"),
- use_color_material);
- glUniform1i(glGetUniformLocation(program, "use_texture_2d"),
- use_texture_2d);
if (use_lighting) {
float color[4];
@@ -376,8 +371,10 @@ void openSubdiv_osdGLDisplayInit(void)
{
static bool need_init = true;
if (need_init) {
- g_flat_fill_program = linkProgram("#define FLAT_SHADING\n");
- g_smooth_fill_program = linkProgram("#define SMOOTH_SHADING\n");
+ g_flat_fill_solid_program = linkProgram("#define FLAT_SHADING\n");
+ g_flat_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define FLAT_SHADING\n");
+ g_smooth_fill_solid_program = linkProgram("#define SMOOTH_SHADING\n");
+ g_smooth_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define SMOOTH_SHADING\n");
g_wireframe_program = linkProgram("#define WIREFRAME\n");
glGenBuffers(1, &g_lighting_ub);
@@ -394,11 +391,17 @@ void openSubdiv_osdGLDisplayDeinit(void)
if (g_lighting_ub != 0) {
glDeleteBuffers(1, &g_lighting_ub);
}
- if (g_flat_fill_program) {
- glDeleteProgram(g_flat_fill_program);
+ if (g_flat_fill_solid_program) {
+ glDeleteProgram(g_flat_fill_solid_program);
+ }
+ if (g_flat_fill_texture2d_program) {
+ glDeleteProgram(g_flat_fill_texture2d_program);
+ }
+ if (g_smooth_fill_solid_program) {
+ glDeleteProgram(g_flat_fill_solid_program);
}
- if (g_smooth_fill_program) {
- glDeleteProgram(g_flat_fill_program);
+ if (g_smooth_fill_texture2d_program) {
+ glDeleteProgram(g_smooth_fill_texture2d_program);
}
if (g_wireframe_program) {
glDeleteProgram(g_wireframe_program);
@@ -505,12 +508,26 @@ static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh,
return program;
}
- program = g_smooth_fill_program;
if (fill_quads) {
int model;
+ GLboolean use_texture_2d;
glGetIntegerv(GL_SHADE_MODEL, &model);
+ glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
if (model == GL_FLAT) {
- program = g_flat_fill_program;
+ if (use_texture_2d) {
+ program = g_flat_fill_texture2d_program;
+ }
+ else {
+ program = g_flat_fill_solid_program;
+ }
+ }
+ else {
+ if (use_texture_2d) {
+ program = g_smooth_fill_texture2d_program;
+ }
+ else {
+ program = g_smooth_fill_solid_program;
+ }
}
}
else {