Index: source/blender/render/intern/source/shadeinput.c =================================================================== --- source/blender/render/intern/source/shadeinput.c (revision 12834) +++ source/blender/render/intern/source/shadeinput.c (working copy) @@ -754,6 +754,11 @@ VECCOPY(shi->vn, shi->facenor); } + /* normal in worldspace, used in Diffuse SH IBL, and nodes */ + VECCOPY(shi->worldnor, shi->vn); + Mat4Mul3Vecfl(R.viewinv, shi->worldnor); + VecMulf(shi->worldnor, -1.0f); + /* used in nodes */ VECCOPY(shi->vno, shi->vn); Index: source/blender/render/intern/source/shadeoutput.c =================================================================== --- source/blender/render/intern/source/shadeoutput.c (revision 12834) +++ source/blender/render/intern/source/shadeoutput.c (working copy) @@ -1573,6 +1573,10 @@ } } + /* ibl, adds results in diff and shad pass */ + if(R.wrld.mode & WO_IMAGE_BASED_LIGHTING) + image_based_lighting(shi, shr); + /* lighting pass */ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) { GroupObject *go; Index: source/blender/render/intern/source/convertblender.c =================================================================== --- source/blender/render/intern/source/convertblender.c (revision 12834) +++ source/blender/render/intern/source/convertblender.c (working copy) @@ -4241,8 +4241,17 @@ init_render_hammersley(re); else if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT) init_ao_sphere(&re->wrld); + + if (re->wrld.aocolor == WO_AODIFFUSESH) + ibl_diffusesh_prefilter(re); } + if(re->wrld.mode & WO_IMAGE_BASED_LIGHTING) { + if (re->wrld.ibl_method == WO_IBL_DIFFUSESH) { + ibl_diffusesh_prefilter(re); + } + } + /* still bad... doing all */ init_render_textures(re); init_render_materials(re->r.mode, &re->wrld.ambr); Index: source/blender/render/intern/include/render_types.h =================================================================== --- source/blender/render/intern/include/render_types.h (revision 12834) +++ source/blender/render/intern/include/render_types.h (working copy) @@ -33,6 +33,7 @@ /* ------------------------------------------------------------------------- */ #include "DNA_color_types.h" +#include "DNA_image_types.h" #include "DNA_scene_types.h" #include "DNA_world_types.h" #include "DNA_object_types.h" Index: source/blender/render/intern/include/rendercore.h =================================================================== --- source/blender/render/intern/include/rendercore.h (revision 12834) +++ source/blender/render/intern/include/rendercore.h (working copy) @@ -104,5 +104,8 @@ extern void init_render_hammersley(Render *re); extern void free_render_qmcsampler(Render *re); +extern void ibl_diffusesh_prefilter(Render *re); + #endif /* RENDER_EXT_H */ Index: source/blender/render/extern/include/RE_shader_ext.h =================================================================== --- source/blender/render/extern/include/RE_shader_ext.h (revision 12834) +++ source/blender/render/extern/include/RE_shader_ext.h (working copy) @@ -127,6 +127,7 @@ float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[4], rad[3]; float refcol[4], displace[3]; float strand, tang[3], stress, winspeed[4]; + float worldnor[3]; ShadeInputUV uv[8]; /* 8 = MAX_MTFACE */ ShadeInputCol col[8]; /* 8 = MAX_MCOL */ Index: source/blender/python/api2_2x/World.h =================================================================== --- source/blender/python/api2_2x/World.h (revision 12834) +++ source/blender/python/api2_2x/World.h (working copy) @@ -34,6 +34,7 @@ #define EXPP_WORLD_H #include +#include "DNA_image_types.h" #include "DNA_world_types.h" #define BPy_World_Check(v) ((v)->ob_type==&World_Type) Index: source/blender/blenkernel/intern/world.c =================================================================== --- source/blender/blenkernel/intern/world.c (revision 12834) +++ source/blender/blenkernel/intern/world.c (working copy) @@ -37,6 +37,7 @@ #include #include "MEM_guardedalloc.h" +#include "DNA_image_types.h" #include "DNA_world_types.h" #include "DNA_texture_types.h" #include "DNA_scriptlink_types.h" @@ -86,6 +87,7 @@ World *add_world(char *name) { World *wrld; + ImageUser *iuser; wrld= alloc_libblock(&G.main->world, ID_WO, name); @@ -107,6 +109,14 @@ wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default wrld->preview = NULL; + + iuser = &(wrld->ibl_iuser); + + iuser->sfra= 1; + iuser->fie_ima= 2; + iuser->ok= 1; + + wrld->ibl_multiplier = 1.0; return wrld; } Index: source/blender/makesdna/DNA_world_types.h =================================================================== --- source/blender/makesdna/DNA_world_types.h (revision 12834) +++ source/blender/makesdna/DNA_world_types.h (working copy) @@ -39,12 +39,18 @@ struct Ipo; struct MTex; +struct Image; +struct ImageUser; #ifndef MAX_MTEX #define MAX_MTEX 10 #endif +typedef struct Ibl { + float dsh_coeffs[9][3]; +} Ibl; + /** * World defines general modeling data such as a background fill, * gravity, color model, stars, etc. It mixes game-data, rendering @@ -110,13 +116,20 @@ float *aosphere, *aotables; + short ibl_method; + short pad3; + float ibl_multiplier; + struct Image *ibl_image; + struct ImageUser ibl_iuser; struct Ipo *ipo; struct MTex *mtex[10]; /* previews */ struct PreviewImage *preview; - + + float dsh_coeffs[9][3]; + int padblah; ScriptLink scriptlink; } World; @@ -137,6 +150,7 @@ #define WO_DOF 4 #define WO_ACTIVITY_CULLING 8 #define WO_AMB_OCC 16 +#define WO_IMAGE_BASED_LIGHTING 32 /* aomix */ #define WO_AOADD 0 @@ -156,7 +170,11 @@ #define WO_AOPLAIN 0 #define WO_AOSKYCOL 1 #define WO_AOSKYTEX 2 +#define WO_AODIFFUSESH 3 +/* ibl_method */ +#define WO_IBL_DIFFUSESH 0 + /* texco (also in DNA_material_types.h) */ #define TEXCO_ANGMAP 64 #define TEXCO_H_SPHEREMAP 256 Index: source/blender/src/buttons_shading.c =================================================================== --- source/blender/src/buttons_shading.c (revision 12834) +++ source/blender/src/buttons_shading.c (working copy) @@ -2131,13 +2131,70 @@ } +static void world_panel_ibl(World *wrld) +{ + uiBlock *block; + short yco=PANEL_YMAX; + char *strp; + struct ImageUser *iuser= &(wrld->ibl_iuser); + uiBut *but; + + block= uiNewBlock(&curarea->uiblocks, "world_panel_ibl", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Amb Occ", "World"); + if(uiNewPanel(curarea, block, "Image Based Lighting", "World", PANELX, PANELY, PANELW, PANELH)==0) return; + + uiDefButBitS(block, TOG, WO_IMAGE_BASED_LIGHTING, B_REDR, "Image Based Lighting", + X2CLM1, yco-=BUTH, BUTW1, BUTH, &wrld->mode, 0, 0, 0, 0, "Enables lighting from an environment image (light probe)"); + + yco -= YSPACE; + + uiDefButF(block, NUM, B_REDR, "Multiplier:", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->ibl_multiplier, 0.0, 100.0, 1.0, 0, "Multiply the final result to brighten or darken the lighting"); + + uiDefButS(block, MENU, B_REDR, "Calculation Method %t|Diffuse Irradiance (Spherical Harmonics) %x0", + X2CLM2, yco, BUTW2, BUTH, &wrld->ibl_method, 0, 0, 0, 0, ""); + + yco -= YSPACE; + + /* Browse */ + IMAnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), NULL, &iuser->menunr); + + uiBlockBeginAlign(block); + but= uiDefButS(block, MENU, B_REDR, strp, + X2CLM1, yco-=BUTH, ICONBUTW, BUTH, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie"); + uiButSetFunc(but, image_browse_cb, &(wrld->ibl_image), iuser); + + MEM_freeN(strp); + + if (wrld->ibl_image != NULL) { + if (wrld->ibl_image->source != IMA_SRC_FILE) { + uiDefBut(block, LABEL, 0, "Still images only", + X2CLM1, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); /* for align in panel */ + return; + } + uiSetButLock(wrld->ibl_image->id.lib!=NULL, ERROR_LIBDATA_MESSAGE); + + but= uiDefBut(block, TEX, B_IDNAME, "IM:", + X2CLM1+ICONBUTW, yco, BUTW2-ICONBUTW, BUTH, wrld->ibl_image->id.name+2, 0.0, 21.0, 0, 0, "Current Image Datablock name."); + uiButSetFunc(but, test_idbutton_cb, wrld->ibl_image->id.name, NULL); + + but= uiDefIconBut(block, BUT, B_REDR, ICON_X, + X2CLM2, yco, ICONBUTW, BUTH, 0, 0, 0, 0, 0, "Unlink Image block"); + uiButSetFunc(but, image_unlink_cb, &(wrld->ibl_image), NULL); + + } else { + but= uiDefBut(block, BUT, B_REDR, "Load", + X2CLM1+ICONBUTW, yco, BUTW2-ICONBUTW, BUTH, NULL, 0, 0, 0, 0, "Load new Image"); + uiButSetFunc(but, image_load_fs_cb, &(wrld->ibl_image), iuser); + } +} + static void world_panel_amb_occ(World *wrld) { uiBlock *block; short yco=PANEL_YMAX; block= uiNewBlock(&curarea->uiblocks, "world_panel_amb_oc", UI_EMBOSS, UI_HELV, curarea->win); - uiNewPanelTabbed("Mist / Stars / Physics", "World"); if(uiNewPanel(curarea, block, "Amb Occ", "World", PANELX, PANELY, PANELW, PANELH)==0) return; uiBlockSetCol(block, TH_BUT_SETTING1); @@ -2203,12 +2260,8 @@ /* color treatment */ uiBlockBeginAlign(block); - uiDefButS(block, ROW, B_REDR, "Plain", - X3CLM1, yco-=BUTH, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)"); - uiDefButS(block, ROW, B_REDR, "Sky Color", - X3CLM2, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy"); - uiDefButS(block, ROW, B_REDR, "Sky Texture", - X3CLM3, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy"); + uiDefButS(block, MENU, B_REDR, "Plain %x0|Sky Color %x1|Sky Texture %x2|Diffuse SH %x3", + X3CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aocolor, 0.0, (float)WO_AOPLAIN, 0, 0, ""); uiBlockEndAlign(block); yco -= YSPACE; @@ -4229,6 +4282,7 @@ if(wrld) { world_panel_mistaph(wrld); world_panel_amb_occ(wrld); + world_panel_ibl(wrld); world_panel_texture(wrld); world_panel_mapto(wrld); } Index: source/blender/blenloader/intern/readfile.c =================================================================== --- source/blender/blenloader/intern/readfile.c (revision 12834) +++ source/blender/blenloader/intern/readfile.c (working copy) @@ -7196,6 +7196,8 @@ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 11)) { Object *ob; bActionStrip *strip; + World *wrld; + ImageUser *iuser; /* nla-strips - scale */ for (ob= main->object.first; ob; ob= ob->id.next) { @@ -7215,6 +7217,16 @@ if (strip->scale == 0.0f) strip->scale= 1.0f; } } + + for(wrld=main->world.first; wrld; wrld= wrld->id.next) { + iuser = &(wrld->ibl_iuser); + + iuser->sfra= 1; + iuser->fie_ima= 2; + iuser->ok= 1; + wrld->ibl_multiplier = 1.0; + } + } Index: source/blender/nodes/intern/SHD_util.h =================================================================== --- source/blender/nodes/intern/SHD_util.h (revision 12834) +++ source/blender/nodes/intern/SHD_util.h (working copy) @@ -109,6 +109,7 @@ #define GEOM_OUT_NORMAL 5 #define GEOM_OUT_VCOL 6 #define GEOM_OUT_FRONTBACK 7 +#define GEOM_OUT_WORLDNORMAL 8 /* input socket defines */ Index: source/blender/nodes/intern/SHD_nodes/SHD_geom.c =================================================================== --- source/blender/nodes/intern/SHD_nodes/SHD_geom.c (revision 12834) +++ source/blender/nodes/intern/SHD_nodes/SHD_geom.c (working copy) @@ -39,9 +39,10 @@ { SOCK_VECTOR, 0, "View", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, { SOCK_VECTOR, 0, "Orco", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, { SOCK_VECTOR, 0, "UV", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, - { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VECTOR, 0, "View Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, { SOCK_RGBA, 0, "Vertex Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { SOCK_VALUE, 0, "Front/Back", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "World Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, { -1, 0, "" } }; @@ -73,6 +74,7 @@ VECCOPY(out[GEOM_OUT_ORCO]->vec, shi->lo); VECCOPY(out[GEOM_OUT_UV]->vec, suv->uv); VECCOPY(out[GEOM_OUT_NORMAL]->vec, shi->vno); + VECCOPY(out[GEOM_OUT_WORLDNORMAL]->vec, shi->worldnor); if (shi->totcol) { /* find vertex color layer by name */