-Rewrote GLES2 lighting and shadows and optimized state changes, did many optimizations, added vertex lighting.

-Did some fixes to GLES3 too
This commit is contained in:
Juan Linietsky 2018-09-23 12:12:30 -03:00
parent 7e3ce79ea9
commit 65fd37c149
17 changed files with 2025 additions and 1205 deletions

File diff suppressed because it is too large Load Diff

View File

@ -53,12 +53,34 @@
class RasterizerSceneGLES2 : public RasterizerScene { class RasterizerSceneGLES2 : public RasterizerScene {
public: public:
enum ShadowFilterMode {
SHADOW_FILTER_NEAREST,
SHADOW_FILTER_PCF5,
SHADOW_FILTER_PCF13,
};
ShadowFilterMode shadow_filter_mode;
RID default_material; RID default_material;
RID default_material_twosided; RID default_material_twosided;
RID default_shader; RID default_shader;
RID default_shader_twosided; RID default_shader_twosided;
RID default_worldcoord_material;
RID default_worldcoord_material_twosided;
RID default_worldcoord_shader;
RID default_worldcoord_shader_twosided;
RID default_overdraw_material;
RID default_overdraw_shader;
uint64_t render_pass;
uint64_t scene_pass; uint64_t scene_pass;
uint32_t current_material_index;
uint32_t current_geometry_index;
uint32_t current_light_index;
uint32_t current_refprobe_index;
uint32_t current_shader_index;
RasterizerStorageGLES2 *storage; RasterizerStorageGLES2 *storage;
struct State { struct State {
@ -172,11 +194,16 @@ public:
bool cull_front; bool cull_front;
bool cull_disabled; bool cull_disabled;
bool used_sss; bool used_sss;
bool used_screen_texture;
bool using_contact_shadows; bool using_contact_shadows;
VS::ViewportDebugDraw debug_draw; VS::ViewportDebugDraw debug_draw;
*/ */
bool used_screen_texture;
bool shadow_is_dual_parabolloid;
float dual_parbolloid_direction;
float dual_parbolloid_zfar;
} state; } state;
/* SHADOW ATLAS API */ /* SHADOW ATLAS API */
@ -373,6 +400,10 @@ public:
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0); virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
virtual void light_instance_mark_visible(RID p_light_instance); virtual void light_instance_mark_visible(RID p_light_instance);
LightInstance **render_light_instances;
int render_directional_lights;
int render_light_instance_count;
/* REFLECTION INSTANCE */ /* REFLECTION INSTANCE */
virtual RID gi_probe_instance_create(); virtual RID gi_probe_instance_create();
@ -382,40 +413,18 @@ public:
/* RENDER LIST */ /* RENDER LIST */
struct RenderList { enum LightMode {
enum { LIGHTMODE_NORMAL,
DEFAULT_MAX_ELEMENTS = 65536, LIGHTMODE_UNSHADED,
SORT_FLAG_SKELETON = 1, LIGHTMODE_LIGHTMAP,
SORT_FLAG_INSTANCING = 2, LIGHTMODE_LIGHTMAP_CAPTURE,
MAX_DIRECTIONAL_LIGHTS = 16, };
MAX_LIGHTS = 4096,
MAX_REFLECTIONS = 1024,
SORT_KEY_PRIORITY_SHIFT = 56, struct RenderList {
SORT_KEY_PRIORITY_MASK = 0xFF,
//depth layer for opaque (56-52) enum {
SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT = 52, MAX_LIGHTS = 255,
SORT_KEY_OPAQUE_DEPTH_LAYER_MASK = 0xF, DEFAULT_MAX_ELEMENTS = 65536
//64 bits unsupported in MSVC
#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,
SORT_KEY_MIRROR_FLAG = 1
}; };
int max_elements; int max_elements;
@ -427,7 +436,38 @@ public:
RasterizerStorageGLES2::Material *material; RasterizerStorageGLES2::Material *material;
RasterizerStorageGLES2::GeometryOwner *owner; RasterizerStorageGLES2::GeometryOwner *owner;
uint64_t sort_key; bool use_accum; //is this an add pass for multipass
bool *use_accum_ptr;
union {
//TODO: should be endian swapped on big endian
struct {
int32_t depth_layer : 16;
int32_t priority : 16;
};
uint32_t depth_key;
};
union {
struct {
//from least significant to most significant in sort, TODO: should be endian swapped on big endian
uint64_t geometry_index : 14;
uint64_t instancing : 1;
uint64_t skeleton : 1;
uint64_t shader_index : 10;
uint64_t material_index : 10;
uint64_t light_index : 8;
uint64_t light_type2 : 1; // if 1==0 : nolight/directional, else omni/spot
uint64_t refprobe_1_index : 8;
uint64_t refprobe_0_index : 8;
uint64_t light_type1 : 1; //no light, directional is 0, omni spot is 1
uint64_t light_mode : 2; // LightMode enum
};
uint64_t sort_key;
};
}; };
Element *base_elements; Element *base_elements;
@ -445,7 +485,11 @@ public:
struct SortByKey { struct SortByKey {
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
return A->sort_key < B->sort_key; if (A->depth_key == B->depth_key) {
return A->sort_key < B->sort_key;
} else {
return A->depth_key < B->depth_key;
}
} }
}; };
@ -476,29 +520,6 @@ public:
} }
} }
struct SortByReverseDepthAndPriority {
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT);
uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT);
if (layer_A == layer_B) {
return A->instance->depth > B->instance->depth;
} else {
return layer_A < layer_B;
}
}
};
void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
SortArray<Element *, SortByReverseDepthAndPriority> sorter;
if (p_alpha) {
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
} else {
sorter.sort(elements, element_count);
}
}
// element adding and stuff // element adding and stuff
_FORCE_INLINE_ Element *add_element() { _FORCE_INLINE_ Element *add_element() {
@ -549,7 +570,6 @@ public:
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass); void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass);
void _render_render_list(RenderList::Element **p_elements, int p_element_count, void _render_render_list(RenderList::Element **p_elements, int p_element_count,
const RID *p_directional_lights, int p_directional_light_count,
const Transform &p_view_transform, const Transform &p_view_transform,
const CameraMatrix &p_projection, const CameraMatrix &p_projection,
RID p_shadow_atlas, RID p_shadow_atlas,
@ -559,14 +579,15 @@ public:
float p_shadow_normal_bias, float p_shadow_normal_bias,
bool p_reverse_cull, bool p_reverse_cull,
bool p_alpha_pass, bool p_alpha_pass,
bool p_shadow, bool p_shadow);
bool p_directional_add);
void _draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy); void _draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy);
void _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0)); _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton); _FORCE_INLINE_ void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
void _render_geometry(RenderList::Element *p_element); _FORCE_INLINE_ void _setup_light_type(LightInstance *p_light, ShadowAtlas *shadow_atlas);
_FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *p_element);
virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count); virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);

