-Lightmap and lightmap capture support for GLES2
-Added hint to not show some properties when running on low end gfx
This commit is contained in:
parent
4db2db2d6b
commit
c83742ba86
19 changed files with 295 additions and 59 deletions
|
@ -116,6 +116,7 @@ enum PropertyUsageFlags {
|
|||
PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 19,
|
||||
PROPERTY_USAGE_INTERNAL = 1 << 20,
|
||||
PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 21, // If the object is duplicated also this property will be duplicated
|
||||
PROPERTY_USAGE_HIGH_END_GFX = 1 << 22,
|
||||
|
||||
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
|
||||
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
|
||||
|
|
|
@ -803,6 +803,8 @@ public:
|
|||
_create_func = _create_current;
|
||||
}
|
||||
|
||||
virtual bool is_low_end() const { return true; }
|
||||
|
||||
RasterizerDummy() {}
|
||||
~RasterizerDummy() {}
|
||||
};
|
||||
|
|
|
@ -66,6 +66,8 @@ public:
|
|||
static void make_current();
|
||||
static void register_config();
|
||||
|
||||
virtual bool is_low_end() const { return true; }
|
||||
|
||||
RasterizerGLES2();
|
||||
~RasterizerGLES2();
|
||||
};
|
||||
|
|
|
@ -2028,6 +2028,10 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
RasterizerStorageGLES2::Texture *prev_lightmap = NULL;
|
||||
float lightmap_energy = 1.0;
|
||||
bool prev_use_lightmap_capture = false;
|
||||
|
||||
for (int i = 0; i < p_element_count; i++) {
|
||||
RenderList::Element *e = p_elements[i];
|
||||
|
||||
|
@ -2039,6 +2043,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
LightInstance *light = NULL;
|
||||
ReflectionProbeInstance *refprobe_1 = NULL;
|
||||
ReflectionProbeInstance *refprobe_2 = NULL;
|
||||
RasterizerStorageGLES2::Texture *lightmap = NULL;
|
||||
bool use_lightmap_capture = false;
|
||||
|
||||
if (!p_shadow) {
|
||||
|
||||
|
@ -2147,15 +2153,44 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE1, refprobe_1 != NULL);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE2, refprobe_2 != NULL);
|
||||
if (refprobe_1 != NULL && refprobe_1 != prev_refprobe_1) {
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, refprobe_1->cubemap);
|
||||
}
|
||||
if (refprobe_2 != NULL && refprobe_2 != prev_refprobe_2) {
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, refprobe_2->cubemap);
|
||||
}
|
||||
rebind = true;
|
||||
}
|
||||
|
||||
use_lightmap_capture = !unshaded && !accum_pass && !e->instance->lightmap_capture_data.empty();
|
||||
|
||||
if (use_lightmap_capture != prev_use_lightmap_capture) {
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP_CAPTURE, use_lightmap_capture);
|
||||
rebind = true;
|
||||
}
|
||||
|
||||
if (!unshaded && !accum_pass && e->instance->lightmap.is_valid()) {
|
||||
|
||||
lightmap = storage->texture_owner.getornull(e->instance->lightmap);
|
||||
lightmap_energy = 1.0;
|
||||
if (lightmap) {
|
||||
RasterizerStorageGLES2::LightmapCapture *capture = storage->lightmap_capture_data_owner.getornull(e->instance->lightmap_capture->base);
|
||||
if (capture) {
|
||||
lightmap_energy = capture->energy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lightmap != prev_lightmap) {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP, lightmap != NULL);
|
||||
if (lightmap != NULL) {
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
|
||||
glBindTexture(GL_TEXTURE_2D, lightmap->tex_id);
|
||||
}
|
||||
rebind = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool instancing = e->instancing;
|
||||
|
@ -2224,6 +2259,10 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
if (refprobe_1 || refprobe_2) {
|
||||
_setup_refprobes(refprobe_1, refprobe_2, p_view_transform, p_env);
|
||||
}
|
||||
|
||||
if (lightmap) {
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHTMAP_ENERGY, lightmap_energy);
|
||||
}
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, view_transform_inverse);
|
||||
|
@ -2239,6 +2278,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
|
||||
|
||||
if (use_lightmap_capture) { //this is per instance, must be set always if present
|
||||
glUniform4fv(state.scene_shader.get_uniform_location(SceneShaderGLES2::LIGHTMAP_CAPTURES), 12, (const GLfloat *)e->instance->lightmap_capture_data.ptr());
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHTMAP_CAPTURE_SKY, false);
|
||||
}
|
||||
|
||||
_render_geometry(e);
|
||||
|
||||
prev_geometry = e->geometry;
|
||||
|
@ -2248,6 +2292,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
prev_light = light;
|
||||
prev_refprobe_1 = refprobe_1;
|
||||
prev_refprobe_2 = refprobe_2;
|
||||
prev_lightmap = lightmap;
|
||||
prev_use_lightmap_capture = use_lightmap_capture;
|
||||
}
|
||||
|
||||
_setup_light_type(NULL, NULL); //clear light stuff
|
||||
|
@ -2260,6 +2306,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_VERTEX_LIGHTING, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE1, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE2, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP_CAPTURE, false);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) {
|
||||
|
@ -2818,6 +2866,44 @@ void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) {
|
|||
}
|
||||
|
||||
bool RasterizerSceneGLES2::free(RID p_rid) {
|
||||
|
||||
if (light_instance_owner.owns(p_rid)) {
|
||||
|
||||
LightInstance *light_instance = light_instance_owner.getptr(p_rid);
|
||||
|
||||
//remove from shadow atlases..
|
||||
for (Set<RID>::Element *E = light_instance->shadow_atlases.front(); E; E = E->next()) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get(E->get());
|
||||
ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_rid));
|
||||
uint32_t key = shadow_atlas->shadow_owners[p_rid];
|
||||
uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
||||
uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK;
|
||||
|
||||
shadow_atlas->quadrants[q].shadows.write[s].owner = RID();
|
||||
shadow_atlas->shadow_owners.erase(p_rid);
|
||||
}
|
||||
|
||||
light_instance_owner.free(p_rid);
|
||||
memdelete(light_instance);
|
||||
|
||||
} else if (shadow_atlas_owner.owns(p_rid)) {
|
||||
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get(p_rid);
|
||||
shadow_atlas_set_size(p_rid, 0);
|
||||
shadow_atlas_owner.free(p_rid);
|
||||
memdelete(shadow_atlas);
|
||||
} else if (reflection_probe_instance_owner.owns(p_rid)) {
|
||||
|
||||
ReflectionProbeInstance *reflection_instance = reflection_probe_instance_owner.get(p_rid);
|
||||
|
||||
reflection_probe_release_atlas_index(p_rid);
|
||||
reflection_probe_instance_owner.free(p_rid);
|
||||
memdelete(reflection_instance);
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -496,22 +496,6 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
|
|||
glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
//set swizle for older format compatibility
|
||||
#ifdef GLES_OVER_GL
|
||||
switch (texture->format) {
|
||||
|
||||
case Image::FORMAT_L8: {
|
||||
|
||||
} break;
|
||||
case Image::FORMAT_LA8: {
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
||||
} break;
|
||||
}
|
||||
#endif
|
||||
|
||||
int mipmaps = ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1;
|
||||
|
||||
int w = img->get_width();
|
||||
|
@ -591,7 +575,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
|
|||
|
||||
PoolVector<uint8_t> data;
|
||||
|
||||
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0);
|
||||
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1);
|
||||
|
||||
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
|
||||
PoolVector<uint8_t>::Write wb = data.write();
|
||||
|
@ -3595,46 +3579,100 @@ void RasterizerStorageGLES2::gi_probe_dynamic_data_update(RID p_gi_probe_data, i
|
|||
///////
|
||||
|
||||
RID RasterizerStorageGLES2::lightmap_capture_create() {
|
||||
return RID();
|
||||
|
||||
LightmapCapture *capture = memnew(LightmapCapture);
|
||||
return lightmap_capture_data_owner.make_rid(capture);
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES2::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 RasterizerStorageGLES2::lightmap_capture_get_bounds(RID p_capture) const {
|
||||
return AABB();
|
||||
}
|
||||
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, AABB());
|
||||
return capture->bounds;
|
||||
}
|
||||
void RasterizerStorageGLES2::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> RasterizerStorageGLES2::lightmap_capture_get_octree(RID p_capture) const {
|
||||
return PoolVector<uint8_t>();
|
||||
|
||||
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 RasterizerStorageGLES2::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 RasterizerStorageGLES2::lightmap_capture_get_octree_cell_transform(RID p_capture) const {
|
||||
return Transform();
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, Transform());
|
||||
return capture->cell_xform;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES2::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 RasterizerStorageGLES2::lightmap_capture_get_octree_cell_subdiv(RID p_capture) const {
|
||||
return 0;
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, 0);
|
||||
return capture->cell_subdiv;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES2::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 RasterizerStorageGLES2::lightmap_capture_get_energy(RID p_capture) const {
|
||||
return 0.0;
|
||||
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, 0);
|
||||
return capture->energy;
|
||||
}
|
||||
|
||||
const PoolVector<RasterizerStorage::LightmapCaptureOctree> *RasterizerStorageGLES2::lightmap_capture_get_octree_ptr(RID p_capture) const {
|
||||
return NULL;
|
||||
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
|
||||
ERR_FAIL_COND_V(!capture, NULL);
|
||||
return &capture->octree;
|
||||
}
|
||||
|
||||
///////
|
||||
|
@ -3773,10 +3811,10 @@ void RasterizerStorageGLES2::instance_add_dependency(RID p_base, RasterizerScene
|
|||
inst = gi_probe_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;*/
|
||||
/*case VS::INSTANCE_LIGHTMAP_CAPTURE: {
|
||||
case VS::INSTANCE_LIGHTMAP_CAPTURE: {
|
||||
inst = lightmap_capture_data_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;*/
|
||||
} break;
|
||||
default: {
|
||||
if (!inst) {
|
||||
ERR_FAIL();
|
||||
|
@ -3819,11 +3857,11 @@ void RasterizerStorageGLES2::instance_remove_dependency(RID p_base, RasterizerSc
|
|||
/*case VS::INSTANCE_GI_PROBE: {
|
||||
inst = gi_probe_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;
|
||||
} break; */
|
||||
case VS::INSTANCE_LIGHTMAP_CAPTURE: {
|
||||
inst = lightmap_capture_data_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;*/
|
||||
} break;
|
||||
default: {
|
||||
|
||||
if (!inst) {
|
||||
|
@ -4094,6 +4132,8 @@ VS::InstanceType RasterizerStorageGLES2::get_base_type(RID p_rid) const {
|
|||
return VS::INSTANCE_IMMEDIATE;
|
||||
} else if (reflection_probe_owner.owns(p_rid)) {
|
||||
return VS::INSTANCE_REFLECTION_PROBE;
|
||||
} else if (lightmap_capture_data_owner.owns(p_rid)) {
|
||||
return VS::INSTANCE_LIGHTMAP_CAPTURE;
|
||||
} else {
|
||||
return VS::INSTANCE_NONE;
|
||||
}
|
||||
|
@ -4281,7 +4321,15 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
|
|||
memdelete(reflection_probe);
|
||||
|
||||
return true;
|
||||
} else if (lightmap_capture_data_owner.owns(p_rid)) {
|
||||
|
||||
// delete the texture
|
||||
LightmapCapture *lightmap_capture = lightmap_capture_data_owner.get(p_rid);
|
||||
lightmap_capture->instance_remove_deps();
|
||||
|
||||
lightmap_capture_data_owner.free(p_rid);
|
||||
memdelete(lightmap_capture);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1046,6 +1046,21 @@ public:
|
|||
|
||||
/* LIGHTMAP */
|
||||
|
||||
struct LightmapCapture : public Instanciable {
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
|
@ -27,15 +27,15 @@ attribute vec3 normal_attrib; // attrib:1
|
|||
attribute vec4 tangent_attrib; // attrib:2
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR_INTERP
|
||||
#if defined(ENABLE_COLOR_INTERP)
|
||||
attribute vec4 color_attrib; // attrib:3
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV_INTERP
|
||||
#if defined(ENABLE_UV_INTERP)
|
||||
attribute vec2 uv_attrib; // attrib:4
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2_INTERP
|
||||
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
|
||||
attribute vec2 uv2_attrib; // attrib:5
|
||||
#endif
|
||||
|
||||
|
@ -102,15 +102,15 @@ varying vec3 tangent_interp;
|
|||
varying vec3 binormal_interp;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR_INTERP
|
||||
#if defined(ENABLE_COLOR_INTERP)
|
||||
varying vec4 color_interp;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV_INTERP
|
||||
#if defined(ENABLE_UV_INTERP)
|
||||
varying vec2 uv_interp;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2_INTERP
|
||||
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
|
||||
varying vec2 uv2_interp;
|
||||
#endif
|
||||
|
||||
|
@ -317,18 +317,18 @@ void main() {
|
|||
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR_INTERP
|
||||
#if defined(ENABLE_COLOR_INTERP)
|
||||
color_interp = color_attrib;
|
||||
#ifdef USE_INSTANCING
|
||||
color_interp *= instance_color;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV_INTERP
|
||||
#if defined(ENABLE_UV_INTERP)
|
||||
uv_interp = uv_attrib;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2_INTERP
|
||||
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
|
||||
uv2_interp = uv2_attrib;
|
||||
#endif
|
||||
|
||||
|
@ -521,7 +521,7 @@ VERTEX_SHADER_CODE
|
|||
|
||||
#if defined(LIGHT_USE_PSSM4)
|
||||
shadow_coord3 = light_shadow_matrix3 * vi4;
|
||||
shadow_coord3 = light_shadow_matrix3 * vi4;
|
||||
shadow_coord4 = light_shadow_matrix4 * vi4;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -612,7 +612,7 @@ uniform mat4 world_transform;
|
|||
|
||||
uniform highp float time;
|
||||
|
||||
#ifdef SCREEN_UV_USED
|
||||
#if defined(SCREEN_UV_USED)
|
||||
uniform vec2 screen_pixel_size;
|
||||
#endif
|
||||
|
||||
|
@ -643,7 +643,7 @@ uniform mat4 refprobe1_local_matrix;
|
|||
|
||||
uniform bool refprobe1_exterior;
|
||||
|
||||
uniform highp samplerCube reflection_probe1; //texunit:-4
|
||||
uniform highp samplerCube reflection_probe1; //texunit:-5
|
||||
|
||||
uniform float refprobe1_intensity;
|
||||
uniform vec4 refprobe1_ambient;
|
||||
|
@ -670,7 +670,7 @@ uniform mat4 refprobe2_local_matrix;
|
|||
|
||||
uniform bool refprobe2_exterior;
|
||||
|
||||
uniform highp samplerCube reflection_probe2; //texunit:-5
|
||||
uniform highp samplerCube reflection_probe2; //texunit:-6
|
||||
|
||||
uniform float refprobe2_intensity;
|
||||
uniform vec4 refprobe2_ambient;
|
||||
|
@ -773,7 +773,16 @@ void reflection_process(samplerCube reflection_map,
|
|||
|
||||
#endif //use refprobe 1 or 2
|
||||
|
||||
#ifdef USE_LIGHTMAP
|
||||
uniform mediump sampler2D lightmap; //texunit:-4
|
||||
uniform mediump float lightmap_energy;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTMAP_CAPTURE
|
||||
uniform mediump vec4[12] lightmap_captures;
|
||||
uniform bool lightmap_capture_sky;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_RADIANCE_MAP
|
||||
|
||||
|
@ -866,15 +875,15 @@ varying vec3 tangent_interp;
|
|||
varying vec3 binormal_interp;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR_INTERP
|
||||
#if defined(ENABLE_COLOR_INTERP)
|
||||
varying vec4 color_interp;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV_INTERP
|
||||
#if defined(ENABLE_UV_INTERP)
|
||||
varying vec2 uv_interp;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2_INTERP
|
||||
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
|
||||
varying vec2 uv2_interp;
|
||||
#endif
|
||||
|
||||
|
@ -1285,11 +1294,11 @@ void main() {
|
|||
#endif
|
||||
float normaldepth = 1.0;
|
||||
|
||||
#ifdef ALPHA_SCISSOR_USED
|
||||
#if defined(ALPHA_SCISSOR_USED)
|
||||
float alpha_scissor = 0.5;
|
||||
#endif
|
||||
|
||||
#ifdef SCREEN_UV_USED
|
||||
#if defined(SCREEN_UV_USED)
|
||||
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
|
||||
#endif
|
||||
|
||||
|
@ -1319,7 +1328,7 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
vec3 eye_position = -normalize(vertex_interp);
|
||||
|
||||
#ifdef ALPHA_SCISSOR_USED
|
||||
#if defined(ALPHA_SCISSOR_USED)
|
||||
if (alpha < alpha_scissor) {
|
||||
discard;
|
||||
}
|
||||
|
@ -1404,6 +1413,47 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
#endif //use reflection probe 1
|
||||
|
||||
#ifdef USE_LIGHTMAP
|
||||
//ambient light will come entirely from lightmap is lightmap is used
|
||||
ambient_light = texture2D(lightmap, uv2_interp).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
|
||||
|
||||
|
||||
#endif //BASE PASS
|
||||
|
||||
//
|
||||
|
|
|
@ -66,6 +66,8 @@ public:
|
|||
static void make_current();
|
||||
static void register_config();
|
||||
|
||||
virtual bool is_low_end() const { return false; }
|
||||
|
||||
RasterizerGLES3();
|
||||
~RasterizerGLES3();
|
||||
};
|
||||
|
|
|
@ -1029,7 +1029,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer)
|
|||
|
||||
PoolVector<uint8_t> data;
|
||||
|
||||
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0);
|
||||
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1);
|
||||
|
||||
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
|
||||
PoolVector<uint8_t>::Write wb = data.write();
|
||||
|
@ -7364,7 +7364,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
|
|||
GIProbeData *gi_probe_data = gi_probe_data_owner.get(p_rid);
|
||||
|
||||
glDeleteTextures(1, &gi_probe_data->tex_id);
|
||||
gi_probe_owner.free(p_rid);
|
||||
gi_probe_data_owner.free(p_rid);
|
||||
memdelete(gi_probe_data);
|
||||
} else if (lightmap_capture_data_owner.owns(p_rid)) {
|
||||
|
||||
|
@ -7372,7 +7372,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
|
|||
LightmapCapture *lightmap_capture = lightmap_capture_data_owner.get(p_rid);
|
||||
lightmap_capture->instance_remove_deps();
|
||||
|
||||
gi_probe_owner.free(p_rid);
|
||||
lightmap_capture_data_owner.free(p_rid);
|
||||
memdelete(lightmap_capture);
|
||||
|
||||
} else if (canvas_occluder_owner.owns(p_rid)) {
|
||||
|
|
|
@ -1449,6 +1449,9 @@ void EditorInspector::update_tree() {
|
|||
} else if (!(p.usage & PROPERTY_USAGE_EDITOR))
|
||||
continue;
|
||||
|
||||
if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && VS::get_singleton()->is_low_end())
|
||||
continue; //do not show this property in low end gfx
|
||||
|
||||
if (p.name == "script" && (hide_script || bool(object->call("_hide_script_from_inspector")))) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -68,12 +68,9 @@ def include_file_in_legacygl_header(filename, header_data, depth):
|
|||
|
||||
line = fs.readline()
|
||||
|
||||
if line.find("#ifdef ") != -1 or line.find("#elif defined(") != -1:
|
||||
if line.find("#ifdef ") != -1:
|
||||
if line.find("#ifdef ") != -1:
|
||||
ifdefline = line.replace("#ifdef ", "").strip()
|
||||
else:
|
||||
ifdefline = line.replace("#elif defined(", "").strip()
|
||||
ifdefline = ifdefline.replace(")", "").strip()
|
||||
|
||||
if line.find("_EN_") != -1:
|
||||
enumbase = ifdefline[:ifdefline.find("_EN_")]
|
||||
|
|
|
@ -1369,6 +1369,12 @@ void SpatialMaterial::_validate_feature(const String &text, Feature feature, Pro
|
|||
}
|
||||
}
|
||||
|
||||
void SpatialMaterial::_validate_high_end(const String &text, PropertyInfo &property) const {
|
||||
if (property.name.begins_with(text)) {
|
||||
property.usage |= PROPERTY_USAGE_HIGH_END_GFX;
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialMaterial::_validate_property(PropertyInfo &property) const {
|
||||
_validate_feature("normal", FEATURE_NORMAL_MAPPING, property);
|
||||
_validate_feature("emission", FEATURE_EMISSION, property);
|
||||
|
@ -1382,6 +1388,12 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
|
|||
_validate_feature("refraction", FEATURE_REFRACTION, property);
|
||||
_validate_feature("detail", FEATURE_DETAIL, property);
|
||||
|
||||
_validate_high_end("refraction", property);
|
||||
_validate_high_end("subsurf_scatter", property);
|
||||
_validate_high_end("anisotropy", property);
|
||||
_validate_high_end("clearcoat", property);
|
||||
_validate_high_end("depth", property);
|
||||
|
||||
if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
|
||||
property.usage = 0;
|
||||
}
|
||||
|
|
|
@ -442,6 +442,8 @@ private:
|
|||
|
||||
static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff
|
||||
|
||||
void _validate_high_end(const String &text, PropertyInfo &property) const;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _validate_property(PropertyInfo &property) const;
|
||||
|
|
|
@ -207,6 +207,9 @@ void ImageTexture::set_flags(uint32_t p_flags) {
|
|||
|
||||
flags=p_flags|cube; */
|
||||
flags = p_flags;
|
||||
if (w == 0 || h == 0) {
|
||||
return; //uninitialized, do not set to texture
|
||||
}
|
||||
VisualServer::get_singleton()->texture_set_flags(texture, p_flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -1107,6 +1107,8 @@ public:
|
|||
virtual void end_frame(bool p_swap_buffers) = 0;
|
||||
virtual void finalize() = 0;
|
||||
|
||||
virtual bool is_low_end() const = 0;
|
||||
|
||||
virtual ~Rasterizer() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -189,6 +189,9 @@ void VisualServerRaster::call_set_use_vsync(bool p_enable) {
|
|||
OS::get_singleton()->_set_use_vsync(p_enable);
|
||||
}
|
||||
|
||||
bool VisualServerRaster::is_low_end() const {
|
||||
return VSG::rasterizer->is_low_end();
|
||||
}
|
||||
VisualServerRaster::VisualServerRaster() {
|
||||
|
||||
VSG::canvas = memnew(VisualServerCanvas);
|
||||
|
|
|
@ -690,6 +690,8 @@ public:
|
|||
|
||||
virtual void call_set_use_vsync(bool p_enable);
|
||||
|
||||
virtual bool is_low_end() const;
|
||||
|
||||
VisualServerRaster();
|
||||
~VisualServerRaster();
|
||||
|
||||
|
|
|
@ -609,6 +609,10 @@ public:
|
|||
|
||||
static void set_use_vsync_callback(bool p_enable);
|
||||
|
||||
virtual bool is_low_end() const {
|
||||
return visual_server->is_low_end();
|
||||
}
|
||||
|
||||
VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread);
|
||||
~VisualServerWrapMT();
|
||||
|
||||
|
|
|
@ -1037,6 +1037,8 @@ public:
|
|||
|
||||
virtual void call_set_use_vsync(bool p_enable) = 0;
|
||||
|
||||
virtual bool is_low_end() const = 0;
|
||||
|
||||
VisualServer();
|
||||
virtual ~VisualServer();
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue