BGE: Fix T43592: World GLSL

This patch will fix the world GLSL (mist, background, ambient) update for the BGE.

Reviewers: moguri, brecht

Reviewed By: moguri, brecht

Subscribers: panzergame

Differential Revision: https://developer.blender.org/D151
This commit is contained in:
Thomas Szepe 2015-03-23 22:32:49 +01:00
parent da5fb82a63
commit c73693d4a5
Notes: blender-bot 2023-02-14 09:30:52 +01:00
Referenced by issue #43592, Mist-Color not animatable
6 changed files with 119 additions and 26 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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);

View File

@ -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);
}
}
}