View File

@ -52,6 +52,8 @@ GLuint RasterizerStorageGLES2::system_fbo = 0;
#define _GL_HALF_FLOAT_OES 0x8D61 #define _GL_HALF_FLOAT_OES 0x8D61
#endif #endif
#define _EXT_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
void RasterizerStorageGLES2::bind_quad_array() const { void RasterizerStorageGLES2::bind_quad_array() const {
glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
@ -4225,6 +4227,12 @@ void RasterizerStorageGLES2::initialize() {
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
#ifdef GLES_OVER_GL
glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS);
#endif
config.force_vertex_shading = GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
} }
void RasterizerStorageGLES2::finalize() { void RasterizerStorageGLES2::finalize() {

View File

@ -406,6 +406,9 @@ public:
String path; String path;
uint32_t index;
uint64_t last_pass;
struct CanvasItem { struct CanvasItem {
enum BlendMode { enum BlendMode {
@ -491,6 +494,7 @@ public:
valid = false; valid = false;
custom_code_id = 0; custom_code_id = 0;
version = 1; version = 1;
last_pass = 0;
} }
}; };

View File

@ -31,6 +31,7 @@
#include "shader_compiler_gles2.h" #include "shader_compiler_gles2.h"
#include "core/os/os.h" #include "core/os/os.h"
#include "core/project_settings.h"
#include "core/string_buffer.h" #include "core/string_buffer.h"
#include "core/string_builder.h" #include "core/string_builder.h"
@ -830,6 +831,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize";
// gl_InstanceID is not available in OpenGL ES 2.0 // gl_InstanceID is not available in OpenGL ES 2.0
actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "0"; actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "0";
actions[VS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
//builtins //builtins
@ -900,16 +902,30 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley");
if (!force_lambert) {
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
}
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx");
if (!force_blinn) {
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
} else {
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n";
}
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
/* PARTICLES SHADER */ /* PARTICLES SHADER */

View File

@ -57,7 +57,7 @@
ShaderGLES2 *ShaderGLES2::active = NULL; ShaderGLES2 *ShaderGLES2::active = NULL;
// #define DEBUG_SHADER //#define DEBUG_SHADER
#ifdef DEBUG_SHADER #ifdef DEBUG_SHADER
@ -132,6 +132,11 @@ bool ShaderGLES2::bind() {
ERR_FAIL_COND_V(!version, false); ERR_FAIL_COND_V(!version, false);
if (!version->ok) { //broken, unable to bind (do not throw error, you saw it before already when it failed compilation).
glUseProgram(0);
return false;
}
glUseProgram(version->id); glUseProgram(version->id);
// find out uniform names and locations // find out uniform names and locations
@ -171,72 +176,24 @@ void ShaderGLES2::unbind() {
active = NULL; active = NULL;
} }
static String _fix_error_code_line(const String &p_error, int p_code_start, int p_offset) { static void _display_error_with_code(const String &p_error, const Vector<const char *> &p_code) {
int last_find_pos = -1; int line = 1;
// NVIDIA String total_code;
String error = p_error;
while ((last_find_pos = p_error.find("(", last_find_pos + 1)) != -1) {
int end_pos = last_find_pos + 1; for (int i = 0; i < p_code.size(); i++) {
total_code += String(p_code[i]);
while (true) {
if (p_error[end_pos] >= '0' && p_error[end_pos] <= '9') {
end_pos++;
continue;
} else if (p_error[end_pos] == ')') {
break;
} else {
end_pos = -1;
break;
}
}
if (end_pos == -1)
continue;
String numstr = error.substr(last_find_pos + 1, (end_pos - last_find_pos) - 1);
String begin = error.substr(0, last_find_pos + 1);
String end = error.substr(end_pos, error.length());
int num = numstr.to_int() + p_code_start - p_offset;
error = begin + itos(num) + end;
} }
// ATI Vector<String> lines = String(total_code).split("\n");
last_find_pos = -1;
while ((last_find_pos = p_error.find("ERROR: ", last_find_pos + 1)) != -1) {
last_find_pos += 6; for (int j = 0; j < lines.size(); j++) {
int end_pos = last_find_pos + 1;
while (true) { print_line(itos(line) + ": " + lines[j]);
line++;
if (p_error[end_pos] >= '0' && p_error[end_pos] <= '9') {
end_pos++;
continue;
} else if (p_error[end_pos] == ':') {
break;
} else {
end_pos = -1;
break;
}
}
continue;
if (end_pos == -1)
continue;
String numstr = error.substr(last_find_pos + 1, (end_pos - last_find_pos) - 1);
String begin = error.substr(0, last_find_pos + 1);
String end = error.substr(end_pos, error.length());
int num = numstr.to_int() + p_code_start - p_offset;
error = begin + itos(num) + end;
} }
return error;
ERR_PRINTS(p_error);
} }
ShaderGLES2::Version *ShaderGLES2::get_current_version() { ShaderGLES2::Version *ShaderGLES2::get_current_version() {
@ -316,7 +273,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
if (cc) { if (cc) {
for (int i = 0; i < cc->custom_defines.size(); i++) { for (int i = 0; i < cc->custom_defines.size(); i++) {
strings.push_back(cc->custom_defines.write[i]); strings.push_back(cc->custom_defines.write[i]);
DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i])); DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i].get_data()));
} }
} }
@ -375,9 +332,8 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
String err_string = get_shader_name() + ": Vertex shader compilation failed:\n"; String err_string = get_shader_name() + ": Vertex shader compilation failed:\n";
err_string += ilogmem; err_string += ilogmem;
err_string = _fix_error_code_line(err_string, vertex_code_start, define_line_ofs);
ERR_PRINTS(err_string); _display_error_with_code(err_string, strings);
Memory::free_static(ilogmem); Memory::free_static(ilogmem);
glDeleteShader(v.vert_id); glDeleteShader(v.vert_id);
@ -451,9 +407,8 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
String err_string = get_shader_name() + ": Fragment shader compilation failed:\n"; String err_string = get_shader_name() + ": Fragment shader compilation failed:\n";
err_string += ilogmem; err_string += ilogmem;
err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs);
ERR_PRINTS(err_string); _display_error_with_code(err_string, strings);
Memory::free_static(ilogmem); Memory::free_static(ilogmem);
glDeleteShader(v.frag_id); glDeleteShader(v.frag_id);
@ -503,9 +458,8 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
String err_string = get_shader_name() + ": Program linking failed:\n"; String err_string = get_shader_name() + ": Program linking failed:\n";
err_string += ilogmem; err_string += ilogmem;
err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs);
ERR_PRINTS(err_string); _display_error_with_code(err_string, strings);
Memory::free_static(ilogmem); Memory::free_static(ilogmem);
glDeleteShader(v.frag_id); glDeleteShader(v.frag_id);

