-Add lightmapper
-Fixes to unwrapper (remove degenerates), makes Thekla not crash -Added optional cancel button in EditorProgress -Added function to force processing of events (needed for cancel button)
This commit is contained in:
@@ -1849,6 +1849,20 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE2_ENABLED, false);
|
||||
}
|
||||
} else if (!e->instance->lightmap_capture_data.empty()) {
|
||||
|
||||
glUniform4fv(state.scene_shader.get_uniform_location(SceneShaderGLES3::LIGHTMAP_CAPTURES), 12, (const GLfloat *)e->instance->lightmap_capture_data.ptr());
|
||||
state.scene_shader.set_uniform(SceneShaderGLES3::LIGHTMAP_CAPTURE_SKY, false);
|
||||
|
||||
} else if (e->instance->lightmap.is_valid()) {
|
||||
RasterizerStorageGLES3::Texture *lightmap = storage->texture_owner.getornull(e->instance->lightmap);
|
||||
RasterizerStorageGLES3::LightmapCapture *capture = storage->lightmap_capture_data_owner.getornull(e->instance->lightmap_capture->base);
|
||||
|
||||
if (lightmap && capture) {
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9);
|
||||
glBindTexture(GL_TEXTURE_2D, lightmap->tex_id);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES3::LIGHTMAP_ENERGY, capture->energy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1971,6 +1985,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHTMAP_CAPTURE, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHTMAP, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, false);
|
||||
|
||||
@@ -1978,6 +1994,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
||||
} else {
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, e->instance->gi_probe_instances.size() > 0);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHTMAP, e->instance->lightmap.is_valid() && e->instance->gi_probe_instances.size() == 0);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHTMAP_CAPTURE, !e->instance->lightmap_capture_data.empty() && !e->instance->lightmap.is_valid() && e->instance->gi_probe_instances.size() == 0);
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, false);
|
||||
|
||||
@@ -2148,6 +2166,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHTMAP, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHTMAP_CAPTURE, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, false);
|
||||
@@ -2274,6 +2294,14 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
||||
e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
|
||||
}
|
||||
|
||||
if (e->instance->lightmap.is_valid()) {
|
||||
e->sort_key |= SORT_KEY_LIGHTMAP_FLAG;
|
||||
}
|
||||
|
||||
if (!e->instance->lightmap_capture_data.empty()) {
|
||||
e->sort_key |= SORT_KEY_LIGHTMAP_CAPTURE_FLAG;
|
||||
}
|
||||
|
||||
e->sort_key |= uint64_t(p_material->render_priority + 128) << RenderList::SORT_KEY_PRIORITY_SHIFT;
|
||||
} else {
|
||||
e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
|
||||
|
||||
@@ -662,19 +662,21 @@ public:
|
||||
SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT = 52,
|
||||
SORT_KEY_OPAQUE_DEPTH_LAYER_MASK = 0xF,
|
||||
//64 bits unsupported in MSVC
|
||||
#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 51)
|
||||
#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 50)
|
||||
#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 49)
|
||||
#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 48)
|
||||
SORT_KEY_SHADING_SHIFT = 48,
|
||||
SORT_KEY_SHADING_MASK = 15,
|
||||
//48-32 material index
|
||||
SORT_KEY_MATERIAL_INDEX_SHIFT = 32,
|
||||
//32-12 geometry index
|
||||
SORT_KEY_GEOMETRY_INDEX_SHIFT = 12,
|
||||
//bits 12-8 geometry type
|
||||
SORT_KEY_GEOMETRY_TYPE_SHIFT = 8,
|
||||
//bits 0-7 for flags
|
||||
#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 49)
|
||||
#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 48)
|
||||
#define SORT_KEY_LIGHTMAP_CAPTURE_FLAG (uint64_t(1) << 47)
|
||||
#define SORT_KEY_LIGHTMAP_FLAG (uint64_t(1) << 46)
|
||||
#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 45)
|
||||
#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 44)
|
||||
SORT_KEY_SHADING_SHIFT = 44,
|
||||
SORT_KEY_SHADING_MASK = 63,
|
||||
//44-28 material index
|
||||
SORT_KEY_MATERIAL_INDEX_SHIFT = 28,
|
||||
//28-8 geometry index
|
||||
SORT_KEY_GEOMETRY_INDEX_SHIFT = 8,
|
||||
//bits 5-7 geometry type
|
||||
SORT_KEY_GEOMETRY_TYPE_SHIFT = 5,
|
||||
//bits 0-5 for flags
|
||||
SORT_KEY_OPAQUE_PRE_PASS = 8,
|
||||
SORT_KEY_CULL_DISABLED_FLAG = 4,
|
||||
SORT_KEY_SKELETON_FLAG = 2,
|
||||
|
||||
@@ -5216,6 +5216,104 @@ void RasterizerStorageGLES3::gi_probe_dynamic_data_update(RID p_gi_probe_data, i
|
||||
//glTexImage3D(GL_TEXTURE_3D,p_mipmap,GL_RGBA8,gipd->width>>p_mipmap,gipd->height>>p_mipmap,gipd->depth>>p_mipmap,0,GL_RGBA,GL_UNSIGNED_BYTE,p_data);
|
||||
//glTexImage3D(GL_TEXTURE_3D,p_mipmap,GL_RGBA8,gipd->width>>p_mipmap,gipd->height>>p_mipmap,gipd->depth>>p_mipmap,0,GL_RGBA,GL_UNSIGNED_BYTE,data.ptr());
|
||||
}
|
||||
/////////////////////////////
|
||||
|
||||
RID RasterizerStorageGLES3::lightmap_capture_create() {
|
||||
|
||||
LightmapCapture *capture = memnew(LightmapCapture);
|
||||
return lightmap_capture_data_owner.make_rid(capture);
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) {
|
||||
|
||||
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND(!capture);
|
||||
capture->bounds = p_bounds;
|
||||
capture->instance_change_notify();
|
||||
}
|
||||
AABB RasterizerStorageGLES3::lightmap_capture_get_bounds(RID p_capture) const {
|
||||
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, AABB());
|
||||
return capture->bounds;
|
||||
}
|
||||
void RasterizerStorageGLES3::lightmap_capture_set_octree(RID p_capture, const PoolVector<uint8_t> &p_octree) {
|
||||
|
||||
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND(!capture);
|
||||
|
||||
ERR_FAIL_COND(p_octree.size() == 0 || (p_octree.size() % sizeof(LightmapCaptureOctree)) != 0);
|
||||
|
||||
capture->octree.resize(p_octree.size() / sizeof(LightmapCaptureOctree));
|
||||
if (p_octree.size()) {
|
||||
PoolVector<LightmapCaptureOctree>::Write w = capture->octree.write();
|
||||
PoolVector<uint8_t>::Read r = p_octree.read();
|
||||
copymem(w.ptr(), r.ptr(), p_octree.size());
|
||||
}
|
||||
capture->instance_change_notify();
|
||||
}
|
||||
PoolVector<uint8_t> RasterizerStorageGLES3::lightmap_capture_get_octree(RID p_capture) const {
|
||||
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, PoolVector<uint8_t>());
|
||||
|
||||
if (capture->octree.size() == 0)
|
||||
return PoolVector<uint8_t>();
|
||||
|
||||
PoolVector<uint8_t> ret;
|
||||
ret.resize(capture->octree.size() * sizeof(LightmapCaptureOctree));
|
||||
{
|
||||
PoolVector<LightmapCaptureOctree>::Read r = capture->octree.read();
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
copymem(w.ptr(), r.ptr(), ret.size());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) {
|
||||
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND(!capture);
|
||||
capture->cell_xform = p_xform;
|
||||
}
|
||||
|
||||
Transform RasterizerStorageGLES3::lightmap_capture_get_octree_cell_transform(RID p_capture) const {
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, Transform());
|
||||
return capture->cell_xform;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) {
|
||||
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND(!capture);
|
||||
capture->cell_subdiv = p_subdiv;
|
||||
}
|
||||
|
||||
int RasterizerStorageGLES3::lightmap_capture_get_octree_cell_subdiv(RID p_capture) const {
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, 0);
|
||||
return capture->cell_subdiv;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::lightmap_capture_set_energy(RID p_capture, float p_energy) {
|
||||
|
||||
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND(!capture);
|
||||
capture->energy = p_energy;
|
||||
}
|
||||
|
||||
float RasterizerStorageGLES3::lightmap_capture_get_energy(RID p_capture) const {
|
||||
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, 0);
|
||||
return capture->energy;
|
||||
}
|
||||
|
||||
const PoolVector<RasterizerStorage::LightmapCaptureOctree> *RasterizerStorageGLES3::lightmap_capture_get_octree_ptr(RID p_capture) const {
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, NULL);
|
||||
return &capture->octree;
|
||||
}
|
||||
|
||||
///////
|
||||
|
||||
@@ -5817,6 +5915,10 @@ void RasterizerStorageGLES3::instance_add_dependency(RID p_base, RasterizerScene
|
||||
inst = gi_probe_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;
|
||||
case VS::INSTANCE_LIGHTMAP_CAPTURE: {
|
||||
inst = lightmap_capture_data_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;
|
||||
default: {
|
||||
if (!inst) {
|
||||
ERR_FAIL();
|
||||
@@ -5860,6 +5962,10 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base, RasterizerSc
|
||||
inst = gi_probe_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;
|
||||
case VS::INSTANCE_LIGHTMAP_CAPTURE: {
|
||||
inst = lightmap_capture_data_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;
|
||||
default: {
|
||||
|
||||
if (!inst) {
|
||||
@@ -6609,6 +6715,10 @@ VS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
|
||||
return VS::INSTANCE_GI_PROBE;
|
||||
}
|
||||
|
||||
if (lightmap_capture_data_owner.owns(p_rid)) {
|
||||
return VS::INSTANCE_LIGHTMAP_CAPTURE;
|
||||
}
|
||||
|
||||
return VS::INSTANCE_NONE;
|
||||
}
|
||||
|
||||
@@ -6795,6 +6905,13 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
|
||||
glDeleteTextures(1, &gi_probe_data->tex_id);
|
||||
gi_probe_owner.free(p_rid);
|
||||
memdelete(gi_probe_data);
|
||||
} else if (lightmap_capture_data_owner.owns(p_rid)) {
|
||||
|
||||
// delete the texture
|
||||
LightmapCapture *lightmap_capture = lightmap_capture_data_owner.get(p_rid);
|
||||
|
||||
gi_probe_owner.free(p_rid);
|
||||
memdelete(lightmap_capture);
|
||||
|
||||
} else if (canvas_occluder_owner.owns(p_rid)) {
|
||||
|
||||
|
||||
@@ -1069,6 +1069,38 @@ public:
|
||||
virtual RID gi_probe_dynamic_data_create(int p_width, int p_height, int p_depth, GIProbeCompression p_compression);
|
||||
virtual void gi_probe_dynamic_data_update(RID p_gi_probe_data, int p_depth_slice, int p_slice_count, int p_mipmap, const void *p_data);
|
||||
|
||||
/* LIGHTMAP CAPTURE */
|
||||
|
||||
virtual RID lightmap_capture_create();
|
||||
virtual void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds);
|
||||
virtual AABB lightmap_capture_get_bounds(RID p_capture) const;
|
||||
virtual void lightmap_capture_set_octree(RID p_capture, const PoolVector<uint8_t> &p_octree);
|
||||
virtual PoolVector<uint8_t> lightmap_capture_get_octree(RID p_capture) const;
|
||||
virtual void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform);
|
||||
virtual Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const;
|
||||
virtual void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv);
|
||||
virtual int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const;
|
||||
|
||||
virtual void lightmap_capture_set_energy(RID p_capture, float p_energy);
|
||||
virtual float lightmap_capture_get_energy(RID p_capture) const;
|
||||
|
||||
virtual const PoolVector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const;
|
||||
|
||||
struct LightmapCapture : public Instantiable {
|
||||
|
||||
PoolVector<LightmapCaptureOctree> octree;
|
||||
AABB bounds;
|
||||
Transform cell_xform;
|
||||
int cell_subdiv;
|
||||
float energy;
|
||||
LightmapCapture() {
|
||||
energy = 1.0;
|
||||
cell_subdiv = 1;
|
||||
}
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightmapCapture> lightmap_capture_data_owner;
|
||||
|
||||
/* PARTICLES */
|
||||
|
||||
struct Particles : public GeometryOwner {
|
||||
|
||||
@@ -35,7 +35,7 @@ layout(location=3) in vec4 color_attrib;
|
||||
layout(location=4) in vec2 uv_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_UV2_INTERP)
|
||||
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
|
||||
layout(location=5) in vec2 uv2_attrib;
|
||||
#endif
|
||||
|
||||
@@ -223,7 +223,7 @@ out vec4 color_interp;
|
||||
out vec2 uv_interp;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_UV2_INTERP)
|
||||
#if defined(ENABLE_UV2_INTERP) || defined (USE_LIGHTMAP)
|
||||
out vec2 uv2_interp;
|
||||
#endif
|
||||
|
||||
@@ -234,9 +234,6 @@ out vec3 binormal_interp;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(USE_MATERIAL)
|
||||
|
||||
layout(std140) uniform UniformData { //ubo:1
|
||||
@@ -356,7 +353,7 @@ void main() {
|
||||
uv_interp = uv_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_UV2_INTERP)
|
||||
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
|
||||
uv2_interp = uv2_attrib;
|
||||
#endif
|
||||
|
||||
@@ -549,7 +546,7 @@ in vec4 color_interp;
|
||||
in vec2 uv_interp;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_UV2_INTERP)
|
||||
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
|
||||
in vec2 uv2_interp;
|
||||
#endif
|
||||
|
||||
@@ -1357,7 +1354,7 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
|
||||
|
||||
reflection_accum+=reflection;
|
||||
}
|
||||
|
||||
#ifndef USE_LIGHTMAP
|
||||
if (reflections[idx].ambient.a>0.0) { //compute ambient using skybox
|
||||
|
||||
|
||||
@@ -1403,8 +1400,20 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
|
||||
ambient_accum+=ambient_out;
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_LIGHTMAP
|
||||
uniform mediump sampler2D lightmap; //texunit:-9
|
||||
uniform mediump float lightmap_energy;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTMAP_CAPTURE
|
||||
uniform mediump vec4[12] lightmap_captures;
|
||||
uniform bool lightmap_capture_sky;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_GI_PROBES
|
||||
|
||||
uniform mediump sampler3D gi_probe1; //texunit:-9
|
||||
@@ -1632,7 +1641,7 @@ void main() {
|
||||
vec2 uv = uv_interp;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_UV2_INTERP)
|
||||
#if defined(ENABLE_UV2_INTERP) || defined (USE_LIGHTMAP)
|
||||
vec2 uv2 = uv2_interp;
|
||||
#endif
|
||||
|
||||
@@ -1745,7 +1754,7 @@ FRAGMENT_SHADER_CODE
|
||||
//vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y);
|
||||
|
||||
}
|
||||
|
||||
#ifndef USE_LIGHTMAP
|
||||
{
|
||||
|
||||
vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
|
||||
@@ -1754,6 +1763,7 @@ FRAGMENT_SHADER_CODE
|
||||
ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution);
|
||||
//ambient_light=vec3(0.0,0.0,0.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -1938,6 +1948,48 @@ FRAGMENT_SHADER_CODE
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTMAP
|
||||
ambient_light = texture(lightmap,uv2).rgb * lightmap_energy;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTMAP_CAPTURE
|
||||
{
|
||||
vec3 cone_dirs[12] = vec3[] (
|
||||
vec3(0, 0, 1),
|
||||
vec3(0.866025, 0, 0.5),
|
||||
vec3(0.267617, 0.823639, 0.5),
|
||||
vec3(-0.700629, 0.509037, 0.5),
|
||||
vec3(-0.700629, -0.509037, 0.5),
|
||||
vec3(0.267617, -0.823639, 0.5),
|
||||
vec3(0, 0, -1),
|
||||
vec3(0.866025, 0, -0.5),
|
||||
vec3(0.267617, 0.823639, -0.5),
|
||||
vec3(-0.700629, 0.509037, -0.5),
|
||||
vec3(-0.700629, -0.509037, -0.5),
|
||||
vec3(0.267617, -0.823639, -0.5)
|
||||
);
|
||||
|
||||
|
||||
vec3 local_normal = normalize(camera_matrix * vec4(normal,0.0)).xyz;
|
||||
vec4 captured = vec4(0.0);
|
||||
float sum = 0.0;
|
||||
for(int i=0;i<12;i++) {
|
||||
float amount = max(0.0,dot(local_normal,cone_dirs[i])); //not correct, but creates a nice wrap around effect
|
||||
captured += lightmap_captures[i]*amount;
|
||||
sum+=amount;
|
||||
}
|
||||
|
||||
captured/=sum;
|
||||
|
||||
if (lightmap_capture_sky) {
|
||||
ambient_light = mix( ambient_light, captured.rgb, captured.a);
|
||||
} else {
|
||||
ambient_light = captured.rgb;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_FORWARD_LIGHTING
|
||||
|
||||
|
||||
@@ -1952,11 +2004,11 @@ FRAGMENT_SHADER_CODE
|
||||
} else {
|
||||
specular_light+=env_reflection_light;
|
||||
}
|
||||
|
||||
#ifndef USE_LIGHTMAP
|
||||
if (ambient_accum.a>0.0) {
|
||||
ambient_light+=ambient_accum.rgb/ambient_accum.a;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_VERTEX_LIGHTING
|
||||
|
||||
Reference in New Issue
Block a user