diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 116eb48bf88..86916a37d43 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2481,13 +2481,14 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object } } -static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) +static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d) { ListBase shadows; View3DShadow *shadow; Scene *sce_iter; Base *base; Object *ob; + World *world = scene->world; SceneRenderLayer *srl = v3d->scenelock ? BLI_findlink(&scene->r.layers, scene->r.actlay) : NULL; BLI_listbase_clear(&shadows); @@ -2552,6 +2553,14 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) } BLI_freelistN(&shadows); + + /* update world values */ + if (world) { + GPU_mist_update_enable(world->mode & WO_MIST); + GPU_mist_update_values(world->mistype, world->miststa, world->mistdist, world->misi, &world->horr); + GPU_horizon_update_color(&world->horr); + GPU_ambient_update_color(&world->ambr); + } } /* *********************** customdata **************** */ @@ -2875,7 +2884,7 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) { /* shadow buffers, before we setup matrices */ if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) - gpu_update_lamps_shadows(scene, v3d); + gpu_update_lamps_shadows_world(scene, v3d); } /* @@ -3527,8 +3536,8 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3 /* shadow buffers, before we setup matrices */ if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) - gpu_update_lamps_shadows(scene, v3d); - + gpu_update_lamps_shadows_world(scene, v3d); + /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */ if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) { rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE; diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 2d21b1aeb1d..e27916e5bf7 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -149,6 +149,14 @@ typedef enum GPUDynamicType { GPU_DYNAMIC_LAMP_ATT2 = 18, GPU_DYNAMIC_LAMP_SPOTSIZE = 19, GPU_DYNAMIC_LAMP_SPOTBLEND = 20, + GPU_DYNAMIC_MIST_ENABLE = 21, + GPU_DYNAMIC_MIST_START = 22, + GPU_DYNAMIC_MIST_DISTANCE = 23, + GPU_DYNAMIC_MIST_INTENSITY = 24, + GPU_DYNAMIC_MIST_TYPE = 25, + GPU_DYNAMIC_MIST_COLOR = 26, + GPU_DYNAMIC_HORIZON_COLOR = 27, + GPU_DYNAMIC_AMBIENT_COLOR = 28, } GPUDynamicType; GPUNodeLink *GPU_attribute(CustomDataType type, const char *name); @@ -273,6 +281,12 @@ void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); int GPU_lamp_shadow_layer(GPULamp *lamp); GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow, GPUNodeLink **energy); +/* World */ +void GPU_mist_update_enable(short enable); +void GPU_mist_update_values(int type, float start, float dist, float inten, float color[3]); +void GPU_horizon_update_color(float color[3]); +void GPU_ambient_update_color(float color[3]); + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index a9c35896a89..480972d161f 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -76,6 +76,16 @@ typedef enum DynMatProperty { DYN_LAMP_PERSMAT = 8, } DynMatProperty; +static struct GPUWorld { + float mistenabled; + float mistype; + float miststart; + float mistdistance; + float mistintensity; + float mistcol[4]; + float horicol[3]; + float ambcol[4]; +} GPUWorld; struct GPUMaterial { Scene *scene; @@ -1469,13 +1479,39 @@ void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); } +void GPU_mist_update_enable(short enable) +{ + GPUWorld.mistenabled = (float)enable; +} + +void GPU_mist_update_values(int type, float start, float dist, float inten, float color[3]) +{ + GPUWorld.mistype = (float)type; + GPUWorld.miststart = start; + GPUWorld.mistdistance = dist; + GPUWorld.mistintensity = inten; + copy_v3_v3(GPUWorld.mistcol, color); + GPUWorld.mistcol[3] = 1.0f; +} + +void GPU_horizon_update_color(float color[3]) +{ + copy_v3_v3(GPUWorld.horicol, color); +} + +void GPU_ambient_update_color(float color[3]) +{ + copy_v3_v3(GPUWorld.ambcol, color); + GPUWorld.ambcol[3] = 1.0f; +} + void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) { GPUMaterial *mat = shi->gpumat; GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac; Material *ma = shi->mat; World *world = mat->scene->world; - float linfac, logfac, misttype; + float linfac, logfac; memset(shr, 0, sizeof(*shr)); @@ -1526,10 +1562,10 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) } /* ambient color */ - if (world->ambr != 0.0f || world->ambg != 0.0f || world->ambb != 0.0f) { - if (GPU_link_changed(shi->amb) || ma->amb != 0.0f) - GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb), - GPU_uniform(&world->ambr), &shr->combined); + if (GPU_link_changed(shi->amb) || ma->amb != 0.0f) { + GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb), + GPU_dynamic_uniform(GPUWorld.ambcol, GPU_DYNAMIC_AMBIENT_COLOR, NULL), + &shr->combined); } } @@ -1551,21 +1587,22 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) if (ma->shade_flag & MA_OBCOLOR) GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); - if (world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) { - misttype = world->mistype; - + if (!(ma->mode & MA_NOMIST)) { GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION), - GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist), - GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac); + GPU_dynamic_uniform(&GPUWorld.mistenabled, GPU_DYNAMIC_MIST_ENABLE, NULL), + GPU_dynamic_uniform(&GPUWorld.miststart, GPU_DYNAMIC_MIST_START, NULL), + GPU_dynamic_uniform(&GPUWorld.mistdistance, GPU_DYNAMIC_MIST_DISTANCE, NULL), + GPU_dynamic_uniform(&GPUWorld.mistype, GPU_DYNAMIC_MIST_TYPE, NULL), + GPU_dynamic_uniform(&GPUWorld.mistintensity, GPU_DYNAMIC_MIST_INTENSITY, NULL), &mistfac); GPU_link(mat, "mix_blend", mistfac, shr->combined, - GPU_uniform(&world->horr), &shr->combined); + GPU_dynamic_uniform(GPUWorld.mistcol, GPU_DYNAMIC_MIST_COLOR, NULL), &shr->combined); } if (!mat->alpha) { if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f)) - GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr), - shr->combined, &shr->combined); + GPU_link(mat, "shade_world_mix", GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL), + shr->combined, &shr->combined); GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined); } diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 5268dea5d55..8edffe787eb 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2099,18 +2099,23 @@ void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outco outcol = linfac*(1.0 - exp(col*logfac)); } -void shade_mist_factor(vec3 co, float miststa, float mistdist, float misttype, float misi, out float outfac) +void shade_mist_factor(vec3 co, float enable, float miststa, float mistdist, float misttype, float misi, out float outfac) { - float fac, zcor; + if(enable == 1.0) { + float fac, zcor; - zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2]; - - fac = clamp((zcor-miststa)/mistdist, 0.0, 1.0); - if(misttype == 0.0) fac *= fac; - else if(misttype == 1.0); - else fac = sqrt(fac); + zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2]; + + fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0); + if(misttype == 0.0) fac *= fac; + else if(misttype == 1.0); + else fac = sqrt(fac); - outfac = 1.0 - (1.0-fac)*(1.0-misi); + outfac = 1.0 - (1.0 - fac) * (1.0 - misi); + } + else { + outfac = 0.0; + } } void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol) diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c index e4580e8035b..b2dc7e866ff 100644 --- a/source/blender/python/intern/gpu.c +++ b/source/blender/python/intern/gpu.c @@ -95,6 +95,14 @@ static PyObject *PyInit_gpu(void) PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DBUFFER); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DIMAGE); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DSHADOW); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_ENABLE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_START); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_DISTANCE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_INTENSITY); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_TYPE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_COLOR); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_HORIZON_COLOR); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_AMBIENT_COLOR); PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1I); PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1F); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 8c6cb2b32d4..2907371267a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -80,6 +80,8 @@ #include "KX_NavMeshObject.h" +#include "GPU_material.h" + #define DEFAULT_LOGIC_TIC_RATE 60.0 //#define DEFAULT_PHYSICS_TIC_RATE 60.0 @@ -975,6 +977,9 @@ void KX_KetsjiEngine::SetBackGround(KX_WorldInfo* wi) wi->getBackColorBlue(), 0.0 ); + + float horicolor[] = {wi->getBackColorRed(), wi->getBackColorGreen(), wi->getBackColorBlue()}; + GPU_horizon_update_color(horicolor); } } } @@ -993,6 +998,9 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi) wi->getAmbientColorBlue() ); + float ambcolor[] = {wi->getAmbientColorRed(), wi->getAmbientColorGreen(), wi->getAmbientColorBlue()}; + GPU_ambient_update_color(ambcolor); + if (wi->hasMist()) { m_rasterizer->SetFog( @@ -1004,10 +1012,22 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi) wi->getMistColorGreen(), wi->getMistColorBlue() ); + + float mistcolor[] = {wi->getMistColorRed(), wi->getMistColorGreen(), wi->getMistColorBlue()}; + GPU_mist_update_values( + wi->getMistType(), + wi->getMistStart(), + wi->getMistDistance(), + wi->getMistIntensity(), + mistcolor + ); + m_rasterizer->EnableFog(true); + GPU_mist_update_enable(true); } else { m_rasterizer->EnableFog(false); + GPU_mist_update_enable(false); } } }