View File

@ -468,7 +468,8 @@ public:
// like forward declared nested classes. // like forward declared nested classes.
void use_material(void *p_material); void use_material(void *p_material);
uint32_t get_version() const { return new_conditional_version.version; } _FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; }
_FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) { void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) {

File diff suppressed because it is too large Load Diff

View File

@ -1557,8 +1557,11 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
RasterizerStorageGLES3::MultiMesh *multi_mesh = static_cast<RasterizerStorageGLES3::MultiMesh *>(e->owner); RasterizerStorageGLES3::MultiMesh *multi_mesh = static_cast<RasterizerStorageGLES3::MultiMesh *>(e->owner);
RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry); RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
int amount = MAX(multi_mesh->size, multi_mesh->visible_instances); int amount = MIN(multi_mesh->size, multi_mesh->visible_instances);
if (amount == -1) {
amount = multi_mesh->size;
}
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) { if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
@ -2364,15 +2367,16 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT; e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT;
e->sort_key |= uint64_t(e->instance->base_type) << RenderList::SORT_KEY_GEOMETRY_TYPE_SHIFT; e->sort_key |= uint64_t(e->instance->base_type) << RenderList::SORT_KEY_GEOMETRY_TYPE_SHIFT;
if (e->material->last_pass != render_pass) {
e->material->last_pass = render_pass;
e->material->index = current_material_index++;
}
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
if (!p_depth_pass) { if (!p_depth_pass) {
if (e->material->last_pass != render_pass) {
e->material->last_pass = render_pass;
e->material->index = current_material_index++;
}
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
if (e->instance->gi_probe_instances.size()) { if (e->instance->gi_probe_instances.size()) {
e->sort_key |= SORT_KEY_GI_PROBES_FLAG; e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
} }
@ -2386,9 +2390,6 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
} }
e->sort_key |= uint64_t(p_material->render_priority + 128) << RenderList::SORT_KEY_PRIORITY_SHIFT; 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;
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
} }
/* /*
@ -2738,7 +2739,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
ubo_data.shadow_split_offsets[j] = li->shadow_transform[j].split; ubo_data.shadow_split_offsets[j] = li->shadow_transform[j].split;
Transform modelview = (p_camera_inverse_transform * li->shadow_transform[j].transform).inverse(); Transform modelview = (p_camera_inverse_transform * li->shadow_transform[j].transform).affine_inverse();
CameraMatrix bias; CameraMatrix bias;
bias.set_light_bias(); bias.set_light_bias();
@ -3131,7 +3132,6 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
current_material_index = 0; current_material_index = 0;
state.used_sss = false; state.used_sss = false;
state.used_screen_texture = false; state.used_screen_texture = false;
//fill list //fill list
for (int i = 0; i < p_cull_count; i++) { for (int i = 0; i < p_cull_count; i++) {
@ -5147,13 +5147,13 @@ void RasterizerSceneGLES3::initialize() {
void RasterizerSceneGLES3::iteration() { void RasterizerSceneGLES3::iteration() {
shadow_filter_mode = ShadowFilterMode(int(ProjectSettings::get_singleton()->get("rendering/quality/shadows/filter_mode"))); shadow_filter_mode = ShadowFilterMode(int(GLOBAL_GET("rendering/quality/shadows/filter_mode")));
subsurface_scatter_follow_surface = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/follow_surface"); subsurface_scatter_follow_surface = GLOBAL_GET("rendering/quality/subsurface_scattering/follow_surface");
subsurface_scatter_weight_samples = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/weight_samples"); subsurface_scatter_weight_samples = GLOBAL_GET("rendering/quality/subsurface_scattering/weight_samples");
subsurface_scatter_quality = SubSurfaceScatterQuality(int(ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/quality"))); subsurface_scatter_quality = SubSurfaceScatterQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/quality")));
subsurface_scatter_size = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/scale"); subsurface_scatter_size = GLOBAL_GET("rendering/quality/subsurface_scattering/scale");
state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, ProjectSettings::get_singleton()->get("rendering/quality/voxel_cone_tracing/high_quality")); state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, GLOBAL_GET("rendering/quality/voxel_cone_tracing/high_quality"));
} }
void RasterizerSceneGLES3::finalize() { void RasterizerSceneGLES3::finalize() {

View File

@ -31,6 +31,7 @@
#include "shader_compiler_gles3.h" #include "shader_compiler_gles3.h"
#include "core/os/os.h" #include "core/os/os.h"
#include "core/project_settings.h"
#define SL ShaderLanguage #define SL ShaderLanguage
@ -860,6 +861,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer"; actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor";
actions[VS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
//for light //for light
actions[VS::SHADER_SPATIAL].renames["VIEW"] = "view"; actions[VS::SHADER_SPATIAL].renames["VIEW"] = "view";
@ -901,12 +903,24 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley");
if (!force_lambert) {
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
}
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx");
if (!force_blinn) {
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
} else {
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n";
}
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";

View File

@ -122,6 +122,11 @@ bool ShaderGLES3::bind() {
ERR_FAIL_COND_V(!version, false); ERR_FAIL_COND_V(!version, false);
if (!version->ok) { //broken, unable to bind (do not throw error, you saw it before already when it failed compilation).
glUseProgram(0);
return false;
}
glUseProgram(version->id); glUseProgram(version->id);
DEBUG_TEST_ERROR("Use Program"); DEBUG_TEST_ERROR("Use Program");

View File

@ -336,6 +336,7 @@ public:
} }
uint32_t get_version() const { return new_conditional_version.version; } uint32_t get_version() const { return new_conditional_version.version; }
_FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) { void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) {

View File

@ -3,6 +3,8 @@
#define M_PI 3.14159265359 #define M_PI 3.14159265359
#define SHADER_IS_SRGB false
/* /*
from VisualServer: from VisualServer:
@ -514,6 +516,7 @@ VERTEX_SHADER_CODE
/* clang-format off */ /* clang-format off */
[fragment] [fragment]
/* texture unit usage, N is max_texture_unity-N /* texture unit usage, N is max_texture_unity-N
1-skeleton 1-skeleton
@ -533,6 +536,7 @@ uniform highp mat4 world_transform;
/* clang-format on */ /* clang-format on */
#define M_PI 3.14159265359 #define M_PI 3.14159265359
#define SHADER_IS_SRGB false
/* Varyings */ /* Varyings */
@ -1020,18 +1024,30 @@ LIGHT_SHADER_CODE
#if defined(SPECULAR_BLINN) #if defined(SPECULAR_BLINN)
//normalized blinn
vec3 H = normalize(V + L); vec3 H = normalize(V + L);
float cNdotH = max(dot(N, H), 0.0); float cNdotH = max(dot(N, H), 0.0);
float intensity = pow(cNdotH, (1.0 - roughness) * 256.0); float cVdotH = max(dot(V, H), 0.0);
float cLdotH = max(dot(L, H), 0.0);
float shininess = exp2( 15.0 * (1.0 - roughness) + 1.0 ) * 0.25;
float blinn = pow( cNdotH, shininess );
blinn *= (shininess + 8.0) / (8.0 * 3.141592654);
float intensity = ( blinn ) / max( 4.0 * cNdotV * cNdotL, 0.75 );
specular_light += light_color * intensity * specular_blob_intensity * attenuation; specular_light += light_color * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_PHONG) #elif defined(SPECULAR_PHONG)
vec3 R = normalize(-reflect(L, N)); vec3 R = normalize(-reflect(L, N));
float cRdotV = max(0.0, dot(R, V)); float cRdotV = max(0.0, dot(R, V));
float intensity = pow(cRdotV, (1.0 - roughness) * 256.0); float shininess = exp2( 15.0 * (1.0 - roughness) + 1.0 ) * 0.25;
float phong = pow( cRdotV, shininess );
phong *= (shininess + 8.0) / (8.0 * 3.141592654);
float intensity = ( phong ) / max( 4.0 * cNdotV * cNdotL, 0.75 );
specular_light += light_color * intensity * specular_blob_intensity * attenuation; specular_light += light_color * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_TOON) #elif defined(SPECULAR_TOON)
vec3 R = normalize(-reflect(L, N)); vec3 R = normalize(-reflect(L, N));
@ -1070,11 +1086,11 @@ LIGHT_SHADER_CODE
float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha); float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
#endif #endif
// F // F
float F0 = 1.0; // FIXME //float F0 = 1.0;
float cLdotH5 = SchlickFresnel(cLdotH); //float cLdotH5 = SchlickFresnel(cLdotH);
float F = mix(cLdotH5, 1.0, F0); //float F = mix(cLdotH5, 1.0, F0);
float specular_brdf_NL = cNdotL * D * F * G; float specular_brdf_NL = cNdotL * D /* F */ * G;
specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
#endif #endif

View File

@ -232,7 +232,11 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2
fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n") fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n")
if header_data.conditionals: if header_data.conditionals:
fd.write("\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n") fd.write("\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n")
fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; ERR_FAIL_COND( get_active()!=this );\n\n ") fd.write("\t#ifdef DEBUG_ENABLED\n ")
fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; if (!is_version_valid()) return; ERR_FAIL_COND( get_active()!=this ); \n\n ")
fd.write("\t#else\n ")
fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; \n\n ")
fd.write("\t#endif\n")
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n") fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n")
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n") fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n")
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n")

View File

@ -562,7 +562,9 @@ void SpatialMaterial::_update_shader() {
if (flags[FLAG_SRGB_VERTEX_COLOR]) { if (flags[FLAG_SRGB_VERTEX_COLOR]) {
code += "\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n"; code += "\tif (!OUTPUT_IS_SRGB) {\n";
code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n";
code += "\t}\n";
} }
if (flags[FLAG_USE_POINT_SIZE]) { if (flags[FLAG_USE_POINT_SIZE]) {

View File

@ -78,6 +78,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
@ -112,6 +113,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
@ -138,6 +141,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["DIFFUSE_LIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["DIFFUSE_LIGHT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["SPECULAR_LIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["SPECULAR_LIGHT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[VS::SHADER_SPATIAL].functions["light"].can_discard = true; shader_modes[VS::SHADER_SPATIAL].functions["light"].can_discard = true;

View File

@ -2393,6 +2393,10 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true); GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);
GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley", false);
GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley.mobile", true);
GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx", false);
GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true);
GLOBAL_DEF("rendering/quality/depth_prepass/enable", true); GLOBAL_DEF("rendering/quality/depth_prepass/enable", true);
GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno"); GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno");