Merging phase 1 of the BGE Harmony branch:

* Shadow color now usable in the BGE
 * Simplified the shadow panel while "Blender Game" renderer is active
 * Added variance shadow maps for the BGE
 * Buffered shadows on sun lamps in the BGE (orthographic)
 * Light textures in the BGE
This commit is contained in:
2012-05-01 02:50:17 +00:00
parent 7cb037db86
commit ae4fda82b0
29 changed files with 2414 additions and 1705 deletions

View File

@@ -187,10 +187,61 @@ class DATA_PT_sunsky(DataButtonsPanel, Panel):
sub.prop(lamp, "atmosphere_inscattering", slider=True, text="Inscattering")
sub.prop(lamp, "atmosphere_extinction", slider=True, text="Extinction")
class DATA_PT_shadow_game(DataButtonsPanel, bpy.types.Panel):
bl_label = "Shadow"
COMPAT_ENGINES = {'BLENDER_GAME'}
@classmethod
def poll(cls, context):
COMPAT_LIGHTS = {'SPOT', 'SUN'}
lamp = context.lamp
engine = context.scene.render.engine
return (lamp and lamp.type in COMPAT_LIGHTS) and (engine in cls.COMPAT_ENGINES)
def draw_header(self, context):
lamp = context.lamp
self.layout.prop(lamp, "use_shadow", text="")
def draw(self, context):
layout = self.layout
lamp = context.lamp
split = layout.split()
col = split.column()
col.prop(lamp, "shadow_color", text="")
col = split.column()
col.prop(lamp, "use_shadow_layer", text="This Layer Only")
col.prop(lamp, "use_only_shadow")
col = layout.column()
col.label("Buffer Type:")
col.prop(lamp, "ge_shadow_buffer_type", text="", toggle=True)
col.label("Quality:")
col = layout.column(align=True)
col.prop(lamp, "shadow_buffer_size", text="Size")
col.prop(lamp, "shadow_buffer_bias", text="Bias")
col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
row = layout.row()
row.label("Clipping:")
row = layout.row(align=True)
row.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
row.prop(lamp, "shadow_buffer_clip_end", text="Clip End")
if lamp.type == 'SUN':
row = layout.row()
row.prop(lamp, "shadow_frustum_size", text="Frustum Size")
layout.active = lamp.use_shadow
class DATA_PT_shadow(DataButtonsPanel, Panel):
bl_label = "Shadow"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
@classmethod
def poll(cls, context):

View File

@@ -96,6 +96,7 @@ void *add_lamp(const char *name)
la->skyblendfac= 1.0f;
la->sky_colorspace= BLI_XYZ_CIE;
la->sky_exposure= 1.0f;
la->shadow_frustum_size= 10.0f;
curvemapping_initialize(la->curfalloff);
return la;

View File

@@ -13343,6 +13343,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
{
Lamp *la;
for (la= main->lamp.first; la; la= la->id.next) {
if (la->shadow_frustum_size == 0.0)
la->shadow_frustum_size= 10.0f;
}
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */

View File

@@ -50,8 +50,13 @@ set(SRC
intern/gpu_draw.c
intern/gpu_extensions.c
intern/gpu_material.c
intern/gpu_shader_material.glsl.c
intern/gpu_shader_vertex.glsl.c
shaders/gpu_shader_material.glsl.c
shaders/gpu_shader_vertex.glsl.c
shaders/gpu_shader_sep_gaussian_blur_frag.glsl.c
shaders/gpu_shader_sep_gaussian_blur_vert.glsl.c
shaders/gpu_shader_vsm_store_frag.glsl.c
shaders/gpu_shader_vsm_store_vert.glsl.c
GPU_buffers.h
GPU_draw.h

View File

@@ -109,6 +109,7 @@ GPUTexture *GPU_texture_create_1D(int w, float *pixels, char err_out[256]);
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_vsm_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);
@@ -140,6 +141,7 @@ void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex);
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
@@ -169,6 +171,15 @@ void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex
int GPU_shader_get_attribute(GPUShader *shader, const 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_shaders();
/* Vertex attributes for shaders */
#define GPU_MAX_ATTRIB 32

View File

@@ -225,6 +225,7 @@ GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Ob
void GPU_lamp_free(struct Object *ob);
int GPU_lamp_has_shadow_buffer(GPULamp *lamp);
void GPU_lamp_update_buffer_mats(GPULamp *lamp);
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]);
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);

View File

@@ -2,6 +2,7 @@
Import ('env')
sources = env.Glob('intern/*.c')
sources += env.Glob('shaders/*.c')
defs = [ 'GLEW_STATIC' ]

View File

@@ -258,6 +258,8 @@ void GPU_codegen_exit(void)
FUNCTION_HASH = NULL;
}
GPU_shader_free_builtin_shaders();
if (glsl_material_library) {
MEM_freeN(glsl_material_library);
glsl_material_library = NULL;

View File

@@ -67,6 +67,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;
@@ -77,7 +88,8 @@ static struct GPUGlobal {
GPUDeviceType device;
GPUOSType os;
GPUDriverType driver;
} GG = {1, 0, 0, 0, 0};
GPUShaders shaders;
} GG = {1, 0};
/* GPU Types */
@@ -588,6 +600,25 @@ GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
return tex;
}
/**
* A shadow map for VSM needs two components (depth and depth^2)
*/
GPUTexture *GPU_texture_create_vsm_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 */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
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;
@@ -846,6 +877,65 @@ void GPU_framebuffer_restore(void)
}
}
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, texture_source_uniform;
if (!blur_shader)
return;
scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU");
texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource");
/* Blurring horizontally */
/* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid
pushing unnecessary matrices onto the OpenGL stack. */
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 {
@@ -1173,6 +1263,45 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name)
return index;
}
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
{
GPUShader *retval = NULL;
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);
retval = GG.shaders.vsm_store;
break;
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);
retval = GG.shaders.sep_gaussian_blur;
break;
}
if (retval == NULL)
printf("Unable to create a GPUShader for builtin shader: %d\n", shader);
return retval;
}
void GPU_shader_free_builtin_shaders()
{
if (GG.shaders.vsm_store)
{
MEM_freeN(GG.shaders.vsm_store);
GG.shaders.vsm_store = NULL;
}
if (GG.shaders.sep_gaussian_blur)
{
MEM_freeN(GG.shaders.sep_gaussian_blur);
GG.shaders.sep_gaussian_blur = NULL;
}
}
#if 0
/* GPUPixelBuffer */

View File

@@ -118,6 +118,7 @@ struct GPULamp {
float spotsi, spotbl, k;
float dist, att1, att2;
float shadow_color[3];
float bias, d, clipend;
int size;
@@ -131,11 +132,17 @@ struct GPULamp {
float dynpersmat[4][4];
GPUFrameBuffer *fb;
GPUFrameBuffer *blurfb;
GPUTexture *tex;
GPUTexture *depthtex;
GPUTexture *blurtex;
ListBase materials;
};
/* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in);
/* Functions */
static GPUMaterial *GPU_material_construct_begin(Material *ma)
@@ -323,8 +330,12 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float v
if (material->dynproperty & DYN_LAMP_IMAT)
mult_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
if (material->dynproperty & DYN_LAMP_PERSMAT)
{
if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */
GPU_lamp_update_buffer_mats(lamp);
mult_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
}
}
GPU_pass_update_uniforms(material->pass);
}
@@ -614,12 +625,35 @@ static void add_user_list(ListBase *list, void *data)
BLI_addtail(list, link);
}
static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **rgb)
{
GPUNodeLink *tex_rgb;
MTex *mtex = NULL;
int i;
float one = 1.f;
for (i=0; i<MAX_MTEX; ++i) {
mtex = lamp->la->mtex[i];
if (mtex && mtex->tex->type & TEX_IMAGE && mtex->tex->ima) {
mat->dynproperty |= DYN_LAMP_PERSMAT;
GPU_link(mat, "shade_light_texture",
GPU_builtin(GPU_VIEW_POSITION),
GPU_image(mtex->tex->ima, &mtex->tex->iuser),
GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
&tex_rgb);
texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb);
}
}
}
static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp)
{
Material *ma= shi->mat;
GPUMaterial *mat= shi->gpumat;
GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view;
GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL;
GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL, *lcol;
float one = 1.0f;
if ((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
@@ -671,6 +705,9 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
i = is;
GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol);
shade_light_textures(mat, lamp, &lcol);
#if 0
if (ma->mode & MA_TANGENT_VN)
GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);
@@ -683,19 +720,28 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) {
mat->dynproperty |= DYN_LAMP_PERSMAT;
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
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), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac);
} else {
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);
}
if (lamp->mode & LA_ONLYSHADOW) {
GPU_link(mat, "shade_only_shadow", i, shadfac,
GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), &shadfac);
if (!(lamp->mode & LA_NO_DIFF))
GPU_link(mat, "shade_only_shadow_diffuse", shadfac, shi->rgb,
shr->diff, &shr->diff);
if (!(lamp->mode & LA_NO_DIFF)) {
GPU_link(mat, "mix_mult", shadfac, shr->diff,
GPU_uniform(lamp->shadow_color), &shr->diff);
}
if (!(lamp->mode & LA_NO_SPEC))
GPU_link(mat, "shade_only_shadow_specular", shadfac, shi->specrgb,
@@ -705,8 +751,6 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
add_user_list(&lamp->materials, shi->gpumat->ma);
return;
}
GPU_link(mat, "math_multiply", i, shadfac, &i);
}
}
else if ((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) {
@@ -720,7 +764,10 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
if (GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
if (!(lamp->mode & LA_NO_DIFF)) {
GPUNodeLink *rgb;
GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &rgb);
GPU_link(mat, "shade_mul_value", i, lcol, &rgb);
GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
GPU_link(mat, "mix_mult", shadfac, rgb, GPU_uniform(lamp->shadow_color), &rgb);
GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
}
}
@@ -730,7 +777,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
(GPU_link_changed(shi->spec) || ma->spec != 0.0f)) {
if (lamp->type == LA_HEMI) {
GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol);
GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
}
else {
@@ -753,11 +800,11 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
if (ma->mode & MA_RAMP_SPEC) {
GPUNodeLink *spec;
do_specular_ramp(shi, specfac, t, &spec);
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), spec, &outcol);
GPU_link(mat, "shade_add_spec", t, lcol, spec, &outcol);
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
}
else {
GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol);
GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
}
}
@@ -1562,13 +1609,18 @@ static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l
lamp->bias *= 0.25f;
/* makeshadowbuf */
if (lamp->type == LA_SUN) {
wsize = la->shadow_frustum_size;
orthographic_m4( lamp->winmat,-wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
}
else {
angle= saacos(lamp->spotsi);
temp= 0.5f*lamp->size*cosf(angle)/sinf(angle);
pixsize= (lamp->d)/temp;
wsize= pixsize*0.5f*lamp->size;
perspective_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
}
}
static void gpu_lamp_shadow_free(GPULamp *lamp)
{
@@ -1576,10 +1628,22 @@ static void gpu_lamp_shadow_free(GPULamp *lamp)
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)
@@ -1604,7 +1668,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
la = ob->data;
gpu_lamp_from_blender(scene, ob, par, la, lamp);
if (la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) {
if ((la->type==LA_SPOT || la->type==LA_SUN) && (la->mode & LA_SHAD_BUF)) {
/* opengl */
lamp->fb = GPU_framebuffer_create();
if (!lamp->fb) {
@@ -1612,7 +1676,21 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
/* 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;
}
/* Shadow color map */
lamp->tex = GPU_texture_create_vsm_shadow_map(lamp->size, NULL);
if (!lamp->tex) {
gpu_lamp_shadow_free(lamp);
return lamp;
@@ -1623,7 +1701,47 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
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_vsm_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;
}
}
else {
lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
if(!lamp->tex) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
}
GPU_framebuffer_restore();
lamp->shadow_color[0] = la->shdwr;
lamp->shadow_color[1] = la->shdwg;
lamp->shadow_color[2] = la->shdwb;
}
else {
lamp->shadow_color[0] = 1.0;
lamp->shadow_color[1] = 1.0;
lamp->shadow_color[2] = 1.0;
}
return lamp;
@@ -1663,7 +1781,7 @@ int GPU_lamp_has_shadow_buffer(GPULamp *lamp)
lamp->tex && lamp->fb);
}
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
void GPU_lamp_update_buffer_mats(GPULamp *lamp)
{
float rangemat[4][4], persmat[4][4];
@@ -1686,11 +1804,18 @@ void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize
rangemat[3][2] = 0.5f;
mult_m4_m4m4(lamp->persmat, rangemat, persmat);
}
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
{
GPU_lamp_update_buffer_mats(lamp);
/* opengl */
glDisable(GL_SCISSOR_TEST);
GPU_framebuffer_texture_bind(lamp->fb, lamp->tex,
GPU_texture_opengl_width(lamp->tex), GPU_texture_opengl_height(lamp->tex));
if(lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
/* set matrices */
copy_m4_m4(viewmat, lamp->viewmat);
@@ -1700,6 +1825,11 @@ void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
{
if(lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
GPU_shader_unbind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
}
GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
GPU_framebuffer_restore();
glEnable(GL_SCISSOR_TEST);

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +0,0 @@
/** \file blender/gpu/intern/gpu_shader_vertex.glsl.c
* \ingroup gpu
*/
/* DataToC output of file <gpu_shader_vertex_glsl> */
int datatoc_gpu_shader_vertex_glsl_size= 228;
char datatoc_gpu_shader_vertex_glsl[]= {
10,118, 97,114,
121,105,110,103, 32,118,101, 99, 51, 32,118, 97,114,112,111,115,105,116,105,111,110, 59, 10,118, 97,114,121,105,110,103, 32,118,
101, 99, 51, 32,118, 97,114,110,111,114,109, 97,108, 59, 10, 10,118,111,105,100, 32,109, 97,105,110, 40, 41, 10,123, 10, 9,118,
101, 99, 52, 32, 99,111, 32, 61, 32,103,108, 95, 77,111,100,101,108, 86,105,101,119, 77, 97,116,114,105,120, 32, 42, 32,103,108,
95, 86,101,114,116,101,120, 59, 10, 10, 9,118, 97,114,112,111,115,105,116,105,111,110, 32, 61, 32, 99,111, 46,120,121,122, 59,
10, 9,118, 97,114,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,103,108, 95, 78,111,114,109, 97,
108, 77, 97,116,114,105,120, 32, 42, 32,103,108, 95, 78,111,114,109, 97,108, 41, 59, 10, 9,103,108, 95, 80,111,115,105,116,105,
111,110, 32, 61, 32,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 32, 42, 32, 99,111, 59, 10, 10,
0};

View File

@@ -1859,10 +1859,53 @@ void test_shadowbuf(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, flo
//float bias = (1.5 - inp*inp)*shadowbias;
co.z -= shadowbias*co.w;
if (co.w > 0.0 && co.x > 0.0 && co.x/co.w < 1.0 && co.y > 0.0 && co.y/co.w < 1.0)
result = shadow2DProj(shadowmap, co).x;
else
result = 1.0;
}
}
void test_shadowbuf_vsm(vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, float inp, out float result)
{
if(inp <= 0.0) {
result = 0.0;
}
else {
vec4 co = shadowpersmat*vec4(rco, 1.0);
if (co.w > 0.0 && co.x > 0.0 && co.x/co.w < 1.0 && co.y > 0.0 && co.y/co.w < 1.0) {
vec2 moments = texture2DProj(shadowmap, co).rg;
float dist = co.z/co.w;
float p = 0.0;
if(dist <= moments.x)
p = 1.0;
float variance = moments.y - (moments.x*moments.x);
variance = max(variance, shadowbias/10.0);
float d = moments.x - dist;
float p_max = variance / (variance + d*d);
// Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1]
p_max = clamp((p_max-bleedbias)/(1.0-bleedbias), 0.0, 1.0);
result = max(p, p_max);
}
else {
result = 1.0;
}
}
}
void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result)
{
vec4 co = shadowpersmat*vec4(rco, 1.0);
result = texture2DProj(cookie, co);
}
void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
{
outcol = linfac*(1.0 - exp(col*logfac));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
uniform vec2 ScaleU;
uniform sampler2D textureSource;
void main()
{
vec4 color = vec4(0.0);
color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -2.0*ScaleU.x, -2.0*ScaleU.y ) )*0.09375;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2( -1.0*ScaleU.x, -1.0*ScaleU.y ) )*0.234375;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 0.0 , 0.0) )*0.3125;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 1.0*ScaleU.x, 1.0*ScaleU.y ) )*0.234375;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 2.0*ScaleU.x, 2.0*ScaleU.y ) )*0.09375;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2( 3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;
gl_FragColor = color;
}

View File

@@ -0,0 +1,33 @@
/* DataToC output of file <gpu_shader_sep_gaussian_blur_frag_glsl> */
int datatoc_gpu_shader_sep_gaussian_blur_frag_glsl_size = 848;
char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[] = {
117,110,105,102,111,114,109, 32,118,101, 99, 50, 32, 83, 99, 97,
108,101, 85, 59, 13, 10,117,110,105,102,111,114,109, 32,115, 97,109,112,108,101,114, 50, 68, 32,116,101,120,116,117,114,101, 83,
111,117,114, 99,101, 59, 13, 10, 13, 10,118,111,105,100, 32,109, 97,105,110, 40, 41, 13, 10,123, 13, 10, 9,118,101, 99, 52, 32,
99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40, 48, 46, 48, 41, 59, 13, 10, 9, 99,111,108,111,114, 32, 43, 61, 32,116,101,
120,116,117,114,101, 50, 68, 40, 32,116,101,120,116,117,114,101, 83,111,117,114, 99,101, 44, 32,103,108, 95, 84,101,120, 67,111,
111,114,100, 91, 48, 93, 46,115,116, 32, 43, 32,118,101, 99, 50, 40, 32, 45, 51, 46, 48, 42, 83, 99, 97,108,101, 85, 46,120, 44,
32, 45, 51, 46, 48, 42, 83, 99, 97,108,101, 85, 46,121, 32, 41, 32, 41, 32, 42, 32, 48, 46, 48, 49, 53, 54, 50, 53, 59, 13, 10,
9, 99,111,108,111,114, 32, 43, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 32,116,101,120,116,117,114,101, 83,111,117,114,
99,101, 44, 32,103,108, 95, 84,101,120, 67,111,111,114,100, 91, 48, 93, 46,115,116, 32, 43, 32,118,101, 99, 50, 40, 32, 45, 50,
46, 48, 42, 83, 99, 97,108,101, 85, 46,120, 44, 32, 45, 50, 46, 48, 42, 83, 99, 97,108,101, 85, 46,121, 32, 41, 32, 41, 42, 48,
46, 48, 57, 51, 55, 53, 59, 13, 10, 9, 99,111,108,111,114, 32, 43, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 32,116,101,
120,116,117,114,101, 83,111,117,114, 99,101, 44, 32,103,108, 95, 84,101,120, 67,111,111,114,100, 91, 48, 93, 46,115,116, 32, 43,
32,118,101, 99, 50, 40, 32, 45, 49, 46, 48, 42, 83, 99, 97,108,101, 85, 46,120, 44, 32, 45, 49, 46, 48, 42, 83, 99, 97,108,101,
85, 46,121, 32, 41, 32, 41, 42, 48, 46, 50, 51, 52, 51, 55, 53, 59, 13, 10, 9, 99,111,108,111,114, 32, 43, 61, 32,116,101,120,
116,117,114,101, 50, 68, 40, 32,116,101,120,116,117,114,101, 83,111,117,114, 99,101, 44, 32,103,108, 95, 84,101,120, 67,111,111,
114,100, 91, 48, 93, 46,115,116, 32, 43, 32,118,101, 99, 50, 40, 32, 48, 46, 48, 32, 44, 32, 48, 46, 48, 41, 32, 41, 42, 48, 46,
51, 49, 50, 53, 59, 13, 10, 9, 99,111,108,111,114, 32, 43, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 32,116,101,120,116,
117,114,101, 83,111,117,114, 99,101, 44, 32,103,108, 95, 84,101,120, 67,111,111,114,100, 91, 48, 93, 46,115,116, 32, 43, 32,118,
101, 99, 50, 40, 32, 49, 46, 48, 42, 83, 99, 97,108,101, 85, 46,120, 44, 32, 32, 49, 46, 48, 42, 83, 99, 97,108,101, 85, 46,121,
32, 41, 32, 41, 42, 48, 46, 50, 51, 52, 51, 55, 53, 59, 13, 10, 9, 99,111,108,111,114, 32, 43, 61, 32,116,101,120,116,117,114,
101, 50, 68, 40, 32,116,101,120,116,117,114,101, 83,111,117,114, 99,101, 44, 32,103,108, 95, 84,101,120, 67,111,111,114,100, 91,
48, 93, 46,115,116, 32, 43, 32,118,101, 99, 50, 40, 32, 50, 46, 48, 42, 83, 99, 97,108,101, 85, 46,120, 44, 32, 32, 50, 46, 48,
42, 83, 99, 97,108,101, 85, 46,121, 32, 41, 32, 41, 42, 48, 46, 48, 57, 51, 55, 53, 59, 13, 10, 9, 99,111,108,111,114, 32, 43,
61, 32,116,101,120,116,117,114,101, 50, 68, 40, 32,116,101,120,116,117,114,101, 83,111,117,114, 99,101, 44, 32,103,108, 95, 84,
101,120, 67,111,111,114,100, 91, 48, 93, 46,115,116, 32, 43, 32,118,101, 99, 50, 40, 32, 51, 46, 48, 42, 83, 99, 97,108,101, 85,
46,120, 44, 32, 45, 51, 46, 48, 42, 83, 99, 97,108,101, 85, 46,121, 32, 41, 32, 41, 32, 42, 32, 48, 46, 48, 49, 53, 54, 50, 53,
59, 13, 10, 13, 10, 9,103,108, 95, 70,114, 97,103, 67,111,108,111,114, 32, 61, 32, 99,111,108,111,114, 59, 13, 10,125, 13, 10,
0};

View File

@@ -0,0 +1,6 @@
void main()
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
}

View File

@@ -0,0 +1,9 @@
/* DataToC output of file <gpu_shader_sep_gaussian_blur_vert_glsl> */
int datatoc_gpu_shader_sep_gaussian_blur_vert_glsl_size = 92;
char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[] = {
13, 10,118,111,105,100, 32,109, 97,105,110, 40, 41, 13, 10,123, 13, 10, 9, 9,103,108, 95, 80,111,115,105,116,
105,111,110, 32, 61, 32,102,116,114, 97,110,115,102,111,114,109, 40, 41, 59, 13, 10, 9, 9,103,108, 95, 84,101,120, 67,111,111,
114,100, 91, 48, 93, 32, 61, 32, 32,103,108, 95, 77,117,108,116,105, 84,101,120, 67,111,111,114,100, 48, 59, 13, 10,125, 13, 10,
0};

View File

@@ -0,0 +1,14 @@
/* DataToC output of file <gpu_shader_vertex_glsl> */
int datatoc_gpu_shader_vertex_glsl_size = 240;
char datatoc_gpu_shader_vertex_glsl[] = {
13, 10,118, 97,114,121,105,110,103, 32,118,101, 99, 51, 32,118,
97,114,112,111,115,105,116,105,111,110, 59, 13, 10,118, 97,114,121,105,110,103, 32,118,101, 99, 51, 32,118, 97,114,110,111,114,
109, 97,108, 59, 13, 10, 13, 10,118,111,105,100, 32,109, 97,105,110, 40, 41, 13, 10,123, 13, 10, 9,118,101, 99, 52, 32, 99,111,
32, 61, 32,103,108, 95, 77,111,100,101,108, 86,105,101,119, 77, 97,116,114,105,120, 32, 42, 32,103,108, 95, 86,101,114,116,101,
120, 59, 13, 10, 13, 10, 9,118, 97,114,112,111,115,105,116,105,111,110, 32, 61, 32, 99,111, 46,120,121,122, 59, 13, 10, 9,118,
97,114,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,103,108, 95, 78,111,114,109, 97,108, 77, 97,
116,114,105,120, 32, 42, 32,103,108, 95, 78,111,114,109, 97,108, 41, 59, 13, 10, 9,103,108, 95, 80,111,115,105,116,105,111,110,
32, 61, 32,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 32, 42, 32, 99,111, 59, 13, 10, 13, 10,
0};

View File

@@ -0,0 +1,21 @@
/**
* This fragment shader was initially found at http://fabiensanglard.net/shadowmappingVSM/index.php
*/
varying vec4 v_position;
void main()
{
float depth = v_position.z / v_position.w;
depth = depth * 0.5 + 0.5;
float moment1 = depth;
float moment2 = depth * depth;
// Adjusting moments using partial derivative
float dx = dFdx(depth);
float dy = dFdy(depth);
moment2 += 0.25*(dx*dx+dy*dy);
gl_FragColor = vec4(moment1, moment2, 0.0, 0.0);
}

View File

@@ -0,0 +1,22 @@
/* DataToC output of file <gpu_shader_vsm_store_frag_glsl> */
int datatoc_gpu_shader_vsm_store_frag_glsl_size = 482;
char datatoc_gpu_shader_vsm_store_frag_glsl[] = {
47, 42,
42, 13, 10, 32, 42, 32, 84,104,105,115, 32,102,114, 97,103,109,101,110,116, 32,115,104, 97,100,101,114, 32,119, 97,115, 32,105,
110,105,116,105, 97,108,108,121, 32,102,111,117,110,100, 32, 97,116, 32,104,116,116,112, 58, 47, 47,102, 97, 98,105,101,110,115,
97,110,103,108, 97,114,100, 46,110,101,116, 47,115,104, 97,100,111,119,109, 97,112,112,105,110,103, 86, 83, 77, 47,105,110,100,
101,120, 46,112,104,112, 13, 10, 32, 42, 47, 13, 10, 13, 10,118, 97,114,121,105,110,103, 32,118,101, 99, 52, 32,118, 95,112,111,
115,105,116,105,111,110, 59, 13, 10, 13, 10,118,111,105,100, 32,109, 97,105,110, 40, 41, 13, 10,123, 13, 10, 9,102,108,111, 97,
116, 32,100,101,112,116,104, 32, 61, 32,118, 95,112,111,115,105,116,105,111,110, 46,122, 32, 47, 32,118, 95,112,111,115,105,116,
105,111,110, 46,119, 59, 13, 10, 9,100,101,112,116,104, 32, 61, 32,100,101,112,116,104, 32, 42, 32, 48, 46, 53, 32, 43, 32, 48,
46, 53, 59, 13, 10, 13, 10, 9,102,108,111, 97,116, 32,109,111,109,101,110,116, 49, 32, 61, 32,100,101,112,116,104, 59, 13, 10,
9,102,108,111, 97,116, 32,109,111,109,101,110,116, 50, 32, 61, 32,100,101,112,116,104, 32, 42, 32,100,101,112,116,104, 59, 13,
10, 13, 10, 9, 47, 47, 32, 65,100,106,117,115,116,105,110,103, 32,109,111,109,101,110,116,115, 32,117,115,105,110,103, 32,112,
97,114,116,105, 97,108, 32,100,101,114,105,118, 97,116,105,118,101, 13, 10, 9,102,108,111, 97,116, 32,100,120, 32, 61, 32,100,
70,100,120, 40,100,101,112,116,104, 41, 59, 13, 10, 9,102,108,111, 97,116, 32,100,121, 32, 61, 32,100, 70,100,121, 40,100,101,
112,116,104, 41, 59, 13, 10, 9,109,111,109,101,110,116, 50, 32, 43, 61, 32, 48, 46, 50, 53, 42, 40,100,120, 42,100,120, 43,100,
121, 42,100,121, 41, 59, 13, 10, 13, 10, 9,103,108, 95, 70,114, 97,103, 67,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40,109,
111,109,101,110,116, 49, 44, 32,109,111,109,101,110,116, 50, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 59, 13, 10,125, 13, 10,
0};

View File

@@ -0,0 +1,7 @@
varying vec4 v_position;
void main()
{
gl_Position = ftransform();
v_position = gl_Position;
}

View File

@@ -0,0 +1,10 @@
/* DataToC output of file <gpu_shader_vsm_store_vert_glsl> */
int datatoc_gpu_shader_vsm_store_vert_glsl_size = 105;
char datatoc_gpu_shader_vsm_store_vert_glsl[] = {
118, 97,114,121,105,110,103, 32,118,
101, 99, 52, 32,118, 95,112,111,115,105,116,105,111,110, 59, 13, 10, 13, 10,118,111,105,100, 32,109, 97,105,110, 40, 41, 13, 10,
123, 13, 10, 9,103,108, 95, 80,111,115,105,116,105,111,110, 32, 61, 32,102,116,114, 97,110,115,102,111,114,109, 40, 41, 59, 13,
10, 9,118, 95,112,111,115,105,116,105,111,110, 32, 61, 32,103,108, 95, 80,111,115,105,116,105,111,110, 59, 13, 10,125, 13, 10,
0};

View File

@@ -66,7 +66,7 @@ typedef struct Lamp {
short pad2;
float clipsta, clipend, shadspotsize;
float bias, soft, compressthresh, pad5[3];
float bias, soft, compressthresh, bleedbias, pad5[2];
short bufsize, samp, buffers, filtertype;
char bufflag, buftype;
@@ -76,7 +76,7 @@ typedef struct Lamp {
float area_size, area_sizey, area_sizez;
float adapt_thresh;
short ray_samp_method;
short pad1;
short shadowmap_type;
/* texact is for buttons */
short texact, shadhalostep;
@@ -96,8 +96,9 @@ typedef struct Lamp {
float atm_distance_factor;
float skyblendfac;
float sky_exposure;
float shadow_frustum_size; /* BGE Only */
short sky_colorspace;
char pad4[6];
char pad4[2];
struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */
struct MTex *mtex[18]; /* MAX_MTEX */
@@ -205,6 +206,9 @@ typedef struct Lamp {
#define LAMAP_COL 1
#define LAMAP_SHAD 2
/* shadowmap_type */
#define LA_SHADMAP_SIMPLE 0
#define LA_SHADMAP_VARIANCE 1
#endif /* __DNA_LAMP_TYPES_H__ */

View File

@@ -86,6 +86,24 @@ static void rna_Lamp_active_texture_set(PointerRNA *ptr, PointerRNA value)
set_current_lamp_texture(la, value.data);
}
static int rna_use_shadow_get(PointerRNA *ptr)
{
Lamp *la = (Lamp*)ptr->data;
return la->mode & LA_SHAD_BUF;
}
static void rna_use_shadow_set(PointerRNA *ptr, int value)
{
Lamp *la = (Lamp*)ptr->data;
if (value)
{
la->mode |= LA_SHAD_BUF;
la->mode &= ~LA_SHAD_RAY;
}
else
la->mode &= ~(LA_SHAD_BUF + LA_SHAD_RAY);
}
static StructRNA* rna_Lamp_refine(struct PointerRNA *ptr)
{
Lamp *la = (Lamp*)ptr->data;
@@ -464,12 +482,135 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area)
{LA_SAMP_CONSTANT, "CONSTANT_JITTERED", 0, "Constant Jittered", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_shadbuftype_items[] = {
{LA_SHADBUF_REGULAR, "REGULAR", 0, "Classical", "Classic shadow buffer"},
{LA_SHADBUF_HALFWAY, "HALFWAY", 0, "Classic-Halfway",
"Regular buffer, averaging the closest and 2nd closest Z value to reducing "
"bias artifacts"},
{LA_SHADBUF_IRREGULAR, "IRREGULAR", 0, "Irregular",
"Irregular buffer produces sharp shadow always, but it doesn't show up for raytracing"},
{LA_SHADBUF_DEEP, "DEEP", 0, "Deep",
"Deep shadow buffer supports transparency and better filtering, at the cost of "
"more memory usage and processing time"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_shadbuffiltertype_items[] = {
{LA_SHADBUF_BOX , "BOX", 0, "Box", "Apply the Box filter to shadow buffer samples"},
{LA_SHADBUF_TENT, "TENT", 0, "Tent", "Apply the Tent Filter to shadow buffer samples"},
{LA_SHADBUF_GAUSS, "GAUSS", 0, "Gauss", "Apply the Gauss filter to shadow buffer samples"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_numbuffer_items[] = {
{1, "BUFFERS_1", 0, "1", "Only one buffer rendered"},
{4, "BUFFERS_4", 0, "4", "Renders 4 buffers for better AA, this quadruples memory usage"},
{9, "BUFFERS_9", 0, "9", "Renders 9 buffers for better AA, this uses nine times more memory"},
{0, NULL, 0, NULL, NULL}};
/* GE only */
static EnumPropertyItem prop_ge_shadowbuffer_type_items[] = {
{LA_SHADMAP_SIMPLE, "SIMPLE", 0, "Simple", "Simple shadow maps"},
{LA_SHADMAP_VARIANCE, "VARIANCE", 0, "Variance", "Variance shadow maps"},
{0, NULL, 0, NULL, NULL}};
prop= RNA_def_property(srna, "use_shadow", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_use_shadow_get", "rna_use_shadow_set");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "shadow_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, (spot)? prop_spot_shadow_items: prop_shadow_items);
RNA_def_property_ui_text(prop, "Shadow Method", "Method to compute lamp shadow with");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "bufsize");
RNA_def_property_range(prop, 512, 10240);
RNA_def_property_ui_text(prop, "Shadow Buffer Size",
"Resolution of the shadow buffer, higher values give crisper shadows "
"but use more memory");
RNA_def_property_int_funcs(prop, NULL, "rna_Lamp_buffer_size_set", NULL);
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "filtertype");
RNA_def_property_enum_items(prop, prop_shadbuffiltertype_items);
RNA_def_property_ui_text(prop, "Shadow Filter Type", "Type of shadow filter (Buffer Shadows)");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_sample_buffers", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "buffers");
RNA_def_property_enum_items(prop, prop_numbuffer_items);
RNA_def_property_ui_text(prop, "Shadow Sample Buffers",
"Number of shadow buffers to render for better AA, this increases memory usage");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_clip_start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipsta");
RNA_def_property_range(prop, 0.0f, 9999.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Clip Start",
"Shadow map clip start, below which objects will not generate shadows");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "shadow_buffer_clip_end", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipend");
RNA_def_property_range(prop, 0.0f, 9999.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Clip End",
"Shadow map clip end, beyond which objects will not generate shadows");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "shadow_buffer_bias", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bias");
RNA_def_property_range(prop, 0.001f, 5.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Bias", "Shadow buffer sampling bias");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_bleed_bias", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bleedbias");
RNA_def_property_range(prop, 0.f, 1.f);
RNA_def_property_ui_text(prop, "Shadow Buffer Bleed Bias", "Bias for reducing light-bleed on variance shadow maps");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_soft", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "soft");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Soft", "Size of shadow buffer sampling area");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samp");
RNA_def_property_range(prop, 1, 16);
RNA_def_property_ui_text(prop, "Samples", "Number of shadow buffer samples");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "buftype");
RNA_def_property_enum_items(prop, prop_shadbuftype_items);
RNA_def_property_ui_text(prop, "Shadow Buffer Type", "Type of shadow buffer");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "ge_shadow_buffer_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shadowmap_type");
RNA_def_property_enum_items(prop, prop_ge_shadowbuffer_type_items);
RNA_def_property_ui_text(prop, "Shadow Map Type", "The shadow mapping algorithm used");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "use_auto_clip_start", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_START);
RNA_def_property_ui_text(prop, "Autoclip Start",
"Automatic calculation of clipping-start, based on visible vertices");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "use_auto_clip_end", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_END);
RNA_def_property_ui_text(prop, "Autoclip End", "Automatic calculation of clipping-end, based on visible vertices");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "compression_threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "compressthresh");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Compress", "Deep shadow map compression threshold");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "shdwr");
RNA_def_property_array(prop, 3);
@@ -599,18 +740,6 @@ static void rna_def_spot_lamp(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem prop_shadbuftype_items[] = {
{LA_SHADBUF_REGULAR, "REGULAR", 0, "Classical", "Classic shadow buffer"},
{LA_SHADBUF_HALFWAY, "HALFWAY", 0, "Classic-Halfway",
"Regular buffer, averaging the closest and 2nd closest Z value to reducing "
"bias artifacts"},
{LA_SHADBUF_IRREGULAR, "IRREGULAR", 0, "Irregular",
"Irregular buffer produces sharp shadow always, but it doesn't show up for raytracing"},
{LA_SHADBUF_DEEP, "DEEP", 0, "Deep",
"Deep shadow buffer supports transparency and better filtering, at the cost of "
"more memory usage and processing time"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_shadbuffiltertype_items[] = {
{LA_SHADBUF_BOX, "BOX", 0, "Box", "Apply the Box filter to shadow buffer samples"},
{LA_SHADBUF_TENT, "TENT", 0, "Tent", "Apply the Tent Filter to shadow buffer samples"},
@@ -653,28 +782,6 @@ static void rna_def_spot_lamp(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Halo Step", "Volumetric halo sampling frequency");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "bufsize");
RNA_def_property_range(prop, 512, 10240);
RNA_def_property_ui_text(prop, "Shadow Buffer Size",
"Resolution of the shadow buffer, higher values give crisper shadows "
"but use more memory");
RNA_def_property_int_funcs(prop, NULL, "rna_Lamp_buffer_size_set", NULL);
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "filtertype");
RNA_def_property_enum_items(prop, prop_shadbuffiltertype_items);
RNA_def_property_ui_text(prop, "Shadow Filter Type", "Type of shadow filter (Buffer Shadows)");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_sample_buffers", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "buffers");
RNA_def_property_enum_items(prop, prop_numbuffer_items);
RNA_def_property_ui_text(prop, "Shadow Sample Buffers",
"Number of shadow buffers to render for better AA, this increases memory usage");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "spot_blend", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spotblend");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -694,61 +801,6 @@ static void rna_def_spot_lamp(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Cone",
"Draw transparent cone in 3D view to visualize which objects are contained in it");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "shadow_buffer_clip_start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipsta");
RNA_def_property_range(prop, 0.0f, 9999.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Clip Start",
"Shadow map clip start, below which objects will not generate shadows");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "shadow_buffer_clip_end", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipend");
RNA_def_property_range(prop, 0.0f, 9999.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Clip End",
"Shadow map clip end, beyond which objects will not generate shadows");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "shadow_buffer_bias", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bias");
RNA_def_property_range(prop, 0.001f, 5.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Bias", "Shadow buffer sampling bias");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_soft", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "soft");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Shadow Buffer Soft", "Size of shadow buffer sampling area");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samp");
RNA_def_property_range(prop, 1, 16);
RNA_def_property_ui_text(prop, "Samples", "Number of shadow buffer samples");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "shadow_buffer_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "buftype");
RNA_def_property_enum_items(prop, prop_shadbuftype_items);
RNA_def_property_ui_text(prop, "Shadow Buffer Type", "Type of shadow buffer");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
prop = RNA_def_property(srna, "use_auto_clip_start", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_START);
RNA_def_property_ui_text(prop, "Autoclip Start",
"Automatic calculation of clipping-start, based on visible vertices");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "use_auto_clip_end", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_END);
RNA_def_property_ui_text(prop, "Autoclip End", "Automatic calculation of clipping-end, based on visible vertices");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "compression_threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "compressthresh");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Compress", "Deep shadow map compression threshold");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
}
static void rna_def_sun_lamp(BlenderRNA *brna)
@@ -771,6 +823,13 @@ static void rna_def_sun_lamp(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Sky Settings", "Sky related settings for sun lamps");
rna_def_lamp_sky_settings(brna);
/* BGE Only */
prop= RNA_def_property(srna, "shadow_frustum_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shadow_frustum_size");
RNA_def_property_ui_range(prop, 0.001, 100.0, 2, 1);
RNA_def_property_ui_text(prop, "Frustum Size", "Size of the frustum used for creating the shadow map");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
}
static void rna_def_hemi_lamp(BlenderRNA *brna)

View File

@@ -45,6 +45,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_lamp_types.h"
#include "GPU_material.h"
KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
@@ -267,6 +268,22 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
GPU_lamp_shadow_buffer_unbind(lamp);
}
struct Image *KX_LightObject::GetTextureImage(short texslot)
{
Lamp *la = (Lamp*)GetBlenderObject()->data;
if (texslot >= MAX_MTEX || texslot < 0)
{
printf("KX_LightObject::GetTextureImage(): texslot exceeds slot bounds (0-%d)\n", MAX_MTEX-1);
return NULL;
}
if (la->mtex[texslot])
return la->mtex[texslot]->tex->ima;
return NULL;
}
#ifdef WITH_PYTHON
/* ------------------------------------------------------------------------- */
/* Python Integration Hooks */

View File

@@ -66,6 +66,7 @@ public:
int GetShadowLayer();
void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans);
void UnbindShadowBuffer(class RAS_IRasterizer *ras);
struct Image *GetTextureImage(short texslot);
void Update();
void UpdateScene(class KX_Scene *kxscene) {m_lightobj.m_scene = (void*)kxscene;}

View File

@@ -30,6 +30,7 @@ http://www.gnu.org/copyleft/lesser.txt.
#include <structmember.h>
#include <KX_GameObject.h>
#include <KX_Light.h>
#include <RAS_MeshObject.h>
#include <DNA_mesh_types.h>
#include <DNA_meshdata_types.h>
@@ -59,6 +60,7 @@ http://www.gnu.org/copyleft/lesser.txt.
// Blender GameObject type
BlendType<KX_GameObject> gameObjectType ("KX_GameObject");
BlendType<KX_LightObject> lightObjectType ("KX_LightObject");
// load texture
@@ -105,6 +107,16 @@ RAS_IPolyMaterial * getMaterial (PyObject *obj, short matID)
return NULL;
}
// get pointer to a lamp
KX_LightObject * getLamp(PyObject *obj)
{
// if object is available
if (obj == NULL) return NULL;
// returns NULL if obj is not a KX_LightObject
return lightObjectType.checkType(obj);
}
// get material ID
short getMaterialID(PyObject * obj, const char *name)
@@ -206,6 +218,7 @@ int Texture_init (Texture *self, PyObject *args, PyObject *kwds)
{
// get pointer to texture image
RAS_IPolyMaterial * mat = getMaterial(obj, matID);
KX_LightObject * lamp = getLamp(obj);
if (mat != NULL)
{
// is it blender material or polygon material
@@ -227,6 +240,12 @@ int Texture_init (Texture *self, PyObject *args, PyObject *kwds)
self->m_useMatTexture = false;
}
}
else if (lamp != NULL)
{
self->m_imgTexture = lamp->GetTextureImage(texID);
self->m_useMatTexture = false;
}
// check if texture is available, if not, initialization failed
if (self->m_imgTexture == NULL && self->m_matTexture == NULL)
// throw exception if initialization failed