mirror of
https://github.com/godotengine/godot
synced 2024-09-05 09:08:28 +00:00
Merge pull request #41219 from akien-mga/gles2-takes-holidays
Remove obsolete GLES2 backend code
This commit is contained in:
commit
0d815ed157
|
@ -162,11 +162,6 @@ Comment: The FreeType Project
|
||||||
Copyright: 1996-2020, David Turner, Robert Wilhelm, and Werner Lemberg.
|
Copyright: 1996-2020, David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||||
License: FTL
|
License: FTL
|
||||||
|
|
||||||
Files: ./thirdparty/glad/
|
|
||||||
Comment: glad
|
|
||||||
Copyright: 2013-2019, David Herberth
|
|
||||||
License: Expat
|
|
||||||
|
|
||||||
Files: ./thirdparty/glslang/
|
Files: ./thirdparty/glslang/
|
||||||
Comment: glslang
|
Comment: glslang
|
||||||
Copyright: 2015-2018 Google, Inc.
|
Copyright: 2015-2018 Google, Inc.
|
||||||
|
|
11
SConstruct
11
SConstruct
|
@ -12,7 +12,7 @@ from collections import OrderedDict
|
||||||
|
|
||||||
# Local
|
# Local
|
||||||
import methods
|
import methods
|
||||||
import gles_builders
|
import glsl_builders
|
||||||
import version
|
import version
|
||||||
from platform_methods import run_in_subprocess
|
from platform_methods import run_in_subprocess
|
||||||
|
|
||||||
|
@ -630,18 +630,13 @@ if selected_platform in platform_list:
|
||||||
|
|
||||||
if not env["platform"] == "server":
|
if not env["platform"] == "server":
|
||||||
GLSL_BUILDERS = {
|
GLSL_BUILDERS = {
|
||||||
"GLES2_GLSL": env.Builder(
|
|
||||||
action=env.Run(gles_builders.build_gles2_headers, 'Building GLES2_GLSL header: "$TARGET"'),
|
|
||||||
suffix="glsl.gen.h",
|
|
||||||
src_suffix=".glsl",
|
|
||||||
),
|
|
||||||
"RD_GLSL": env.Builder(
|
"RD_GLSL": env.Builder(
|
||||||
action=env.Run(gles_builders.build_rd_headers, 'Building RD_GLSL header: "$TARGET"'),
|
action=env.Run(glsl_builders.build_rd_headers, 'Building RD_GLSL header: "$TARGET"'),
|
||||||
suffix="glsl.gen.h",
|
suffix="glsl.gen.h",
|
||||||
src_suffix=".glsl",
|
src_suffix=".glsl",
|
||||||
),
|
),
|
||||||
"GLSL_HEADER": env.Builder(
|
"GLSL_HEADER": env.Builder(
|
||||||
action=env.Run(gles_builders.build_raw_headers, 'Building GLSL header: "$TARGET"'),
|
action=env.Run(glsl_builders.build_raw_headers, 'Building GLSL header: "$TARGET"'),
|
||||||
suffix="glsl.gen.h",
|
suffix="glsl.gen.h",
|
||||||
src_suffix=".glsl",
|
src_suffix=".glsl",
|
||||||
),
|
),
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
Adds the specified color to the end of the ramp, with the specified offset.
|
Adds the specified color to the end of the ramp, with the specified offset.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_color" qualifiers="const">
|
<method name="get_color">
|
||||||
<return type="Color">
|
<return type="Color">
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="point" type="int">
|
<argument index="0" name="point" type="int">
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
Returns the color of the ramp color at index [code]point[/code].
|
Returns the color of the ramp color at index [code]point[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_offset" qualifiers="const">
|
<method name="get_offset">
|
||||||
<return type="float">
|
<return type="float">
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="point" type="int">
|
<argument index="0" name="point" type="int">
|
||||||
|
|
|
@ -990,10 +990,6 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600">
|
<member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600">
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/quality/2d/gles2_use_nvidia_rect_flicker_workaround" type="bool" setter="" getter="" default="false">
|
|
||||||
Some NVIDIA GPU drivers have a bug which produces flickering issues for the [code]draw_rect[/code] method, especially as used in [TileMap]. Refer to [url=https://github.com/godotengine/godot/issues/9913]GitHub issue 9913[/url] for details.
|
|
||||||
If [code]true[/code], this option enables a "safe" code path for such NVIDIA GPUs at the cost of performance. This option only impacts the GLES2 rendering backend, and only desktop platforms. It is not necessary when using the Vulkan backend.
|
|
||||||
</member>
|
|
||||||
<member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false">
|
<member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false">
|
||||||
If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles.
|
If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -24,9 +24,7 @@ SConscript("winmidi/SCsub")
|
||||||
|
|
||||||
# Graphics drivers
|
# Graphics drivers
|
||||||
if env["platform"] != "server" and env["platform"] != "javascript":
|
if env["platform"] != "server" and env["platform"] != "javascript":
|
||||||
# SConscript('gles2/SCsub')
|
|
||||||
SConscript("vulkan/SCsub")
|
SConscript("vulkan/SCsub")
|
||||||
SConscript("gl_context/SCsub")
|
|
||||||
else:
|
else:
|
||||||
SConscript("dummy/SCsub")
|
SConscript("dummy/SCsub")
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
if env["platform"] in ["haiku", "osx", "windows", "linuxbsd"]:
|
|
||||||
# Thirdparty source files
|
|
||||||
thirdparty_dir = "#thirdparty/glad/"
|
|
||||||
thirdparty_sources = [
|
|
||||||
"glad.c",
|
|
||||||
]
|
|
||||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
|
||||||
|
|
||||||
env.Prepend(CPPPATH=[thirdparty_dir])
|
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["GLAD_ENABLED"])
|
|
||||||
env.Append(CPPDEFINES=["GLES_OVER_GL"])
|
|
||||||
|
|
||||||
env_thirdparty = env.Clone()
|
|
||||||
env_thirdparty.disable_warnings()
|
|
||||||
env_thirdparty.add_source_files(env.drivers_sources, thirdparty_sources)
|
|
||||||
|
|
||||||
# Godot source files
|
|
||||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
|
||||||
|
|
||||||
SConscript("shaders/SCsub")
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,147 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rasterizer_canvas_gles2.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef RASTERIZERCANVASGLES2_H
|
|
||||||
#define RASTERIZERCANVASGLES2_H
|
|
||||||
|
|
||||||
#include "rasterizer_storage_gles2.h"
|
|
||||||
#include "servers/rendering/rasterizer.h"
|
|
||||||
|
|
||||||
#include "shaders/canvas.glsl.gen.h"
|
|
||||||
#include "shaders/lens_distorted.glsl.gen.h"
|
|
||||||
|
|
||||||
#include "shaders/canvas_shadow.glsl.gen.h"
|
|
||||||
|
|
||||||
class RasterizerSceneGLES2;
|
|
||||||
|
|
||||||
class RasterizerCanvasGLES2 : public RasterizerCanvas {
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
INSTANCE_ATTRIB_BASE = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Uniforms {
|
|
||||||
Transform projection_matrix;
|
|
||||||
|
|
||||||
Transform2D modelview_matrix;
|
|
||||||
Transform2D extra_matrix;
|
|
||||||
|
|
||||||
Color final_modulate;
|
|
||||||
|
|
||||||
float time;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Data {
|
|
||||||
GLuint canvas_quad_vertices;
|
|
||||||
GLuint polygon_buffer;
|
|
||||||
GLuint polygon_index_buffer;
|
|
||||||
|
|
||||||
uint32_t polygon_buffer_size;
|
|
||||||
uint32_t polygon_index_buffer_size;
|
|
||||||
|
|
||||||
GLuint ninepatch_vertices;
|
|
||||||
GLuint ninepatch_elements;
|
|
||||||
|
|
||||||
} data;
|
|
||||||
|
|
||||||
struct State {
|
|
||||||
Uniforms uniforms;
|
|
||||||
bool canvas_texscreen_used;
|
|
||||||
CanvasShaderGLES2 canvas_shader;
|
|
||||||
CanvasShadowShaderGLES2 canvas_shadow_shader;
|
|
||||||
LensDistortedShaderGLES2 lens_shader;
|
|
||||||
|
|
||||||
bool using_texture_rect;
|
|
||||||
bool using_ninepatch;
|
|
||||||
bool using_skeleton;
|
|
||||||
|
|
||||||
Transform2D skeleton_transform;
|
|
||||||
Transform2D skeleton_transform_inverse;
|
|
||||||
Size2i skeleton_texture_size;
|
|
||||||
|
|
||||||
RID current_tex;
|
|
||||||
RID current_normal;
|
|
||||||
RasterizerStorageGLES2::Texture *current_tex_ptr;
|
|
||||||
|
|
||||||
Transform vp;
|
|
||||||
Light *using_light;
|
|
||||||
bool using_shadow;
|
|
||||||
bool using_transparent_rt;
|
|
||||||
|
|
||||||
} state;
|
|
||||||
|
|
||||||
typedef void Texture;
|
|
||||||
|
|
||||||
RasterizerSceneGLES2 *scene_render;
|
|
||||||
|
|
||||||
RasterizerStorageGLES2 *storage;
|
|
||||||
|
|
||||||
bool use_nvidia_rect_workaround;
|
|
||||||
|
|
||||||
virtual RID light_internal_create();
|
|
||||||
virtual void light_internal_update(RID p_rid, Light *p_light);
|
|
||||||
virtual void light_internal_free(RID p_rid);
|
|
||||||
|
|
||||||
void _set_uniforms();
|
|
||||||
|
|
||||||
virtual void canvas_begin();
|
|
||||||
virtual void canvas_end();
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs);
|
|
||||||
_FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights = nullptr, const int *p_bones = nullptr);
|
|
||||||
_FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
|
|
||||||
_FORCE_INLINE_ void _draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material);
|
|
||||||
void _copy_screen(const Rect2 &p_rect);
|
|
||||||
_FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect);
|
|
||||||
|
|
||||||
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
|
|
||||||
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow);
|
|
||||||
|
|
||||||
virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache);
|
|
||||||
|
|
||||||
virtual void reset_canvas();
|
|
||||||
|
|
||||||
RasterizerStorageGLES2::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map);
|
|
||||||
|
|
||||||
void _bind_quad_buffer();
|
|
||||||
void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src);
|
|
||||||
void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
|
|
||||||
|
|
||||||
void initialize();
|
|
||||||
void finalize();
|
|
||||||
|
|
||||||
virtual void draw_window_margins(int *black_margin, RID *black_image);
|
|
||||||
|
|
||||||
RasterizerCanvasGLES2();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RASTERIZERCANVASGLES2_H
|
|
|
@ -1,494 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rasterizer_gles2.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include "rasterizer_gles2.h"
|
|
||||||
|
|
||||||
#include "core/os/os.h"
|
|
||||||
#include "core/project_settings.h"
|
|
||||||
|
|
||||||
#define _EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
|
|
||||||
#define _EXT_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
|
|
||||||
#define _EXT_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
|
|
||||||
#define _EXT_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
|
|
||||||
#define _EXT_DEBUG_SOURCE_API_ARB 0x8246
|
|
||||||
#define _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
|
|
||||||
#define _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
|
|
||||||
#define _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
|
|
||||||
#define _EXT_DEBUG_SOURCE_APPLICATION_ARB 0x824A
|
|
||||||
#define _EXT_DEBUG_SOURCE_OTHER_ARB 0x824B
|
|
||||||
#define _EXT_DEBUG_TYPE_ERROR_ARB 0x824C
|
|
||||||
#define _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
|
|
||||||
#define _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
|
|
||||||
#define _EXT_DEBUG_TYPE_PORTABILITY_ARB 0x824F
|
|
||||||
#define _EXT_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
|
|
||||||
#define _EXT_DEBUG_TYPE_OTHER_ARB 0x8251
|
|
||||||
#define _EXT_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
|
|
||||||
#define _EXT_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
|
|
||||||
#define _EXT_DEBUG_LOGGED_MESSAGES_ARB 0x9145
|
|
||||||
#define _EXT_DEBUG_SEVERITY_HIGH_ARB 0x9146
|
|
||||||
#define _EXT_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
|
|
||||||
#define _EXT_DEBUG_SEVERITY_LOW_ARB 0x9148
|
|
||||||
#define _EXT_DEBUG_OUTPUT 0x92E0
|
|
||||||
|
|
||||||
#ifndef GLAPIENTRY
|
|
||||||
#if defined(WINDOWS_ENABLED) && !defined(UWP_ENABLED)
|
|
||||||
#define GLAPIENTRY APIENTRY
|
|
||||||
#else
|
|
||||||
#define GLAPIENTRY
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef IPHONE_ENABLED
|
|
||||||
// We include EGL below to get debug callback on GLES2 platforms,
|
|
||||||
// but EGL is not available on iOS.
|
|
||||||
#define CAN_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(GLES_OVER_GL) && defined(CAN_DEBUG)
|
|
||||||
#include <GLES2/gl2.h>
|
|
||||||
#include <GLES2/gl2ext.h>
|
|
||||||
#include <GLES2/gl2platform.h>
|
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
|
||||||
#include <EGL/eglext.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
|
|
||||||
#define strcpy strcpy_s
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CAN_DEBUG
|
|
||||||
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
|
|
||||||
if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB)
|
|
||||||
return; //these are ultimately annoying, so removing for now
|
|
||||||
|
|
||||||
char debSource[256], debType[256], debSev[256];
|
|
||||||
|
|
||||||
if (source == _EXT_DEBUG_SOURCE_API_ARB)
|
|
||||||
strcpy(debSource, "OpenGL");
|
|
||||||
else if (source == _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
|
|
||||||
strcpy(debSource, "Windows");
|
|
||||||
else if (source == _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB)
|
|
||||||
strcpy(debSource, "Shader Compiler");
|
|
||||||
else if (source == _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB)
|
|
||||||
strcpy(debSource, "Third Party");
|
|
||||||
else if (source == _EXT_DEBUG_SOURCE_APPLICATION_ARB)
|
|
||||||
strcpy(debSource, "Application");
|
|
||||||
else if (source == _EXT_DEBUG_SOURCE_OTHER_ARB)
|
|
||||||
strcpy(debSource, "Other");
|
|
||||||
|
|
||||||
if (type == _EXT_DEBUG_TYPE_ERROR_ARB)
|
|
||||||
strcpy(debType, "Error");
|
|
||||||
else if (type == _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB)
|
|
||||||
strcpy(debType, "Deprecated behavior");
|
|
||||||
else if (type == _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB)
|
|
||||||
strcpy(debType, "Undefined behavior");
|
|
||||||
else if (type == _EXT_DEBUG_TYPE_PORTABILITY_ARB)
|
|
||||||
strcpy(debType, "Portability");
|
|
||||||
else if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB)
|
|
||||||
strcpy(debType, "Performance");
|
|
||||||
else if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
|
|
||||||
strcpy(debType, "Other");
|
|
||||||
|
|
||||||
if (severity == _EXT_DEBUG_SEVERITY_HIGH_ARB)
|
|
||||||
strcpy(debSev, "High");
|
|
||||||
else if (severity == _EXT_DEBUG_SEVERITY_MEDIUM_ARB)
|
|
||||||
strcpy(debSev, "Medium");
|
|
||||||
else if (severity == _EXT_DEBUG_SEVERITY_LOW_ARB)
|
|
||||||
strcpy(debSev, "Low");
|
|
||||||
|
|
||||||
String output = String() + "GL ERROR: Source: " + debSource + "\tType: " + debType + "\tID: " + itos(id) + "\tSeverity: " + debSev + "\tMessage: " + message;
|
|
||||||
|
|
||||||
ERR_PRINT(output);
|
|
||||||
}
|
|
||||||
#endif // CAN_DEBUG
|
|
||||||
|
|
||||||
typedef void (*DEBUGPROCARB)(GLenum source,
|
|
||||||
GLenum type,
|
|
||||||
GLuint id,
|
|
||||||
GLenum severity,
|
|
||||||
GLsizei length,
|
|
||||||
const char *message,
|
|
||||||
const void *userParam);
|
|
||||||
|
|
||||||
typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam);
|
|
||||||
|
|
||||||
RasterizerStorage *RasterizerGLES2::get_storage() {
|
|
||||||
return storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerCanvas *RasterizerGLES2::get_canvas() {
|
|
||||||
return canvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerScene *RasterizerGLES2::get_scene() {
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error RasterizerGLES2::is_viable() {
|
|
||||||
#ifdef GLAD_ENABLED
|
|
||||||
if (!gladLoadGL()) {
|
|
||||||
ERR_PRINT("Error initializing GLAD");
|
|
||||||
return ERR_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them
|
|
||||||
#ifdef OPENGL_ENABLED // OpenGL 2.1 Profile required
|
|
||||||
if (GLVersion.major < 2 || (GLVersion.major == 2 && GLVersion.minor < 1)) {
|
|
||||||
#else // OpenGL ES 2.0
|
|
||||||
if (GLVersion.major < 2) {
|
|
||||||
#endif
|
|
||||||
return ERR_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GLES_OVER_GL
|
|
||||||
//Test GL_ARB_framebuffer_object extension
|
|
||||||
if (!GLAD_GL_ARB_framebuffer_object) {
|
|
||||||
//Try older GL_EXT_framebuffer_object extension
|
|
||||||
if (GLAD_GL_EXT_framebuffer_object) {
|
|
||||||
glIsRenderbuffer = glIsRenderbufferEXT;
|
|
||||||
glBindRenderbuffer = glBindRenderbufferEXT;
|
|
||||||
glDeleteRenderbuffers = glDeleteRenderbuffersEXT;
|
|
||||||
glGenRenderbuffers = glGenRenderbuffersEXT;
|
|
||||||
glRenderbufferStorage = glRenderbufferStorageEXT;
|
|
||||||
glGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT;
|
|
||||||
glIsFramebuffer = glIsFramebufferEXT;
|
|
||||||
glBindFramebuffer = glBindFramebufferEXT;
|
|
||||||
glDeleteFramebuffers = glDeleteFramebuffersEXT;
|
|
||||||
glGenFramebuffers = glGenFramebuffersEXT;
|
|
||||||
glCheckFramebufferStatus = glCheckFramebufferStatusEXT;
|
|
||||||
glFramebufferTexture1D = glFramebufferTexture1DEXT;
|
|
||||||
glFramebufferTexture2D = glFramebufferTexture2DEXT;
|
|
||||||
glFramebufferTexture3D = glFramebufferTexture3DEXT;
|
|
||||||
glFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
|
|
||||||
glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
|
|
||||||
glGenerateMipmap = glGenerateMipmapEXT;
|
|
||||||
} else {
|
|
||||||
return ERR_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GLAD_GL_EXT_framebuffer_multisample) {
|
|
||||||
glRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
|
|
||||||
}
|
|
||||||
#endif // GLES_OVER_GL
|
|
||||||
|
|
||||||
#endif // GLAD_ENABLED
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::initialize() {
|
|
||||||
print_verbose("Using GLES2 video driver");
|
|
||||||
|
|
||||||
#ifdef GLAD_ENABLED
|
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
|
||||||
if (GLAD_GL_ARB_debug_output) {
|
|
||||||
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
|
||||||
glDebugMessageCallbackARB(_gl_debug_print, nullptr);
|
|
||||||
glEnable(_EXT_DEBUG_OUTPUT);
|
|
||||||
} else {
|
|
||||||
print_line("OpenGL debugging not supported!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // GLAD_ENABLED
|
|
||||||
|
|
||||||
// For debugging
|
|
||||||
#ifdef CAN_DEBUG
|
|
||||||
#ifdef GLES_OVER_GL
|
|
||||||
if (OS::get_singleton()->is_stdout_verbose() && GLAD_GL_ARB_debug_output) {
|
|
||||||
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
|
|
||||||
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
|
|
||||||
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
|
|
||||||
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PORTABILITY_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
|
|
||||||
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PERFORMANCE_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
|
|
||||||
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_OTHER_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
|
|
||||||
/* glDebugMessageInsertARB(
|
|
||||||
GL_DEBUG_SOURCE_API_ARB,
|
|
||||||
GL_DEBUG_TYPE_OTHER_ARB, 1,
|
|
||||||
GL_DEBUG_SEVERITY_HIGH_ARB, 5, "hello");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
|
||||||
DebugMessageCallbackARB callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallback");
|
|
||||||
if (!callback) {
|
|
||||||
callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallbackKHR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback) {
|
|
||||||
print_line("godot: ENABLING GL DEBUG");
|
|
||||||
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
|
||||||
callback(_gl_debug_print, nullptr);
|
|
||||||
glEnable(_EXT_DEBUG_OUTPUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // GLES_OVER_GL
|
|
||||||
#endif // CAN_DEBUG
|
|
||||||
|
|
||||||
print_line("OpenGL ES 2.0 Renderer: " + RenderingServer::get_singleton()->get_video_adapter_name());
|
|
||||||
storage->initialize();
|
|
||||||
canvas->initialize();
|
|
||||||
scene->initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::begin_frame(double frame_step) {
|
|
||||||
time_total += frame_step;
|
|
||||||
|
|
||||||
if (frame_step == 0) {
|
|
||||||
//to avoid hiccups
|
|
||||||
frame_step = 0.001;
|
|
||||||
}
|
|
||||||
|
|
||||||
double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
|
|
||||||
time_total = Math::fmod(time_total, time_roll_over);
|
|
||||||
|
|
||||||
storage->frame.time[0] = time_total;
|
|
||||||
storage->frame.time[1] = Math::fmod(time_total, 3600);
|
|
||||||
storage->frame.time[2] = Math::fmod(time_total, 900);
|
|
||||||
storage->frame.time[3] = Math::fmod(time_total, 60);
|
|
||||||
storage->frame.count++;
|
|
||||||
storage->frame.delta = frame_step;
|
|
||||||
|
|
||||||
storage->update_dirty_resources();
|
|
||||||
|
|
||||||
storage->info.render_final = storage->info.render;
|
|
||||||
storage->info.render.reset();
|
|
||||||
|
|
||||||
scene->iteration();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::set_current_render_target(RID p_render_target) {
|
|
||||||
if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) {
|
|
||||||
// pending clear request. Do that first.
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
|
|
||||||
glClearColor(storage->frame.clear_request_color.r,
|
|
||||||
storage->frame.clear_request_color.g,
|
|
||||||
storage->frame.clear_request_color.b,
|
|
||||||
storage->frame.clear_request_color.a);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_render_target.is_valid()) {
|
|
||||||
RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
|
|
||||||
storage->frame.current_rt = rt;
|
|
||||||
ERR_FAIL_COND(!rt);
|
|
||||||
storage->frame.clear_request = false;
|
|
||||||
|
|
||||||
glViewport(0, 0, rt->width, rt->height);
|
|
||||||
} else {
|
|
||||||
storage->frame.current_rt = nullptr;
|
|
||||||
storage->frame.clear_request = false;
|
|
||||||
glViewport(0, 0, DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::restore_render_target(bool p_3d_was_drawn) {
|
|
||||||
ERR_FAIL_COND(storage->frame.current_rt == nullptr);
|
|
||||||
RasterizerStorageGLES2::RenderTarget *rt = storage->frame.current_rt;
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
|
|
||||||
glViewport(0, 0, rt->width, rt->height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::clear_render_target(const Color &p_color) {
|
|
||||||
ERR_FAIL_COND(!storage->frame.current_rt);
|
|
||||||
|
|
||||||
storage->frame.clear_request = true;
|
|
||||||
storage->frame.clear_request_color = p_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
|
|
||||||
if (p_image.is_null() || p_image->empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int window_w = OS::get_singleton()->get_video_mode(0).width;
|
|
||||||
int window_h = OS::get_singleton()->get_video_mode(0).height;
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
glViewport(0, 0, window_w, window_h);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
glDepthMask(GL_FALSE);
|
|
||||||
if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
||||||
} else {
|
|
||||||
glClearColor(p_color.r, p_color.g, p_color.b, 1.0);
|
|
||||||
}
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
canvas->canvas_begin();
|
|
||||||
|
|
||||||
RID texture = storage->texture_create();
|
|
||||||
storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), RS::TEXTURE_TYPE_2D, p_use_filter ? RS::TEXTURE_FLAG_FILTER : 0);
|
|
||||||
storage->texture_set_data(texture, p_image);
|
|
||||||
|
|
||||||
Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
|
|
||||||
Rect2 screenrect;
|
|
||||||
if (p_scale) {
|
|
||||||
if (window_w > window_h) {
|
|
||||||
//scale horizontally
|
|
||||||
screenrect.size.y = window_h;
|
|
||||||
screenrect.size.x = imgrect.size.x * window_h / imgrect.size.y;
|
|
||||||
screenrect.position.x = (window_w - screenrect.size.x) / 2;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//scale vertically
|
|
||||||
screenrect.size.x = window_w;
|
|
||||||
screenrect.size.y = imgrect.size.y * window_w / imgrect.size.x;
|
|
||||||
screenrect.position.y = (window_h - screenrect.size.y) / 2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
screenrect = imgrect;
|
|
||||||
screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(texture);
|
|
||||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, t->tex_id);
|
|
||||||
canvas->draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1));
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
canvas->canvas_end();
|
|
||||||
|
|
||||||
storage->free(texture);
|
|
||||||
|
|
||||||
end_frame(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen) {
|
|
||||||
ERR_FAIL_COND(storage->frame.current_rt);
|
|
||||||
|
|
||||||
RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
|
|
||||||
ERR_FAIL_COND(!rt);
|
|
||||||
|
|
||||||
canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
|
|
||||||
|
|
||||||
canvas->state.canvas_shader.set_custom_shader(0);
|
|
||||||
canvas->state.canvas_shader.bind();
|
|
||||||
|
|
||||||
canvas->canvas_begin();
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
|
|
||||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
|
|
||||||
if (rt->external.fbo != 0) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, rt->external.color);
|
|
||||||
} else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO normals
|
|
||||||
|
|
||||||
canvas->draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1));
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
canvas->canvas_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
|
|
||||||
ERR_FAIL_COND(storage->frame.current_rt);
|
|
||||||
|
|
||||||
RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
|
|
||||||
ERR_FAIL_COND(!rt);
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
// render to our framebuffer
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
|
|
||||||
|
|
||||||
// output our texture
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
|
||||||
|
|
||||||
canvas->draw_lens_distortion_rect(p_screen_rect, p_k1, p_k2, p_eye_center, p_oversample);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::end_frame(bool p_swap_buffers) {
|
|
||||||
if (OS::get_singleton()->is_layered_allowed()) {
|
|
||||||
if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
|
|
||||||
#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
|
|
||||||
Size2 wndsize = OS::get_singleton()->get_layered_buffer_size();
|
|
||||||
uint8_t *data = OS::get_singleton()->get_layered_buffer_data();
|
|
||||||
if (data) {
|
|
||||||
glReadPixels(0, 0, wndsize.x, wndsize.y, GL_BGRA, GL_UNSIGNED_BYTE, data);
|
|
||||||
OS::get_singleton()->swap_layered_buffer();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
//clear alpha
|
|
||||||
glColorMask(false, false, false, true);
|
|
||||||
glClearColor(0, 0, 0, 1);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glColorMask(true, true, true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_swap_buffers)
|
|
||||||
OS::get_singleton()->swap_buffers();
|
|
||||||
else
|
|
||||||
glFinish();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::finalize() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Rasterizer *RasterizerGLES2::_create_current() {
|
|
||||||
return memnew(RasterizerGLES2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::make_current() {
|
|
||||||
_create_func = _create_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerGLES2::register_config() {
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerGLES2::RasterizerGLES2() {
|
|
||||||
storage = memnew(RasterizerStorageGLES2);
|
|
||||||
canvas = memnew(RasterizerCanvasGLES2);
|
|
||||||
scene = memnew(RasterizerSceneGLES2);
|
|
||||||
canvas->storage = storage;
|
|
||||||
canvas->scene_render = scene;
|
|
||||||
storage->canvas = canvas;
|
|
||||||
scene->storage = storage;
|
|
||||||
storage->scene = scene;
|
|
||||||
|
|
||||||
time_total = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerGLES2::~RasterizerGLES2() {
|
|
||||||
memdelete(storage);
|
|
||||||
memdelete(canvas);
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rasterizer_gles2.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef RASTERIZERGLES2_H
|
|
||||||
#define RASTERIZERGLES2_H
|
|
||||||
|
|
||||||
#include "rasterizer_canvas_gles2.h"
|
|
||||||
#include "rasterizer_scene_gles2.h"
|
|
||||||
#include "rasterizer_storage_gles2.h"
|
|
||||||
#include "servers/rendering/rasterizer.h"
|
|
||||||
|
|
||||||
class RasterizerGLES2 : public Rasterizer {
|
|
||||||
static Rasterizer *_create_current();
|
|
||||||
|
|
||||||
RasterizerStorageGLES2 *storage;
|
|
||||||
RasterizerCanvasGLES2 *canvas;
|
|
||||||
RasterizerSceneGLES2 *scene;
|
|
||||||
|
|
||||||
double time_total;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual RasterizerStorage *get_storage();
|
|
||||||
virtual RasterizerCanvas *get_canvas();
|
|
||||||
virtual RasterizerScene *get_scene();
|
|
||||||
|
|
||||||
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true);
|
|
||||||
|
|
||||||
virtual void initialize();
|
|
||||||
virtual void begin_frame(double frame_step);
|
|
||||||
virtual void set_current_render_target(RID p_render_target);
|
|
||||||
virtual void restore_render_target(bool p_3d_was_drawn);
|
|
||||||
virtual void clear_render_target(const Color &p_color);
|
|
||||||
virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0);
|
|
||||||
virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
|
|
||||||
virtual void end_frame(bool p_swap_buffers);
|
|
||||||
virtual void finalize();
|
|
||||||
|
|
||||||
static Error is_viable();
|
|
||||||
static void make_current();
|
|
||||||
static void register_config();
|
|
||||||
|
|
||||||
virtual bool is_low_end() const { return true; }
|
|
||||||
|
|
||||||
RasterizerGLES2();
|
|
||||||
~RasterizerGLES2();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RASTERIZERGLES2_H
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,655 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* rasterizer_scene_gles2.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef RASTERIZERSCENEGLES2_H
|
|
||||||
#define RASTERIZERSCENEGLES2_H
|
|
||||||
|
|
||||||
/* Must come before shaders or the Windows build fails... */
|
|
||||||
#include "rasterizer_storage_gles2.h"
|
|
||||||
|
|
||||||
#include "shaders/cube_to_dp.glsl.gen.h"
|
|
||||||
#include "shaders/effect_blur.glsl.gen.h"
|
|
||||||
#include "shaders/scene.glsl.gen.h"
|
|
||||||
#include "shaders/tonemap.glsl.gen.h"
|
|
||||||
|
|
||||||
class RasterizerSceneGLES2 : public RasterizerScene {
|
|
||||||
public:
|
|
||||||
enum ShadowFilterMode {
|
|
||||||
SHADOW_FILTER_NEAREST,
|
|
||||||
SHADOW_FILTER_PCF5,
|
|
||||||
SHADOW_FILTER_PCF13,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
INSTANCE_ATTRIB_BASE = 8,
|
|
||||||
INSTANCE_BONE_BASE = 13,
|
|
||||||
};
|
|
||||||
|
|
||||||
ShadowFilterMode shadow_filter_mode;
|
|
||||||
|
|
||||||
RID default_material;
|
|
||||||
RID default_material_twosided;
|
|
||||||
RID default_shader;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
struct State {
|
|
||||||
bool texscreen_copied;
|
|
||||||
int current_blend_mode;
|
|
||||||
float current_line_width;
|
|
||||||
int current_depth_draw;
|
|
||||||
bool current_depth_test;
|
|
||||||
GLuint current_main_tex;
|
|
||||||
|
|
||||||
SceneShaderGLES2 scene_shader;
|
|
||||||
CubeToDpShaderGLES2 cube_to_dp_shader;
|
|
||||||
TonemapShaderGLES2 tonemap_shader;
|
|
||||||
EffectBlurShaderGLES2 effect_blur_shader;
|
|
||||||
|
|
||||||
GLuint sky_verts;
|
|
||||||
|
|
||||||
GLuint immediate_buffer;
|
|
||||||
Color default_ambient;
|
|
||||||
Color default_bg;
|
|
||||||
|
|
||||||
bool cull_front;
|
|
||||||
bool cull_disabled;
|
|
||||||
|
|
||||||
bool used_screen_texture;
|
|
||||||
bool shadow_is_dual_parabolloid;
|
|
||||||
float dual_parbolloid_direction;
|
|
||||||
float dual_parbolloid_zfar;
|
|
||||||
|
|
||||||
bool render_no_shadows;
|
|
||||||
|
|
||||||
Vector2 viewport_size;
|
|
||||||
|
|
||||||
Vector2 screen_pixel_size;
|
|
||||||
} state;
|
|
||||||
|
|
||||||
/* SHADOW ATLAS API */
|
|
||||||
|
|
||||||
uint64_t shadow_atlas_realloc_tolerance_msec;
|
|
||||||
|
|
||||||
struct ShadowAtlas {
|
|
||||||
enum {
|
|
||||||
QUADRANT_SHIFT = 27,
|
|
||||||
SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1,
|
|
||||||
SHADOW_INVALID = 0xFFFFFFFF,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Quadrant {
|
|
||||||
uint32_t subdivision;
|
|
||||||
|
|
||||||
struct Shadow {
|
|
||||||
RID owner;
|
|
||||||
uint64_t version;
|
|
||||||
uint64_t alloc_tick;
|
|
||||||
|
|
||||||
Shadow() {
|
|
||||||
version = 0;
|
|
||||||
alloc_tick = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector<Shadow> shadows;
|
|
||||||
|
|
||||||
Quadrant() {
|
|
||||||
subdivision = 0;
|
|
||||||
}
|
|
||||||
} quadrants[4];
|
|
||||||
|
|
||||||
int size_order[4];
|
|
||||||
uint32_t smallest_subdiv;
|
|
||||||
|
|
||||||
int size;
|
|
||||||
|
|
||||||
GLuint fbo;
|
|
||||||
GLuint depth;
|
|
||||||
GLuint color;
|
|
||||||
|
|
||||||
Map<RID, uint32_t> shadow_owners;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ShadowCubeMap {
|
|
||||||
GLuint fbo[6];
|
|
||||||
GLuint cubemap;
|
|
||||||
uint32_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector<ShadowCubeMap> shadow_cubemaps;
|
|
||||||
|
|
||||||
RID_PtrOwner<ShadowAtlas> shadow_atlas_owner;
|
|
||||||
|
|
||||||
RID shadow_atlas_create();
|
|
||||||
void shadow_atlas_set_size(RID p_atlas, int p_size);
|
|
||||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
|
|
||||||
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
|
||||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
|
|
||||||
|
|
||||||
struct DirectionalShadow {
|
|
||||||
GLuint fbo;
|
|
||||||
GLuint depth;
|
|
||||||
GLuint color;
|
|
||||||
|
|
||||||
int light_count;
|
|
||||||
int size;
|
|
||||||
int current_light;
|
|
||||||
} directional_shadow;
|
|
||||||
|
|
||||||
virtual int get_directional_light_shadow_size(RID p_light_intance);
|
|
||||||
virtual void set_directional_shadow_count(int p_count);
|
|
||||||
|
|
||||||
/* REFLECTION PROBE ATLAS API */
|
|
||||||
|
|
||||||
virtual RID reflection_atlas_create();
|
|
||||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_size);
|
|
||||||
virtual void reflection_atlas_set_subdivision(RID p_ref_atlas, int p_subdiv);
|
|
||||||
|
|
||||||
/* REFLECTION CUBEMAPS */
|
|
||||||
|
|
||||||
/* REFLECTION PROBE INSTANCE */
|
|
||||||
|
|
||||||
struct ReflectionProbeInstance {
|
|
||||||
RasterizerStorageGLES2::ReflectionProbe *probe_ptr;
|
|
||||||
RID probe;
|
|
||||||
RID self;
|
|
||||||
RID atlas;
|
|
||||||
|
|
||||||
int reflection_atlas_index;
|
|
||||||
|
|
||||||
int render_step;
|
|
||||||
int reflection_index;
|
|
||||||
|
|
||||||
GLuint fbo[6];
|
|
||||||
GLuint color[6];
|
|
||||||
GLuint depth;
|
|
||||||
GLuint cubemap;
|
|
||||||
|
|
||||||
int current_resolution;
|
|
||||||
mutable bool dirty;
|
|
||||||
|
|
||||||
uint64_t last_pass;
|
|
||||||
uint32_t index;
|
|
||||||
|
|
||||||
Transform transform;
|
|
||||||
};
|
|
||||||
|
|
||||||
mutable RID_PtrOwner<ReflectionProbeInstance> reflection_probe_instance_owner;
|
|
||||||
|
|
||||||
ReflectionProbeInstance **reflection_probe_instances;
|
|
||||||
int reflection_probe_count;
|
|
||||||
|
|
||||||
virtual RID reflection_probe_instance_create(RID p_probe);
|
|
||||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform);
|
|
||||||
virtual void reflection_probe_release_atlas_index(RID p_instance);
|
|
||||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance);
|
|
||||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance);
|
|
||||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas);
|
|
||||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance);
|
|
||||||
|
|
||||||
/* ENVIRONMENT API */
|
|
||||||
|
|
||||||
struct Environment {
|
|
||||||
RS::EnvironmentBG bg_mode;
|
|
||||||
|
|
||||||
RID sky;
|
|
||||||
float sky_custom_fov;
|
|
||||||
Basis sky_orientation;
|
|
||||||
|
|
||||||
Color bg_color;
|
|
||||||
float bg_energy;
|
|
||||||
float sky_ambient;
|
|
||||||
|
|
||||||
int camera_feed_id;
|
|
||||||
|
|
||||||
Color ambient_color;
|
|
||||||
float ambient_energy;
|
|
||||||
float ambient_sky_contribution;
|
|
||||||
|
|
||||||
int canvas_max_layer;
|
|
||||||
|
|
||||||
bool glow_enabled;
|
|
||||||
int glow_levels;
|
|
||||||
float glow_intensity;
|
|
||||||
float glow_strength;
|
|
||||||
float glow_bloom;
|
|
||||||
RS::EnvironmentGlowBlendMode glow_blend_mode;
|
|
||||||
float glow_hdr_bleed_threshold;
|
|
||||||
float glow_hdr_bleed_scale;
|
|
||||||
float glow_hdr_luminance_cap;
|
|
||||||
bool glow_bicubic_upscale;
|
|
||||||
|
|
||||||
bool dof_blur_far_enabled;
|
|
||||||
float dof_blur_far_distance;
|
|
||||||
float dof_blur_far_transition;
|
|
||||||
float dof_blur_far_amount;
|
|
||||||
RS::EnvironmentDOFBlurQuality dof_blur_far_quality;
|
|
||||||
|
|
||||||
bool dof_blur_near_enabled;
|
|
||||||
float dof_blur_near_distance;
|
|
||||||
float dof_blur_near_transition;
|
|
||||||
float dof_blur_near_amount;
|
|
||||||
RS::EnvironmentDOFBlurQuality dof_blur_near_quality;
|
|
||||||
|
|
||||||
bool adjustments_enabled;
|
|
||||||
float adjustments_brightness;
|
|
||||||
float adjustments_contrast;
|
|
||||||
float adjustments_saturation;
|
|
||||||
RID color_correction;
|
|
||||||
|
|
||||||
bool fog_enabled;
|
|
||||||
Color fog_color;
|
|
||||||
Color fog_sun_color;
|
|
||||||
float fog_sun_amount;
|
|
||||||
|
|
||||||
bool fog_depth_enabled;
|
|
||||||
float fog_depth_begin;
|
|
||||||
float fog_depth_end;
|
|
||||||
float fog_depth_curve;
|
|
||||||
bool fog_transmit_enabled;
|
|
||||||
float fog_transmit_curve;
|
|
||||||
bool fog_height_enabled;
|
|
||||||
float fog_height_min;
|
|
||||||
float fog_height_max;
|
|
||||||
float fog_height_curve;
|
|
||||||
|
|
||||||
Environment() :
|
|
||||||
bg_mode(RS::ENV_BG_CLEAR_COLOR),
|
|
||||||
sky_custom_fov(0.0),
|
|
||||||
bg_energy(1.0),
|
|
||||||
sky_ambient(0),
|
|
||||||
camera_feed_id(0),
|
|
||||||
ambient_energy(1.0),
|
|
||||||
ambient_sky_contribution(0.0),
|
|
||||||
canvas_max_layer(0),
|
|
||||||
glow_enabled(false),
|
|
||||||
glow_levels((1 << 2) | (1 << 4)),
|
|
||||||
glow_intensity(0.8),
|
|
||||||
glow_strength(1.0),
|
|
||||||
glow_bloom(0.0),
|
|
||||||
glow_blend_mode(RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT),
|
|
||||||
glow_hdr_bleed_threshold(1.0),
|
|
||||||
glow_hdr_bleed_scale(2.0),
|
|
||||||
glow_hdr_luminance_cap(12.0),
|
|
||||||
glow_bicubic_upscale(false),
|
|
||||||
dof_blur_far_enabled(false),
|
|
||||||
dof_blur_far_distance(10),
|
|
||||||
dof_blur_far_transition(5),
|
|
||||||
dof_blur_far_amount(0.1),
|
|
||||||
dof_blur_far_quality(RS::ENV_DOF_BLUR_QUALITY_MEDIUM),
|
|
||||||
dof_blur_near_enabled(false),
|
|
||||||
dof_blur_near_distance(2),
|
|
||||||
dof_blur_near_transition(1),
|
|
||||||
dof_blur_near_amount(0.1),
|
|
||||||
dof_blur_near_quality(RS::ENV_DOF_BLUR_QUALITY_MEDIUM),
|
|
||||||
adjustments_enabled(false),
|
|
||||||
adjustments_brightness(1.0),
|
|
||||||
adjustments_contrast(1.0),
|
|
||||||
adjustments_saturation(1.0),
|
|
||||||
fog_enabled(false),
|
|
||||||
fog_color(Color(0.5, 0.5, 0.5)),
|
|
||||||
fog_sun_color(Color(0.8, 0.8, 0.0)),
|
|
||||||
fog_sun_amount(0),
|
|
||||||
fog_depth_enabled(true),
|
|
||||||
fog_depth_begin(10),
|
|
||||||
fog_depth_end(0),
|
|
||||||
fog_depth_curve(1),
|
|
||||||
fog_transmit_enabled(true),
|
|
||||||
fog_transmit_curve(1),
|
|
||||||
fog_height_enabled(false),
|
|
||||||
fog_height_min(10),
|
|
||||||
fog_height_max(0),
|
|
||||||
fog_height_curve(1) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mutable RID_PtrOwner<Environment> environment_owner;
|
|
||||||
|
|
||||||
virtual RID environment_create();
|
|
||||||
|
|
||||||
virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg);
|
|
||||||
virtual void environment_set_sky(RID p_env, RID p_sky);
|
|
||||||
virtual void environment_set_sky_custom_fov(RID p_env, float p_scale);
|
|
||||||
virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation);
|
|
||||||
virtual void environment_set_bg_color(RID p_env, const Color &p_color);
|
|
||||||
virtual void environment_set_bg_energy(RID p_env, float p_energy);
|
|
||||||
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer);
|
|
||||||
virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0);
|
|
||||||
virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id);
|
|
||||||
|
|
||||||
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, RS::EnvironmentDOFBlurQuality p_quality);
|
|
||||||
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, RS::EnvironmentDOFBlurQuality p_quality);
|
|
||||||
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale);
|
|
||||||
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture);
|
|
||||||
|
|
||||||
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness);
|
|
||||||
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness);
|
|
||||||
|
|
||||||
virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
|
|
||||||
|
|
||||||
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp);
|
|
||||||
|
|
||||||
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount);
|
|
||||||
virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve);
|
|
||||||
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
|
|
||||||
|
|
||||||
virtual bool is_environment(RID p_env);
|
|
||||||
|
|
||||||
virtual RS::EnvironmentBG environment_get_background(RID p_env);
|
|
||||||
virtual int environment_get_canvas_max_layer(RID p_env);
|
|
||||||
|
|
||||||
/* LIGHT INSTANCE */
|
|
||||||
|
|
||||||
struct LightInstance {
|
|
||||||
struct ShadowTransform {
|
|
||||||
CameraMatrix camera;
|
|
||||||
Transform transform;
|
|
||||||
float farplane;
|
|
||||||
float split;
|
|
||||||
float bias_scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
ShadowTransform shadow_transform[4];
|
|
||||||
|
|
||||||
RID self;
|
|
||||||
RID light;
|
|
||||||
|
|
||||||
RasterizerStorageGLES2::Light *light_ptr;
|
|
||||||
Transform transform;
|
|
||||||
|
|
||||||
Vector3 light_vector;
|
|
||||||
Vector3 spot_vector;
|
|
||||||
float linear_att;
|
|
||||||
|
|
||||||
// TODO passes and all that stuff ?
|
|
||||||
uint64_t last_scene_pass;
|
|
||||||
uint64_t last_scene_shadow_pass;
|
|
||||||
|
|
||||||
uint16_t light_index;
|
|
||||||
uint16_t light_directional_index;
|
|
||||||
|
|
||||||
Rect2 directional_rect;
|
|
||||||
|
|
||||||
Set<RID> shadow_atlases; // atlases where this light is registered
|
|
||||||
};
|
|
||||||
|
|
||||||
mutable RID_PtrOwner<LightInstance> light_instance_owner;
|
|
||||||
|
|
||||||
virtual RID light_instance_create(RID p_light);
|
|
||||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
|
|
||||||
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 bool light_instances_can_render_shadow_cube() const { return storage->config.support_shadow_cubemaps; }
|
|
||||||
|
|
||||||
LightInstance **render_light_instances;
|
|
||||||
int render_directional_lights;
|
|
||||||
int render_light_instance_count;
|
|
||||||
|
|
||||||
/* REFLECTION INSTANCE */
|
|
||||||
|
|
||||||
virtual RID gi_probe_instance_create();
|
|
||||||
virtual void gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data);
|
|
||||||
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
|
|
||||||
virtual void gi_probe_instance_set_bounds(RID p_probe, const Vector3 &p_bounds);
|
|
||||||
|
|
||||||
/* RENDER LIST */
|
|
||||||
|
|
||||||
enum LightMode {
|
|
||||||
LIGHTMODE_NORMAL,
|
|
||||||
LIGHTMODE_UNSHADED,
|
|
||||||
LIGHTMODE_LIGHTMAP,
|
|
||||||
LIGHTMODE_LIGHTMAP_CAPTURE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RenderList {
|
|
||||||
enum {
|
|
||||||
MAX_LIGHTS = 255,
|
|
||||||
MAX_REFLECTION_PROBES = 255,
|
|
||||||
DEFAULT_MAX_ELEMENTS = 65536
|
|
||||||
};
|
|
||||||
|
|
||||||
int max_elements;
|
|
||||||
|
|
||||||
struct Element {
|
|
||||||
RasterizerScene::InstanceBase *instance;
|
|
||||||
|
|
||||||
RasterizerStorageGLES2::Geometry *geometry;
|
|
||||||
RasterizerStorageGLES2::Material *material;
|
|
||||||
RasterizerStorageGLES2::GeometryOwner *owner;
|
|
||||||
|
|
||||||
bool use_accum; //is this an add pass for multipass
|
|
||||||
bool *use_accum_ptr;
|
|
||||||
bool front_facing;
|
|
||||||
|
|
||||||
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 **elements;
|
|
||||||
|
|
||||||
int element_count;
|
|
||||||
int alpha_element_count;
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
element_count = 0;
|
|
||||||
alpha_element_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sorts
|
|
||||||
|
|
||||||
struct SortByKey {
|
|
||||||
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
|
||||||
if (A->depth_key == B->depth_key) {
|
|
||||||
return A->sort_key < B->sort_key;
|
|
||||||
} else {
|
|
||||||
return A->depth_key < B->depth_key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void sort_by_key(bool p_alpha) {
|
|
||||||
SortArray<Element *, SortByKey> sorter;
|
|
||||||
|
|
||||||
if (p_alpha) {
|
|
||||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
|
||||||
} else {
|
|
||||||
sorter.sort(elements, element_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SortByDepth {
|
|
||||||
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
|
||||||
return A->instance->depth < B->instance->depth;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void sort_by_depth(bool p_alpha) { //used for shadows
|
|
||||||
|
|
||||||
SortArray<Element *, SortByDepth> sorter;
|
|
||||||
if (p_alpha) {
|
|
||||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
|
||||||
} else {
|
|
||||||
sorter.sort(elements, element_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SortByReverseDepthAndPriority {
|
|
||||||
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
|
||||||
if (A->priority == B->priority) {
|
|
||||||
return A->instance->depth > B->instance->depth;
|
|
||||||
} else {
|
|
||||||
return A->priority < B->priority;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
_FORCE_INLINE_ Element *add_element() {
|
|
||||||
if (element_count + alpha_element_count >= max_elements)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
elements[element_count] = &base_elements[element_count];
|
|
||||||
return elements[element_count++];
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ Element *add_alpha_element() {
|
|
||||||
if (element_count + alpha_element_count >= max_elements) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx = max_elements - alpha_element_count - 1;
|
|
||||||
elements[idx] = &base_elements[idx];
|
|
||||||
alpha_element_count++;
|
|
||||||
return elements[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
element_count = 0;
|
|
||||||
alpha_element_count = 0;
|
|
||||||
|
|
||||||
elements = memnew_arr(Element *, max_elements);
|
|
||||||
base_elements = memnew_arr(Element, max_elements);
|
|
||||||
|
|
||||||
for (int i = 0; i < max_elements; i++) {
|
|
||||||
elements[i] = &base_elements[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderList() {
|
|
||||||
max_elements = DEFAULT_MAX_ELEMENTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
~RenderList() {
|
|
||||||
memdelete_arr(elements);
|
|
||||||
memdelete_arr(base_elements);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RenderList render_list;
|
|
||||||
|
|
||||||
void _add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass);
|
|
||||||
void _add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass);
|
|
||||||
|
|
||||||
void _copy_texture_to_buffer(GLuint p_texture, GLuint p_buffer);
|
|
||||||
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,
|
|
||||||
const Transform &p_view_transform,
|
|
||||||
const CameraMatrix &p_projection,
|
|
||||||
RID p_shadow_atlas,
|
|
||||||
Environment *p_env,
|
|
||||||
GLuint p_base_env,
|
|
||||||
float p_shadow_bias,
|
|
||||||
float p_shadow_normal_bias,
|
|
||||||
bool p_reverse_cull,
|
|
||||||
bool p_alpha_pass,
|
|
||||||
bool p_shadow);
|
|
||||||
|
|
||||||
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, const Basis &p_sky_orientation);
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void _set_cull(bool p_front, bool p_disabled, bool p_reverse_cull);
|
|
||||||
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
|
|
||||||
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
|
|
||||||
_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, bool accum_pass);
|
|
||||||
_FORCE_INLINE_ void _setup_refprobes(ReflectionProbeInstance *p_refprobe1, ReflectionProbeInstance *p_refprobe2, const Transform &p_view_transform, Environment *p_env);
|
|
||||||
_FORCE_INLINE_ void _render_geometry(RenderList::Element *p_element);
|
|
||||||
|
|
||||||
void _post_process(Environment *env, const CameraMatrix &p_cam_projection);
|
|
||||||
|
|
||||||
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 bool free(RID p_rid);
|
|
||||||
|
|
||||||
virtual void set_scene_pass(uint64_t p_pass);
|
|
||||||
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw);
|
|
||||||
|
|
||||||
void iteration();
|
|
||||||
void initialize();
|
|
||||||
void finalize();
|
|
||||||
RasterizerSceneGLES2();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RASTERIZERSCENEGLES2_H
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,99 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* shader_compiler_gles2.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SHADERCOMPILERGLES2_H
|
|
||||||
#define SHADERCOMPILERGLES2_H
|
|
||||||
|
|
||||||
#include "core/pair.h"
|
|
||||||
#include "core/string_builder.h"
|
|
||||||
#include "servers/rendering/shader_language.h"
|
|
||||||
#include "servers/rendering/shader_types.h"
|
|
||||||
#include "servers/rendering_server.h"
|
|
||||||
|
|
||||||
class ShaderCompilerGLES2 {
|
|
||||||
public:
|
|
||||||
struct IdentifierActions {
|
|
||||||
Map<StringName, Pair<int *, int>> render_mode_values;
|
|
||||||
Map<StringName, bool *> render_mode_flags;
|
|
||||||
Map<StringName, bool *> usage_flag_pointers;
|
|
||||||
Map<StringName, bool *> write_flag_pointers;
|
|
||||||
|
|
||||||
Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GeneratedCode {
|
|
||||||
Vector<CharString> custom_defines;
|
|
||||||
Vector<StringName> uniforms;
|
|
||||||
Vector<StringName> texture_uniforms;
|
|
||||||
Vector<ShaderLanguage::DataType> texture_types;
|
|
||||||
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
|
|
||||||
|
|
||||||
String vertex_global;
|
|
||||||
String vertex;
|
|
||||||
String fragment_global;
|
|
||||||
String fragment;
|
|
||||||
String light;
|
|
||||||
|
|
||||||
bool uses_fragment_time;
|
|
||||||
bool uses_vertex_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
ShaderLanguage parser;
|
|
||||||
|
|
||||||
struct DefaultIdentifierActions {
|
|
||||||
Map<StringName, String> renames;
|
|
||||||
Map<StringName, String> render_mode_defines;
|
|
||||||
Map<StringName, String> usage_defines;
|
|
||||||
};
|
|
||||||
|
|
||||||
void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added);
|
|
||||||
String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope = true);
|
|
||||||
|
|
||||||
StringName current_func_name;
|
|
||||||
StringName vertex_name;
|
|
||||||
StringName fragment_name;
|
|
||||||
StringName light_name;
|
|
||||||
StringName time_name;
|
|
||||||
|
|
||||||
Set<StringName> used_name_defines;
|
|
||||||
Set<StringName> used_flag_pointers;
|
|
||||||
Set<StringName> used_rmode_defines;
|
|
||||||
Set<StringName> internal_functions;
|
|
||||||
|
|
||||||
DefaultIdentifierActions actions[RS::SHADER_MAX];
|
|
||||||
|
|
||||||
public:
|
|
||||||
Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
|
|
||||||
|
|
||||||
ShaderCompilerGLES2();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SHADERCOMPILERGLES2_H
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,260 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* shader_gles2.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SHADER_GLES2_H
|
|
||||||
#define SHADER_GLES2_H
|
|
||||||
|
|
||||||
// This must come first to avoid windows.h mess
|
|
||||||
#include "platform_config.h"
|
|
||||||
#ifndef GLES2_INCLUDE_H
|
|
||||||
#include <GLES2/gl2.h>
|
|
||||||
#else
|
|
||||||
#include GLES2_INCLUDE_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "core/hash_map.h"
|
|
||||||
#include "core/map.h"
|
|
||||||
#include "core/math/camera_matrix.h"
|
|
||||||
#include "core/pair.h"
|
|
||||||
#include "core/variant.h"
|
|
||||||
#include "servers/rendering/shader_language.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class RasterizerStorageGLES2;
|
|
||||||
|
|
||||||
class ShaderGLES2 {
|
|
||||||
protected:
|
|
||||||
struct Enum {
|
|
||||||
uint64_t mask;
|
|
||||||
uint64_t shift;
|
|
||||||
const char *defines[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EnumValue {
|
|
||||||
uint64_t set_mask;
|
|
||||||
uint64_t clear_mask;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AttributePair {
|
|
||||||
const char *name;
|
|
||||||
int index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct UniformPair {
|
|
||||||
const char *name;
|
|
||||||
Variant::Type type_hint;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TexUnitPair {
|
|
||||||
const char *name;
|
|
||||||
int index;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool uniforms_dirty;
|
|
||||||
|
|
||||||
private:
|
|
||||||
//@TODO Optimize to a fixed set of shader pools and use a LRU
|
|
||||||
int uniform_count;
|
|
||||||
int texunit_pair_count;
|
|
||||||
int conditional_count;
|
|
||||||
int vertex_code_start;
|
|
||||||
int fragment_code_start;
|
|
||||||
int attribute_pair_count;
|
|
||||||
|
|
||||||
struct CustomCode {
|
|
||||||
String vertex;
|
|
||||||
String vertex_globals;
|
|
||||||
String fragment;
|
|
||||||
String fragment_globals;
|
|
||||||
String light;
|
|
||||||
uint32_t version;
|
|
||||||
Vector<StringName> texture_uniforms;
|
|
||||||
Vector<StringName> custom_uniforms;
|
|
||||||
Vector<CharString> custom_defines;
|
|
||||||
Set<uint32_t> versions;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Version {
|
|
||||||
GLuint id;
|
|
||||||
GLuint vert_id;
|
|
||||||
GLuint frag_id;
|
|
||||||
GLint *uniform_location;
|
|
||||||
Vector<GLint> texture_uniform_locations;
|
|
||||||
Map<StringName, GLint> custom_uniform_locations;
|
|
||||||
uint32_t code_version;
|
|
||||||
bool ok;
|
|
||||||
Version() {
|
|
||||||
id = 0;
|
|
||||||
vert_id = 0;
|
|
||||||
frag_id = 0;
|
|
||||||
uniform_location = nullptr;
|
|
||||||
code_version = 0;
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Version *version;
|
|
||||||
|
|
||||||
union VersionKey {
|
|
||||||
struct {
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t code_version;
|
|
||||||
};
|
|
||||||
uint64_t key;
|
|
||||||
bool operator==(const VersionKey &p_key) const { return key == p_key.key; }
|
|
||||||
bool operator<(const VersionKey &p_key) const { return key < p_key.key; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VersionKeyHash {
|
|
||||||
static _FORCE_INLINE_ uint32_t hash(const VersionKey &p_key) { return HashMapHasherDefault::hash(p_key.key); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//this should use a way more cachefriendly version..
|
|
||||||
HashMap<VersionKey, Version, VersionKeyHash> version_map;
|
|
||||||
|
|
||||||
HashMap<uint32_t, CustomCode> custom_code_map;
|
|
||||||
uint32_t last_custom_code;
|
|
||||||
|
|
||||||
VersionKey conditional_version;
|
|
||||||
VersionKey new_conditional_version;
|
|
||||||
|
|
||||||
virtual String get_shader_name() const = 0;
|
|
||||||
|
|
||||||
const char **conditional_defines;
|
|
||||||
const char **uniform_names;
|
|
||||||
const AttributePair *attribute_pairs;
|
|
||||||
const TexUnitPair *texunit_pairs;
|
|
||||||
const char *vertex_code;
|
|
||||||
const char *fragment_code;
|
|
||||||
CharString fragment_code0;
|
|
||||||
CharString fragment_code1;
|
|
||||||
CharString fragment_code2;
|
|
||||||
CharString fragment_code3;
|
|
||||||
|
|
||||||
CharString vertex_code0;
|
|
||||||
CharString vertex_code1;
|
|
||||||
CharString vertex_code2;
|
|
||||||
|
|
||||||
Vector<CharString> custom_defines;
|
|
||||||
|
|
||||||
Version *get_current_version();
|
|
||||||
|
|
||||||
static ShaderGLES2 *active;
|
|
||||||
|
|
||||||
int max_image_units;
|
|
||||||
|
|
||||||
Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value>>> uniform_values;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
_FORCE_INLINE_ int _get_uniform(int p_which) const;
|
|
||||||
_FORCE_INLINE_ void _set_conditional(int p_which, bool p_value);
|
|
||||||
|
|
||||||
void setup(const char **p_conditional_defines,
|
|
||||||
int p_conditional_count,
|
|
||||||
const char **p_uniform_names,
|
|
||||||
int p_uniform_count,
|
|
||||||
const AttributePair *p_attribute_pairs,
|
|
||||||
int p_attribute_count,
|
|
||||||
const TexUnitPair *p_texunit_pairs,
|
|
||||||
int p_texunit_pair_count,
|
|
||||||
const char *p_vertex_code,
|
|
||||||
const char *p_fragment_code,
|
|
||||||
int p_vertex_code_start,
|
|
||||||
int p_fragment_code_start);
|
|
||||||
|
|
||||||
ShaderGLES2();
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
CUSTOM_SHADER_DISABLED = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
GLint get_uniform_location(const String &p_name) const;
|
|
||||||
GLint get_uniform_location(int p_index) const;
|
|
||||||
|
|
||||||
static _FORCE_INLINE_ ShaderGLES2 *get_active() { return active; }
|
|
||||||
bool bind();
|
|
||||||
void unbind();
|
|
||||||
|
|
||||||
inline GLuint get_program() const { return version ? version->id : 0; }
|
|
||||||
|
|
||||||
void clear_caches();
|
|
||||||
|
|
||||||
uint32_t create_custom_shader();
|
|
||||||
void set_custom_shader_code(uint32_t p_code_id,
|
|
||||||
const String &p_vertex,
|
|
||||||
const String &p_vertex_globals,
|
|
||||||
const String &p_fragment,
|
|
||||||
const String &p_light,
|
|
||||||
const String &p_fragment_globals,
|
|
||||||
const Vector<StringName> &p_uniforms,
|
|
||||||
const Vector<StringName> &p_texture_uniforms,
|
|
||||||
const Vector<CharString> &p_custom_defines);
|
|
||||||
|
|
||||||
void set_custom_shader(uint32_t p_code_id);
|
|
||||||
void free_custom_shader(uint32_t p_code_id);
|
|
||||||
|
|
||||||
uint32_t get_version_key() const { return conditional_version.version; }
|
|
||||||
|
|
||||||
// this void* is actually a RasterizerStorageGLES2::Material, but C++ doesn't
|
|
||||||
// like forward declared nested classes.
|
|
||||||
void use_material(void *p_material);
|
|
||||||
|
|
||||||
_FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; }
|
|
||||||
_FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
|
|
||||||
|
|
||||||
virtual void init() = 0;
|
|
||||||
void finish();
|
|
||||||
|
|
||||||
void add_custom_define(const String &p_define) {
|
|
||||||
custom_defines.push_back(p_define.utf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~ShaderGLES2();
|
|
||||||
};
|
|
||||||
|
|
||||||
// called a lot, made inline
|
|
||||||
|
|
||||||
int ShaderGLES2::_get_uniform(int p_which) const {
|
|
||||||
ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
|
|
||||||
ERR_FAIL_COND_V(!version, -1);
|
|
||||||
return version->uniform_location[p_which];
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShaderGLES2::_set_conditional(int p_which, bool p_value) {
|
|
||||||
ERR_FAIL_INDEX(p_which, conditional_count);
|
|
||||||
if (p_value)
|
|
||||||
new_conditional_version.version |= (1 << p_which);
|
|
||||||
else
|
|
||||||
new_conditional_version.version &= ~(1 << p_which);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
if "GLES2_GLSL" in env["BUILDERS"]:
|
|
||||||
env.GLES2_GLSL("copy.glsl")
|
|
||||||
# env.GLES2_GLSL('resolve.glsl');
|
|
||||||
env.GLES2_GLSL("canvas.glsl")
|
|
||||||
env.GLES2_GLSL("canvas_shadow.glsl")
|
|
||||||
env.GLES2_GLSL("scene.glsl")
|
|
||||||
env.GLES2_GLSL("cubemap_filter.glsl")
|
|
||||||
env.GLES2_GLSL("cube_to_dp.glsl")
|
|
||||||
# env.GLES2_GLSL('blend_shape.glsl');
|
|
||||||
# env.GLES2_GLSL('screen_space_reflection.glsl');
|
|
||||||
env.GLES2_GLSL("effect_blur.glsl")
|
|
||||||
# env.GLES2_GLSL('subsurf_scattering.glsl');
|
|
||||||
# env.GLES2_GLSL('ssao.glsl');
|
|
||||||
# env.GLES2_GLSL('ssao_minify.glsl');
|
|
||||||
# env.GLES2_GLSL('ssao_blur.glsl');
|
|
||||||
# env.GLES2_GLSL('exposure.glsl');
|
|
||||||
env.GLES2_GLSL("tonemap.glsl")
|
|
||||||
# env.GLES2_GLSL('particles.glsl');
|
|
||||||
env.GLES2_GLSL("lens_distorted.glsl")
|
|
|
@ -1,194 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
/*
|
|
||||||
from RenderingServer:
|
|
||||||
|
|
||||||
ARRAY_VERTEX=0,
|
|
||||||
ARRAY_NORMAL=1,
|
|
||||||
ARRAY_TANGENT=2,
|
|
||||||
ARRAY_COLOR=3,
|
|
||||||
ARRAY_TEX_UV=4,
|
|
||||||
ARRAY_TEX_UV2=5,
|
|
||||||
ARRAY_BONES=6,
|
|
||||||
ARRAY_WEIGHTS=7,
|
|
||||||
ARRAY_INDEX=8,
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef USE_2D_VERTEX
|
|
||||||
#define VFORMAT vec2
|
|
||||||
#else
|
|
||||||
#define VFORMAT vec3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* INPUT ATTRIBS */
|
|
||||||
|
|
||||||
layout(location = 0) in highp VFORMAT vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
layout(location = 1) in vec3 normal_attrib;
|
|
||||||
|
|
||||||
#ifdef ENABLE_TANGENT
|
|
||||||
layout(location = 2) in vec4 tangent_attrib;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_COLOR
|
|
||||||
layout(location = 3) in vec4 color_attrib;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV
|
|
||||||
layout(location = 4) in vec2 uv_attrib;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV2
|
|
||||||
layout(location = 5) in vec2 uv2_attrib;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_SKELETON
|
|
||||||
layout(location = 6) in ivec4 bone_attrib;
|
|
||||||
layout(location = 7) in vec4 weight_attrib;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* BLEND ATTRIBS */
|
|
||||||
|
|
||||||
#ifdef ENABLE_BLEND
|
|
||||||
|
|
||||||
layout(location = 8) in highp VFORMAT vertex_attrib_blend;
|
|
||||||
layout(location = 9) in vec3 normal_attrib_blend;
|
|
||||||
|
|
||||||
#ifdef ENABLE_TANGENT
|
|
||||||
layout(location = 10) in vec4 tangent_attrib_blend;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_COLOR
|
|
||||||
layout(location = 11) in vec4 color_attrib_blend;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV
|
|
||||||
layout(location = 12) in vec2 uv_attrib_blend;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV2
|
|
||||||
layout(location = 13) in vec2 uv2_attrib_blend;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_SKELETON
|
|
||||||
layout(location = 14) in ivec4 bone_attrib_blend;
|
|
||||||
layout(location = 15) in vec4 weight_attrib_blend;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* OUTPUTS */
|
|
||||||
|
|
||||||
out VFORMAT vertex_out; //tfb:
|
|
||||||
|
|
||||||
#ifdef ENABLE_NORMAL
|
|
||||||
out vec3 normal_out; //tfb:ENABLE_NORMAL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_TANGENT
|
|
||||||
out vec4 tangent_out; //tfb:ENABLE_TANGENT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_COLOR
|
|
||||||
out vec4 color_out; //tfb:ENABLE_COLOR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV
|
|
||||||
out vec2 uv_out; //tfb:ENABLE_UV
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV2
|
|
||||||
out vec2 uv2_out; //tfb:ENABLE_UV2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_SKELETON
|
|
||||||
out ivec4 bone_out; //tfb:ENABLE_SKELETON
|
|
||||||
out vec4 weight_out; //tfb:ENABLE_SKELETON
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform float blend_amount;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
#ifdef ENABLE_BLEND
|
|
||||||
|
|
||||||
vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount;
|
|
||||||
|
|
||||||
#ifdef ENABLE_NORMAL
|
|
||||||
normal_out = normal_attrib_blend + normal_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_TANGENT
|
|
||||||
|
|
||||||
tangent_out.xyz = tangent_attrib_blend.xyz + tangent_attrib.xyz * blend_amount;
|
|
||||||
tangent_out.w = tangent_attrib_blend.w; //just copy, no point in blending his
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_COLOR
|
|
||||||
|
|
||||||
color_out = color_attrib_blend + color_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV
|
|
||||||
|
|
||||||
uv_out = uv_attrib_blend + uv_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV2
|
|
||||||
|
|
||||||
uv2_out = uv2_attrib_blend + uv2_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_SKELETON
|
|
||||||
|
|
||||||
bone_out = bone_attrib_blend;
|
|
||||||
weight_out = weight_attrib_blend + weight_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else //ENABLE_BLEND
|
|
||||||
|
|
||||||
vertex_out = vertex_attrib * blend_amount;
|
|
||||||
|
|
||||||
#ifdef ENABLE_NORMAL
|
|
||||||
normal_out = normal_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_TANGENT
|
|
||||||
|
|
||||||
tangent_out.xyz = tangent_attrib.xyz * blend_amount;
|
|
||||||
tangent_out.w = tangent_attrib.w; //just copy, no point in blending his
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_COLOR
|
|
||||||
|
|
||||||
color_out = color_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV
|
|
||||||
|
|
||||||
uv_out = uv_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_UV2
|
|
||||||
|
|
||||||
uv2_out = uv2_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_SKELETON
|
|
||||||
|
|
||||||
bone_out = bone_attrib;
|
|
||||||
weight_out = weight_attrib * blend_amount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
gl_Position = vec4(0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
|
@ -1,619 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
#extension GL_OES_texture_3D : enable
|
|
||||||
#else
|
|
||||||
#extension GL_EXT_texture_array : enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform highp mat4 projection_matrix;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#include "stdlib.glsl"
|
|
||||||
|
|
||||||
uniform highp mat4 modelview_matrix;
|
|
||||||
uniform highp mat4 extra_matrix;
|
|
||||||
attribute highp vec2 vertex; // attrib:0
|
|
||||||
attribute vec4 color_attrib; // attrib:3
|
|
||||||
attribute vec2 uv_attrib; // attrib:4
|
|
||||||
|
|
||||||
#ifdef USE_SKELETON
|
|
||||||
attribute highp vec4 bone_indices; // attrib:6
|
|
||||||
attribute highp vec4 bone_weights; // attrib:7
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_INSTANCING
|
|
||||||
|
|
||||||
attribute highp vec4 instance_xform0; //attrib:8
|
|
||||||
attribute highp vec4 instance_xform1; //attrib:9
|
|
||||||
attribute highp vec4 instance_xform2; //attrib:10
|
|
||||||
attribute highp vec4 instance_color; //attrib:11
|
|
||||||
|
|
||||||
#ifdef USE_INSTANCE_CUSTOM
|
|
||||||
attribute highp vec4 instance_custom_data; //attrib:12
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SKELETON
|
|
||||||
uniform highp sampler2D skeleton_texture; // texunit:-3
|
|
||||||
uniform highp ivec2 skeleton_texture_size;
|
|
||||||
uniform highp mat4 skeleton_transform;
|
|
||||||
uniform highp mat4 skeleton_transform_inverse;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
varying vec4 color_interp;
|
|
||||||
|
|
||||||
uniform highp vec2 color_texpixel_size;
|
|
||||||
|
|
||||||
#ifdef USE_TEXTURE_RECT
|
|
||||||
|
|
||||||
uniform vec4 dst_rect;
|
|
||||||
uniform vec4 src_rect;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform highp float time;
|
|
||||||
|
|
||||||
#ifdef USE_LIGHTING
|
|
||||||
|
|
||||||
// light matrices
|
|
||||||
uniform highp mat4 light_matrix;
|
|
||||||
uniform highp mat4 light_matrix_inverse;
|
|
||||||
uniform highp mat4 light_local_matrix;
|
|
||||||
uniform highp mat4 shadow_matrix;
|
|
||||||
uniform highp vec4 light_color;
|
|
||||||
uniform highp vec4 light_shadow_color;
|
|
||||||
uniform highp vec2 light_pos;
|
|
||||||
uniform highp float shadowpixel_size;
|
|
||||||
uniform highp float shadow_gradient;
|
|
||||||
uniform highp float light_height;
|
|
||||||
uniform highp float light_outside_alpha;
|
|
||||||
uniform highp float shadow_distance_mult;
|
|
||||||
|
|
||||||
varying vec4 light_uv_interp;
|
|
||||||
varying vec2 transformed_light_uv;
|
|
||||||
varying vec4 local_rot;
|
|
||||||
|
|
||||||
#ifdef USE_SHADOWS
|
|
||||||
varying highp vec2 pos;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const bool at_light_pass = true;
|
|
||||||
#else
|
|
||||||
const bool at_light_pass = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
VERTEX_SHADER_GLOBALS
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
vec2 select(vec2 a, vec2 b, bvec2 c) {
|
|
||||||
vec2 ret;
|
|
||||||
|
|
||||||
ret.x = c.x ? b.x : a.x;
|
|
||||||
ret.y = c.y ? b.y : a.y;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 color = color_attrib;
|
|
||||||
vec2 uv;
|
|
||||||
|
|
||||||
#ifdef USE_INSTANCING
|
|
||||||
mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)));
|
|
||||||
color *= instance_color;
|
|
||||||
|
|
||||||
#ifdef USE_INSTANCE_CUSTOM
|
|
||||||
vec4 instance_custom = instance_custom_data;
|
|
||||||
#else
|
|
||||||
vec4 instance_custom = vec4(0.0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
mat4 extra_matrix_instance = extra_matrix;
|
|
||||||
vec4 instance_custom = vec4(0.0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_TEXTURE_RECT
|
|
||||||
|
|
||||||
if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
|
|
||||||
uv = src_rect.xy + abs(src_rect.zw) * vertex.yx;
|
|
||||||
} else {
|
|
||||||
uv = src_rect.xy + abs(src_rect.zw) * vertex;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0);
|
|
||||||
|
|
||||||
// This is what is done in the GLES 3 bindings and should
|
|
||||||
// take care of flipped rects.
|
|
||||||
//
|
|
||||||
// But it doesn't.
|
|
||||||
// I don't know why, will need to investigate further.
|
|
||||||
|
|
||||||
outvec.xy = dst_rect.xy + abs(dst_rect.zw) * select(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0)));
|
|
||||||
|
|
||||||
// outvec.xy = dst_rect.xy + abs(dst_rect.zw) * vertex;
|
|
||||||
#else
|
|
||||||
vec4 outvec = vec4(vertex.xy, 0.0, 1.0);
|
|
||||||
|
|
||||||
uv = uv_attrib;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float point_size = 1.0;
|
|
||||||
|
|
||||||
{
|
|
||||||
vec2 src_vtx = outvec.xy;
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
VERTEX_SHADER_CODE
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_PointSize = point_size;
|
|
||||||
|
|
||||||
#if !defined(SKIP_TRANSFORM_USED)
|
|
||||||
outvec = extra_matrix_instance * outvec;
|
|
||||||
outvec = modelview_matrix * outvec;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
color_interp = color;
|
|
||||||
|
|
||||||
#ifdef USE_PIXEL_SNAP
|
|
||||||
outvec.xy = floor(outvec + 0.5).xy;
|
|
||||||
// precision issue on some hardware creates artifacts within texture
|
|
||||||
// offset uv by a small amount to avoid
|
|
||||||
uv += 1e-5;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SKELETON
|
|
||||||
|
|
||||||
// look up transform from the "pose texture"
|
|
||||||
if (bone_weights != vec4(0.0)) {
|
|
||||||
highp mat4 bone_transform = mat4(0.0);
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
ivec2 tex_ofs = ivec2(int(bone_indices[i]) * 2, 0);
|
|
||||||
|
|
||||||
highp mat4 b = mat4(
|
|
||||||
texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(0, 0)),
|
|
||||||
texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(1, 0)),
|
|
||||||
vec4(0.0, 0.0, 1.0, 0.0),
|
|
||||||
vec4(0.0, 0.0, 0.0, 1.0));
|
|
||||||
|
|
||||||
bone_transform += b * bone_weights[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
mat4 bone_matrix = skeleton_transform * transpose(bone_transform) * skeleton_transform_inverse;
|
|
||||||
|
|
||||||
outvec = bone_matrix * outvec;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uv_interp = uv;
|
|
||||||
gl_Position = projection_matrix * outvec;
|
|
||||||
|
|
||||||
#ifdef USE_LIGHTING
|
|
||||||
|
|
||||||
light_uv_interp.xy = (light_matrix * outvec).xy;
|
|
||||||
light_uv_interp.zw = (light_local_matrix * outvec).xy;
|
|
||||||
|
|
||||||
transformed_light_uv = (mat3(light_matrix_inverse) * vec3(light_uv_interp.zw, 0.0)).xy; //for normal mapping
|
|
||||||
|
|
||||||
#ifdef USE_SHADOWS
|
|
||||||
pos = outvec.xy;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(1.0, 0.0, 0.0, 0.0))).xy);
|
|
||||||
local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * vec4(0.0, 1.0, 0.0, 0.0))).xy);
|
|
||||||
#ifdef USE_TEXTURE_RECT
|
|
||||||
local_rot.xy *= sign(src_rect.z);
|
|
||||||
local_rot.zw *= sign(src_rect.w);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
#extension GL_OES_texture_3D : enable
|
|
||||||
#else
|
|
||||||
#extension GL_EXT_texture_array : enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// texture2DLodEXT and textureCubeLodEXT are fragment shader specific.
|
|
||||||
// Do not copy these defines in the vertex section.
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
#ifdef GL_EXT_shader_texture_lod
|
|
||||||
#extension GL_EXT_shader_texture_lod : enable
|
|
||||||
#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
#endif // !USE_GLES_OVER_GL
|
|
||||||
|
|
||||||
#ifdef GL_ARB_shader_texture_lod
|
|
||||||
#extension GL_ARB_shader_texture_lod : enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
|
|
||||||
#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "stdlib.glsl"
|
|
||||||
|
|
||||||
uniform sampler2D color_texture; // texunit:-1
|
|
||||||
/* clang-format on */
|
|
||||||
uniform highp vec2 color_texpixel_size;
|
|
||||||
uniform mediump sampler2D normal_texture; // texunit:-2
|
|
||||||
|
|
||||||
varying mediump vec2 uv_interp;
|
|
||||||
varying mediump vec4 color_interp;
|
|
||||||
|
|
||||||
uniform highp float time;
|
|
||||||
|
|
||||||
uniform vec4 final_modulate;
|
|
||||||
|
|
||||||
#ifdef SCREEN_TEXTURE_USED
|
|
||||||
|
|
||||||
uniform sampler2D screen_texture; // texunit:-4
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SCREEN_UV_USED
|
|
||||||
|
|
||||||
uniform vec2 screen_pixel_size;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_LIGHTING
|
|
||||||
|
|
||||||
uniform highp mat4 light_matrix;
|
|
||||||
uniform highp mat4 light_local_matrix;
|
|
||||||
uniform highp mat4 shadow_matrix;
|
|
||||||
uniform highp vec4 light_color;
|
|
||||||
uniform highp vec4 light_shadow_color;
|
|
||||||
uniform highp vec2 light_pos;
|
|
||||||
uniform highp float shadowpixel_size;
|
|
||||||
uniform highp float shadow_gradient;
|
|
||||||
uniform highp float light_height;
|
|
||||||
uniform highp float light_outside_alpha;
|
|
||||||
uniform highp float shadow_distance_mult;
|
|
||||||
|
|
||||||
uniform lowp sampler2D light_texture; // texunit:-4
|
|
||||||
varying vec4 light_uv_interp;
|
|
||||||
varying vec2 transformed_light_uv;
|
|
||||||
|
|
||||||
varying vec4 local_rot;
|
|
||||||
|
|
||||||
#ifdef USE_SHADOWS
|
|
||||||
|
|
||||||
uniform highp sampler2D shadow_texture; // texunit:-5
|
|
||||||
varying highp vec2 pos;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const bool at_light_pass = true;
|
|
||||||
#else
|
|
||||||
const bool at_light_pass = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform bool use_default_normal;
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
FRAGMENT_SHADER_GLOBALS
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void light_compute(
|
|
||||||
inout vec4 light,
|
|
||||||
inout vec2 light_vec,
|
|
||||||
inout float light_height,
|
|
||||||
inout vec4 light_color,
|
|
||||||
vec2 light_uv,
|
|
||||||
inout vec4 shadow_color,
|
|
||||||
inout vec2 shadow_vec,
|
|
||||||
vec3 normal,
|
|
||||||
vec2 uv,
|
|
||||||
#if defined(SCREEN_UV_USED)
|
|
||||||
vec2 screen_uv,
|
|
||||||
#endif
|
|
||||||
vec4 color) {
|
|
||||||
|
|
||||||
#if defined(USE_LIGHT_SHADER_CODE)
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
LIGHT_SHADER_CODE
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 color = color_interp;
|
|
||||||
vec2 uv = uv_interp;
|
|
||||||
#ifdef USE_FORCE_REPEAT
|
|
||||||
//needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that don't support it
|
|
||||||
uv = mod(uv, vec2(1.0, 1.0));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(COLOR_USED)
|
|
||||||
//default behavior, texture by color
|
|
||||||
color *= texture2D(color_texture, uv);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SCREEN_UV_USED
|
|
||||||
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vec3 normal;
|
|
||||||
|
|
||||||
#if defined(NORMAL_USED)
|
|
||||||
|
|
||||||
bool normal_used = true;
|
|
||||||
#else
|
|
||||||
bool normal_used = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (use_default_normal) {
|
|
||||||
normal.xy = texture2D(normal_texture, uv).xy * 2.0 - 1.0;
|
|
||||||
normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
|
|
||||||
normal_used = true;
|
|
||||||
} else {
|
|
||||||
normal = vec3(0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
float normal_depth = 1.0;
|
|
||||||
|
|
||||||
#if defined(NORMALMAP_USED)
|
|
||||||
vec3 normal_map = vec3(0.0, 0.0, 1.0);
|
|
||||||
normal_used = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
FRAGMENT_SHADER_CODE
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#if defined(NORMALMAP_USED)
|
|
||||||
normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
color *= final_modulate;
|
|
||||||
|
|
||||||
#ifdef USE_LIGHTING
|
|
||||||
|
|
||||||
vec2 light_vec = transformed_light_uv;
|
|
||||||
vec2 shadow_vec = transformed_light_uv;
|
|
||||||
|
|
||||||
if (normal_used) {
|
|
||||||
normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
|
|
||||||
}
|
|
||||||
|
|
||||||
float att = 1.0;
|
|
||||||
|
|
||||||
vec2 light_uv = light_uv_interp.xy;
|
|
||||||
vec4 light = texture2D(light_texture, light_uv);
|
|
||||||
|
|
||||||
if (any(lessThan(light_uv_interp.xy, vec2(0.0, 0.0))) || any(greaterThanEqual(light_uv_interp.xy, vec2(1.0, 1.0)))) {
|
|
||||||
color.a *= light_outside_alpha; //invisible
|
|
||||||
|
|
||||||
} else {
|
|
||||||
float real_light_height = light_height;
|
|
||||||
vec4 real_light_color = light_color;
|
|
||||||
vec4 real_light_shadow_color = light_shadow_color;
|
|
||||||
|
|
||||||
#if defined(USE_LIGHT_SHADER_CODE)
|
|
||||||
//light is written by the light shader
|
|
||||||
light_compute(
|
|
||||||
light,
|
|
||||||
light_vec,
|
|
||||||
real_light_height,
|
|
||||||
real_light_color,
|
|
||||||
light_uv,
|
|
||||||
real_light_shadow_color,
|
|
||||||
shadow_vec,
|
|
||||||
normal,
|
|
||||||
uv,
|
|
||||||
#if defined(SCREEN_UV_USED)
|
|
||||||
screen_uv,
|
|
||||||
#endif
|
|
||||||
color);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
light *= real_light_color;
|
|
||||||
|
|
||||||
if (normal_used) {
|
|
||||||
vec3 light_normal = normalize(vec3(light_vec, -real_light_height));
|
|
||||||
light *= max(dot(-light_normal, normal), 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
color *= light;
|
|
||||||
|
|
||||||
#ifdef USE_SHADOWS
|
|
||||||
|
|
||||||
#ifdef SHADOW_VEC_USED
|
|
||||||
mat3 inverse_light_matrix = mat3(light_matrix);
|
|
||||||
inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
|
|
||||||
inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
|
|
||||||
inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
|
|
||||||
shadow_vec = (inverse_light_matrix * vec3(shadow_vec, 0.0)).xy;
|
|
||||||
#else
|
|
||||||
shadow_vec = light_uv_interp.zw;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float angle_to_light = -atan(shadow_vec.x, shadow_vec.y);
|
|
||||||
float PI = 3.14159265358979323846264;
|
|
||||||
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
|
|
||||||
float ang*/
|
|
||||||
|
|
||||||
float su, sz;
|
|
||||||
|
|
||||||
float abs_angle = abs(angle_to_light);
|
|
||||||
vec2 point;
|
|
||||||
float sh;
|
|
||||||
if (abs_angle < 45.0 * PI / 180.0) {
|
|
||||||
point = shadow_vec;
|
|
||||||
sh = 0.0 + (1.0 / 8.0);
|
|
||||||
} else if (abs_angle > 135.0 * PI / 180.0) {
|
|
||||||
point = -shadow_vec;
|
|
||||||
sh = 0.5 + (1.0 / 8.0);
|
|
||||||
} else if (angle_to_light > 0.0) {
|
|
||||||
point = vec2(shadow_vec.y, -shadow_vec.x);
|
|
||||||
sh = 0.25 + (1.0 / 8.0);
|
|
||||||
} else {
|
|
||||||
point = vec2(-shadow_vec.y, shadow_vec.x);
|
|
||||||
sh = 0.75 + (1.0 / 8.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 s = shadow_matrix * vec4(point, 0.0, 1.0);
|
|
||||||
s.xyz /= s.w;
|
|
||||||
su = s.x * 0.5 + 0.5;
|
|
||||||
sz = s.z * 0.5 + 0.5;
|
|
||||||
//sz=lightlength(light_vec);
|
|
||||||
|
|
||||||
highp float shadow_attenuation = 0.0;
|
|
||||||
|
|
||||||
#ifdef USE_RGBA_SHADOWS
|
|
||||||
#define SHADOW_DEPTH(m_tex, m_uv) dot(texture2D((m_tex), (m_uv)), vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0))
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define SHADOW_DEPTH(m_tex, m_uv) (texture2D((m_tex), (m_uv)).r)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SHADOW_USE_GRADIENT
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
/* GLSL es 100 doesn't support line continuation characters(backslashes) */
|
|
||||||
#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); shadow_attenuation += 1.0 - smoothstep(sd, sd + shadow_gradient, sz); }
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); shadow_attenuation += step(sz, sd); }
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SHADOW_FILTER_NEAREST
|
|
||||||
|
|
||||||
SHADOW_TEST(su);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SHADOW_FILTER_PCF3
|
|
||||||
|
|
||||||
SHADOW_TEST(su + shadowpixel_size);
|
|
||||||
SHADOW_TEST(su);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size);
|
|
||||||
shadow_attenuation /= 3.0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SHADOW_FILTER_PCF5
|
|
||||||
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 2.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size);
|
|
||||||
SHADOW_TEST(su);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 2.0);
|
|
||||||
shadow_attenuation /= 5.0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SHADOW_FILTER_PCF7
|
|
||||||
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 3.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 2.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size);
|
|
||||||
SHADOW_TEST(su);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 2.0);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 3.0);
|
|
||||||
shadow_attenuation /= 7.0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SHADOW_FILTER_PCF9
|
|
||||||
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 4.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 3.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 2.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size);
|
|
||||||
SHADOW_TEST(su);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 2.0);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 3.0);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 4.0);
|
|
||||||
shadow_attenuation /= 9.0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SHADOW_FILTER_PCF13
|
|
||||||
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 6.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 5.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 4.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 3.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size * 2.0);
|
|
||||||
SHADOW_TEST(su + shadowpixel_size);
|
|
||||||
SHADOW_TEST(su);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 2.0);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 3.0);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 4.0);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 5.0);
|
|
||||||
SHADOW_TEST(su - shadowpixel_size * 6.0);
|
|
||||||
shadow_attenuation /= 13.0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//color *= shadow_attenuation;
|
|
||||||
color = mix(real_light_shadow_color, color, shadow_attenuation);
|
|
||||||
//use shadows
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//use lighting
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gl_FragColor = color;
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute highp vec3 vertex; // attrib:0
|
|
||||||
|
|
||||||
uniform highp mat4 projection_matrix;
|
|
||||||
/* clang-format on */
|
|
||||||
uniform highp mat4 light_matrix;
|
|
||||||
uniform highp mat4 world_matrix;
|
|
||||||
uniform highp float distance_norm;
|
|
||||||
|
|
||||||
varying highp vec4 position_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex, 1.0)));
|
|
||||||
position_interp = gl_Position;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
varying highp vec4 position_interp;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; // bias
|
|
||||||
|
|
||||||
#ifdef USE_RGBA_SHADOWS
|
|
||||||
|
|
||||||
highp vec4 comp = fract(depth * vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0));
|
|
||||||
comp -= comp.xxyz * vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
|
|
||||||
gl_FragColor = comp;
|
|
||||||
#else
|
|
||||||
|
|
||||||
gl_FragColor = vec4(depth);
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,191 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute highp vec4 vertex_attrib; // attrib:0
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
|
||||||
attribute vec3 cube_in; // attrib:4
|
|
||||||
#else
|
|
||||||
attribute vec2 uv_in; // attrib:4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute vec2 uv2_in; // attrib:5
|
|
||||||
|
|
||||||
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
|
||||||
varying vec3 cube_interp;
|
|
||||||
#else
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
#endif
|
|
||||||
varying vec2 uv2_interp;
|
|
||||||
|
|
||||||
// These definitions are here because the shader-wrapper builder does
|
|
||||||
// not understand `#elif defined()`
|
|
||||||
#ifdef USE_DISPLAY_TRANSFORM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_COPY_SECTION
|
|
||||||
uniform highp vec4 copy_section;
|
|
||||||
#elif defined(USE_DISPLAY_TRANSFORM)
|
|
||||||
uniform highp mat4 display_transform;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
|
||||||
cube_interp = cube_in;
|
|
||||||
#elif defined(USE_ASYM_PANO)
|
|
||||||
uv_interp = vertex_attrib.xy;
|
|
||||||
#else
|
|
||||||
uv_interp = uv_in;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uv2_interp = uv2_in;
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
|
|
||||||
#ifdef USE_COPY_SECTION
|
|
||||||
uv_interp = copy_section.xy + uv_interp * copy_section.zw;
|
|
||||||
gl_Position.xy = (copy_section.xy + (gl_Position.xy * 0.5 + 0.5) * copy_section.zw) * 2.0 - 1.0;
|
|
||||||
#elif defined(USE_DISPLAY_TRANSFORM)
|
|
||||||
uv_interp = (display_transform * vec4(uv_in, 1.0, 1.0)).xy;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#define M_PI 3.14159265359
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
|
||||||
varying vec3 cube_interp;
|
|
||||||
#else
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
#endif
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#ifdef USE_ASYM_PANO
|
|
||||||
uniform highp mat4 pano_transform;
|
|
||||||
uniform highp vec4 asym_proj;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_CUBEMAP
|
|
||||||
uniform samplerCube source_cube; // texunit:0
|
|
||||||
#else
|
|
||||||
uniform sampler2D source; // texunit:0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SEP_CBCR_TEXTURE
|
|
||||||
uniform sampler2D CbCr; //texunit:1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
varying vec2 uv2_interp;
|
|
||||||
|
|
||||||
#ifdef USE_MULTIPLIER
|
|
||||||
uniform float multiplier;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_CUSTOM_ALPHA
|
|
||||||
uniform float custom_alpha;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_PANORAMA) || defined(USE_ASYM_PANO)
|
|
||||||
uniform highp mat4 sky_transform;
|
|
||||||
|
|
||||||
vec4 texturePanorama(sampler2D pano, vec3 normal) {
|
|
||||||
vec2 st = vec2(
|
|
||||||
atan(normal.x, normal.z),
|
|
||||||
acos(normal.y));
|
|
||||||
|
|
||||||
if (st.x < 0.0)
|
|
||||||
st.x += M_PI * 2.0;
|
|
||||||
|
|
||||||
st /= vec2(M_PI * 2.0, M_PI);
|
|
||||||
|
|
||||||
return texture2D(pano, st);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
#ifdef USE_PANORAMA
|
|
||||||
|
|
||||||
vec3 cube_normal = normalize(cube_interp);
|
|
||||||
cube_normal.z = -cube_normal.z;
|
|
||||||
cube_normal = mat3(sky_transform) * cube_normal;
|
|
||||||
cube_normal.z = -cube_normal.z;
|
|
||||||
|
|
||||||
vec4 color = texturePanorama(source, cube_normal);
|
|
||||||
|
|
||||||
#elif defined(USE_ASYM_PANO)
|
|
||||||
|
|
||||||
// When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
|
|
||||||
// Asymmetrical projection means the center of projection is no longer in the center of the screen but shifted.
|
|
||||||
// The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
|
|
||||||
|
|
||||||
vec3 cube_normal;
|
|
||||||
cube_normal.z = -1.0;
|
|
||||||
cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
|
|
||||||
cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
|
|
||||||
cube_normal = mat3(sky_transform) * mat3(pano_transform) * cube_normal;
|
|
||||||
cube_normal.z = -cube_normal.z;
|
|
||||||
|
|
||||||
vec4 color = texturePanorama(source, normalize(cube_normal.xyz));
|
|
||||||
|
|
||||||
#elif defined(USE_CUBEMAP)
|
|
||||||
vec4 color = textureCube(source_cube, normalize(cube_interp));
|
|
||||||
#elif defined(SEP_CBCR_TEXTURE)
|
|
||||||
vec4 color;
|
|
||||||
color.r = texture2D(source, uv_interp).r;
|
|
||||||
color.gb = texture2D(CbCr, uv_interp).rg - vec2(0.5, 0.5);
|
|
||||||
color.a = 1.0;
|
|
||||||
#else
|
|
||||||
vec4 color = texture2D(source, uv_interp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef YCBCR_TO_RGB
|
|
||||||
// YCbCr -> RGB conversion
|
|
||||||
|
|
||||||
// Using BT.601, which is the standard for SDTV is provided as a reference
|
|
||||||
color.rgb = mat3(
|
|
||||||
vec3(1.00000, 1.00000, 1.00000),
|
|
||||||
vec3(0.00000, -0.34413, 1.77200),
|
|
||||||
vec3(1.40200, -0.71414, 0.00000)) *
|
|
||||||
color.rgb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_NO_ALPHA
|
|
||||||
color.a = 1.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_CUSTOM_ALPHA
|
|
||||||
color.a = custom_alpha;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_MULTIPLIER
|
|
||||||
color.rgb *= multiplier;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gl_FragColor = color;
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute highp vec4 vertex_attrib; // attrib:0
|
|
||||||
/* clang-format on */
|
|
||||||
attribute vec2 uv_in; // attrib:4
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uv_interp = uv_in;
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform highp samplerCube source_cube; //texunit:0
|
|
||||||
/* clang-format on */
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
|
|
||||||
uniform bool z_flip;
|
|
||||||
uniform highp float z_far;
|
|
||||||
uniform highp float z_near;
|
|
||||||
uniform highp float bias;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
highp vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0);
|
|
||||||
/*
|
|
||||||
if (z_flip) {
|
|
||||||
normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
|
|
||||||
} else {
|
|
||||||
normal.z = -0.5 + 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
//normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
|
|
||||||
//normal.xy *= 1.0 + normal.z;
|
|
||||||
|
|
||||||
normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
|
|
||||||
normal = normalize(normal);
|
|
||||||
/*
|
|
||||||
normal.z = 0.5;
|
|
||||||
normal = normalize(normal);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!z_flip) {
|
|
||||||
normal.z = -normal.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
//normal = normalize(vec3( uv_interp * 2.0 - 1.0, 1.0 ));
|
|
||||||
float depth = textureCube(source_cube, normal).r;
|
|
||||||
|
|
||||||
// absolute values for direction cosines, bigger value equals closer to basis axis
|
|
||||||
vec3 unorm = abs(normal);
|
|
||||||
|
|
||||||
if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
|
|
||||||
// x code
|
|
||||||
unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0);
|
|
||||||
} else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
|
|
||||||
// y code
|
|
||||||
unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0);
|
|
||||||
} else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
|
|
||||||
// z code
|
|
||||||
unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
|
|
||||||
} else {
|
|
||||||
// oh-no we messed up code
|
|
||||||
// has to be
|
|
||||||
unorm = vec3(1.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float depth_fix = 1.0 / dot(normal, unorm);
|
|
||||||
|
|
||||||
depth = 2.0 * depth - 1.0;
|
|
||||||
float linear_depth = 2.0 * z_near * z_far / (z_far + z_near - depth * (z_far - z_near));
|
|
||||||
gl_FragDepth = (linear_depth * depth_fix + bias) / z_far;
|
|
||||||
}
|
|
|
@ -1,231 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute highp vec2 vertex; // attrib:0
|
|
||||||
/* clang-format on */
|
|
||||||
attribute highp vec2 uv; // attrib:4
|
|
||||||
|
|
||||||
varying highp vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uv_interp = uv;
|
|
||||||
gl_Position = vec4(vertex, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
// texture2DLodEXT and textureCubeLodEXT are fragment shader specific.
|
|
||||||
// Do not copy these defines in the vertex section.
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
#ifdef GL_EXT_shader_texture_lod
|
|
||||||
#extension GL_EXT_shader_texture_lod : enable
|
|
||||||
#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
#endif // !USE_GLES_OVER_GL
|
|
||||||
|
|
||||||
#ifdef GL_ARB_shader_texture_lod
|
|
||||||
#extension GL_ARB_shader_texture_lod : enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
|
|
||||||
#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
|
||||||
uniform sampler2D source_panorama; //texunit:0
|
|
||||||
#else
|
|
||||||
uniform samplerCube source_cube; //texunit:0
|
|
||||||
#endif
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
uniform int face_id;
|
|
||||||
uniform float roughness;
|
|
||||||
varying highp vec2 uv_interp;
|
|
||||||
|
|
||||||
uniform sampler2D radical_inverse_vdc_cache; // texunit:1
|
|
||||||
|
|
||||||
#define M_PI 3.14159265359
|
|
||||||
|
|
||||||
#ifdef LOW_QUALITY
|
|
||||||
|
|
||||||
#define SAMPLE_COUNT 64
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define SAMPLE_COUNT 512
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
|
||||||
|
|
||||||
vec4 texturePanorama(sampler2D pano, vec3 normal) {
|
|
||||||
vec2 st = vec2(
|
|
||||||
atan(normal.x, normal.z),
|
|
||||||
acos(normal.y));
|
|
||||||
|
|
||||||
if (st.x < 0.0)
|
|
||||||
st.x += M_PI * 2.0;
|
|
||||||
|
|
||||||
st /= vec2(M_PI * 2.0, M_PI);
|
|
||||||
|
|
||||||
return texture2DLod(pano, st, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vec3 texelCoordToVec(vec2 uv, int faceID) {
|
|
||||||
mat3 faceUvVectors[6];
|
|
||||||
|
|
||||||
// -x
|
|
||||||
faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
|
|
||||||
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
|
|
||||||
|
|
||||||
// +x
|
|
||||||
faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
|
|
||||||
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
|
|
||||||
|
|
||||||
// -y
|
|
||||||
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
|
|
||||||
faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
|
|
||||||
|
|
||||||
// +y
|
|
||||||
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z
|
|
||||||
faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face
|
|
||||||
|
|
||||||
// -z
|
|
||||||
faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
|
|
||||||
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
|
|
||||||
|
|
||||||
// +z
|
|
||||||
faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
|
|
||||||
|
|
||||||
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
|
|
||||||
vec3 result;
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
if (i == faceID) {
|
|
||||||
result = (faceUvVectors[i][0] * uv.x) + (faceUvVectors[i][1] * uv.y) + faceUvVectors[i][2];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return normalize(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
|
|
||||||
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
|
|
||||||
|
|
||||||
// Compute distribution direction
|
|
||||||
float Phi = 2.0 * M_PI * Xi.x;
|
|
||||||
float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y));
|
|
||||||
float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
|
|
||||||
|
|
||||||
// Convert to spherical direction
|
|
||||||
vec3 H;
|
|
||||||
H.x = SinTheta * cos(Phi);
|
|
||||||
H.y = SinTheta * sin(Phi);
|
|
||||||
H.z = CosTheta;
|
|
||||||
|
|
||||||
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
|
||||||
vec3 TangentX = normalize(cross(UpVector, N));
|
|
||||||
vec3 TangentY = cross(N, TangentX);
|
|
||||||
|
|
||||||
// Tangent to world space
|
|
||||||
return TangentX * H.x + TangentY * H.y + N * H.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
float radical_inverse_VdC(int i) {
|
|
||||||
return texture2D(radical_inverse_vdc_cache, vec2(float(i) / 512.0, 0.0)).x;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Hammersley(int i, int N) {
|
|
||||||
return vec2(float(i) / float(N), radical_inverse_VdC(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
uniform bool z_flip;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec3 color = vec3(0.0);
|
|
||||||
|
|
||||||
vec2 uv = (uv_interp * 2.0) - 1.0;
|
|
||||||
vec3 N = texelCoordToVec(uv, face_id);
|
|
||||||
|
|
||||||
#ifdef USE_DIRECT_WRITE
|
|
||||||
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
|
||||||
|
|
||||||
gl_FragColor = vec4(texturePanorama(source_panorama, N).rgb, 1.0);
|
|
||||||
#else
|
|
||||||
|
|
||||||
gl_FragColor = vec4(textureCube(source_cube, N).rgb, 1.0);
|
|
||||||
#endif //USE_SOURCE_PANORAMA
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
vec4 sum = vec4(0.0);
|
|
||||||
|
|
||||||
for (int sample_num = 0; sample_num < SAMPLE_COUNT; sample_num++) {
|
|
||||||
vec2 xi = Hammersley(sample_num, SAMPLE_COUNT);
|
|
||||||
|
|
||||||
vec3 H = ImportanceSampleGGX(xi, roughness, N);
|
|
||||||
vec3 V = N;
|
|
||||||
vec3 L = (2.0 * dot(V, H) * H - V);
|
|
||||||
|
|
||||||
float NdotL = clamp(dot(N, L), 0.0, 1.0);
|
|
||||||
|
|
||||||
if (NdotL > 0.0) {
|
|
||||||
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
|
||||||
vec3 val = texturePanorama(source_panorama, L).rgb;
|
|
||||||
#else
|
|
||||||
vec3 val = textureCubeLod(source_cube, L, 0.0).rgb;
|
|
||||||
#endif
|
|
||||||
//mix using Linear, to approximate high end back-end
|
|
||||||
val = mix(pow((val + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), val * (1.0 / 12.92), vec3(lessThan(val, vec3(0.04045))));
|
|
||||||
|
|
||||||
sum.rgb += val * NdotL;
|
|
||||||
|
|
||||||
sum.a += NdotL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sum /= sum.a;
|
|
||||||
|
|
||||||
vec3 a = vec3(0.055);
|
|
||||||
sum.rgb = mix((vec3(1.0) + a) * pow(sum.rgb, vec3(1.0 / 2.4)) - a, 12.92 * sum.rgb, vec3(lessThan(sum.rgb, vec3(0.0031308))));
|
|
||||||
|
|
||||||
gl_FragColor = vec4(sum.rgb, 1.0);
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,308 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute vec2 vertex_attrib; // attrib:0
|
|
||||||
/* clang-format on */
|
|
||||||
attribute vec2 uv_in; // attrib:4
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
|
|
||||||
#ifdef USE_BLUR_SECTION
|
|
||||||
|
|
||||||
uniform vec4 blur_section;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uv_interp = uv_in;
|
|
||||||
gl_Position = vec4(vertex_attrib, 0.0, 1.0);
|
|
||||||
#ifdef USE_BLUR_SECTION
|
|
||||||
|
|
||||||
uv_interp = blur_section.xy + uv_interp * blur_section.zw;
|
|
||||||
gl_Position.xy = (blur_section.xy + (gl_Position.xy * 0.5 + 0.5) * blur_section.zw) * 2.0 - 1.0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
// texture2DLodEXT and textureCubeLodEXT are fragment shader specific.
|
|
||||||
// Do not copy these defines in the vertex section.
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
#ifdef GL_EXT_shader_texture_lod
|
|
||||||
#extension GL_EXT_shader_texture_lod : enable
|
|
||||||
#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
#endif // !USE_GLES_OVER_GL
|
|
||||||
|
|
||||||
#ifdef GL_ARB_shader_texture_lod
|
|
||||||
#extension GL_ARB_shader_texture_lod : enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
|
|
||||||
#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
/* clang-format on */
|
|
||||||
uniform sampler2D source_color; //texunit:0
|
|
||||||
|
|
||||||
uniform float lod;
|
|
||||||
uniform vec2 pixel_size;
|
|
||||||
|
|
||||||
#if defined(GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL)
|
|
||||||
|
|
||||||
uniform float glow_strength;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(DOF_FAR_BLUR) || defined(DOF_NEAR_BLUR)
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#ifdef DOF_QUALITY_LOW
|
|
||||||
const int dof_kernel_size = 5;
|
|
||||||
const int dof_kernel_from = 2;
|
|
||||||
const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DOF_QUALITY_MEDIUM
|
|
||||||
const int dof_kernel_size = 11;
|
|
||||||
const int dof_kernel_from = 5;
|
|
||||||
const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DOF_QUALITY_HIGH
|
|
||||||
const int dof_kernel_size = 21;
|
|
||||||
const int dof_kernel_from = 10;
|
|
||||||
const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform sampler2D dof_source_depth; //texunit:1
|
|
||||||
uniform float dof_begin;
|
|
||||||
uniform float dof_end;
|
|
||||||
uniform vec2 dof_dir;
|
|
||||||
uniform float dof_radius;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GLOW_FIRST_PASS
|
|
||||||
|
|
||||||
uniform highp float luminance_cap;
|
|
||||||
|
|
||||||
uniform float glow_bloom;
|
|
||||||
uniform float glow_hdr_threshold;
|
|
||||||
uniform float glow_hdr_scale;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform float camera_z_far;
|
|
||||||
uniform float camera_z_near;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
#ifdef GLOW_GAUSSIAN_HORIZONTAL
|
|
||||||
vec2 pix_size = pixel_size;
|
|
||||||
pix_size *= 0.5; //reading from larger buffer, so use more samples
|
|
||||||
vec4 color = texture2DLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.174938;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.165569;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.140367;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.106595;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.165569;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.140367;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.106595;
|
|
||||||
color *= glow_strength;
|
|
||||||
gl_FragColor = color;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GLOW_GAUSSIAN_VERTICAL
|
|
||||||
vec4 color = texture2DLod(source_color, uv_interp + vec2(0.0, 0.0) * pixel_size, lod) * 0.288713;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(0.0, 1.0) * pixel_size, lod) * 0.233062;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(0.0, 2.0) * pixel_size, lod) * 0.122581;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(0.0, -1.0) * pixel_size, lod) * 0.233062;
|
|
||||||
color += texture2DLod(source_color, uv_interp + vec2(0.0, -2.0) * pixel_size, lod) * 0.122581;
|
|
||||||
color *= glow_strength;
|
|
||||||
gl_FragColor = color;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
#if defined(DOF_FAR_BLUR) || defined(DOF_NEAR_BLUR)
|
|
||||||
|
|
||||||
#ifdef DOF_QUALITY_LOW
|
|
||||||
const int dof_kernel_size = 5;
|
|
||||||
const int dof_kernel_from = 2;
|
|
||||||
float dof_kernel[5];
|
|
||||||
dof_kernel[0] = 0.153388;
|
|
||||||
dof_kernel[1] = 0.221461;
|
|
||||||
dof_kernel[2] = 0.250301;
|
|
||||||
dof_kernel[3] = 0.221461;
|
|
||||||
dof_kernel[4] = 0.153388;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DOF_QUALITY_MEDIUM
|
|
||||||
const int dof_kernel_size = 11;
|
|
||||||
const int dof_kernel_from = 5;
|
|
||||||
float dof_kernel[11];
|
|
||||||
dof_kernel[0] = 0.055037;
|
|
||||||
dof_kernel[1] = 0.072806;
|
|
||||||
dof_kernel[2] = 0.090506;
|
|
||||||
dof_kernel[3] = 0.105726;
|
|
||||||
dof_kernel[4] = 0.116061;
|
|
||||||
dof_kernel[5] = 0.119726;
|
|
||||||
dof_kernel[6] = 0.116061;
|
|
||||||
dof_kernel[7] = 0.105726;
|
|
||||||
dof_kernel[8] = 0.090506;
|
|
||||||
dof_kernel[9] = 0.072806;
|
|
||||||
dof_kernel[10] = 0.055037;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DOF_QUALITY_HIGH
|
|
||||||
const int dof_kernel_size = 21;
|
|
||||||
const int dof_kernel_from = 10;
|
|
||||||
float dof_kernel[21];
|
|
||||||
dof_kernel[0] = 0.028174;
|
|
||||||
dof_kernel[1] = 0.032676;
|
|
||||||
dof_kernel[2] = 0.037311;
|
|
||||||
dof_kernel[3] = 0.041944;
|
|
||||||
dof_kernel[4] = 0.046421;
|
|
||||||
dof_kernel[5] = 0.050582;
|
|
||||||
dof_kernel[6] = 0.054261;
|
|
||||||
dof_kernel[7] = 0.057307;
|
|
||||||
dof_kernel[8] = 0.059587;
|
|
||||||
dof_kernel[9] = 0.060998;
|
|
||||||
dof_kernel[10] = 0.061476;
|
|
||||||
dof_kernel[11] = 0.060998;
|
|
||||||
dof_kernel[12] = 0.059587;
|
|
||||||
dof_kernel[13] = 0.057307;
|
|
||||||
dof_kernel[14] = 0.054261;
|
|
||||||
dof_kernel[15] = 0.050582;
|
|
||||||
dof_kernel[16] = 0.046421;
|
|
||||||
dof_kernel[17] = 0.041944;
|
|
||||||
dof_kernel[18] = 0.037311;
|
|
||||||
dof_kernel[19] = 0.032676;
|
|
||||||
dof_kernel[20] = 0.028174;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif //!USE_GLES_OVER_GL
|
|
||||||
|
|
||||||
#ifdef DOF_FAR_BLUR
|
|
||||||
|
|
||||||
vec4 color_accum = vec4(0.0);
|
|
||||||
|
|
||||||
float depth = texture2DLod(dof_source_depth, uv_interp, 0.0).r;
|
|
||||||
depth = depth * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float amount = smoothstep(dof_begin, dof_end, depth);
|
|
||||||
float k_accum = 0.0;
|
|
||||||
|
|
||||||
for (int i = 0; i < dof_kernel_size; i++) {
|
|
||||||
int int_ofs = i - dof_kernel_from;
|
|
||||||
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius;
|
|
||||||
|
|
||||||
float tap_k = dof_kernel[i];
|
|
||||||
|
|
||||||
float tap_depth = texture2D(dof_source_depth, tap_uv, 0.0).r;
|
|
||||||
tap_depth = tap_depth * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
tap_depth = ((tap_depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
|
|
||||||
#endif
|
|
||||||
float tap_amount = int_ofs == 0 ? 1.0 : smoothstep(dof_begin, dof_end, tap_depth);
|
|
||||||
tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
|
|
||||||
|
|
||||||
vec4 tap_color = texture2DLod(source_color, tap_uv, 0.0) * tap_k;
|
|
||||||
|
|
||||||
k_accum += tap_k * tap_amount;
|
|
||||||
color_accum += tap_color * tap_amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k_accum > 0.0) {
|
|
||||||
color_accum /= k_accum;
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_FragColor = color_accum; ///k_accum;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DOF_NEAR_BLUR
|
|
||||||
|
|
||||||
vec4 color_accum = vec4(0.0);
|
|
||||||
|
|
||||||
float max_accum = 0.0;
|
|
||||||
|
|
||||||
for (int i = 0; i < dof_kernel_size; i++) {
|
|
||||||
int int_ofs = i - dof_kernel_from;
|
|
||||||
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius;
|
|
||||||
float ofs_influence = max(0.0, 1.0 - abs(float(int_ofs)) / float(dof_kernel_from));
|
|
||||||
|
|
||||||
float tap_k = dof_kernel[i];
|
|
||||||
|
|
||||||
vec4 tap_color = texture2DLod(source_color, tap_uv, 0.0);
|
|
||||||
|
|
||||||
float tap_depth = texture2D(dof_source_depth, tap_uv, 0.0).r;
|
|
||||||
tap_depth = tap_depth * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
tap_depth = ((tap_depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
|
|
||||||
#endif
|
|
||||||
float tap_amount = 1.0 - smoothstep(dof_end, dof_begin, tap_depth);
|
|
||||||
tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
|
|
||||||
|
|
||||||
#ifdef DOF_NEAR_FIRST_TAP
|
|
||||||
|
|
||||||
tap_color.a = 1.0 - smoothstep(dof_end, dof_begin, tap_depth);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
max_accum = max(max_accum, tap_amount * ofs_influence);
|
|
||||||
|
|
||||||
color_accum += tap_color * tap_k;
|
|
||||||
}
|
|
||||||
|
|
||||||
color_accum.a = max(color_accum.a, sqrt(max_accum));
|
|
||||||
|
|
||||||
gl_FragColor = color_accum;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GLOW_FIRST_PASS
|
|
||||||
|
|
||||||
float luminance = max(gl_FragColor.r, max(gl_FragColor.g, gl_FragColor.b));
|
|
||||||
float feedback = max(smoothstep(glow_hdr_threshold, glow_hdr_threshold + glow_hdr_scale, luminance), glow_bloom);
|
|
||||||
|
|
||||||
gl_FragColor = min(gl_FragColor * feedback, vec4(luminance_cap));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
uniform highp sampler2D source_exposure; //texunit:0
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#ifdef EXPOSURE_BEGIN
|
|
||||||
|
|
||||||
uniform highp ivec2 source_render_size;
|
|
||||||
uniform highp ivec2 target_size;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EXPOSURE_END
|
|
||||||
|
|
||||||
uniform highp sampler2D prev_exposure; //texunit:1
|
|
||||||
uniform highp float exposure_adjust;
|
|
||||||
uniform highp float min_luminance;
|
|
||||||
uniform highp float max_luminance;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
layout(location = 0) out highp float exposure;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
#ifdef EXPOSURE_BEGIN
|
|
||||||
|
|
||||||
ivec2 src_pos = ivec2(gl_FragCoord.xy) * source_render_size / target_size;
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
//more precise and expensive, but less jittery
|
|
||||||
ivec2 next_pos = ivec2(gl_FragCoord.xy + ivec2(1)) * source_render_size / target_size;
|
|
||||||
next_pos = max(next_pos, src_pos + ivec2(1)); //so it at least reads one pixel
|
|
||||||
highp vec3 source_color = vec3(0.0);
|
|
||||||
for (int i = src_pos.x; i < next_pos.x; i++) {
|
|
||||||
for (int j = src_pos.y; j < next_pos.y; j++) {
|
|
||||||
source_color += texelFetch(source_exposure, ivec2(i, j), 0).rgb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
source_color /= float((next_pos.x - src_pos.x) * (next_pos.y - src_pos.y));
|
|
||||||
#else
|
|
||||||
highp vec3 source_color = texelFetch(source_exposure, src_pos, 0).rgb;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
exposure = max(source_color.r, max(source_color.g, source_color.b));
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
|
||||||
exposure = texelFetch(source_exposure, coord * 3 + ivec2(0, 0), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 0), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 0), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(0, 1), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 1), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 1), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(0, 2), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 2), 0).r;
|
|
||||||
exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 2), 0).r;
|
|
||||||
exposure *= (1.0 / 9.0);
|
|
||||||
|
|
||||||
#ifdef EXPOSURE_END
|
|
||||||
|
|
||||||
#ifdef EXPOSURE_FORCE_SET
|
|
||||||
//will stay as is
|
|
||||||
#else
|
|
||||||
highp float prev_lum = texelFetch(prev_exposure, ivec2(0, 0), 0).r; //1 pixel previous exposure
|
|
||||||
exposure = clamp(prev_lum + (exposure - prev_lum) * exposure_adjust, min_luminance, max_luminance);
|
|
||||||
|
|
||||||
#endif //EXPOSURE_FORCE_SET
|
|
||||||
|
|
||||||
#endif //EXPOSURE_END
|
|
||||||
|
|
||||||
#endif //EXPOSURE_BEGIN
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute highp vec2 vertex; // attrib:0
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
uniform vec2 offset;
|
|
||||||
uniform vec2 scale;
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uv_interp = vertex.xy * 2.0 - 1.0;
|
|
||||||
|
|
||||||
vec2 v = vertex.xy * scale + offset;
|
|
||||||
gl_Position = vec4(v, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform sampler2D source; //texunit:0
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
uniform vec2 eye_center;
|
|
||||||
uniform float k1;
|
|
||||||
uniform float k2;
|
|
||||||
uniform float upscale;
|
|
||||||
uniform float aspect_ratio;
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 coords = uv_interp;
|
|
||||||
vec2 offset = coords - eye_center;
|
|
||||||
|
|
||||||
// take aspect ratio into account
|
|
||||||
offset.y /= aspect_ratio;
|
|
||||||
|
|
||||||
// distort
|
|
||||||
vec2 offset_sq = offset * offset;
|
|
||||||
float radius_sq = offset_sq.x + offset_sq.y;
|
|
||||||
float radius_s4 = radius_sq * radius_sq;
|
|
||||||
float distortion_scale = 1.0 + (k1 * radius_sq) + (k2 * radius_s4);
|
|
||||||
offset *= distortion_scale;
|
|
||||||
|
|
||||||
// reapply aspect ratio
|
|
||||||
offset.y *= aspect_ratio;
|
|
||||||
|
|
||||||
// add our eye center back in
|
|
||||||
coords = offset + eye_center;
|
|
||||||
coords /= upscale;
|
|
||||||
|
|
||||||
// and check our color
|
|
||||||
if (coords.x < -1.0 || coords.y < -1.0 || coords.x > 1.0 || coords.y > 1.0) {
|
|
||||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
||||||
} else {
|
|
||||||
coords = (coords + vec2(1.0)) / vec2(2.0);
|
|
||||||
gl_FragColor = texture2D(source, coords);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,261 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 color;
|
|
||||||
/* clang-format on */
|
|
||||||
layout(location = 1) in highp vec4 velocity_active;
|
|
||||||
layout(location = 2) in highp vec4 custom;
|
|
||||||
layout(location = 3) in highp vec4 xform_1;
|
|
||||||
layout(location = 4) in highp vec4 xform_2;
|
|
||||||
layout(location = 5) in highp vec4 xform_3;
|
|
||||||
|
|
||||||
struct Attractor {
|
|
||||||
vec3 pos;
|
|
||||||
vec3 dir;
|
|
||||||
float radius;
|
|
||||||
float eat_radius;
|
|
||||||
float strength;
|
|
||||||
float attenuation;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_ATTRACTORS 64
|
|
||||||
|
|
||||||
uniform bool emitting;
|
|
||||||
uniform float system_phase;
|
|
||||||
uniform float prev_system_phase;
|
|
||||||
uniform int total_particles;
|
|
||||||
uniform float explosiveness;
|
|
||||||
uniform float randomness;
|
|
||||||
uniform float time;
|
|
||||||
uniform float delta;
|
|
||||||
|
|
||||||
uniform int attractor_count;
|
|
||||||
uniform Attractor attractors[MAX_ATTRACTORS];
|
|
||||||
uniform bool clear;
|
|
||||||
uniform uint cycle;
|
|
||||||
uniform float lifetime;
|
|
||||||
uniform mat4 emission_transform;
|
|
||||||
uniform uint random_seed;
|
|
||||||
|
|
||||||
out highp vec4 out_color; //tfb:
|
|
||||||
out highp vec4 out_velocity_active; //tfb:
|
|
||||||
out highp vec4 out_custom; //tfb:
|
|
||||||
out highp vec4 out_xform_1; //tfb:
|
|
||||||
out highp vec4 out_xform_2; //tfb:
|
|
||||||
out highp vec4 out_xform_3; //tfb:
|
|
||||||
|
|
||||||
#if defined(USE_MATERIAL)
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
layout(std140) uniform UniformData { //ubo:0
|
|
||||||
|
|
||||||
MATERIAL_UNIFORMS
|
|
||||||
|
|
||||||
};
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
VERTEX_SHADER_GLOBALS
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
uint hash(uint x) {
|
|
||||||
x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
|
|
||||||
x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
|
|
||||||
x = (x >> uint(16)) ^ x;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
#ifdef PARTICLES_COPY
|
|
||||||
|
|
||||||
out_color = color;
|
|
||||||
out_velocity_active = velocity_active;
|
|
||||||
out_custom = custom;
|
|
||||||
out_xform_1 = xform_1;
|
|
||||||
out_xform_2 = xform_2;
|
|
||||||
out_xform_3 = xform_3;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
bool apply_forces = true;
|
|
||||||
bool apply_velocity = true;
|
|
||||||
float local_delta = delta;
|
|
||||||
|
|
||||||
float mass = 1.0;
|
|
||||||
|
|
||||||
float restart_phase = float(gl_VertexID) / float(total_particles);
|
|
||||||
|
|
||||||
if (randomness > 0.0) {
|
|
||||||
uint seed = cycle;
|
|
||||||
if (restart_phase >= system_phase) {
|
|
||||||
seed -= uint(1);
|
|
||||||
}
|
|
||||||
seed *= uint(total_particles);
|
|
||||||
seed += uint(gl_VertexID);
|
|
||||||
float random = float(hash(seed) % uint(65536)) / 65536.0;
|
|
||||||
restart_phase += randomness * random * 1.0 / float(total_particles);
|
|
||||||
}
|
|
||||||
|
|
||||||
restart_phase *= (1.0 - explosiveness);
|
|
||||||
bool restart = false;
|
|
||||||
bool shader_active = velocity_active.a > 0.5;
|
|
||||||
|
|
||||||
if (system_phase > prev_system_phase) {
|
|
||||||
// restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed
|
|
||||||
|
|
||||||
if (restart_phase >= prev_system_phase && restart_phase < system_phase) {
|
|
||||||
restart = true;
|
|
||||||
#ifdef USE_FRACTIONAL_DELTA
|
|
||||||
local_delta = (system_phase - restart_phase) * lifetime;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (restart_phase >= prev_system_phase) {
|
|
||||||
restart = true;
|
|
||||||
#ifdef USE_FRACTIONAL_DELTA
|
|
||||||
local_delta = (1.0 - restart_phase + system_phase) * lifetime;
|
|
||||||
#endif
|
|
||||||
} else if (restart_phase < system_phase) {
|
|
||||||
restart = true;
|
|
||||||
#ifdef USE_FRACTIONAL_DELTA
|
|
||||||
local_delta = (system_phase - restart_phase) * lifetime;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint current_cycle = cycle;
|
|
||||||
|
|
||||||
if (system_phase < restart_phase) {
|
|
||||||
current_cycle -= uint(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID);
|
|
||||||
int index = int(gl_VertexID);
|
|
||||||
|
|
||||||
if (restart) {
|
|
||||||
shader_active = emitting;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat4 xform;
|
|
||||||
|
|
||||||
#if defined(ENABLE_KEEP_DATA)
|
|
||||||
if (clear) {
|
|
||||||
#else
|
|
||||||
if (clear || restart) {
|
|
||||||
#endif
|
|
||||||
out_color = vec4(1.0);
|
|
||||||
out_velocity_active = vec4(0.0);
|
|
||||||
out_custom = vec4(0.0);
|
|
||||||
if (!restart)
|
|
||||||
shader_active = false;
|
|
||||||
|
|
||||||
xform = mat4(
|
|
||||||
vec4(1.0, 0.0, 0.0, 0.0),
|
|
||||||
vec4(0.0, 1.0, 0.0, 0.0),
|
|
||||||
vec4(0.0, 0.0, 1.0, 0.0),
|
|
||||||
vec4(0.0, 0.0, 0.0, 1.0));
|
|
||||||
} else {
|
|
||||||
out_color = color;
|
|
||||||
out_velocity_active = velocity_active;
|
|
||||||
out_custom = custom;
|
|
||||||
xform = transpose(mat4(xform_1, xform_2, xform_3, vec4(vec3(0.0), 1.0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shader_active) {
|
|
||||||
//execute shader
|
|
||||||
|
|
||||||
{
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
VERTEX_SHADER_CODE
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(DISABLE_FORCE)
|
|
||||||
|
|
||||||
if (false) {
|
|
||||||
vec3 force = vec3(0.0);
|
|
||||||
for (int i = 0; i < attractor_count; i++) {
|
|
||||||
vec3 rel_vec = xform[3].xyz - attractors[i].pos;
|
|
||||||
float dist = length(rel_vec);
|
|
||||||
if (attractors[i].radius < dist)
|
|
||||||
continue;
|
|
||||||
if (attractors[i].eat_radius > 0.0 && attractors[i].eat_radius > dist) {
|
|
||||||
out_velocity_active.a = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rel_vec = normalize(rel_vec);
|
|
||||||
|
|
||||||
float attenuation = pow(dist / attractors[i].radius, attractors[i].attenuation);
|
|
||||||
|
|
||||||
if (attractors[i].dir == vec3(0.0)) {
|
|
||||||
//towards center
|
|
||||||
force += attractors[i].strength * rel_vec * attenuation * mass;
|
|
||||||
} else {
|
|
||||||
force += attractors[i].strength * attractors[i].dir * attenuation * mass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out_velocity_active.xyz += force * local_delta;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(DISABLE_VELOCITY)
|
|
||||||
|
|
||||||
if (true) {
|
|
||||||
xform[3].xyz += out_velocity_active.xyz * local_delta;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
xform = mat4(0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
xform = transpose(xform);
|
|
||||||
|
|
||||||
out_velocity_active.a = mix(0.0, 1.0, shader_active);
|
|
||||||
|
|
||||||
out_xform_1 = xform[0];
|
|
||||||
out_xform_2 = xform[1];
|
|
||||||
out_xform_3 = xform[2];
|
|
||||||
|
|
||||||
#endif //PARTICLES_COPY
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
//any code here is never executed, stuff is filled just so it works
|
|
||||||
|
|
||||||
#if defined(USE_MATERIAL)
|
|
||||||
|
|
||||||
layout(std140) uniform UniformData {
|
|
||||||
|
|
||||||
MATERIAL_UNIFORMS
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FRAGMENT_SHADER_GLOBALS
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
{
|
|
||||||
|
|
||||||
LIGHT_SHADER_CODE
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
FRAGMENT_SHADER_CODE
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
|
@ -1,42 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
layout(location = 4) in vec2 uv_in;
|
|
||||||
|
|
||||||
out vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uv_interp = uv_in;
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#if !defined(GLES_OVER_GL)
|
|
||||||
precision mediump float;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
in vec2 uv_interp;
|
|
||||||
/* clang-format on */
|
|
||||||
uniform sampler2D source_specular; //texunit:0
|
|
||||||
uniform sampler2D source_ssr; //texunit:1
|
|
||||||
|
|
||||||
uniform vec2 pixel_size;
|
|
||||||
|
|
||||||
in vec2 uv2_interp;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 frag_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 specular = texture(source_specular, uv_interp);
|
|
||||||
|
|
||||||
#ifdef USE_SSR
|
|
||||||
vec4 ssr = textureLod(source_ssr, uv_interp, 0.0);
|
|
||||||
specular.rgb = mix(specular.rgb, ssr.rgb * specular.a, ssr.a);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
frag_color = vec4(specular.rgb, 1.0);
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,284 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
layout(location = 4) in vec2 uv_in;
|
|
||||||
|
|
||||||
out vec2 uv_interp;
|
|
||||||
out vec2 pos_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uv_interp = uv_in;
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
pos_interp.xy = gl_Position.xy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
in vec2 uv_interp;
|
|
||||||
/* clang-format on */
|
|
||||||
in vec2 pos_interp;
|
|
||||||
|
|
||||||
uniform sampler2D source_diffuse; //texunit:0
|
|
||||||
uniform sampler2D source_normal_roughness; //texunit:1
|
|
||||||
uniform sampler2D source_depth; //texunit:2
|
|
||||||
|
|
||||||
uniform float camera_z_near;
|
|
||||||
uniform float camera_z_far;
|
|
||||||
|
|
||||||
uniform vec2 viewport_size;
|
|
||||||
uniform vec2 pixel_size;
|
|
||||||
|
|
||||||
uniform float filter_mipmap_levels;
|
|
||||||
|
|
||||||
uniform mat4 inverse_projection;
|
|
||||||
uniform mat4 projection;
|
|
||||||
|
|
||||||
uniform int num_steps;
|
|
||||||
uniform float depth_tolerance;
|
|
||||||
uniform float distance_fade;
|
|
||||||
uniform float curve_fade_in;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 frag_color;
|
|
||||||
|
|
||||||
vec2 view_to_screen(vec3 view_pos, out float w) {
|
|
||||||
vec4 projected = projection * vec4(view_pos, 1.0);
|
|
||||||
projected.xyz /= projected.w;
|
|
||||||
projected.xy = projected.xy * 0.5 + 0.5;
|
|
||||||
w = projected.w;
|
|
||||||
return projected.xy;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define M_PI 3.14159265359
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 diffuse = texture(source_diffuse, uv_interp);
|
|
||||||
vec4 normal_roughness = texture(source_normal_roughness, uv_interp);
|
|
||||||
|
|
||||||
vec3 normal;
|
|
||||||
|
|
||||||
normal = normal_roughness.xyz * 2.0 - 1.0;
|
|
||||||
|
|
||||||
float roughness = normal_roughness.w;
|
|
||||||
|
|
||||||
float depth_tex = texture(source_depth, uv_interp).r;
|
|
||||||
|
|
||||||
vec4 world_pos = inverse_projection * vec4(uv_interp * 2.0 - 1.0, depth_tex * 2.0 - 1.0, 1.0);
|
|
||||||
vec3 vertex = world_pos.xyz / world_pos.w;
|
|
||||||
|
|
||||||
vec3 view_dir = normalize(vertex);
|
|
||||||
vec3 ray_dir = normalize(reflect(view_dir, normal));
|
|
||||||
|
|
||||||
if (dot(ray_dir, normal) < 0.001) {
|
|
||||||
frag_color = vec4(0.0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
|
|
||||||
|
|
||||||
//ray_dir = normalize(vec3(1,1,-1));
|
|
||||||
|
|
||||||
////////////////
|
|
||||||
|
|
||||||
//make ray length and clip it against the near plane (don't want to trace beyond visible)
|
|
||||||
float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far;
|
|
||||||
vec3 ray_end = vertex + ray_dir * ray_len;
|
|
||||||
|
|
||||||
float w_begin;
|
|
||||||
vec2 vp_line_begin = view_to_screen(vertex, w_begin);
|
|
||||||
float w_end;
|
|
||||||
vec2 vp_line_end = view_to_screen(ray_end, w_end);
|
|
||||||
vec2 vp_line_dir = vp_line_end - vp_line_begin;
|
|
||||||
|
|
||||||
//we need to interpolate w along the ray, to generate perspective correct reflections
|
|
||||||
|
|
||||||
w_begin = 1.0 / w_begin;
|
|
||||||
w_end = 1.0 / w_end;
|
|
||||||
|
|
||||||
float z_begin = vertex.z * w_begin;
|
|
||||||
float z_end = ray_end.z * w_end;
|
|
||||||
|
|
||||||
vec2 line_begin = vp_line_begin / pixel_size;
|
|
||||||
vec2 line_dir = vp_line_dir / pixel_size;
|
|
||||||
float z_dir = z_end - z_begin;
|
|
||||||
float w_dir = w_end - w_begin;
|
|
||||||
|
|
||||||
// clip the line to the viewport edges
|
|
||||||
|
|
||||||
float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x));
|
|
||||||
float scale_max_y = min(1.0, 0.99 * (1.0 - vp_line_begin.y) / max(1e-5, vp_line_dir.y));
|
|
||||||
float scale_min_x = min(1.0, 0.99 * vp_line_begin.x / max(1e-5, -vp_line_dir.x));
|
|
||||||
float scale_min_y = min(1.0, 0.99 * vp_line_begin.y / max(1e-5, -vp_line_dir.y));
|
|
||||||
float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y);
|
|
||||||
line_dir *= line_clip;
|
|
||||||
z_dir *= line_clip;
|
|
||||||
w_dir *= line_clip;
|
|
||||||
|
|
||||||
//clip z and w advance to line advance
|
|
||||||
vec2 line_advance = normalize(line_dir); //down to pixel
|
|
||||||
float step_size = length(line_advance) / length(line_dir);
|
|
||||||
float z_advance = z_dir * step_size; // adapt z advance to line advance
|
|
||||||
float w_advance = w_dir * step_size; // adapt w advance to line advance
|
|
||||||
|
|
||||||
//make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice)
|
|
||||||
float advance_angle_adj = 1.0 / max(abs(line_advance.x), abs(line_advance.y));
|
|
||||||
line_advance *= advance_angle_adj; // adapt z advance to line advance
|
|
||||||
z_advance *= advance_angle_adj;
|
|
||||||
w_advance *= advance_angle_adj;
|
|
||||||
|
|
||||||
vec2 pos = line_begin;
|
|
||||||
float z = z_begin;
|
|
||||||
float w = w_begin;
|
|
||||||
float z_from = z / w;
|
|
||||||
float z_to = z_from;
|
|
||||||
float depth;
|
|
||||||
vec2 prev_pos = pos;
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
float steps_taken = 0.0;
|
|
||||||
|
|
||||||
for (int i = 0; i < num_steps; i++) {
|
|
||||||
pos += line_advance;
|
|
||||||
z += z_advance;
|
|
||||||
w += w_advance;
|
|
||||||
|
|
||||||
//convert to linear depth
|
|
||||||
|
|
||||||
depth = texture(source_depth, pos * pixel_size).r * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
|
||||||
#endif
|
|
||||||
depth = -depth;
|
|
||||||
|
|
||||||
z_from = z_to;
|
|
||||||
z_to = z / w;
|
|
||||||
|
|
||||||
if (depth > z_to) {
|
|
||||||
//if depth was surpassed
|
|
||||||
if (depth <= max(z_to, z_from) + depth_tolerance) {
|
|
||||||
//check the depth tolerance
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
steps_taken += 1.0;
|
|
||||||
prev_pos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
float margin_blend = 1.0;
|
|
||||||
|
|
||||||
vec2 margin = vec2((viewport_size.x + viewport_size.y) * 0.5 * 0.05); //make a uniform margin
|
|
||||||
if (any(bvec4(lessThan(pos, -margin), greaterThan(pos, viewport_size + margin)))) {
|
|
||||||
//clip outside screen + margin
|
|
||||||
frag_color = vec4(0.0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
//blend fading out towards external margin
|
|
||||||
vec2 margin_grad = mix(pos - viewport_size, -pos, lessThan(pos, vec2(0.0)));
|
|
||||||
margin_blend = 1.0 - smoothstep(0.0, margin.x, max(margin_grad.x, margin_grad.y));
|
|
||||||
//margin_blend=1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 final_pos;
|
|
||||||
float grad;
|
|
||||||
grad = steps_taken / float(num_steps);
|
|
||||||
float initial_fade = curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), curve_fade_in);
|
|
||||||
float fade = pow(clamp(1.0 - grad, 0.0, 1.0), distance_fade) * initial_fade;
|
|
||||||
final_pos = pos;
|
|
||||||
|
|
||||||
#ifdef REFLECT_ROUGHNESS
|
|
||||||
|
|
||||||
vec4 final_color;
|
|
||||||
//if roughness is enabled, do screen space cone tracing
|
|
||||||
if (roughness > 0.001) {
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//use a blurred version (in consecutive mipmaps) of the screen to simulate roughness
|
|
||||||
|
|
||||||
float gloss = 1.0 - roughness;
|
|
||||||
float cone_angle = roughness * M_PI * 0.5;
|
|
||||||
vec2 cone_dir = final_pos - line_begin;
|
|
||||||
float cone_len = length(cone_dir);
|
|
||||||
cone_dir = normalize(cone_dir); //will be used normalized from now on
|
|
||||||
float max_mipmap = filter_mipmap_levels - 1.0;
|
|
||||||
float gloss_mult = gloss;
|
|
||||||
|
|
||||||
float rem_alpha = 1.0;
|
|
||||||
final_color = vec4(0.0);
|
|
||||||
|
|
||||||
for (int i = 0; i < 7; i++) {
|
|
||||||
float op_len = 2.0 * tan(cone_angle) * cone_len; //opposite side of iso triangle
|
|
||||||
float radius;
|
|
||||||
{
|
|
||||||
//fit to sphere inside cone (sphere ends at end of cone), something like this:
|
|
||||||
// ___
|
|
||||||
// \O/
|
|
||||||
// V
|
|
||||||
//
|
|
||||||
// as it avoids bleeding from beyond the reflection as much as possible. As a plus
|
|
||||||
// it also makes the rough reflection more elongated.
|
|
||||||
float a = op_len;
|
|
||||||
float h = cone_len;
|
|
||||||
float a2 = a * a;
|
|
||||||
float fh2 = 4.0f * h * h;
|
|
||||||
radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
|
|
||||||
}
|
|
||||||
|
|
||||||
//find the place where screen must be sampled
|
|
||||||
vec2 sample_pos = (line_begin + cone_dir * (cone_len - radius)) * pixel_size;
|
|
||||||
//radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels
|
|
||||||
float mipmap = clamp(log2(radius), 0.0, max_mipmap);
|
|
||||||
|
|
||||||
//mipmap = max(mipmap-1.0,0.0);
|
|
||||||
//do sampling
|
|
||||||
|
|
||||||
vec4 sample_color;
|
|
||||||
{
|
|
||||||
sample_color = textureLod(source_diffuse, sample_pos, mipmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
//multiply by gloss
|
|
||||||
sample_color.rgb *= gloss_mult;
|
|
||||||
sample_color.a = gloss_mult;
|
|
||||||
|
|
||||||
rem_alpha -= sample_color.a;
|
|
||||||
if (rem_alpha < 0.0) {
|
|
||||||
sample_color.rgb *= (1.0 - abs(rem_alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
final_color += sample_color;
|
|
||||||
|
|
||||||
if (final_color.a >= 0.95) {
|
|
||||||
// This code of accumulating gloss and aborting on near one
|
|
||||||
// makes sense when you think of cone tracing.
|
|
||||||
// Think of it as if roughness was 0, then we could abort on the first
|
|
||||||
// iteration. For lesser roughness values, we need more iterations, but
|
|
||||||
// each needs to have less influence given the sphere is smaller
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cone_len -= radius * 2.0; //go to next (smaller) circle.
|
|
||||||
|
|
||||||
gloss_mult *= gloss;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final_color = textureLod(source_diffuse, final_pos * pixel_size, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
frag_color = vec4(final_color.rgb, fade * margin_blend);
|
|
||||||
|
|
||||||
#else
|
|
||||||
frag_color = vec4(textureLod(source_diffuse, final_pos * pixel_size, 0.0).rgb, fade * margin_blend);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
|
||||||
frag_color = vec4(0.0, 0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,283 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
gl_Position.z = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#define TWO_PI 6.283185307179586476925286766559
|
|
||||||
|
|
||||||
#ifdef SSAO_QUALITY_HIGH
|
|
||||||
|
|
||||||
#define NUM_SAMPLES (80)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SSAO_QUALITY_LOW
|
|
||||||
|
|
||||||
#define NUM_SAMPLES (15)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH)
|
|
||||||
|
|
||||||
#define NUM_SAMPLES (40)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
|
|
||||||
// miplevel to maintain reasonable spatial locality in the cache
|
|
||||||
// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
|
|
||||||
// If it is too high (> 5), we'll get bad performance because we're not using the MIP levels effectively
|
|
||||||
#define LOG_MAX_OFFSET (3)
|
|
||||||
|
|
||||||
// This must be less than or equal to the MAX_MIP_LEVEL defined in SSAO.cpp
|
|
||||||
#define MAX_MIP_LEVEL (4)
|
|
||||||
|
|
||||||
// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent
|
|
||||||
// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9
|
|
||||||
|
|
||||||
const int ROTATIONS[] = int[](
|
|
||||||
1, 1, 2, 3, 2, 5, 2, 3, 2,
|
|
||||||
3, 3, 5, 5, 3, 4, 7, 5, 5, 7,
|
|
||||||
9, 8, 5, 5, 7, 7, 7, 8, 5, 8,
|
|
||||||
11, 12, 7, 10, 13, 8, 11, 8, 7, 14,
|
|
||||||
11, 11, 13, 12, 13, 19, 17, 13, 11, 18,
|
|
||||||
19, 11, 11, 14, 17, 21, 15, 16, 17, 18,
|
|
||||||
13, 17, 11, 17, 19, 18, 25, 18, 19, 19,
|
|
||||||
29, 21, 19, 27, 31, 29, 21, 18, 17, 29,
|
|
||||||
31, 31, 23, 18, 25, 26, 25, 23, 19, 34,
|
|
||||||
19, 27, 21, 25, 39, 29, 17, 21, 27);
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
//#define NUM_SPIRAL_TURNS (7)
|
|
||||||
const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES - 1];
|
|
||||||
|
|
||||||
uniform sampler2D source_depth; //texunit:0
|
|
||||||
uniform highp usampler2D source_depth_mipmaps; //texunit:1
|
|
||||||
uniform sampler2D source_normal; //texunit:2
|
|
||||||
|
|
||||||
uniform ivec2 screen_size;
|
|
||||||
uniform float camera_z_far;
|
|
||||||
uniform float camera_z_near;
|
|
||||||
|
|
||||||
uniform float intensity_div_r6;
|
|
||||||
uniform float radius;
|
|
||||||
|
|
||||||
#ifdef ENABLE_RADIUS2
|
|
||||||
uniform float intensity_div_r62;
|
|
||||||
uniform float radius2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform float bias;
|
|
||||||
uniform float proj_scale;
|
|
||||||
|
|
||||||
layout(location = 0) out float visibility;
|
|
||||||
|
|
||||||
uniform vec4 proj_info;
|
|
||||||
|
|
||||||
vec3 reconstructCSPosition(vec2 S, float z) {
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
return vec3((S.xy * proj_info.xy + proj_info.zw), z);
|
|
||||||
#else
|
|
||||||
return vec3((S.xy * proj_info.xy + proj_info.zw) * z, z);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 getPosition(ivec2 ssP) {
|
|
||||||
vec3 P;
|
|
||||||
P.z = texelFetch(source_depth, ssP, 0).r;
|
|
||||||
|
|
||||||
P.z = P.z * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
P.z = ((P.z + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
|
|
||||||
#endif
|
|
||||||
P.z = -P.z;
|
|
||||||
|
|
||||||
// Offset to pixel center
|
|
||||||
P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
|
|
||||||
return P;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reconstructs screen-space unit normal from screen-space position */
|
|
||||||
vec3 reconstructCSFaceNormal(vec3 C) {
|
|
||||||
return normalize(cross(dFdy(C), dFdx(C)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a unit vector and a screen-space radius for the tap on a unit disk (the caller should scale by the actual disk radius) */
|
|
||||||
vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR) {
|
|
||||||
// Radius relative to ssR
|
|
||||||
float alpha = (float(sampleNumber) + 0.5) * (1.0 / float(NUM_SAMPLES));
|
|
||||||
float angle = alpha * (float(NUM_SPIRAL_TURNS) * 6.28) + spinAngle;
|
|
||||||
|
|
||||||
ssR = alpha;
|
|
||||||
return vec2(cos(angle), sin(angle));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */
|
|
||||||
vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) {
|
|
||||||
// Derivation:
|
|
||||||
// mipLevel = floor(log(ssR / MAX_OFFSET));
|
|
||||||
int mipLevel = clamp(int(floor(log2(ssR))) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
|
|
||||||
|
|
||||||
ivec2 ssP = ivec2(ssR * unitOffset) + ssC;
|
|
||||||
|
|
||||||
vec3 P;
|
|
||||||
|
|
||||||
// We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
|
|
||||||
// Manually clamp to the texture size because texelFetch bypasses the texture unit
|
|
||||||
ivec2 mipP = clamp(ssP >> mipLevel, ivec2(0), (screen_size >> mipLevel) - ivec2(1));
|
|
||||||
|
|
||||||
if (mipLevel < 1) {
|
|
||||||
//read from depth buffer
|
|
||||||
P.z = texelFetch(source_depth, mipP, 0).r;
|
|
||||||
P.z = P.z * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
P.z = ((P.z + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
P.z = -P.z;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//read from mipmaps
|
|
||||||
uint d = texelFetch(source_depth_mipmaps, mipP, mipLevel - 1).r;
|
|
||||||
P.z = -(float(d) / 65535.0) * camera_z_far;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset to pixel center
|
|
||||||
P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
|
|
||||||
|
|
||||||
return P;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds
|
|
||||||
to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius
|
|
||||||
|
|
||||||
Note that units of H() in the HPG12 paper are meters, not
|
|
||||||
unitless. The whole falloff/sampling function is therefore
|
|
||||||
unitless. In this implementation, we factor out (9 / radius).
|
|
||||||
|
|
||||||
Four versions of the falloff function are implemented below
|
|
||||||
*/
|
|
||||||
float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in float p_radius, in int tapIndex, in float randomPatternRotationAngle) {
|
|
||||||
// Offset on the unit disk, spun for this pixel
|
|
||||||
float ssR;
|
|
||||||
vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR);
|
|
||||||
ssR *= ssDiskRadius;
|
|
||||||
|
|
||||||
// The occluding point in camera space
|
|
||||||
vec3 Q = getOffsetPosition(ssC, unitOffset, ssR);
|
|
||||||
|
|
||||||
vec3 v = Q - C;
|
|
||||||
|
|
||||||
float vv = dot(v, v);
|
|
||||||
float vn = dot(v, n_C);
|
|
||||||
|
|
||||||
const float epsilon = 0.01;
|
|
||||||
float radius2 = p_radius * p_radius;
|
|
||||||
|
|
||||||
// A: From the HPG12 paper
|
|
||||||
// Note large epsilon to avoid overdarkening within cracks
|
|
||||||
//return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6;
|
|
||||||
|
|
||||||
// B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
|
|
||||||
float f = max(radius2 - vv, 0.0);
|
|
||||||
return f * f * f * max((vn - bias) / (epsilon + vv), 0.0);
|
|
||||||
|
|
||||||
// C: Medium contrast (which looks better at high radii), no division. Note that the
|
|
||||||
// contribution still falls off with radius^2, but we've adjusted the rate in a way that is
|
|
||||||
// more computationally efficient and happens to be aesthetically pleasing.
|
|
||||||
// return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0);
|
|
||||||
|
|
||||||
// D: Low contrast, no division operation
|
|
||||||
// return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
// Pixel being shaded
|
|
||||||
ivec2 ssC = ivec2(gl_FragCoord.xy);
|
|
||||||
|
|
||||||
// World space point being shaded
|
|
||||||
vec3 C = getPosition(ssC);
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (C.z <= -camera_z_far*0.999) {
|
|
||||||
// We're on the skybox
|
|
||||||
visibility=1.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
//visibility=-C.z/camera_z_far;
|
|
||||||
//return;
|
|
||||||
#if 0
|
|
||||||
vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
|
|
||||||
#else
|
|
||||||
vec3 n_C = reconstructCSFaceNormal(C);
|
|
||||||
n_C = -n_C;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Hash function used in the HPG12 AlchemyAO paper
|
|
||||||
float randomPatternRotationAngle = mod(float((3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10), TWO_PI);
|
|
||||||
|
|
||||||
// Reconstruct normals from positions. These will lead to 1-pixel black lines
|
|
||||||
// at depth discontinuities, however the blur will wipe those out so they are not visible
|
|
||||||
// in the final image.
|
|
||||||
|
|
||||||
// Choose the screen-space sample radius
|
|
||||||
// proportional to the projected area of the sphere
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
float ssDiskRadius = -proj_scale * radius;
|
|
||||||
#else
|
|
||||||
float ssDiskRadius = -proj_scale * radius / C.z;
|
|
||||||
#endif
|
|
||||||
float sum = 0.0;
|
|
||||||
for (int i = 0; i < NUM_SAMPLES; ++i) {
|
|
||||||
sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius, i, randomPatternRotationAngle);
|
|
||||||
}
|
|
||||||
|
|
||||||
float A = max(0.0, 1.0 - sum * intensity_div_r6 * (5.0 / float(NUM_SAMPLES)));
|
|
||||||
|
|
||||||
#ifdef ENABLE_RADIUS2
|
|
||||||
|
|
||||||
//go again for radius2
|
|
||||||
randomPatternRotationAngle = mod(float((5 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 11), TWO_PI);
|
|
||||||
|
|
||||||
// Reconstruct normals from positions. These will lead to 1-pixel black lines
|
|
||||||
// at depth discontinuities, however the blur will wipe those out so they are not visible
|
|
||||||
// in the final image.
|
|
||||||
|
|
||||||
// Choose the screen-space sample radius
|
|
||||||
// proportional to the projected area of the sphere
|
|
||||||
ssDiskRadius = -proj_scale * radius2 / C.z;
|
|
||||||
|
|
||||||
sum = 0.0;
|
|
||||||
for (int i = 0; i < NUM_SAMPLES; ++i) {
|
|
||||||
sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius2, i, randomPatternRotationAngle);
|
|
||||||
}
|
|
||||||
|
|
||||||
A = min(A, max(0.0, 1.0 - sum * intensity_div_r62 * (5.0 / float(NUM_SAMPLES))));
|
|
||||||
#endif
|
|
||||||
// Bilateral box-filter over a quad for free, respecting depth edges
|
|
||||||
// (the difference that this makes is subtle)
|
|
||||||
if (abs(dFdx(C.z)) < 0.02) {
|
|
||||||
A -= dFdx(A) * (float(ssC.x & 1) - 0.5);
|
|
||||||
}
|
|
||||||
if (abs(dFdy(C.z)) < 0.02) {
|
|
||||||
A -= dFdy(A) * (float(ssC.y & 1) - 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
visibility = A;
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
gl_Position.z = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
uniform sampler2D source_ssao; //texunit:0
|
|
||||||
/* clang-format on */
|
|
||||||
uniform sampler2D source_depth; //texunit:1
|
|
||||||
uniform sampler2D source_normal; //texunit:3
|
|
||||||
|
|
||||||
layout(location = 0) out float visibility;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Tunable Parameters:
|
|
||||||
|
|
||||||
/** Increase to make depth edges crisper. Decrease to reduce flicker. */
|
|
||||||
uniform float edge_sharpness;
|
|
||||||
|
|
||||||
/** Step in 2-pixel intervals since we already blurred against neighbors in the
|
|
||||||
first AO pass. This constant can be increased while R decreases to improve
|
|
||||||
performance at the expense of some dithering artifacts.
|
|
||||||
|
|
||||||
Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was
|
|
||||||
unobjectionable after shading was applied but eliminated most temporal incoherence
|
|
||||||
from using small numbers of sample taps.
|
|
||||||
*/
|
|
||||||
|
|
||||||
uniform int filter_scale;
|
|
||||||
|
|
||||||
/** Filter radius in pixels. This will be multiplied by SCALE. */
|
|
||||||
#define R (4)
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Gaussian coefficients
|
|
||||||
const float gaussian[R + 1] =
|
|
||||||
//float[](0.356642, 0.239400, 0.072410, 0.009869);
|
|
||||||
//float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0
|
|
||||||
float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0
|
|
||||||
//float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
|
|
||||||
|
|
||||||
/** (1, 0) or (0, 1)*/
|
|
||||||
uniform ivec2 axis;
|
|
||||||
|
|
||||||
uniform float camera_z_far;
|
|
||||||
uniform float camera_z_near;
|
|
||||||
|
|
||||||
uniform ivec2 screen_size;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
ivec2 ssC = ivec2(gl_FragCoord.xy);
|
|
||||||
|
|
||||||
float depth = texelFetch(source_depth, ssC, 0).r;
|
|
||||||
//vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
|
|
||||||
|
|
||||||
depth = depth * 2.0 - 1.0;
|
|
||||||
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
|
||||||
|
|
||||||
float depth_divide = 1.0 / camera_z_far;
|
|
||||||
|
|
||||||
//depth *= depth_divide;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (depth > camera_z_far * 0.999) {
|
|
||||||
discard; //skybox
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
float sum = texelFetch(source_ssao, ssC, 0).r;
|
|
||||||
|
|
||||||
// Base weight for depth falloff. Increase this for more blurriness,
|
|
||||||
// decrease it for better edge discrimination
|
|
||||||
float BASE = gaussian[0];
|
|
||||||
float totalWeight = BASE;
|
|
||||||
sum *= totalWeight;
|
|
||||||
|
|
||||||
ivec2 clamp_limit = screen_size - ivec2(1);
|
|
||||||
|
|
||||||
for (int r = -R; r <= R; ++r) {
|
|
||||||
// We already handled the zero case above. This loop should be unrolled and the static branch optimized out,
|
|
||||||
// so the IF statement has no runtime cost
|
|
||||||
if (r != 0) {
|
|
||||||
ivec2 ppos = ssC + axis * (r * filter_scale);
|
|
||||||
float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r;
|
|
||||||
ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit);
|
|
||||||
float temp_depth = texelFetch(source_depth, rpos, 0).r;
|
|
||||||
//vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0;
|
|
||||||
|
|
||||||
temp_depth = temp_depth * 2.0 - 1.0;
|
|
||||||
temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near));
|
|
||||||
// temp_depth *= depth_divide;
|
|
||||||
|
|
||||||
// spatial domain: offset gaussian tap
|
|
||||||
float weight = 0.3 + gaussian[abs(r)];
|
|
||||||
//weight *= max(0.0,dot(temp_normal,normal));
|
|
||||||
|
|
||||||
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
|
||||||
weight *= max(0.0, 1.0 - edge_sharpness * abs(temp_depth - depth));
|
|
||||||
|
|
||||||
sum += value * weight;
|
|
||||||
totalWeight += weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const float epsilon = 0.0001;
|
|
||||||
visibility = sum / (totalWeight + epsilon);
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
#ifdef MINIFY_START
|
|
||||||
|
|
||||||
#define SDEPTH_TYPE highp sampler2D
|
|
||||||
uniform float camera_z_far;
|
|
||||||
uniform float camera_z_near;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define SDEPTH_TYPE mediump usampler2D
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform SDEPTH_TYPE source_depth; //texunit:0
|
|
||||||
|
|
||||||
uniform ivec2 from_size;
|
|
||||||
uniform int source_mipmap;
|
|
||||||
|
|
||||||
layout(location = 0) out mediump uint depth;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
ivec2 ssP = ivec2(gl_FragCoord.xy);
|
|
||||||
|
|
||||||
// Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling.
|
|
||||||
// On DX9, the bit-and can be implemented with floating-point modulo
|
|
||||||
|
|
||||||
#ifdef MINIFY_START
|
|
||||||
float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r;
|
|
||||||
fdepth = fdepth * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
fdepth = ((fdepth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near));
|
|
||||||
#endif
|
|
||||||
fdepth /= camera_z_far;
|
|
||||||
depth = uint(clamp(fdepth * 65535.0, 0.0, 65535.0));
|
|
||||||
|
|
||||||
#else
|
|
||||||
depth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r;
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,440 +0,0 @@
|
||||||
|
|
||||||
vec2 select2(vec2 a, vec2 b, bvec2 c) {
|
|
||||||
vec2 ret;
|
|
||||||
|
|
||||||
ret.x = c.x ? b.x : a.x;
|
|
||||||
ret.y = c.y ? b.y : a.y;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 select3(vec3 a, vec3 b, bvec3 c) {
|
|
||||||
vec3 ret;
|
|
||||||
|
|
||||||
ret.x = c.x ? b.x : a.x;
|
|
||||||
ret.y = c.y ? b.y : a.y;
|
|
||||||
ret.z = c.z ? b.z : a.z;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 select4(vec4 a, vec4 b, bvec4 c) {
|
|
||||||
vec4 ret;
|
|
||||||
|
|
||||||
ret.x = c.x ? b.x : a.x;
|
|
||||||
ret.y = c.y ? b.y : a.y;
|
|
||||||
ret.z = c.z ? b.z : a.z;
|
|
||||||
ret.w = c.w ? b.w : a.w;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 texel2DFetch(highp sampler2D tex, ivec2 size, ivec2 coord) {
|
|
||||||
float x_coord = float(2 * coord.x + 1) / float(size.x * 2);
|
|
||||||
float y_coord = float(2 * coord.y + 1) / float(size.y * 2);
|
|
||||||
|
|
||||||
return texture2DLod(tex, vec2(x_coord, y_coord), 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(SINH_USED)
|
|
||||||
|
|
||||||
highp float sinh(highp float x) {
|
|
||||||
return 0.5 * (exp(x) - exp(-x));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 sinh(highp vec2 x) {
|
|
||||||
return 0.5 * vec2(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 sinh(highp vec3 x) {
|
|
||||||
return 0.5 * vec3(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y), exp(x.z) - exp(-x.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 sinh(highp vec4 x) {
|
|
||||||
return 0.5 * vec4(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y), exp(x.z) - exp(-x.z), exp(x.w) - exp(-x.w));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(COSH_USED)
|
|
||||||
|
|
||||||
highp float cosh(highp float x) {
|
|
||||||
return 0.5 * (exp(x) + exp(-x));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 cosh(highp vec2 x) {
|
|
||||||
return 0.5 * vec2(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 cosh(highp vec3 x) {
|
|
||||||
return 0.5 * vec3(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y), exp(x.z) + exp(-x.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 cosh(highp vec4 x) {
|
|
||||||
return 0.5 * vec4(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y), exp(x.z) + exp(-x.z), exp(x.w) + exp(-x.w));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TANH_USED)
|
|
||||||
|
|
||||||
highp float tanh(highp float x) {
|
|
||||||
highp float exp2x = exp(2.0 * x);
|
|
||||||
return (exp2x - 1.0) / (exp2x + 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 tanh(highp vec2 x) {
|
|
||||||
highp float exp2x = exp(2.0 * x.x);
|
|
||||||
highp float exp2y = exp(2.0 * x.y);
|
|
||||||
return vec2((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 tanh(highp vec3 x) {
|
|
||||||
highp float exp2x = exp(2.0 * x.x);
|
|
||||||
highp float exp2y = exp(2.0 * x.y);
|
|
||||||
highp float exp2z = exp(2.0 * x.z);
|
|
||||||
return vec3((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0), (exp2z - 1.0) / (exp2z + 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 tanh(highp vec4 x) {
|
|
||||||
highp float exp2x = exp(2.0 * x.x);
|
|
||||||
highp float exp2y = exp(2.0 * x.y);
|
|
||||||
highp float exp2z = exp(2.0 * x.z);
|
|
||||||
highp float exp2w = exp(2.0 * x.w);
|
|
||||||
return vec4((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0), (exp2z - 1.0) / (exp2z + 1.0), (exp2w - 1.0) / (exp2w + 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ASINH_USED)
|
|
||||||
|
|
||||||
highp float asinh(highp float x) {
|
|
||||||
return sign(x) * log(abs(x) + sqrt(1.0 + x * x));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 asinh(highp vec2 x) {
|
|
||||||
return vec2(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 asinh(highp vec3 x) {
|
|
||||||
return vec3(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)), sign(x.z) * log(abs(x.z) + sqrt(1.0 + x.z * x.z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 asinh(highp vec4 x) {
|
|
||||||
return vec4(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)), sign(x.z) * log(abs(x.z) + sqrt(1.0 + x.z * x.z)), sign(x.w) * log(abs(x.w) + sqrt(1.0 + x.w * x.w)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ACOSH_USED)
|
|
||||||
|
|
||||||
highp float acosh(highp float x) {
|
|
||||||
return log(x + sqrt(x * x - 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 acosh(highp vec2 x) {
|
|
||||||
return vec2(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 acosh(highp vec3 x) {
|
|
||||||
return vec3(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)), log(x.z + sqrt(x.z * x.z - 1.0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 acosh(highp vec4 x) {
|
|
||||||
return vec4(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)), log(x.z + sqrt(x.z * x.z - 1.0)), log(x.w + sqrt(x.w * x.w - 1.0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ATANH_USED)
|
|
||||||
|
|
||||||
highp float atanh(highp float x) {
|
|
||||||
return 0.5 * log((1.0 + x) / (1.0 - x));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 atanh(highp vec2 x) {
|
|
||||||
return 0.5 * vec2(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 atanh(highp vec3 x) {
|
|
||||||
return 0.5 * vec3(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)), log((1.0 + x.z) / (1.0 - x.z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 atanh(highp vec4 x) {
|
|
||||||
return 0.5 * vec4(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)), log((1.0 + x.z) / (1.0 - x.z)), log((1.0 + x.w) / (1.0 - x.w)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ROUND_USED)
|
|
||||||
|
|
||||||
highp float round(highp float x) {
|
|
||||||
return floor(x + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 round(highp vec2 x) {
|
|
||||||
return floor(x + vec2(0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 round(highp vec3 x) {
|
|
||||||
return floor(x + vec3(0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 round(highp vec4 x) {
|
|
||||||
return floor(x + vec4(0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ROUND_EVEN_USED)
|
|
||||||
|
|
||||||
highp float roundEven(highp float x) {
|
|
||||||
highp float t = x + 0.5;
|
|
||||||
highp float f = floor(t);
|
|
||||||
highp float r;
|
|
||||||
if (t == f) {
|
|
||||||
if (x > 0)
|
|
||||||
r = f - mod(f, 2);
|
|
||||||
else
|
|
||||||
r = f + mod(f, 2);
|
|
||||||
} else
|
|
||||||
r = f;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 roundEven(highp vec2 x) {
|
|
||||||
return vec2(roundEven(x.x), roundEven(x.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 roundEven(highp vec3 x) {
|
|
||||||
return vec3(roundEven(x.x), roundEven(x.y), roundEven(x.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 roundEven(highp vec4 x) {
|
|
||||||
return vec4(roundEven(x.x), roundEven(x.y), roundEven(x.z), roundEven(x.w));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(IS_INF_USED)
|
|
||||||
|
|
||||||
bool isinf(highp float x) {
|
|
||||||
return (2 * x == x) && (x != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bvec2 isinf(highp vec2 x) {
|
|
||||||
return bvec2((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
bvec3 isinf(highp vec3 x) {
|
|
||||||
return bvec3((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0), (2 * x.z == x.z) && (x.z != 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
bvec4 isinf(highp vec4 x) {
|
|
||||||
return bvec4((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0), (2 * x.z == x.z) && (x.z != 0), (2 * x.w == x.w) && (x.w != 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(IS_NAN_USED)
|
|
||||||
|
|
||||||
bool isnan(highp float x) {
|
|
||||||
return x != x;
|
|
||||||
}
|
|
||||||
|
|
||||||
bvec2 isnan(highp vec2 x) {
|
|
||||||
return bvec2(x.x != x.x, x.y != x.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
bvec3 isnan(highp vec3 x) {
|
|
||||||
return bvec3(x.x != x.x, x.y != x.y, x.z != x.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
bvec4 isnan(highp vec4 x) {
|
|
||||||
return bvec4(x.x != x.x, x.y != x.y, x.z != x.z, x.w != x.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TRUNC_USED)
|
|
||||||
|
|
||||||
highp float trunc(highp float x) {
|
|
||||||
return x < 0 ? -floor(-x) : floor(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 trunc(highp vec2 x) {
|
|
||||||
return vec2(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 trunc(highp vec3 x) {
|
|
||||||
return vec3(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y), x.z < 0 ? -floor(-x.z) : floor(x.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 trunc(highp vec4 x) {
|
|
||||||
return vec4(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y), x.z < 0 ? -floor(-x.z) : floor(x.z), x.w < 0 ? -floor(-x.w) : floor(x.w));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(DETERMINANT_USED)
|
|
||||||
|
|
||||||
highp float determinant(highp mat2 m) {
|
|
||||||
return m[0].x * m[1].y - m[1].x * m[0].y;
|
|
||||||
}
|
|
||||||
|
|
||||||
highp float determinant(highp mat3 m) {
|
|
||||||
return m[0].x * (m[1].y * m[2].z - m[2].y * m[1].z) - m[1].x * (m[0].y * m[2].z - m[2].y * m[0].z) + m[2].x * (m[0].y * m[1].z - m[1].y * m[0].z);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp float determinant(highp mat4 m) {
|
|
||||||
highp float s00 = m[2].z * m[3].w - m[3].z * m[2].w;
|
|
||||||
highp float s01 = m[2].y * m[3].w - m[3].y * m[2].w;
|
|
||||||
highp float s02 = m[2].y * m[3].z - m[3].y * m[2].z;
|
|
||||||
highp float s03 = m[2].x * m[3].w - m[3].x * m[2].w;
|
|
||||||
highp float s04 = m[2].x * m[3].z - m[3].x * m[2].z;
|
|
||||||
highp float s05 = m[2].x * m[3].y - m[3].x * m[2].y;
|
|
||||||
highp vec4 c = vec4((m[1].y * s00 - m[1].z * s01 + m[1].w * s02), -(m[1].x * s00 - m[1].z * s03 + m[1].w * s04), (m[1].x * s01 - m[1].y * s03 + m[1].w * s05), -(m[1].x * s02 - m[1].y * s04 + m[1].z * s05));
|
|
||||||
return m[0].x * c.x + m[0].y * c.y + m[0].z * c.z + m[0].w * c.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(INVERSE_USED)
|
|
||||||
|
|
||||||
highp mat2 inverse(highp mat2 m) {
|
|
||||||
highp float d = 1.0 / (m[0].x * m[1].y - m[1].x * m[0].y);
|
|
||||||
return mat2(
|
|
||||||
vec2(m[1].y * d, -m[0].y * d),
|
|
||||||
vec2(-m[1].x * d, m[0].x * d));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp mat3 inverse(highp mat3 m) {
|
|
||||||
highp float d = 1.0 / (m[0].x * (m[1].y * m[2].z - m[2].y * m[1].z) - m[1].x * (m[0].y * m[2].z - m[2].y * m[0].z) + m[2].x * (m[0].y * m[1].z - m[1].y * m[0].z));
|
|
||||||
return mat3(
|
|
||||||
vec3((m[1].y * m[2].z - m[2].y * m[1].z), -(m[1].x * m[2].z - m[2].x * m[1].z), (m[1].x * m[2].y - m[2].x * m[1].y)) * d,
|
|
||||||
vec3(-(m[0].y * m[2].z - m[2].y * m[0].z), (m[0].x * m[2].z - m[2].x * m[0].z), -(m[0].x * m[2].y - m[2].x * m[0].y)) * d,
|
|
||||||
vec3((m[0].y * m[1].z - m[1].y * m[0].z), -(m[0].x * m[1].z - m[1].x * m[0].z), (m[0].x * m[1].y - m[1].x * m[0].y)) * d);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp mat4 inverse(highp mat4 m) {
|
|
||||||
highp float c00 = m[2].z * m[3].w - m[3].z * m[2].w;
|
|
||||||
highp float c02 = m[1].z * m[3].w - m[3].z * m[1].w;
|
|
||||||
highp float c03 = m[1].z * m[2].w - m[2].z * m[1].w;
|
|
||||||
|
|
||||||
highp float c04 = m[2].y * m[3].w - m[3].y * m[2].w;
|
|
||||||
highp float c06 = m[1].y * m[3].w - m[3].y * m[1].w;
|
|
||||||
highp float c07 = m[1].y * m[2].w - m[2].y * m[1].w;
|
|
||||||
|
|
||||||
highp float c08 = m[2].y * m[3].z - m[3].y * m[2].z;
|
|
||||||
highp float c10 = m[1].y * m[3].z - m[3].y * m[1].z;
|
|
||||||
highp float c11 = m[1].y * m[2].z - m[2].y * m[1].z;
|
|
||||||
|
|
||||||
highp float c12 = m[2].x * m[3].w - m[3].x * m[2].w;
|
|
||||||
highp float c14 = m[1].x * m[3].w - m[3].x * m[1].w;
|
|
||||||
highp float c15 = m[1].x * m[2].w - m[2].x * m[1].w;
|
|
||||||
|
|
||||||
highp float c16 = m[2].x * m[3].z - m[3].x * m[2].z;
|
|
||||||
highp float c18 = m[1].x * m[3].z - m[3].x * m[1].z;
|
|
||||||
highp float c19 = m[1].x * m[2].z - m[2].x * m[1].z;
|
|
||||||
|
|
||||||
highp float c20 = m[2].x * m[3].y - m[3].x * m[2].y;
|
|
||||||
highp float c22 = m[1].x * m[3].y - m[3].x * m[1].y;
|
|
||||||
highp float c23 = m[1].x * m[2].y - m[2].x * m[1].y;
|
|
||||||
|
|
||||||
vec4 f0 = vec4(c00, c00, c02, c03);
|
|
||||||
vec4 f1 = vec4(c04, c04, c06, c07);
|
|
||||||
vec4 f2 = vec4(c08, c08, c10, c11);
|
|
||||||
vec4 f3 = vec4(c12, c12, c14, c15);
|
|
||||||
vec4 f4 = vec4(c16, c16, c18, c19);
|
|
||||||
vec4 f5 = vec4(c20, c20, c22, c23);
|
|
||||||
|
|
||||||
vec4 v0 = vec4(m[1].x, m[0].x, m[0].x, m[0].x);
|
|
||||||
vec4 v1 = vec4(m[1].y, m[0].y, m[0].y, m[0].y);
|
|
||||||
vec4 v2 = vec4(m[1].z, m[0].z, m[0].z, m[0].z);
|
|
||||||
vec4 v3 = vec4(m[1].w, m[0].w, m[0].w, m[0].w);
|
|
||||||
|
|
||||||
vec4 inv0 = vec4(v1 * f0 - v2 * f1 + v3 * f2);
|
|
||||||
vec4 inv1 = vec4(v0 * f0 - v2 * f3 + v3 * f4);
|
|
||||||
vec4 inv2 = vec4(v0 * f1 - v1 * f3 + v3 * f5);
|
|
||||||
vec4 inv3 = vec4(v0 * f2 - v1 * f4 + v2 * f5);
|
|
||||||
|
|
||||||
vec4 sa = vec4(+1, -1, +1, -1);
|
|
||||||
vec4 sb = vec4(-1, +1, -1, +1);
|
|
||||||
|
|
||||||
mat4 inv = mat4(inv0 * sa, inv1 * sb, inv2 * sa, inv3 * sb);
|
|
||||||
|
|
||||||
vec4 r0 = vec4(inv[0].x, inv[1].x, inv[2].x, inv[3].x);
|
|
||||||
vec4 d0 = vec4(m[0] * r0);
|
|
||||||
|
|
||||||
highp float d1 = (d0.x + d0.y) + (d0.z + d0.w);
|
|
||||||
highp float d = 1.0 / d1;
|
|
||||||
|
|
||||||
return inv * d;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
|
|
||||||
#if defined(TRANSPOSE_USED)
|
|
||||||
|
|
||||||
highp mat2 transpose(highp mat2 m) {
|
|
||||||
return mat2(
|
|
||||||
vec2(m[0].x, m[1].x),
|
|
||||||
vec2(m[0].y, m[1].y));
|
|
||||||
}
|
|
||||||
|
|
||||||
highp mat3 transpose(highp mat3 m) {
|
|
||||||
return mat3(
|
|
||||||
vec3(m[0].x, m[1].x, m[2].x),
|
|
||||||
vec3(m[0].y, m[1].y, m[2].y),
|
|
||||||
vec3(m[0].z, m[1].z, m[2].z));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
highp mat4 transpose(highp mat4 m) {
|
|
||||||
return mat4(
|
|
||||||
vec4(m[0].x, m[1].x, m[2].x, m[3].x),
|
|
||||||
vec4(m[0].y, m[1].y, m[2].y, m[3].y),
|
|
||||||
vec4(m[0].z, m[1].z, m[2].z, m[3].z),
|
|
||||||
vec4(m[0].w, m[1].w, m[2].w, m[3].w));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OUTER_PRODUCT_USED)
|
|
||||||
|
|
||||||
highp mat2 outerProduct(highp vec2 c, highp vec2 r) {
|
|
||||||
return mat2(c * r.x, c * r.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp mat3 outerProduct(highp vec3 c, highp vec3 r) {
|
|
||||||
return mat3(c * r.x, c * r.y, c * r.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
highp mat4 outerProduct(highp vec4 c, highp vec4 r) {
|
|
||||||
return mat4(c * r.x, c * r.y, c * r.z, c * r.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(FMA_USED)
|
|
||||||
|
|
||||||
highp float fma(highp float a, highp float b, highp float c) {
|
|
||||||
return a * b + c;
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec2 fma(highp vec2 a, highp vec2 b, highp vec2 c) {
|
|
||||||
return a * b + c;
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec3 fma(highp vec3 a, highp vec3 b, highp vec3 c) {
|
|
||||||
return a * b + c;
|
|
||||||
}
|
|
||||||
|
|
||||||
highp vec4 fma(highp vec4 a, highp vec4 b, highp vec4 c) {
|
|
||||||
return a * b + c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,171 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 vertex_attrib;
|
|
||||||
/* clang-format on */
|
|
||||||
layout(location = 4) in vec2 uv_in;
|
|
||||||
|
|
||||||
out vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uv_interp = uv_in;
|
|
||||||
gl_Position = vertex_attrib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
//#define QUALIFIER uniform // some guy on the interweb says it may be faster with this
|
|
||||||
#define QUALIFIER const
|
|
||||||
|
|
||||||
#ifdef USE_25_SAMPLES
|
|
||||||
const int kernel_size = 25;
|
|
||||||
/* clang-format on */
|
|
||||||
QUALIFIER vec2 kernel[25] = vec2[](
|
|
||||||
vec2(0.530605, 0.0),
|
|
||||||
vec2(0.000973794, -3.0),
|
|
||||||
vec2(0.00333804, -2.52083),
|
|
||||||
vec2(0.00500364, -2.08333),
|
|
||||||
vec2(0.00700976, -1.6875),
|
|
||||||
vec2(0.0094389, -1.33333),
|
|
||||||
vec2(0.0128496, -1.02083),
|
|
||||||
vec2(0.017924, -0.75),
|
|
||||||
vec2(0.0263642, -0.520833),
|
|
||||||
vec2(0.0410172, -0.333333),
|
|
||||||
vec2(0.0493588, -0.1875),
|
|
||||||
vec2(0.0402784, -0.0833333),
|
|
||||||
vec2(0.0211412, -0.0208333),
|
|
||||||
vec2(0.0211412, 0.0208333),
|
|
||||||
vec2(0.0402784, 0.0833333),
|
|
||||||
vec2(0.0493588, 0.1875),
|
|
||||||
vec2(0.0410172, 0.333333),
|
|
||||||
vec2(0.0263642, 0.520833),
|
|
||||||
vec2(0.017924, 0.75),
|
|
||||||
vec2(0.0128496, 1.02083),
|
|
||||||
vec2(0.0094389, 1.33333),
|
|
||||||
vec2(0.00700976, 1.6875),
|
|
||||||
vec2(0.00500364, 2.08333),
|
|
||||||
vec2(0.00333804, 2.52083),
|
|
||||||
vec2(0.000973794, 3.0));
|
|
||||||
#endif //USE_25_SAMPLES
|
|
||||||
|
|
||||||
#ifdef USE_17_SAMPLES
|
|
||||||
const int kernel_size = 17;
|
|
||||||
QUALIFIER vec2 kernel[17] = vec2[](
|
|
||||||
vec2(0.536343, 0.0),
|
|
||||||
vec2(0.00317394, -2.0),
|
|
||||||
vec2(0.0100386, -1.53125),
|
|
||||||
vec2(0.0144609, -1.125),
|
|
||||||
vec2(0.0216301, -0.78125),
|
|
||||||
vec2(0.0347317, -0.5),
|
|
||||||
vec2(0.0571056, -0.28125),
|
|
||||||
vec2(0.0582416, -0.125),
|
|
||||||
vec2(0.0324462, -0.03125),
|
|
||||||
vec2(0.0324462, 0.03125),
|
|
||||||
vec2(0.0582416, 0.125),
|
|
||||||
vec2(0.0571056, 0.28125),
|
|
||||||
vec2(0.0347317, 0.5),
|
|
||||||
vec2(0.0216301, 0.78125),
|
|
||||||
vec2(0.0144609, 1.125),
|
|
||||||
vec2(0.0100386, 1.53125),
|
|
||||||
vec2(0.00317394, 2.0));
|
|
||||||
#endif //USE_17_SAMPLES
|
|
||||||
|
|
||||||
#ifdef USE_11_SAMPLES
|
|
||||||
const int kernel_size = 11;
|
|
||||||
QUALIFIER vec2 kernel[11] = vec2[](
|
|
||||||
vec2(0.560479, 0.0),
|
|
||||||
vec2(0.00471691, -2.0),
|
|
||||||
vec2(0.0192831, -1.28),
|
|
||||||
vec2(0.03639, -0.72),
|
|
||||||
vec2(0.0821904, -0.32),
|
|
||||||
vec2(0.0771802, -0.08),
|
|
||||||
vec2(0.0771802, 0.08),
|
|
||||||
vec2(0.0821904, 0.32),
|
|
||||||
vec2(0.03639, 0.72),
|
|
||||||
vec2(0.0192831, 1.28),
|
|
||||||
vec2(0.00471691, 2.0));
|
|
||||||
#endif //USE_11_SAMPLES
|
|
||||||
|
|
||||||
uniform float max_radius;
|
|
||||||
uniform float camera_z_far;
|
|
||||||
uniform float camera_z_near;
|
|
||||||
uniform float unit_size;
|
|
||||||
uniform vec2 dir;
|
|
||||||
in vec2 uv_interp;
|
|
||||||
|
|
||||||
uniform sampler2D source_diffuse; //texunit:0
|
|
||||||
uniform sampler2D source_sss; //texunit:1
|
|
||||||
uniform sampler2D source_depth; //texunit:2
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 frag_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
float strength = texture(source_sss, uv_interp).r;
|
|
||||||
strength *= strength; //stored as sqrt
|
|
||||||
|
|
||||||
// Fetch color of current pixel:
|
|
||||||
vec4 base_color = texture(source_diffuse, uv_interp);
|
|
||||||
|
|
||||||
if (strength > 0.0) {
|
|
||||||
// Fetch linear depth of current pixel:
|
|
||||||
float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0;
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
float scale = unit_size; //remember depth is negative by default in OpenGL
|
|
||||||
#else
|
|
||||||
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
|
||||||
float scale = unit_size / depth; //remember depth is negative by default in OpenGL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Calculate the final step to fetch the surrounding pixels:
|
|
||||||
vec2 step = max_radius * scale * dir;
|
|
||||||
step *= strength; // Modulate it using the alpha channel.
|
|
||||||
step *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3.
|
|
||||||
|
|
||||||
// Accumulate the center sample:
|
|
||||||
vec3 color_accum = base_color.rgb;
|
|
||||||
color_accum *= kernel[0].x;
|
|
||||||
#ifdef ENABLE_STRENGTH_WEIGHTING
|
|
||||||
float color_weight = kernel[0].x;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Accumulate the other samples:
|
|
||||||
for (int i = 1; i < kernel_size; i++) {
|
|
||||||
// Fetch color and depth for current sample:
|
|
||||||
vec2 offset = uv_interp + kernel[i].y * step;
|
|
||||||
vec3 color = texture(source_diffuse, offset).rgb;
|
|
||||||
|
|
||||||
#ifdef ENABLE_FOLLOW_SURFACE
|
|
||||||
// If the difference in depth is huge, we lerp color back to "colorM":
|
|
||||||
float depth_cmp = texture(source_depth, offset).r * 2.0 - 1.0;
|
|
||||||
|
|
||||||
#ifdef USE_ORTHOGONAL_PROJECTION
|
|
||||||
depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
|
|
||||||
#else
|
|
||||||
depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float s = clamp(300.0f * scale * max_radius * abs(depth - depth_cmp), 0.0, 1.0);
|
|
||||||
color = mix(color, base_color.rgb, s);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Accumulate:
|
|
||||||
color *= kernel[i].x;
|
|
||||||
|
|
||||||
#ifdef ENABLE_STRENGTH_WEIGHTING
|
|
||||||
float color_s = texture(source_sss, offset).r;
|
|
||||||
color_weight += color_s * kernel[i].x;
|
|
||||||
color *= color_s;
|
|
||||||
#endif
|
|
||||||
color_accum += color;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_STRENGTH_WEIGHTING
|
|
||||||
color_accum /= color_weight;
|
|
||||||
#endif
|
|
||||||
frag_color = vec4(color_accum, base_color.a); //keep alpha (used for SSAO)
|
|
||||||
} else {
|
|
||||||
frag_color = base_color;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,289 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
[vertex]
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attribute vec2 vertex_attrib; // attrib:0
|
|
||||||
/* clang-format on */
|
|
||||||
attribute vec2 uv_in; // attrib:4
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(vertex_attrib, 0.0, 1.0);
|
|
||||||
|
|
||||||
uv_interp = uv_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
[fragment]
|
|
||||||
|
|
||||||
|
|
||||||
// texture2DLodEXT and textureCubeLodEXT are fragment shader specific.
|
|
||||||
// Do not copy these defines in the vertex section.
|
|
||||||
#ifndef USE_GLES_OVER_GL
|
|
||||||
#ifdef GL_EXT_shader_texture_lod
|
|
||||||
#extension GL_EXT_shader_texture_lod : enable
|
|
||||||
#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
#endif // !USE_GLES_OVER_GL
|
|
||||||
|
|
||||||
#ifdef GL_ARB_shader_texture_lod
|
|
||||||
#extension GL_ARB_shader_texture_lod : enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
|
|
||||||
#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
|
|
||||||
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Allows the use of bitshift operators for bicubic upscale
|
|
||||||
#ifdef GL_EXT_gpu_shader4
|
|
||||||
#extension GL_EXT_gpu_shader4 : enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "stdlib.glsl"
|
|
||||||
|
|
||||||
varying vec2 uv_interp;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
uniform highp sampler2D source; //texunit:0
|
|
||||||
|
|
||||||
#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7)
|
|
||||||
#define USING_GLOW // only use glow when at least one glow level is selected
|
|
||||||
|
|
||||||
#ifdef USE_MULTI_TEXTURE_GLOW
|
|
||||||
uniform highp sampler2D source_glow1; //texunit:1
|
|
||||||
uniform highp sampler2D source_glow2; //texunit:2
|
|
||||||
uniform highp sampler2D source_glow3; //texunit:3
|
|
||||||
uniform highp sampler2D source_glow4; //texunit:4
|
|
||||||
uniform highp sampler2D source_glow5; //texunit:5
|
|
||||||
uniform highp sampler2D source_glow6; //texunit:6
|
|
||||||
uniform highp sampler2D source_glow7; //texunit:7
|
|
||||||
#else
|
|
||||||
uniform highp sampler2D source_glow; //texunit:1
|
|
||||||
#endif
|
|
||||||
uniform highp float glow_intensity;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_BCS
|
|
||||||
uniform vec3 bcs;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_COLOR_CORRECTION
|
|
||||||
uniform sampler2D color_correction; //texunit:2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GL_EXT_gpu_shader4
|
|
||||||
#ifdef USE_GLOW_FILTER_BICUBIC
|
|
||||||
// w0, w1, w2, and w3 are the four cubic B-spline basis functions
|
|
||||||
float w0(float a) {
|
|
||||||
return (1.0 / 6.0) * (a * (a * (-a + 3.0) - 3.0) + 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float w1(float a) {
|
|
||||||
return (1.0 / 6.0) * (a * a * (3.0 * a - 6.0) + 4.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float w2(float a) {
|
|
||||||
return (1.0 / 6.0) * (a * (a * (-3.0 * a + 3.0) + 3.0) + 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float w3(float a) {
|
|
||||||
return (1.0 / 6.0) * (a * a * a);
|
|
||||||
}
|
|
||||||
|
|
||||||
// g0 and g1 are the two amplitude functions
|
|
||||||
float g0(float a) {
|
|
||||||
return w0(a) + w1(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
float g1(float a) {
|
|
||||||
return w2(a) + w3(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
// h0 and h1 are the two offset functions
|
|
||||||
float h0(float a) {
|
|
||||||
return -1.0 + w1(a) / (w0(a) + w1(a));
|
|
||||||
}
|
|
||||||
|
|
||||||
float h1(float a) {
|
|
||||||
return 1.0 + w3(a) / (w2(a) + w3(a));
|
|
||||||
}
|
|
||||||
|
|
||||||
uniform ivec2 glow_texture_size;
|
|
||||||
|
|
||||||
vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) {
|
|
||||||
float lod = float(p_lod);
|
|
||||||
vec2 tex_size = vec2(glow_texture_size >> p_lod);
|
|
||||||
vec2 pixel_size = vec2(1.0) / tex_size;
|
|
||||||
|
|
||||||
uv = uv * tex_size + vec2(0.5);
|
|
||||||
|
|
||||||
vec2 iuv = floor(uv);
|
|
||||||
vec2 fuv = fract(uv);
|
|
||||||
|
|
||||||
float g0x = g0(fuv.x);
|
|
||||||
float g1x = g1(fuv.x);
|
|
||||||
float h0x = h0(fuv.x);
|
|
||||||
float h1x = h1(fuv.x);
|
|
||||||
float h0y = h0(fuv.y);
|
|
||||||
float h1y = h1(fuv.y);
|
|
||||||
|
|
||||||
vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5)) * pixel_size;
|
|
||||||
vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5)) * pixel_size;
|
|
||||||
vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5)) * pixel_size;
|
|
||||||
vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5)) * pixel_size;
|
|
||||||
|
|
||||||
return (g0(fuv.y) * (g0x * texture2DLod(tex, p0, lod) + g1x * texture2DLod(tex, p1, lod))) +
|
|
||||||
(g1(fuv.y) * (g0x * texture2DLod(tex, p2, lod) + g1x * texture2DLod(tex, p3, lod)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod)
|
|
||||||
#else //!USE_GLOW_FILTER_BICUBIC
|
|
||||||
#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2DLod(m_tex, m_uv, float(m_lod))
|
|
||||||
#endif //USE_GLOW_FILTER_BICUBIC
|
|
||||||
|
|
||||||
#else //!GL_EXT_gpu_shader4
|
|
||||||
#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2DLod(m_tex, m_uv, float(m_lod))
|
|
||||||
#endif //GL_EXT_gpu_shader4
|
|
||||||
|
|
||||||
vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blending mode
|
|
||||||
#ifdef USE_GLOW_REPLACE
|
|
||||||
color = glow;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_SCREEN
|
|
||||||
color = max((color + glow) - (color * glow), vec3(0.0));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_SOFTLIGHT
|
|
||||||
glow = glow * vec3(0.5) + vec3(0.5);
|
|
||||||
|
|
||||||
color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r)));
|
|
||||||
color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g)));
|
|
||||||
color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) // no other selected -> additive
|
|
||||||
color += glow;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 apply_bcs(vec3 color, vec3 bcs) {
|
|
||||||
color = mix(vec3(0.0), color, bcs.x);
|
|
||||||
color = mix(vec3(0.5), color, bcs.y);
|
|
||||||
color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, bcs.z);
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 apply_color_correction(vec3 color, sampler2D correction_tex) {
|
|
||||||
color.r = texture2D(correction_tex, vec2(color.r, 0.0)).r;
|
|
||||||
color.g = texture2D(correction_tex, vec2(color.g, 0.0)).g;
|
|
||||||
color.b = texture2D(correction_tex, vec2(color.b, 0.0)).b;
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec3 color = texture2DLod(source, uv_interp, 0.0).rgb;
|
|
||||||
|
|
||||||
// Glow
|
|
||||||
|
|
||||||
#ifdef USING_GLOW
|
|
||||||
vec3 glow = vec3(0.0);
|
|
||||||
#ifdef USE_MULTI_TEXTURE_GLOW
|
|
||||||
#ifdef USE_GLOW_LEVEL1
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow1, uv_interp, 0).rgb;
|
|
||||||
#ifdef USE_GLOW_LEVEL2
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow2, uv_interp, 0).rgb;
|
|
||||||
#ifdef USE_GLOW_LEVEL3
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow3, uv_interp, 0).rgb;
|
|
||||||
#ifdef USE_GLOW_LEVEL4
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow4, uv_interp, 0).rgb;
|
|
||||||
#ifdef USE_GLOW_LEVEL5
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow5, uv_interp, 0).rgb;
|
|
||||||
#ifdef USE_GLOW_LEVEL6
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow6, uv_interp, 0).rgb;
|
|
||||||
#ifdef USE_GLOW_LEVEL7
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow7, uv_interp, 0).rgb;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_LEVEL1
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow, uv_interp, 1).rgb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_LEVEL2
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow, uv_interp, 2).rgb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_LEVEL3
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow, uv_interp, 3).rgb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_LEVEL4
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow, uv_interp, 4).rgb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_LEVEL5
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow, uv_interp, 5).rgb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_LEVEL6
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow, uv_interp, 6).rgb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_GLOW_LEVEL7
|
|
||||||
glow += GLOW_TEXTURE_SAMPLE(source_glow, uv_interp, 7).rgb;
|
|
||||||
#endif
|
|
||||||
#endif //USE_MULTI_TEXTURE_GLOW
|
|
||||||
|
|
||||||
glow *= glow_intensity;
|
|
||||||
color = apply_glow(color, glow);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Additional effects
|
|
||||||
|
|
||||||
#ifdef USE_BCS
|
|
||||||
color = apply_bcs(color, bcs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_COLOR_CORRECTION
|
|
||||||
color = apply_color_correction(color, color_correction);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gl_FragColor = vec4(color, 1.0);
|
|
||||||
}
|
|
825
gles_builders.py
825
gles_builders.py
|
@ -1,825 +0,0 @@
|
||||||
"""Functions used to generate source files during build time
|
|
||||||
|
|
||||||
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
|
|
||||||
|
|
||||||
"""
|
|
||||||
from platform_methods import subprocess_main
|
|
||||||
|
|
||||||
|
|
||||||
class LegacyGLHeaderStruct:
|
|
||||||
def __init__(self):
|
|
||||||
self.vertex_lines = []
|
|
||||||
self.fragment_lines = []
|
|
||||||
self.uniforms = []
|
|
||||||
self.attributes = []
|
|
||||||
self.feedbacks = []
|
|
||||||
self.fbos = []
|
|
||||||
self.conditionals = []
|
|
||||||
self.enums = {}
|
|
||||||
self.texunits = []
|
|
||||||
self.texunit_names = []
|
|
||||||
self.ubos = []
|
|
||||||
self.ubo_names = []
|
|
||||||
|
|
||||||
self.vertex_included_files = []
|
|
||||||
self.fragment_included_files = []
|
|
||||||
|
|
||||||
self.reading = ""
|
|
||||||
self.line_offset = 0
|
|
||||||
self.vertex_offset = 0
|
|
||||||
self.fragment_offset = 0
|
|
||||||
|
|
||||||
|
|
||||||
def include_file_in_legacygl_header(filename, header_data, depth):
|
|
||||||
fs = open(filename, "r")
|
|
||||||
line = fs.readline()
|
|
||||||
|
|
||||||
while line:
|
|
||||||
|
|
||||||
if line.find("#[vertex]") != -1:
|
|
||||||
header_data.reading = "vertex"
|
|
||||||
line = fs.readline()
|
|
||||||
header_data.line_offset += 1
|
|
||||||
header_data.vertex_offset = header_data.line_offset
|
|
||||||
continue
|
|
||||||
|
|
||||||
if line.find("#[fragment]") != -1:
|
|
||||||
header_data.reading = "fragment"
|
|
||||||
line = fs.readline()
|
|
||||||
header_data.line_offset += 1
|
|
||||||
header_data.fragment_offset = header_data.line_offset
|
|
||||||
continue
|
|
||||||
|
|
||||||
while line.find("#include ") != -1:
|
|
||||||
includeline = line.replace("#include ", "").strip()[1:-1]
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
|
||||||
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
|
|
||||||
header_data.vertex_included_files += [included_file]
|
|
||||||
if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
|
|
||||||
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
|
||||||
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
|
|
||||||
header_data.fragment_included_files += [included_file]
|
|
||||||
if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
|
|
||||||
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
|
||||||
|
|
||||||
line = fs.readline()
|
|
||||||
|
|
||||||
if line.find("#ifdef ") != -1:
|
|
||||||
if line.find("#ifdef ") != -1:
|
|
||||||
ifdefline = line.replace("#ifdef ", "").strip()
|
|
||||||
|
|
||||||
if line.find("_EN_") != -1:
|
|
||||||
enumbase = ifdefline[: ifdefline.find("_EN_")]
|
|
||||||
ifdefline = ifdefline.replace("_EN_", "_")
|
|
||||||
line = line.replace("_EN_", "_")
|
|
||||||
if enumbase not in header_data.enums:
|
|
||||||
header_data.enums[enumbase] = []
|
|
||||||
if ifdefline not in header_data.enums[enumbase]:
|
|
||||||
header_data.enums[enumbase].append(ifdefline)
|
|
||||||
|
|
||||||
elif not ifdefline in header_data.conditionals:
|
|
||||||
header_data.conditionals += [ifdefline]
|
|
||||||
|
|
||||||
if line.find("uniform") != -1 and line.lower().find("texunit:") != -1:
|
|
||||||
# texture unit
|
|
||||||
texunitstr = line[line.find(":") + 1 :].strip()
|
|
||||||
if texunitstr == "auto":
|
|
||||||
texunit = "-1"
|
|
||||||
else:
|
|
||||||
texunit = str(int(texunitstr))
|
|
||||||
uline = line[: line.lower().find("//")]
|
|
||||||
uline = uline.replace("uniform", "")
|
|
||||||
uline = uline.replace("highp", "")
|
|
||||||
uline = uline.replace(";", "")
|
|
||||||
lines = uline.split(",")
|
|
||||||
for x in lines:
|
|
||||||
|
|
||||||
x = x.strip()
|
|
||||||
x = x[x.rfind(" ") + 1 :]
|
|
||||||
if x.find("[") != -1:
|
|
||||||
# unfiorm array
|
|
||||||
x = x[: x.find("[")]
|
|
||||||
|
|
||||||
if not x in header_data.texunit_names:
|
|
||||||
header_data.texunits += [(x, texunit)]
|
|
||||||
header_data.texunit_names += [x]
|
|
||||||
|
|
||||||
elif line.find("uniform") != -1 and line.lower().find("ubo:") != -1:
|
|
||||||
# uniform buffer object
|
|
||||||
ubostr = line[line.find(":") + 1 :].strip()
|
|
||||||
ubo = str(int(ubostr))
|
|
||||||
uline = line[: line.lower().find("//")]
|
|
||||||
uline = uline[uline.find("uniform") + len("uniform") :]
|
|
||||||
uline = uline.replace("highp", "")
|
|
||||||
uline = uline.replace(";", "")
|
|
||||||
uline = uline.replace("{", "").strip()
|
|
||||||
lines = uline.split(",")
|
|
||||||
for x in lines:
|
|
||||||
|
|
||||||
x = x.strip()
|
|
||||||
x = x[x.rfind(" ") + 1 :]
|
|
||||||
if x.find("[") != -1:
|
|
||||||
# unfiorm array
|
|
||||||
x = x[: x.find("[")]
|
|
||||||
|
|
||||||
if not x in header_data.ubo_names:
|
|
||||||
header_data.ubos += [(x, ubo)]
|
|
||||||
header_data.ubo_names += [x]
|
|
||||||
|
|
||||||
elif line.find("uniform") != -1 and line.find("{") == -1 and line.find(";") != -1:
|
|
||||||
uline = line.replace("uniform", "")
|
|
||||||
uline = uline.replace(";", "")
|
|
||||||
lines = uline.split(",")
|
|
||||||
for x in lines:
|
|
||||||
|
|
||||||
x = x.strip()
|
|
||||||
x = x[x.rfind(" ") + 1 :]
|
|
||||||
if x.find("[") != -1:
|
|
||||||
# unfiorm array
|
|
||||||
x = x[: x.find("[")]
|
|
||||||
|
|
||||||
if not x in header_data.uniforms:
|
|
||||||
header_data.uniforms += [x]
|
|
||||||
|
|
||||||
if line.strip().find("attribute ") == 0 and line.find("attrib:") != -1:
|
|
||||||
uline = line.replace("in ", "")
|
|
||||||
uline = uline.replace("attribute ", "")
|
|
||||||
uline = uline.replace("highp ", "")
|
|
||||||
uline = uline.replace(";", "")
|
|
||||||
uline = uline[uline.find(" ") :].strip()
|
|
||||||
|
|
||||||
if uline.find("//") != -1:
|
|
||||||
name, bind = uline.split("//")
|
|
||||||
if bind.find("attrib:") != -1:
|
|
||||||
name = name.strip()
|
|
||||||
bind = bind.replace("attrib:", "").strip()
|
|
||||||
header_data.attributes += [(name, bind)]
|
|
||||||
|
|
||||||
if line.strip().find("out ") == 0 and line.find("tfb:") != -1:
|
|
||||||
uline = line.replace("out ", "")
|
|
||||||
uline = uline.replace("highp ", "")
|
|
||||||
uline = uline.replace(";", "")
|
|
||||||
uline = uline[uline.find(" ") :].strip()
|
|
||||||
|
|
||||||
if uline.find("//") != -1:
|
|
||||||
name, bind = uline.split("//")
|
|
||||||
if bind.find("tfb:") != -1:
|
|
||||||
name = name.strip()
|
|
||||||
bind = bind.replace("tfb:", "").strip()
|
|
||||||
header_data.feedbacks += [(name, bind)]
|
|
||||||
|
|
||||||
line = line.replace("\r", "")
|
|
||||||
line = line.replace("\n", "")
|
|
||||||
|
|
||||||
if header_data.reading == "vertex":
|
|
||||||
header_data.vertex_lines += [line]
|
|
||||||
if header_data.reading == "fragment":
|
|
||||||
header_data.fragment_lines += [line]
|
|
||||||
|
|
||||||
line = fs.readline()
|
|
||||||
header_data.line_offset += 1
|
|
||||||
|
|
||||||
fs.close()
|
|
||||||
|
|
||||||
return header_data
|
|
||||||
|
|
||||||
|
|
||||||
def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2=False):
|
|
||||||
header_data = LegacyGLHeaderStruct()
|
|
||||||
include_file_in_legacygl_header(filename, header_data, 0)
|
|
||||||
|
|
||||||
out_file = filename + ".gen.h"
|
|
||||||
fd = open(out_file, "w")
|
|
||||||
|
|
||||||
enum_constants = []
|
|
||||||
|
|
||||||
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
|
|
||||||
|
|
||||||
out_file_base = out_file
|
|
||||||
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
|
||||||
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
|
||||||
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
|
||||||
fd.write("#ifndef " + out_file_ifdef + class_suffix + "_120\n")
|
|
||||||
fd.write("#define " + out_file_ifdef + class_suffix + "_120\n")
|
|
||||||
|
|
||||||
out_file_class = (
|
|
||||||
out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix
|
|
||||||
)
|
|
||||||
fd.write("\n\n")
|
|
||||||
fd.write('#include "' + include + '"\n\n\n')
|
|
||||||
fd.write("class " + out_file_class + " : public Shader" + class_suffix + " {\n\n")
|
|
||||||
fd.write('\t virtual String get_shader_name() const { return "' + out_file_class + '"; }\n')
|
|
||||||
|
|
||||||
fd.write("public:\n\n")
|
|
||||||
|
|
||||||
if header_data.conditionals:
|
|
||||||
fd.write("\tenum Conditionals {\n")
|
|
||||||
for x in header_data.conditionals:
|
|
||||||
fd.write("\t\t" + x.upper() + ",\n")
|
|
||||||
fd.write("\t};\n\n")
|
|
||||||
|
|
||||||
if header_data.uniforms:
|
|
||||||
fd.write("\tenum Uniforms {\n")
|
|
||||||
for x in header_data.uniforms:
|
|
||||||
fd.write("\t\t" + x.upper() + ",\n")
|
|
||||||
fd.write("\t};\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:
|
|
||||||
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#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, 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, int8_t p_value) { _FU"
|
|
||||||
" glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint16_t p_value) { _FU"
|
|
||||||
" glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int16_t p_value) { _FU"
|
|
||||||
" glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint32_t p_value) { _FU"
|
|
||||||
" glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int32_t p_value) { _FU"
|
|
||||||
" glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat"
|
|
||||||
" col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat"
|
|
||||||
" vec2[2]={p_vec2.x,p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Size2i& p_vec2) { _FU GLint"
|
|
||||||
" vec2[2]={p_vec2.x,p_vec2.y}; glUniform2iv(get_uniform(p_uniform),1,vec2); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat"
|
|
||||||
" vec3[3]={p_vec3.x,p_vec3.y,p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU"
|
|
||||||
" glUniform2f(get_uniform(p_uniform),p_a,p_b); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU"
|
|
||||||
" glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }\n\n"
|
|
||||||
)
|
|
||||||
fd.write(
|
|
||||||
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU"
|
|
||||||
" glUniform4f(get_uniform(p_uniform),p_a,p_b,p_c,p_d); }\n\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
fd.write(
|
|
||||||
"""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform& p_transform) { _FU
|
|
||||||
|
|
||||||
const Transform &tr = p_transform;
|
|
||||||
|
|
||||||
GLfloat matrix[16]={ /* build a 16x16 matrix */
|
|
||||||
tr.basis.elements[0][0],
|
|
||||||
tr.basis.elements[1][0],
|
|
||||||
tr.basis.elements[2][0],
|
|
||||||
0,
|
|
||||||
tr.basis.elements[0][1],
|
|
||||||
tr.basis.elements[1][1],
|
|
||||||
tr.basis.elements[2][1],
|
|
||||||
0,
|
|
||||||
tr.basis.elements[0][2],
|
|
||||||
tr.basis.elements[1][2],
|
|
||||||
tr.basis.elements[2][2],
|
|
||||||
0,
|
|
||||||
tr.origin.x,
|
|
||||||
tr.origin.y,
|
|
||||||
tr.origin.z,
|
|
||||||
1
|
|
||||||
};
|
|
||||||
|
|
||||||
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
fd.write(
|
|
||||||
"""_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU
|
|
||||||
|
|
||||||
const Transform2D &tr = p_transform;
|
|
||||||
|
|
||||||
GLfloat matrix[16]={ /* build a 16x16 matrix */
|
|
||||||
tr.elements[0][0],
|
|
||||||
tr.elements[0][1],
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
tr.elements[1][0],
|
|
||||||
tr.elements[1][1],
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
tr.elements[2][0],
|
|
||||||
tr.elements[2][1],
|
|
||||||
0,
|
|
||||||
1
|
|
||||||
};
|
|
||||||
|
|
||||||
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
fd.write(
|
|
||||||
"""_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU
|
|
||||||
|
|
||||||
GLfloat matrix[16];
|
|
||||||
|
|
||||||
for (int i=0;i<4;i++) {
|
|
||||||
for (int j=0;j<4;j++) {
|
|
||||||
|
|
||||||
matrix[i*4+j]=p_matrix.matrix[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
fd.write("\n\n#undef _FU\n\n\n")
|
|
||||||
|
|
||||||
fd.write("\tvirtual void init() {\n\n")
|
|
||||||
|
|
||||||
enum_value_count = 0
|
|
||||||
|
|
||||||
if header_data.enums:
|
|
||||||
|
|
||||||
fd.write("\t\t//Written using math, given nonstandarity of 64 bits integer constants..\n")
|
|
||||||
fd.write("\t\tstatic const Enum _enums[]={\n")
|
|
||||||
|
|
||||||
bitofs = len(header_data.conditionals)
|
|
||||||
enum_vals = []
|
|
||||||
|
|
||||||
for xv in header_data.enums:
|
|
||||||
x = header_data.enums[xv]
|
|
||||||
bits = 1
|
|
||||||
amt = len(x)
|
|
||||||
while 2 ** bits < amt:
|
|
||||||
bits += 1
|
|
||||||
strs = "{"
|
|
||||||
for i in range(amt):
|
|
||||||
strs += '"#define ' + x[i] + '\\n",'
|
|
||||||
|
|
||||||
c = {}
|
|
||||||
c["set_mask"] = "uint64_t(" + str(i) + ")<<" + str(bitofs)
|
|
||||||
c["clear_mask"] = (
|
|
||||||
"((uint64_t(1)<<40)-1) ^ (((uint64_t(1)<<" + str(bits) + ") - 1)<<" + str(bitofs) + ")"
|
|
||||||
)
|
|
||||||
enum_vals.append(c)
|
|
||||||
enum_constants.append(x[i])
|
|
||||||
|
|
||||||
strs += "nullptr}"
|
|
||||||
|
|
||||||
fd.write(
|
|
||||||
"\t\t\t{(uint64_t(1<<" + str(bits) + ")-1)<<" + str(bitofs) + "," + str(bitofs) + "," + strs + "},\n"
|
|
||||||
)
|
|
||||||
bitofs += bits
|
|
||||||
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const EnumValue _enum_values[]={\n")
|
|
||||||
|
|
||||||
enum_value_count = len(enum_vals)
|
|
||||||
for x in enum_vals:
|
|
||||||
fd.write("\t\t\t{" + x["set_mask"] + "," + x["clear_mask"] + "},\n")
|
|
||||||
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
|
|
||||||
conditionals_found = []
|
|
||||||
if header_data.conditionals:
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char* _conditional_strings[]={\n")
|
|
||||||
if header_data.conditionals:
|
|
||||||
for x in header_data.conditionals:
|
|
||||||
fd.write('\t\t\t"#define ' + x + '\\n",\n')
|
|
||||||
conditionals_found.append(x)
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
else:
|
|
||||||
fd.write("\t\tstatic const char **_conditional_strings=nullptr;\n")
|
|
||||||
|
|
||||||
if header_data.uniforms:
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char* _uniform_strings[]={\n")
|
|
||||||
if header_data.uniforms:
|
|
||||||
for x in header_data.uniforms:
|
|
||||||
fd.write('\t\t\t"' + x + '",\n')
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
else:
|
|
||||||
fd.write("\t\tstatic const char **_uniform_strings=nullptr;\n")
|
|
||||||
|
|
||||||
if output_attribs:
|
|
||||||
if header_data.attributes:
|
|
||||||
|
|
||||||
fd.write("\t\tstatic AttributePair _attribute_pairs[]={\n")
|
|
||||||
for x in header_data.attributes:
|
|
||||||
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
else:
|
|
||||||
fd.write("\t\tstatic AttributePair *_attribute_pairs=nullptr;\n")
|
|
||||||
|
|
||||||
feedback_count = 0
|
|
||||||
|
|
||||||
if not gles2 and len(header_data.feedbacks):
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const Feedback _feedbacks[]={\n")
|
|
||||||
for x in header_data.feedbacks:
|
|
||||||
name = x[0]
|
|
||||||
cond = x[1]
|
|
||||||
if cond in conditionals_found:
|
|
||||||
fd.write('\t\t\t{"' + name + '",' + str(conditionals_found.index(cond)) + "},\n")
|
|
||||||
else:
|
|
||||||
fd.write('\t\t\t{"' + name + '",-1},\n')
|
|
||||||
|
|
||||||
feedback_count += 1
|
|
||||||
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
else:
|
|
||||||
if gles2:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
fd.write("\t\tstatic const Feedback* _feedbacks=nullptr;\n")
|
|
||||||
|
|
||||||
if header_data.texunits:
|
|
||||||
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
|
|
||||||
for x in header_data.texunits:
|
|
||||||
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
else:
|
|
||||||
fd.write("\t\tstatic TexUnitPair *_texunit_pairs=nullptr;\n")
|
|
||||||
|
|
||||||
if not gles2 and header_data.ubos:
|
|
||||||
fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n")
|
|
||||||
for x in header_data.ubos:
|
|
||||||
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
else:
|
|
||||||
if gles2:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
fd.write("\t\tstatic UBOPair *_ubo_pairs=nullptr;\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char _vertex_code[]={\n")
|
|
||||||
for x in header_data.vertex_lines:
|
|
||||||
for c in x:
|
|
||||||
fd.write(str(ord(c)) + ",")
|
|
||||||
|
|
||||||
fd.write(str(ord("\n")) + ",")
|
|
||||||
fd.write("\t\t0};\n\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const int _vertex_code_start=" + str(header_data.vertex_offset) + ";\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char _fragment_code[]={\n")
|
|
||||||
for x in header_data.fragment_lines:
|
|
||||||
for c in x:
|
|
||||||
fd.write(str(ord(c)) + ",")
|
|
||||||
|
|
||||||
fd.write(str(ord("\n")) + ",")
|
|
||||||
fd.write("\t\t0};\n\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const int _fragment_code_start=" + str(header_data.fragment_offset) + ";\n")
|
|
||||||
|
|
||||||
if output_attribs:
|
|
||||||
if gles2:
|
|
||||||
fd.write(
|
|
||||||
"\t\tsetup(_conditional_strings,"
|
|
||||||
+ str(len(header_data.conditionals))
|
|
||||||
+ ",_uniform_strings,"
|
|
||||||
+ str(len(header_data.uniforms))
|
|
||||||
+ ",_attribute_pairs,"
|
|
||||||
+ str(len(header_data.attributes))
|
|
||||||
+ ", _texunit_pairs,"
|
|
||||||
+ str(len(header_data.texunits))
|
|
||||||
+ ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
fd.write(
|
|
||||||
"\t\tsetup(_conditional_strings,"
|
|
||||||
+ str(len(header_data.conditionals))
|
|
||||||
+ ",_uniform_strings,"
|
|
||||||
+ str(len(header_data.uniforms))
|
|
||||||
+ ",_attribute_pairs,"
|
|
||||||
+ str(len(header_data.attributes))
|
|
||||||
+ ", _texunit_pairs,"
|
|
||||||
+ str(len(header_data.texunits))
|
|
||||||
+ ",_ubo_pairs,"
|
|
||||||
+ str(len(header_data.ubos))
|
|
||||||
+ ",_feedbacks,"
|
|
||||||
+ str(feedback_count)
|
|
||||||
+ ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
if gles2:
|
|
||||||
fd.write(
|
|
||||||
"\t\tsetup(_conditional_strings,"
|
|
||||||
+ str(len(header_data.conditionals))
|
|
||||||
+ ",_uniform_strings,"
|
|
||||||
+ str(len(header_data.uniforms))
|
|
||||||
+ ",_texunit_pairs,"
|
|
||||||
+ str(len(header_data.texunits))
|
|
||||||
+ ",_enums,"
|
|
||||||
+ str(len(header_data.enums))
|
|
||||||
+ ",_enum_values,"
|
|
||||||
+ str(enum_value_count)
|
|
||||||
+ ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
fd.write(
|
|
||||||
"\t\tsetup(_conditional_strings,"
|
|
||||||
+ str(len(header_data.conditionals))
|
|
||||||
+ ",_uniform_strings,"
|
|
||||||
+ str(len(header_data.uniforms))
|
|
||||||
+ ",_texunit_pairs,"
|
|
||||||
+ str(len(header_data.texunits))
|
|
||||||
+ ",_enums,"
|
|
||||||
+ str(len(header_data.enums))
|
|
||||||
+ ",_enum_values,"
|
|
||||||
+ str(enum_value_count)
|
|
||||||
+ ",_ubo_pairs,"
|
|
||||||
+ str(len(header_data.ubos))
|
|
||||||
+ ",_feedbacks,"
|
|
||||||
+ str(feedback_count)
|
|
||||||
+ ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
fd.write("\t}\n\n")
|
|
||||||
|
|
||||||
if enum_constants:
|
|
||||||
|
|
||||||
fd.write("\tenum EnumConditionals {\n")
|
|
||||||
for x in enum_constants:
|
|
||||||
fd.write("\t\t" + x.upper() + ",\n")
|
|
||||||
fd.write("\t};\n\n")
|
|
||||||
fd.write("\tvoid set_enum_conditional(EnumConditionals p_cond) { _set_enum_conditional(p_cond); }\n")
|
|
||||||
|
|
||||||
fd.write("};\n\n")
|
|
||||||
fd.write("#endif\n\n")
|
|
||||||
fd.close()
|
|
||||||
|
|
||||||
|
|
||||||
def build_gles2_headers(target, source, env):
|
|
||||||
for x in source:
|
|
||||||
build_legacygl_header(
|
|
||||||
str(x), include="drivers/gles2/shader_gles2.h", class_suffix="GLES2", output_attribs=True, gles2=True
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class RDHeaderStruct:
|
|
||||||
def __init__(self):
|
|
||||||
self.vertex_lines = []
|
|
||||||
self.fragment_lines = []
|
|
||||||
self.compute_lines = []
|
|
||||||
|
|
||||||
self.vertex_included_files = []
|
|
||||||
self.fragment_included_files = []
|
|
||||||
|
|
||||||
self.reading = ""
|
|
||||||
self.line_offset = 0
|
|
||||||
self.vertex_offset = 0
|
|
||||||
self.fragment_offset = 0
|
|
||||||
self.compute_offset = 0
|
|
||||||
|
|
||||||
|
|
||||||
def include_file_in_rd_header(filename, header_data, depth):
|
|
||||||
fs = open(filename, "r")
|
|
||||||
line = fs.readline()
|
|
||||||
|
|
||||||
while line:
|
|
||||||
|
|
||||||
if line.find("#[vertex]") != -1:
|
|
||||||
header_data.reading = "vertex"
|
|
||||||
line = fs.readline()
|
|
||||||
header_data.line_offset += 1
|
|
||||||
header_data.vertex_offset = header_data.line_offset
|
|
||||||
continue
|
|
||||||
|
|
||||||
if line.find("#[fragment]") != -1:
|
|
||||||
header_data.reading = "fragment"
|
|
||||||
line = fs.readline()
|
|
||||||
header_data.line_offset += 1
|
|
||||||
header_data.fragment_offset = header_data.line_offset
|
|
||||||
continue
|
|
||||||
|
|
||||||
if line.find("#[compute]") != -1:
|
|
||||||
header_data.reading = "compute"
|
|
||||||
line = fs.readline()
|
|
||||||
header_data.line_offset += 1
|
|
||||||
header_data.compute_offset = header_data.line_offset
|
|
||||||
continue
|
|
||||||
|
|
||||||
while line.find("#include ") != -1:
|
|
||||||
includeline = line.replace("#include ", "").strip()[1:-1]
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
|
||||||
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
|
|
||||||
header_data.vertex_included_files += [included_file]
|
|
||||||
if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
|
|
||||||
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
|
||||||
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
|
|
||||||
header_data.fragment_included_files += [included_file]
|
|
||||||
if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
|
|
||||||
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
|
||||||
elif not included_file in header_data.compute_included_files and header_data.reading == "compute":
|
|
||||||
header_data.compute_included_files += [included_file]
|
|
||||||
if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
|
|
||||||
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
|
||||||
|
|
||||||
line = fs.readline()
|
|
||||||
|
|
||||||
line = line.replace("\r", "")
|
|
||||||
line = line.replace("\n", "")
|
|
||||||
|
|
||||||
if header_data.reading == "vertex":
|
|
||||||
header_data.vertex_lines += [line]
|
|
||||||
if header_data.reading == "fragment":
|
|
||||||
header_data.fragment_lines += [line]
|
|
||||||
if header_data.reading == "compute":
|
|
||||||
header_data.compute_lines += [line]
|
|
||||||
|
|
||||||
line = fs.readline()
|
|
||||||
header_data.line_offset += 1
|
|
||||||
|
|
||||||
fs.close()
|
|
||||||
|
|
||||||
return header_data
|
|
||||||
|
|
||||||
|
|
||||||
def build_rd_header(filename):
|
|
||||||
header_data = RDHeaderStruct()
|
|
||||||
include_file_in_rd_header(filename, header_data, 0)
|
|
||||||
|
|
||||||
out_file = filename + ".gen.h"
|
|
||||||
fd = open(out_file, "w")
|
|
||||||
|
|
||||||
enum_constants = []
|
|
||||||
|
|
||||||
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
|
|
||||||
|
|
||||||
out_file_base = out_file
|
|
||||||
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
|
||||||
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
|
||||||
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
|
||||||
fd.write("#ifndef " + out_file_ifdef + "_RD\n")
|
|
||||||
fd.write("#define " + out_file_ifdef + "_RD\n")
|
|
||||||
|
|
||||||
out_file_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD"
|
|
||||||
fd.write("\n")
|
|
||||||
fd.write('#include "servers/rendering/rasterizer_rd/shader_rd.h"\n\n')
|
|
||||||
fd.write("class " + out_file_class + " : public ShaderRD {\n\n")
|
|
||||||
fd.write("public:\n\n")
|
|
||||||
|
|
||||||
fd.write("\t" + out_file_class + "() {\n\n")
|
|
||||||
|
|
||||||
if len(header_data.compute_lines):
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char _compute_code[] = {\n")
|
|
||||||
for x in header_data.compute_lines:
|
|
||||||
for c in x:
|
|
||||||
fd.write(str(ord(c)) + ",")
|
|
||||||
fd.write(str(ord("\n")) + ",")
|
|
||||||
fd.write("\t\t0};\n\n")
|
|
||||||
|
|
||||||
fd.write('\t\tsetup(nullptr, nullptr, _compute_code, "' + out_file_class + '");\n')
|
|
||||||
fd.write("\t}\n")
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char _vertex_code[] = {\n")
|
|
||||||
for x in header_data.vertex_lines:
|
|
||||||
for c in x:
|
|
||||||
fd.write(str(ord(c)) + ",")
|
|
||||||
fd.write(str(ord("\n")) + ",")
|
|
||||||
fd.write("\t\t0};\n\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char _fragment_code[]={\n")
|
|
||||||
for x in header_data.fragment_lines:
|
|
||||||
for c in x:
|
|
||||||
fd.write(str(ord(c)) + ",")
|
|
||||||
fd.write(str(ord("\n")) + ",")
|
|
||||||
fd.write("\t\t0};\n\n")
|
|
||||||
|
|
||||||
fd.write('\t\tsetup(_vertex_code, _fragment_code, nullptr, "' + out_file_class + '");\n')
|
|
||||||
fd.write("\t}\n")
|
|
||||||
|
|
||||||
fd.write("};\n\n")
|
|
||||||
|
|
||||||
fd.write("#endif\n")
|
|
||||||
fd.close()
|
|
||||||
|
|
||||||
|
|
||||||
def build_rd_headers(target, source, env):
|
|
||||||
for x in source:
|
|
||||||
build_rd_header(str(x))
|
|
||||||
|
|
||||||
|
|
||||||
class RAWHeaderStruct:
|
|
||||||
def __init__(self):
|
|
||||||
self.code = ""
|
|
||||||
|
|
||||||
|
|
||||||
def include_file_in_raw_header(filename, header_data, depth):
|
|
||||||
fs = open(filename, "r")
|
|
||||||
line = fs.readline()
|
|
||||||
text = ""
|
|
||||||
|
|
||||||
while line:
|
|
||||||
|
|
||||||
while line.find("#include ") != -1:
|
|
||||||
includeline = line.replace("#include ", "").strip()[1:-1]
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
|
||||||
include_file_in_raw_header(included_file, header_data, depth + 1)
|
|
||||||
|
|
||||||
line = fs.readline()
|
|
||||||
|
|
||||||
header_data.code += line
|
|
||||||
line = fs.readline()
|
|
||||||
|
|
||||||
fs.close()
|
|
||||||
|
|
||||||
|
|
||||||
def build_raw_header(filename):
|
|
||||||
header_data = RAWHeaderStruct()
|
|
||||||
include_file_in_raw_header(filename, header_data, 0)
|
|
||||||
|
|
||||||
out_file = filename + ".gen.h"
|
|
||||||
fd = open(out_file, "w")
|
|
||||||
|
|
||||||
enum_constants = []
|
|
||||||
|
|
||||||
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
|
|
||||||
|
|
||||||
out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl")
|
|
||||||
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
|
||||||
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
|
||||||
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
|
||||||
fd.write("#ifndef " + out_file_ifdef + "_RAW_H\n")
|
|
||||||
fd.write("#define " + out_file_ifdef + "_RAW_H\n")
|
|
||||||
fd.write("\n")
|
|
||||||
fd.write("static const char " + out_file_base + "[] = {\n")
|
|
||||||
for c in header_data.code:
|
|
||||||
fd.write(str(ord(c)) + ",")
|
|
||||||
fd.write("\t\t0};\n\n")
|
|
||||||
fd.write("#endif\n")
|
|
||||||
fd.close()
|
|
||||||
|
|
||||||
|
|
||||||
def build_rd_headers(target, source, env):
|
|
||||||
for x in source:
|
|
||||||
build_rd_header(str(x))
|
|
||||||
|
|
||||||
|
|
||||||
def build_raw_headers(target, source, env):
|
|
||||||
for x in source:
|
|
||||||
build_raw_header(str(x))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
subprocess_main(globals())
|
|
224
glsl_builders.py
Normal file
224
glsl_builders.py
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
"""Functions used to generate source files during build time
|
||||||
|
|
||||||
|
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from platform_methods import subprocess_main
|
||||||
|
|
||||||
|
|
||||||
|
class RDHeaderStruct:
|
||||||
|
def __init__(self):
|
||||||
|
self.vertex_lines = []
|
||||||
|
self.fragment_lines = []
|
||||||
|
self.compute_lines = []
|
||||||
|
|
||||||
|
self.vertex_included_files = []
|
||||||
|
self.fragment_included_files = []
|
||||||
|
|
||||||
|
self.reading = ""
|
||||||
|
self.line_offset = 0
|
||||||
|
self.vertex_offset = 0
|
||||||
|
self.fragment_offset = 0
|
||||||
|
self.compute_offset = 0
|
||||||
|
|
||||||
|
|
||||||
|
def include_file_in_rd_header(filename, header_data, depth):
|
||||||
|
fs = open(filename, "r")
|
||||||
|
line = fs.readline()
|
||||||
|
|
||||||
|
while line:
|
||||||
|
|
||||||
|
if line.find("#[vertex]") != -1:
|
||||||
|
header_data.reading = "vertex"
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.vertex_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.find("#[fragment]") != -1:
|
||||||
|
header_data.reading = "fragment"
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.fragment_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.find("#[compute]") != -1:
|
||||||
|
header_data.reading = "compute"
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.compute_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
while line.find("#include ") != -1:
|
||||||
|
includeline = line.replace("#include ", "").strip()[1:-1]
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
||||||
|
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
|
||||||
|
header_data.vertex_included_files += [included_file]
|
||||||
|
if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
|
||||||
|
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
||||||
|
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
|
||||||
|
header_data.fragment_included_files += [included_file]
|
||||||
|
if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
|
||||||
|
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
||||||
|
elif not included_file in header_data.compute_included_files and header_data.reading == "compute":
|
||||||
|
header_data.compute_included_files += [included_file]
|
||||||
|
if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
|
||||||
|
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
||||||
|
|
||||||
|
line = fs.readline()
|
||||||
|
|
||||||
|
line = line.replace("\r", "")
|
||||||
|
line = line.replace("\n", "")
|
||||||
|
|
||||||
|
if header_data.reading == "vertex":
|
||||||
|
header_data.vertex_lines += [line]
|
||||||
|
if header_data.reading == "fragment":
|
||||||
|
header_data.fragment_lines += [line]
|
||||||
|
if header_data.reading == "compute":
|
||||||
|
header_data.compute_lines += [line]
|
||||||
|
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
|
||||||
|
fs.close()
|
||||||
|
|
||||||
|
return header_data
|
||||||
|
|
||||||
|
|
||||||
|
def build_rd_header(filename):
|
||||||
|
header_data = RDHeaderStruct()
|
||||||
|
include_file_in_rd_header(filename, header_data, 0)
|
||||||
|
|
||||||
|
out_file = filename + ".gen.h"
|
||||||
|
fd = open(out_file, "w")
|
||||||
|
|
||||||
|
enum_constants = []
|
||||||
|
|
||||||
|
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
|
||||||
|
|
||||||
|
out_file_base = out_file
|
||||||
|
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
||||||
|
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
||||||
|
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
||||||
|
fd.write("#ifndef " + out_file_ifdef + "_RD\n")
|
||||||
|
fd.write("#define " + out_file_ifdef + "_RD\n")
|
||||||
|
|
||||||
|
out_file_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD"
|
||||||
|
fd.write("\n")
|
||||||
|
fd.write('#include "servers/rendering/rasterizer_rd/shader_rd.h"\n\n')
|
||||||
|
fd.write("class " + out_file_class + " : public ShaderRD {\n\n")
|
||||||
|
fd.write("public:\n\n")
|
||||||
|
|
||||||
|
fd.write("\t" + out_file_class + "() {\n\n")
|
||||||
|
|
||||||
|
if len(header_data.compute_lines):
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const char _compute_code[] = {\n")
|
||||||
|
for x in header_data.compute_lines:
|
||||||
|
for c in x:
|
||||||
|
fd.write(str(ord(c)) + ",")
|
||||||
|
fd.write(str(ord("\n")) + ",")
|
||||||
|
fd.write("\t\t0};\n\n")
|
||||||
|
|
||||||
|
fd.write('\t\tsetup(nullptr, nullptr, _compute_code, "' + out_file_class + '");\n')
|
||||||
|
fd.write("\t}\n")
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const char _vertex_code[] = {\n")
|
||||||
|
for x in header_data.vertex_lines:
|
||||||
|
for c in x:
|
||||||
|
fd.write(str(ord(c)) + ",")
|
||||||
|
fd.write(str(ord("\n")) + ",")
|
||||||
|
fd.write("\t\t0};\n\n")
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const char _fragment_code[]={\n")
|
||||||
|
for x in header_data.fragment_lines:
|
||||||
|
for c in x:
|
||||||
|
fd.write(str(ord(c)) + ",")
|
||||||
|
fd.write(str(ord("\n")) + ",")
|
||||||
|
fd.write("\t\t0};\n\n")
|
||||||
|
|
||||||
|
fd.write('\t\tsetup(_vertex_code, _fragment_code, nullptr, "' + out_file_class + '");\n')
|
||||||
|
fd.write("\t}\n")
|
||||||
|
|
||||||
|
fd.write("};\n\n")
|
||||||
|
|
||||||
|
fd.write("#endif\n")
|
||||||
|
fd.close()
|
||||||
|
|
||||||
|
|
||||||
|
def build_rd_headers(target, source, env):
|
||||||
|
for x in source:
|
||||||
|
build_rd_header(str(x))
|
||||||
|
|
||||||
|
|
||||||
|
class RAWHeaderStruct:
|
||||||
|
def __init__(self):
|
||||||
|
self.code = ""
|
||||||
|
|
||||||
|
|
||||||
|
def include_file_in_raw_header(filename, header_data, depth):
|
||||||
|
fs = open(filename, "r")
|
||||||
|
line = fs.readline()
|
||||||
|
text = ""
|
||||||
|
|
||||||
|
while line:
|
||||||
|
|
||||||
|
while line.find("#include ") != -1:
|
||||||
|
includeline = line.replace("#include ", "").strip()[1:-1]
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
||||||
|
include_file_in_raw_header(included_file, header_data, depth + 1)
|
||||||
|
|
||||||
|
line = fs.readline()
|
||||||
|
|
||||||
|
header_data.code += line
|
||||||
|
line = fs.readline()
|
||||||
|
|
||||||
|
fs.close()
|
||||||
|
|
||||||
|
|
||||||
|
def build_raw_header(filename):
|
||||||
|
header_data = RAWHeaderStruct()
|
||||||
|
include_file_in_raw_header(filename, header_data, 0)
|
||||||
|
|
||||||
|
out_file = filename + ".gen.h"
|
||||||
|
fd = open(out_file, "w")
|
||||||
|
|
||||||
|
enum_constants = []
|
||||||
|
|
||||||
|
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
|
||||||
|
|
||||||
|
out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl")
|
||||||
|
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
||||||
|
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
||||||
|
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
||||||
|
fd.write("#ifndef " + out_file_ifdef + "_RAW_H\n")
|
||||||
|
fd.write("#define " + out_file_ifdef + "_RAW_H\n")
|
||||||
|
fd.write("\n")
|
||||||
|
fd.write("static const char " + out_file_base + "[] = {\n")
|
||||||
|
for c in header_data.code:
|
||||||
|
fd.write(str(ord(c)) + ",")
|
||||||
|
fd.write("\t\t0};\n\n")
|
||||||
|
fd.write("#endif\n")
|
||||||
|
fd.close()
|
||||||
|
|
||||||
|
|
||||||
|
def build_rd_headers(target, source, env):
|
||||||
|
for x in source:
|
||||||
|
build_rd_header(str(x))
|
||||||
|
|
||||||
|
|
||||||
|
def build_raw_headers(target, source, env):
|
||||||
|
for x in source:
|
||||||
|
build_raw_header(str(x))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
subprocess_main(globals())
|
|
@ -1079,14 +1079,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name",
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name",
|
||||||
PropertyInfo(Variant::STRING,
|
PropertyInfo(Variant::STRING,
|
||||||
"rendering/quality/driver/driver_name",
|
"rendering/quality/driver/driver_name",
|
||||||
PROPERTY_HINT_ENUM, "Vulkan,GLES2"));
|
PROPERTY_HINT_ENUM, "Vulkan"));
|
||||||
if (display_driver == "") {
|
if (display_driver == "") {
|
||||||
display_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
|
display_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assigning here even though it's GLES2-specific, to be sure that it appears in docs
|
|
||||||
GLOBAL_DEF("rendering/quality/2d/gles2_use_nvidia_rect_flicker_workaround", false);
|
|
||||||
|
|
||||||
GLOBAL_DEF("display/window/size/width", 1024);
|
GLOBAL_DEF("display/window/size/width", 1024);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width",
|
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width",
|
||||||
PropertyInfo(Variant::INT, "display/window/size/width",
|
PropertyInfo(Variant::INT, "display/window/size/width",
|
||||||
|
|
|
@ -36,9 +36,6 @@
|
||||||
#include "java_godot_wrapper.h"
|
#include "java_godot_wrapper.h"
|
||||||
#include "os_android.h"
|
#include "os_android.h"
|
||||||
|
|
||||||
#if defined(OPENGL_ENABLED)
|
|
||||||
#include "drivers/gles2/rasterizer_gles2.h"
|
|
||||||
#endif
|
|
||||||
#if defined(VULKAN_ENABLED)
|
#if defined(VULKAN_ENABLED)
|
||||||
#include "drivers/vulkan/rendering_device_vulkan.h"
|
#include "drivers/vulkan/rendering_device_vulkan.h"
|
||||||
#include "platform/android/vulkan/vulkan_context_android.h"
|
#include "platform/android/vulkan/vulkan_context_android.h"
|
||||||
|
|
|
@ -46,10 +46,6 @@
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import <dlfcn.h>
|
#import <dlfcn.h>
|
||||||
|
|
||||||
#if defined(OPENGL_ENABLED)
|
|
||||||
#include "drivers/gles2/rasterizer_gles2.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(VULKAN_ENABLED)
|
#if defined(VULKAN_ENABLED)
|
||||||
#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
|
#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
||||||
#define GLES2_INCLUDE_H <ES2/gl.h>
|
|
||||||
|
|
||||||
#define PLATFORM_REFCOUNT
|
#define PLATFORM_REFCOUNT
|
||||||
|
|
||||||
#define PTHREAD_RENAME_SELF
|
#define PTHREAD_RENAME_SELF
|
||||||
|
|
|
@ -39,10 +39,6 @@
|
||||||
#include "main/main.h"
|
#include "main/main.h"
|
||||||
#include "scene/resources/texture.h"
|
#include "scene/resources/texture.h"
|
||||||
|
|
||||||
#if defined(OPENGL_ENABLED)
|
|
||||||
#include "drivers/gles2/rasterizer_gles2.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(VULKAN_ENABLED)
|
#if defined(VULKAN_ENABLED)
|
||||||
#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
|
#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,5 +35,3 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#define PTHREAD_BSD_SET_NAME
|
#define PTHREAD_BSD_SET_NAME
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h"
|
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
#if defined(OPENGL_ENABLED)
|
#if defined(OPENGL_ENABLED)
|
||||||
#include "drivers/gles2/rasterizer_gles2.h"
|
|
||||||
//TODO - reimplement OpenGLES
|
//TODO - reimplement OpenGLES
|
||||||
|
|
||||||
#import <AppKit/NSOpenGLView.h>
|
#import <AppKit/NSOpenGLView.h>
|
||||||
|
|
|
@ -30,5 +30,4 @@
|
||||||
|
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
||||||
#define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h"
|
|
||||||
#define PTHREAD_RENAME_SELF
|
#define PTHREAD_RENAME_SELF
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
#include "core/io/marshalls.h"
|
#include "core/io/marshalls.h"
|
||||||
#include "core/project_settings.h"
|
#include "core/project_settings.h"
|
||||||
#include "drivers/gles2/rasterizer_gles2.h"
|
|
||||||
#include "drivers/unix/ip_unix.h"
|
#include "drivers/unix/ip_unix.h"
|
||||||
#include "drivers/windows/dir_access_windows.h"
|
#include "drivers/windows/dir_access_windows.h"
|
||||||
#include "drivers/windows/file_access_windows.h"
|
#include "drivers/windows/file_access_windows.h"
|
||||||
|
|
|
@ -29,5 +29,3 @@
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h"
|
|
||||||
|
|
11
thirdparty/README.md
vendored
11
thirdparty/README.md
vendored
|
@ -161,17 +161,6 @@ Files extracted from upstream source:
|
||||||
- `docs/{FTL.TXT,LICENSE.TXT}`
|
- `docs/{FTL.TXT,LICENSE.TXT}`
|
||||||
|
|
||||||
|
|
||||||
## glad
|
|
||||||
|
|
||||||
- Upstream: https://github.com/Dav1dde/glad
|
|
||||||
- Version: 0.1.33 (2019)
|
|
||||||
- License: MIT
|
|
||||||
|
|
||||||
The files we package are automatically generated.
|
|
||||||
See the header of glad.c for instructions on how to generate them for
|
|
||||||
the GLES version Godot targets.
|
|
||||||
|
|
||||||
|
|
||||||
## glslang
|
## glslang
|
||||||
|
|
||||||
- Upstream: https://github.com/KhronosGroup/glslang
|
- Upstream: https://github.com/KhronosGroup/glslang
|
||||||
|
|
290
thirdparty/glad/KHR/khrplatform.h
vendored
290
thirdparty/glad/KHR/khrplatform.h
vendored
|
@ -1,290 +0,0 @@
|
||||||
#ifndef __khrplatform_h_
|
|
||||||
#define __khrplatform_h_
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
|
||||||
**
|
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
** copy of this software and/or associated documentation files (the
|
|
||||||
** "Materials"), to deal in the Materials without restriction, including
|
|
||||||
** without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
** permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
** the following conditions:
|
|
||||||
**
|
|
||||||
** The above copyright notice and this permission notice shall be included
|
|
||||||
** in all copies or substantial portions of the Materials.
|
|
||||||
**
|
|
||||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Khronos platform-specific types and definitions.
|
|
||||||
*
|
|
||||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
|
||||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
|
||||||
* The last semantic modification to khrplatform.h was at commit ID:
|
|
||||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
|
||||||
*
|
|
||||||
* Adopters may modify this file to suit their platform. Adopters are
|
|
||||||
* encouraged to submit platform specific modifications to the Khronos
|
|
||||||
* group so that they can be included in future versions of this file.
|
|
||||||
* Please submit changes by filing pull requests or issues on
|
|
||||||
* the EGL Registry repository linked above.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* See the Implementer's Guidelines for information about where this file
|
|
||||||
* should be located on your system and for more details of its use:
|
|
||||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
|
||||||
*
|
|
||||||
* This file should be included as
|
|
||||||
* #include <KHR/khrplatform.h>
|
|
||||||
* by Khronos client API header files that use its types and defines.
|
|
||||||
*
|
|
||||||
* The types in khrplatform.h should only be used to define API-specific types.
|
|
||||||
*
|
|
||||||
* Types defined in khrplatform.h:
|
|
||||||
* khronos_int8_t signed 8 bit
|
|
||||||
* khronos_uint8_t unsigned 8 bit
|
|
||||||
* khronos_int16_t signed 16 bit
|
|
||||||
* khronos_uint16_t unsigned 16 bit
|
|
||||||
* khronos_int32_t signed 32 bit
|
|
||||||
* khronos_uint32_t unsigned 32 bit
|
|
||||||
* khronos_int64_t signed 64 bit
|
|
||||||
* khronos_uint64_t unsigned 64 bit
|
|
||||||
* khronos_intptr_t signed same number of bits as a pointer
|
|
||||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
|
||||||
* khronos_ssize_t signed size
|
|
||||||
* khronos_usize_t unsigned size
|
|
||||||
* khronos_float_t signed 32 bit floating point
|
|
||||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
|
||||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
|
||||||
* nanoseconds
|
|
||||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
|
||||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
|
||||||
* only be used as a base type when a client API's boolean type is
|
|
||||||
* an enum. Client APIs which use an integer or other type for
|
|
||||||
* booleans cannot use this as the base type for their boolean.
|
|
||||||
*
|
|
||||||
* Tokens defined in khrplatform.h:
|
|
||||||
*
|
|
||||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
|
||||||
*
|
|
||||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
|
||||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
|
||||||
*
|
|
||||||
* Calling convention macros defined in this file:
|
|
||||||
* KHRONOS_APICALL
|
|
||||||
* KHRONOS_APIENTRY
|
|
||||||
* KHRONOS_APIATTRIBUTES
|
|
||||||
*
|
|
||||||
* These may be used in function prototypes as:
|
|
||||||
*
|
|
||||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
|
||||||
* int arg1,
|
|
||||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
|
||||||
# define KHRONOS_STATIC 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APICALL
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This precedes the return type of the function in the function prototype.
|
|
||||||
*/
|
|
||||||
#if defined(KHRONOS_STATIC)
|
|
||||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
|
||||||
* header compatible with static linking. */
|
|
||||||
# define KHRONOS_APICALL
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
# define KHRONOS_APICALL __declspec(dllimport)
|
|
||||||
#elif defined (__SYMBIAN32__)
|
|
||||||
# define KHRONOS_APICALL IMPORT_C
|
|
||||||
#elif defined(__ANDROID__)
|
|
||||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
|
||||||
#else
|
|
||||||
# define KHRONOS_APICALL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APIENTRY
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This follows the return type of the function and precedes the function
|
|
||||||
* name in the function prototype.
|
|
||||||
*/
|
|
||||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(KHRONOS_STATIC)
|
|
||||||
/* Win32 but not WinCE */
|
|
||||||
# define KHRONOS_APIENTRY __stdcall
|
|
||||||
#else
|
|
||||||
# define KHRONOS_APIENTRY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APIATTRIBUTES
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This follows the closing parenthesis of the function prototype arguments.
|
|
||||||
*/
|
|
||||||
#if defined (__ARMCC_2__)
|
|
||||||
#define KHRONOS_APIATTRIBUTES __softfp
|
|
||||||
#else
|
|
||||||
#define KHRONOS_APIATTRIBUTES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* basic type definitions
|
|
||||||
*-----------------------------------------------------------------------*/
|
|
||||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Using <stdint.h>
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(__VMS ) || defined(__sgi)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Using <inttypes.h>
|
|
||||||
*/
|
|
||||||
#include <inttypes.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Win32
|
|
||||||
*/
|
|
||||||
typedef __int32 khronos_int32_t;
|
|
||||||
typedef unsigned __int32 khronos_uint32_t;
|
|
||||||
typedef __int64 khronos_int64_t;
|
|
||||||
typedef unsigned __int64 khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(__sun__) || defined(__digital__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sun or Digital
|
|
||||||
*/
|
|
||||||
typedef int khronos_int32_t;
|
|
||||||
typedef unsigned int khronos_uint32_t;
|
|
||||||
#if defined(__arch64__) || defined(_LP64)
|
|
||||||
typedef long int khronos_int64_t;
|
|
||||||
typedef unsigned long int khronos_uint64_t;
|
|
||||||
#else
|
|
||||||
typedef long long int khronos_int64_t;
|
|
||||||
typedef unsigned long long int khronos_uint64_t;
|
|
||||||
#endif /* __arch64__ */
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hypothetical platform with no float or int64 support
|
|
||||||
*/
|
|
||||||
typedef int khronos_int32_t;
|
|
||||||
typedef unsigned int khronos_uint32_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 0
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 0
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic fallback
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Types that are (so far) the same on all platforms
|
|
||||||
*/
|
|
||||||
typedef signed char khronos_int8_t;
|
|
||||||
typedef unsigned char khronos_uint8_t;
|
|
||||||
typedef signed short int khronos_int16_t;
|
|
||||||
typedef unsigned short int khronos_uint16_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
|
||||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
|
||||||
* to be the only LLP64 architecture in current use.
|
|
||||||
*/
|
|
||||||
#ifdef _WIN64
|
|
||||||
typedef signed long long int khronos_intptr_t;
|
|
||||||
typedef unsigned long long int khronos_uintptr_t;
|
|
||||||
typedef signed long long int khronos_ssize_t;
|
|
||||||
typedef unsigned long long int khronos_usize_t;
|
|
||||||
#else
|
|
||||||
typedef signed long int khronos_intptr_t;
|
|
||||||
typedef unsigned long int khronos_uintptr_t;
|
|
||||||
typedef signed long int khronos_ssize_t;
|
|
||||||
typedef unsigned long int khronos_usize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if KHRONOS_SUPPORT_FLOAT
|
|
||||||
/*
|
|
||||||
* Float type
|
|
||||||
*/
|
|
||||||
typedef float khronos_float_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if KHRONOS_SUPPORT_INT64
|
|
||||||
/* Time types
|
|
||||||
*
|
|
||||||
* These types can be used to represent a time interval in nanoseconds or
|
|
||||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
|
||||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
|
||||||
* time the system booted). The Unadjusted System Time is an unsigned
|
|
||||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
|
||||||
* may be either signed or unsigned.
|
|
||||||
*/
|
|
||||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
|
||||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dummy value used to pad enum types to 32 bits.
|
|
||||||
*/
|
|
||||||
#ifndef KHRONOS_MAX_ENUM
|
|
||||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enumerated boolean type
|
|
||||||
*
|
|
||||||
* Values other than zero should be considered to be true. Therefore
|
|
||||||
* comparisons should not be made against KHRONOS_TRUE.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
KHRONOS_FALSE = 0,
|
|
||||||
KHRONOS_TRUE = 1,
|
|
||||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
|
||||||
} khronos_boolean_enum_t;
|
|
||||||
|
|
||||||
#endif /* __khrplatform_h_ */
|
|
20
thirdparty/glad/LICENSE
vendored
20
thirdparty/glad/LICENSE
vendored
|
@ -1,20 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2013-2018 David Herberth
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1939
thirdparty/glad/glad.c
vendored
1939
thirdparty/glad/glad.c
vendored
File diff suppressed because it is too large
Load diff
3784
thirdparty/glad/glad/glad.h
vendored
3784
thirdparty/glad/glad/glad.h
vendored
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue