[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42616] branches/ge_harmony/source/blender /gpu: Initial VSM commit.

Mitchell Stokes mogurijin at gmail.com
Tue Dec 13 22:23:24 CET 2011


Revision: 42616
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42616
Author:   moguri
Date:     2011-12-13 21:23:08 +0000 (Tue, 13 Dec 2011)
Log Message:
-----------
Initial VSM commit. VSMs are in, and work, but they need more user settable options.
Options that still need to be added:
  * Switching between "Simple" or "Variance" shadow maps
  * Fudge-factor for fixing light bleed ("Bleed Bias"?). Right now this is sort of mapped to shadow bias.
  * Blur settings such as whether or not to blur, and the size of the blur texture. Currently the blur texture is shadow_texture*0.5

Modified Paths:
--------------
    branches/ge_harmony/source/blender/gpu/CMakeLists.txt
    branches/ge_harmony/source/blender/gpu/GPU_extensions.h
    branches/ge_harmony/source/blender/gpu/SConscript
    branches/ge_harmony/source/blender/gpu/intern/gpu_extensions.c
    branches/ge_harmony/source/blender/gpu/intern/gpu_material.c
    branches/ge_harmony/source/blender/gpu/intern/gpu_shader_material.glsl
    branches/ge_harmony/source/blender/gpu/intern/gpu_shader_material.glsl.c

Added Paths:
-----------
    branches/ge_harmony/source/blender/gpu/intern/shaders/
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_sep_gaussian_blur_frag.glsl.c
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_sep_gaussian_blur_vert.glsl.c
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_vsm_store_frag.glsl
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_vsm_store_frag.glsl.c
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_vsm_store_vert.glsl
    branches/ge_harmony/source/blender/gpu/intern/shaders/gpu_shader_vsm_store_vert.glsl.c

Modified: branches/ge_harmony/source/blender/gpu/CMakeLists.txt
===================================================================
--- branches/ge_harmony/source/blender/gpu/CMakeLists.txt	2011-12-13 20:01:59 UTC (rev 42615)
+++ branches/ge_harmony/source/blender/gpu/CMakeLists.txt	2011-12-13 21:23:08 UTC (rev 42616)
@@ -52,6 +52,11 @@
 	intern/gpu_material.c
 	intern/gpu_shader_material.glsl.c
 	intern/gpu_shader_vertex.glsl.c
+	
+	intern/shaders/gpu_shader_sep_gaussian_blur_frag.glsl.c
+	intern/shaders/gpu_shader_sep_gaussian_blur_vert.glsl.c
+	intern/shaders/gpu_shader_vsm_store_frag.glsl.c
+	intern/shaders/gpu_shader_vsm_store_vert.glsl.c
 
 	GPU_buffers.h
 	GPU_draw.h

Modified: branches/ge_harmony/source/blender/gpu/GPU_extensions.h
===================================================================
--- branches/ge_harmony/source/blender/gpu/GPU_extensions.h	2011-12-13 20:01:59 UTC (rev 42615)
+++ branches/ge_harmony/source/blender/gpu/GPU_extensions.h	2011-12-13 21:23:08 UTC (rev 42616)
@@ -107,6 +107,7 @@
 GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels, char err_out[256]);
 GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels);
 GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
+GPUTexture *GPU_texture_create_shadow_map(int size, char err_out[256]);
 GPUTexture *GPU_texture_from_blender(struct Image *ima,
 	struct ImageUser *iuser, double time, int mipmap);
 void GPU_texture_free(GPUTexture *tex);
@@ -138,6 +139,7 @@
 void GPU_framebuffer_free(GPUFrameBuffer *fb);
 
 void GPU_framebuffer_restore(void);
+void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex);
 
 /* GPU OffScreen
    - wrapper around framebuffer and texture for simple offscreen drawing 
@@ -167,6 +169,15 @@
 
 int GPU_shader_get_attribute(GPUShader *shader, char *name);
 
+/* Builtin/Non-generated shaders */
+typedef enum GPUBuiltinShader {
+	GPU_SHADER_VSM_STORE =			(1<<0),
+	GPU_SHADER_SEP_GAUSSIAN_BLUR =	(1<<1),
+} GPUBuiltinShader;
+
+GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader);
+void GPU_shader_free_builtin_shader(GPUBuiltinShader shader);
+
 /* Vertex attributes for shaders */
 
 #define GPU_MAX_ATTRIB		32

Modified: branches/ge_harmony/source/blender/gpu/SConscript
===================================================================
--- branches/ge_harmony/source/blender/gpu/SConscript	2011-12-13 20:01:59 UTC (rev 42615)
+++ branches/ge_harmony/source/blender/gpu/SConscript	2011-12-13 21:23:08 UTC (rev 42616)
@@ -2,6 +2,7 @@
 Import ('env')
 
 sources = env.Glob('intern/*.c')
+sources += env.Glob('intern/shaders/*.c')
 
 defs = [ 'GLEW_STATIC' ]
 

Modified: branches/ge_harmony/source/blender/gpu/intern/gpu_extensions.c
===================================================================
--- branches/ge_harmony/source/blender/gpu/intern/gpu_extensions.c	2011-12-13 20:01:59 UTC (rev 42615)
+++ branches/ge_harmony/source/blender/gpu/intern/gpu_extensions.c	2011-12-13 21:23:08 UTC (rev 42616)
@@ -63,6 +63,17 @@
 	- arb draw buffers? 2.0 core
 */
 
+/* Non-generated shaders */
+extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
+extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
+extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
+extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
+
+typedef struct GPUShaders {
+	GPUShader *vsm_store;
+	GPUShader *sep_gaussian_blur;
+} GPUShaders;
+
 static struct GPUGlobal {
 	GLint maxtextures;
 	GLuint currentfb;
@@ -73,7 +84,8 @@
 	GPUDeviceType device;
 	GPUOSType os;
 	GPUDriverType driver;
-} GG = {1, 0, 0, 0, 0};
+	GPUShaders shaders;
+} GG = {1, 0, 0, 0, 0, 0};
 
 /* GPU Types */
 
@@ -592,6 +604,20 @@
 	return tex;
 }
 
+GPUTexture *GPU_texture_create_shadow_map(int size, char err_out[256])
+{
+	GPUTexture *tex = GPU_texture_create_nD(size, size, 2, NULL, 0, err_out);
+
+	if (tex) {
+		/* Now we tweak some of the settings */
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, size, size, 0, GL_RG, GL_FLOAT, 0);
+
+		GPU_texture_unbind(tex);
+	}
+
+	return tex;
+}
+
 void GPU_texture_bind(GPUTexture *tex, int number)
 {
 	GLenum arbnumber;
@@ -733,6 +759,8 @@
 	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, 
 		tex->target, tex->bindcode, 0);
 
+	/* This breaks variance shadow maps. Disabling doesn't seem to break anything. */
+#if 0
 	if(tex->depth) {
 		glDrawBuffer(GL_NONE);
 		glReadBuffer(GL_NONE);
@@ -741,6 +769,7 @@
 		glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
 		glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
 	}
+#endif
 
 	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 
@@ -850,6 +879,57 @@
 	}
 }
 
+void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex)
+{
+	float scaleh[2] = {1.0f/GPU_texture_opengl_width(blurtex), 0.0f};
+	float scalev[2] = {0.0f, 1.0f/GPU_texture_opengl_height(tex)};
+
+	GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR);
+	int scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU");
+	int texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource");
+		
+	/* Blurring horizontally */
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object);
+
+	GPU_shader_bind(blur_shader);
+	GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float*)scaleh);
+	GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
+	glViewport(0, 0, GPU_texture_opengl_width(blurtex), GPU_texture_opengl_height(blurtex));
+
+	/* Peparing to draw quad */
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+	glMatrixMode(GL_TEXTURE);
+	glLoadIdentity();
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+
+	GPU_texture_bind(tex, 0);
+
+	/* Drawing quad */
+	glBegin(GL_QUADS);
+		glTexCoord2d(0,0);glVertex2f(1,1);
+		glTexCoord2d(1,0);glVertex2f(-1,1);
+		glTexCoord2d(1,1);glVertex2f(-1,-1);
+		glTexCoord2d(0,1);glVertex2f(1,-1);
+	glEnd();
+		
+	/* Blurring vertically */
+
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+	glViewport(0, 0, GPU_texture_opengl_width(tex), GPU_texture_opengl_height(tex));
+	GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float*)scalev);
+	GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
+	GPU_texture_bind(blurtex, 0);
+	glBegin(GL_QUADS);
+		glTexCoord2d(0,0);glVertex2f(1,1);
+		glTexCoord2d(1,0);glVertex2f(-1,1);
+		glTexCoord2d(1,1);glVertex2f(-1,-1);
+		glTexCoord2d(0,1);glVertex2f(1,-1);
+	glEnd();
+	GPU_shader_unbind(blur_shader);
+}
+
 /* GPUOffScreen */
 
 struct GPUOffScreen {
@@ -1175,6 +1255,42 @@
 	return index;
 }
 
+GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
+{
+	switch (shader)
+	{
+	case GPU_SHADER_VSM_STORE:
+		if (!GG.shaders.vsm_store)
+			GG.shaders.vsm_store = GPU_shader_create(datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl, NULL);
+		return GG.shaders.vsm_store;
+	case GPU_SHADER_SEP_GAUSSIAN_BLUR:
+		if (!GG.shaders.sep_gaussian_blur)
+			GG.shaders.sep_gaussian_blur = GPU_shader_create(datatoc_gpu_shader_sep_gaussian_blur_vert_glsl, datatoc_gpu_shader_sep_gaussian_blur_frag_glsl, NULL);
+		return GG.shaders.sep_gaussian_blur;
+	default:
+		return NULL;
+	}
+}
+
+void GPU_shader_free_builtin_shader(GPUBuiltinShader shader)
+{
+	GPUShader **s = NULL;
+	switch (shader)
+	{
+	case GPU_SHADER_VSM_STORE:
+		s = &GG.shaders.vsm_store;
+	case GPU_SHADER_SEP_GAUSSIAN_BLUR:
+		s = &GG.shaders.sep_gaussian_blur;
+	default:
+		s = NULL;
+	}
+
+	if (s) {
+		MEM_freeN(*s);
+		*s = NULL;
+	}
+}
+
 #if 0
 /* GPUPixelBuffer */
 

Modified: branches/ge_harmony/source/blender/gpu/intern/gpu_material.c
===================================================================
--- branches/ge_harmony/source/blender/gpu/intern/gpu_material.c	2011-12-13 20:01:59 UTC (rev 42615)
+++ branches/ge_harmony/source/blender/gpu/intern/gpu_material.c	2011-12-13 21:23:08 UTC (rev 42616)
@@ -132,7 +132,10 @@
 	float dynpersmat[4][4];
 
 	GPUFrameBuffer *fb;
+	GPUFrameBuffer *blurfb;
 	GPUTexture *tex;
+	GPUTexture *depthtex;
+	GPUTexture *blurtex;
 
 	ListBase materials;
 };
@@ -708,11 +711,19 @@
 		if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) {
 			mat->dynproperty |= DYN_LAMP_PERSMAT;
 			
+#if 0
 			GPU_link(mat, "test_shadowbuf",
 				GPU_builtin(GPU_VIEW_POSITION),
 				GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
 				GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
 				GPU_uniform(&lamp->bias), inp, &shadfac);
+#else
+			GPU_link(mat, "test_shadowbuf_vsm",
+				GPU_builtin(GPU_VIEW_POSITION),
+				GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
+				GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
+				GPU_uniform(&lamp->bias), inp, &shadfac);
+#endif
 			
 			if(lamp->mode & LA_ONLYSHADOW) {
 				GPU_link(mat, "shade_only_shadow", i, shadfac,
@@ -1591,10 +1602,22 @@
 		GPU_texture_free(lamp->tex);
 		lamp->tex= NULL;
 	}
+	if(lamp->depthtex) {
+		GPU_texture_free(lamp->depthtex);
+		lamp->depthtex= NULL;
+	}
 	if(lamp->fb) {
 		GPU_framebuffer_free(lamp->fb);
 		lamp->fb= NULL;
 	}
+	if(lamp->blurtex) {
+		GPU_texture_free(lamp->blurtex);
+		lamp->blurtex= NULL;
+	}
+	if(lamp->blurfb) {
+		GPU_framebuffer_free(lamp->blurfb);
+		lamp->blurfb= NULL;
+	}
 }
 
 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
@@ -1627,7 +1650,8 @@
 			return lamp;
 		}
 
-		lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
+		/* Shadow color map */
+		lamp->tex = GPU_texture_create_shadow_map(lamp->size, NULL);
 		if(!lamp->tex) {
 			gpu_lamp_shadow_free(lamp);
 			return lamp;
@@ -1638,6 +1662,37 @@
 			return lamp;
 		}
 
+		/* Shadow depth map */
+		lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
+		if(!lamp->depthtex) {
+			gpu_lamp_shadow_free(lamp);
+			return lamp;
+		}
+		
+		if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, NULL)) {
+			gpu_lamp_shadow_free(lamp);
+			return lamp;
+		}
+
+		/* FBO and texture for blurring */
+		lamp->blurfb = GPU_framebuffer_create();
+		if(!lamp->blurfb) {
+			gpu_lamp_shadow_free(lamp);
+			return lamp;
+		}
+
+		lamp->blurtex = GPU_texture_create_shadow_map(lamp->size*0.5, NULL);
+		if(!lamp->blurtex) {
+			gpu_lamp_shadow_free(lamp);
+			return lamp;
+		}
+		
+		if(!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, NULL)) {
+			gpu_lamp_shadow_free(lamp);
+			return lamp;
+		}
+
+
 		GPU_framebuffer_restore();
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list