|
@@ -43,7 +43,7 @@ using namespace GLES3;
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
// UBI helper functions
|
|
|
|
|
|
-_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data, bool p_linear_color) {
|
|
|
+_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data) {
|
|
|
switch (type) {
|
|
|
case ShaderLanguage::TYPE_BOOL: {
|
|
|
uint32_t *gui = (uint32_t *)data;
|
|
@@ -399,9 +399,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|
|
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
|
|
if (i < s) {
|
|
|
Color color = a[i];
|
|
|
- if (p_linear_color) {
|
|
|
- color = color.srgb_to_linear();
|
|
|
- }
|
|
|
gui[j] = color.r;
|
|
|
gui[j + 1] = color.g;
|
|
|
gui[j + 2] = color.b;
|
|
@@ -433,10 +430,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|
|
if (value.get_type() == Variant::COLOR) {
|
|
|
Color v = value;
|
|
|
|
|
|
- if (p_linear_color) {
|
|
|
- v = v.srgb_to_linear();
|
|
|
- }
|
|
|
-
|
|
|
gui[0] = v.r;
|
|
|
gui[1] = v.g;
|
|
|
gui[2] = v.b;
|
|
@@ -459,9 +452,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|
|
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
|
|
if (i < s) {
|
|
|
Color color = a[i];
|
|
|
- if (p_linear_color) {
|
|
|
- color = color.srgb_to_linear();
|
|
|
- }
|
|
|
gui[j] = color.r;
|
|
|
gui[j + 1] = color.g;
|
|
|
gui[j + 2] = color.b;
|
|
@@ -496,10 +486,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
|
|
if (value.get_type() == Variant::COLOR) {
|
|
|
Color v = value;
|
|
|
|
|
|
- if (p_linear_color) {
|
|
|
- v = v.srgb_to_linear();
|
|
|
- }
|
|
|
-
|
|
|
gui[0] = v.r;
|
|
|
gui[1] = v.g;
|
|
|
gui[2] = v.b;
|
|
@@ -900,6 +886,42 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
// MaterialData
|
|
|
|
|
|
+// Look up table to translate ShaderLanguage::DataType to GL_TEXTURE_*
|
|
|
+static const GLenum target_from_type[ShaderLanguage::TYPE_MAX] = {
|
|
|
+ GL_TEXTURE_2D, // TYPE_VOID,
|
|
|
+ GL_TEXTURE_2D, // TYPE_BOOL,
|
|
|
+ GL_TEXTURE_2D, // TYPE_BVEC2,
|
|
|
+ GL_TEXTURE_2D, // TYPE_BVEC3,
|
|
|
+ GL_TEXTURE_2D, // TYPE_BVEC4,
|
|
|
+ GL_TEXTURE_2D, // TYPE_INT,
|
|
|
+ GL_TEXTURE_2D, // TYPE_IVEC2,
|
|
|
+ GL_TEXTURE_2D, // TYPE_IVEC3,
|
|
|
+ GL_TEXTURE_2D, // TYPE_IVEC4,
|
|
|
+ GL_TEXTURE_2D, // TYPE_UINT,
|
|
|
+ GL_TEXTURE_2D, // TYPE_UVEC2,
|
|
|
+ GL_TEXTURE_2D, // TYPE_UVEC3,
|
|
|
+ GL_TEXTURE_2D, // TYPE_UVEC4,
|
|
|
+ GL_TEXTURE_2D, // TYPE_FLOAT,
|
|
|
+ GL_TEXTURE_2D, // TYPE_VEC2,
|
|
|
+ GL_TEXTURE_2D, // TYPE_VEC3,
|
|
|
+ GL_TEXTURE_2D, // TYPE_VEC4,
|
|
|
+ GL_TEXTURE_2D, // TYPE_MAT2,
|
|
|
+ GL_TEXTURE_2D, // TYPE_MAT3,
|
|
|
+ GL_TEXTURE_2D, // TYPE_MAT4,
|
|
|
+ GL_TEXTURE_2D, // TYPE_SAMPLER2D,
|
|
|
+ GL_TEXTURE_2D, // TYPE_ISAMPLER2D,
|
|
|
+ GL_TEXTURE_2D, // TYPE_USAMPLER2D,
|
|
|
+ GL_TEXTURE_2D_ARRAY, // TYPE_SAMPLER2DARRAY,
|
|
|
+ GL_TEXTURE_2D_ARRAY, // TYPE_ISAMPLER2DARRAY,
|
|
|
+ GL_TEXTURE_2D_ARRAY, // TYPE_USAMPLER2DARRAY,
|
|
|
+ GL_TEXTURE_3D, // TYPE_SAMPLER3D,
|
|
|
+ GL_TEXTURE_3D, // TYPE_ISAMPLER3D,
|
|
|
+ GL_TEXTURE_3D, // TYPE_USAMPLER3D,
|
|
|
+ GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBE,
|
|
|
+ GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBEARRAY,
|
|
|
+ GL_TEXTURE_2D, // TYPE_STRUCT
|
|
|
+};
|
|
|
+
|
|
|
void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) {
|
|
|
MaterialStorage *material_storage = MaterialStorage::get_singleton();
|
|
|
bool uses_global_buffer = false;
|
|
@@ -951,7 +973,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
|
|
|
|
|
|
if (V) {
|
|
|
//user provided
|
|
|
- _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->get(), data, p_use_linear_color);
|
|
|
+ _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->get(), data);
|
|
|
|
|
|
} else if (E.value.default_value.size()) {
|
|
|
//default value
|
|
@@ -961,7 +983,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
|
|
|
//zero because it was not provided
|
|
|
if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
|
|
//colors must be set as black, with alpha as 1.0
|
|
|
- _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
|
|
|
+ _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data);
|
|
|
} else {
|
|
|
//else just zero it out
|
|
|
_fill_std140_ubo_empty(E.value.type, E.value.array_size, data);
|
|
@@ -1275,16 +1297,16 @@ MaterialStorage *MaterialStorage::get_singleton() {
|
|
|
MaterialStorage::MaterialStorage() {
|
|
|
singleton = this;
|
|
|
|
|
|
- shader_data_request_func[RS::SHADER_SPATIAL] = nullptr;
|
|
|
+ shader_data_request_func[RS::SHADER_SPATIAL] = _create_scene_shader_func;
|
|
|
shader_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_shader_func;
|
|
|
shader_data_request_func[RS::SHADER_PARTICLES] = nullptr;
|
|
|
- shader_data_request_func[RS::SHADER_SKY] = nullptr;
|
|
|
+ shader_data_request_func[RS::SHADER_SKY] = _create_sky_shader_func;
|
|
|
shader_data_request_func[RS::SHADER_FOG] = nullptr;
|
|
|
|
|
|
- material_data_request_func[RS::SHADER_SPATIAL] = nullptr;
|
|
|
+ material_data_request_func[RS::SHADER_SPATIAL] = _create_scene_material_func;
|
|
|
material_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_material_func;
|
|
|
material_data_request_func[RS::SHADER_PARTICLES] = nullptr;
|
|
|
- material_data_request_func[RS::SHADER_SKY] = nullptr;
|
|
|
+ material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func;
|
|
|
material_data_request_func[RS::SHADER_FOG] = nullptr;
|
|
|
|
|
|
static_assert(sizeof(GlobalVariables::Value) == 16);
|
|
@@ -1365,16 +1387,12 @@ MaterialStorage::MaterialStorage() {
|
|
|
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
|
|
|
actions.render_mode_defines["light_only"] = "#define MODE_LIGHT_ONLY\n";
|
|
|
|
|
|
- actions.base_texture_binding_index = 1;
|
|
|
- actions.base_uniform_string = "";
|
|
|
- actions.global_buffer_array_variable = "";
|
|
|
-
|
|
|
shaders.compiler_canvas.initialize(actions);
|
|
|
}
|
|
|
|
|
|
{
|
|
|
// Setup Scene compiler
|
|
|
- /*
|
|
|
+
|
|
|
//shader compiler
|
|
|
ShaderCompiler::DefaultIdentifierActions actions;
|
|
|
|
|
@@ -1529,11 +1547,6 @@ MaterialStorage::MaterialStorage() {
|
|
|
actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n";
|
|
|
|
|
|
actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
|
|
|
-
|
|
|
- actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; // linear filter with mipmaps
|
|
|
- actions.custom_samplers["DEPTH_TEXTURE"] = "material_samplers[3]";
|
|
|
- actions.custom_samplers["NORMAL_ROUGHNESS_TEXTURE"] = "material_samplers[1]"; // linear filter
|
|
|
-
|
|
|
actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
|
|
|
actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
|
|
|
actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
|
|
@@ -1541,19 +1554,10 @@ MaterialStorage::MaterialStorage() {
|
|
|
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
|
|
|
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
|
|
|
|
|
|
- actions.sampler_array_name = "material_samplers";
|
|
|
- actions.base_texture_binding_index = 1;
|
|
|
- actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET;
|
|
|
- actions.base_uniform_string = "material.";
|
|
|
- actions.base_varying_index = 10;
|
|
|
-
|
|
|
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
|
|
|
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
|
|
|
- actions.global_buffer_array_variable = "global_variables.data";
|
|
|
- actions.instance_uniform_index_variable = "instances.data[instance_index].instance_uniforms_ofs";
|
|
|
|
|
|
- compiler.initialize(actions);
|
|
|
- */
|
|
|
+ shaders.compiler_scene.initialize(actions);
|
|
|
}
|
|
|
|
|
|
{
|
|
@@ -1626,10 +1630,10 @@ ShaderCompiler::DefaultIdentifierActions actions;
|
|
|
actions.renames["COLOR"] = "color";
|
|
|
actions.renames["ALPHA"] = "alpha";
|
|
|
actions.renames["EYEDIR"] = "cube_normal";
|
|
|
- actions.renames["POSITION"] = "params.position_multiplier.xyz";
|
|
|
+ actions.renames["POSITION"] = "position";
|
|
|
actions.renames["SKY_COORDS"] = "panorama_coords";
|
|
|
actions.renames["SCREEN_UV"] = "uv";
|
|
|
- actions.renames["TIME"] = "params.time";
|
|
|
+ actions.renames["TIME"] = "time";
|
|
|
actions.renames["PI"] = _MKSTR(Math_PI);
|
|
|
actions.renames["TAU"] = _MKSTR(Math_TAU);
|
|
|
actions.renames["E"] = _MKSTR(Math_E);
|
|
@@ -1660,20 +1664,12 @@ ShaderCompiler::DefaultIdentifierActions actions;
|
|
|
actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS";
|
|
|
actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS";
|
|
|
actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS";
|
|
|
- actions.custom_samplers["RADIANCE"] = "material_samplers[3]";
|
|
|
actions.usage_defines["HALF_RES_COLOR"] = "\n#define USES_HALF_RES_COLOR\n";
|
|
|
actions.usage_defines["QUARTER_RES_COLOR"] = "\n#define USES_QUARTER_RES_COLOR\n";
|
|
|
actions.render_mode_defines["disable_fog"] = "#define DISABLE_FOG\n";
|
|
|
|
|
|
- actions.sampler_array_name = "material_samplers";
|
|
|
- actions.base_texture_binding_index = 1;
|
|
|
- actions.texture_layout_set = 1;
|
|
|
- actions.base_uniform_string = "material.";
|
|
|
- actions.base_varying_index = 10;
|
|
|
-
|
|
|
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
|
|
|
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
|
|
|
- actions.global_buffer_array_variable = "global_variables";
|
|
|
|
|
|
shaders.compiler_sky.initialize(actions);
|
|
|
}
|
|
@@ -1873,7 +1869,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
|
|
|
bv.w = v.a;
|
|
|
|
|
|
GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1];
|
|
|
- v = v.srgb_to_linear();
|
|
|
+ //v = v.srgb_to_linear();
|
|
|
bv_linear.x = v.r;
|
|
|
bv_linear.y = v.g;
|
|
|
bv_linear.z = v.b;
|
|
@@ -2311,7 +2307,7 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind
|
|
|
|
|
|
pos += p_index;
|
|
|
|
|
|
- _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos], true); //instances always use linear color in this renderer
|
|
|
+ _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos]);
|
|
|
_global_variable_mark_buffer_dirty(pos, 1);
|
|
|
}
|
|
|
|
|
@@ -2738,7 +2734,8 @@ void MaterialStorage::material_update_dependency(RID p_material, RendererStorage
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// Canvas Shader Data
|
|
|
+/* Canvas Shader Data */
|
|
|
+
|
|
|
void CanvasShaderData::set_code(const String &p_code) {
|
|
|
// compile the shader
|
|
|
|
|
@@ -2915,51 +2912,15 @@ void CanvasMaterialData::update_parameters(const Map<StringName, Variant> &p_par
|
|
|
return update_parameters_internal(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size);
|
|
|
}
|
|
|
|
|
|
-// Look up table to translate ShaderLanguage::DataType to GL_TEXTURE_*
|
|
|
-static const GLenum target_from_type[ShaderLanguage::TYPE_MAX] = {
|
|
|
- GL_TEXTURE_2D, // TYPE_VOID,
|
|
|
- GL_TEXTURE_2D, // TYPE_BOOL,
|
|
|
- GL_TEXTURE_2D, // TYPE_BVEC2,
|
|
|
- GL_TEXTURE_2D, // TYPE_BVEC3,
|
|
|
- GL_TEXTURE_2D, // TYPE_BVEC4,
|
|
|
- GL_TEXTURE_2D, // TYPE_INT,
|
|
|
- GL_TEXTURE_2D, // TYPE_IVEC2,
|
|
|
- GL_TEXTURE_2D, // TYPE_IVEC3,
|
|
|
- GL_TEXTURE_2D, // TYPE_IVEC4,
|
|
|
- GL_TEXTURE_2D, // TYPE_UINT,
|
|
|
- GL_TEXTURE_2D, // TYPE_UVEC2,
|
|
|
- GL_TEXTURE_2D, // TYPE_UVEC3,
|
|
|
- GL_TEXTURE_2D, // TYPE_UVEC4,
|
|
|
- GL_TEXTURE_2D, // TYPE_FLOAT,
|
|
|
- GL_TEXTURE_2D, // TYPE_VEC2,
|
|
|
- GL_TEXTURE_2D, // TYPE_VEC3,
|
|
|
- GL_TEXTURE_2D, // TYPE_VEC4,
|
|
|
- GL_TEXTURE_2D, // TYPE_MAT2,
|
|
|
- GL_TEXTURE_2D, // TYPE_MAT3,
|
|
|
- GL_TEXTURE_2D, // TYPE_MAT4,
|
|
|
- GL_TEXTURE_2D, // TYPE_SAMPLER2D,
|
|
|
- GL_TEXTURE_2D, // TYPE_ISAMPLER2D,
|
|
|
- GL_TEXTURE_2D, // TYPE_USAMPLER2D,
|
|
|
- GL_TEXTURE_2D_ARRAY, // TYPE_SAMPLER2DARRAY,
|
|
|
- GL_TEXTURE_2D_ARRAY, // TYPE_ISAMPLER2DARRAY,
|
|
|
- GL_TEXTURE_2D_ARRAY, // TYPE_USAMPLER2DARRAY,
|
|
|
- GL_TEXTURE_3D, // TYPE_SAMPLER3D,
|
|
|
- GL_TEXTURE_3D, // TYPE_ISAMPLER3D,
|
|
|
- GL_TEXTURE_3D, // TYPE_USAMPLER3D,
|
|
|
- GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBE,
|
|
|
- GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBEARRAY,
|
|
|
- GL_TEXTURE_2D, // TYPE_STRUCT
|
|
|
-};
|
|
|
-
|
|
|
void CanvasMaterialData::bind_uniforms() {
|
|
|
// Bind Material Uniforms
|
|
|
- glBindBufferBase(GL_UNIFORM_BUFFER, RasterizerCanvasGLES3::MATERIAL_UNIFORM_BUFFER_OBJECT, uniform_buffer);
|
|
|
+ glBindBufferBase(GL_UNIFORM_BUFFER, RasterizerCanvasGLES3::MATERIAL_UNIFORM_LOCATION, uniform_buffer);
|
|
|
|
|
|
RID *textures = texture_cache.ptrw();
|
|
|
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
|
|
for (int ti = 0; ti < texture_cache.size(); ti++) {
|
|
|
Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
|
|
|
- glActiveTexture(GL_TEXTURE1 + ti);
|
|
|
+ glActiveTexture(GL_TEXTURE1 + ti); // Start at GL_TEXTURE1 because texture slot 0 is used by the base texture
|
|
|
glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
|
|
|
|
|
|
// Set sampler state here as the same texture can be used in multiple places with different flags
|
|
@@ -2981,4 +2942,543 @@ GLES3::MaterialData *GLES3::_create_canvas_material_func(ShaderData *p_shader) {
|
|
|
return material_data;
|
|
|
}
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
|
+// SKY SHADER
|
|
|
+
|
|
|
+void SkyShaderData::set_code(const String &p_code) {
|
|
|
+ //compile
|
|
|
+
|
|
|
+ code = p_code;
|
|
|
+ valid = false;
|
|
|
+ ubo_size = 0;
|
|
|
+ uniforms.clear();
|
|
|
+
|
|
|
+ if (code.is_empty()) {
|
|
|
+ return; //just invalid, but no error
|
|
|
+ }
|
|
|
+
|
|
|
+ ShaderCompiler::GeneratedCode gen_code;
|
|
|
+ ShaderCompiler::IdentifierActions actions;
|
|
|
+ actions.entry_point_stages["sky"] = ShaderCompiler::STAGE_FRAGMENT;
|
|
|
+
|
|
|
+ uses_time = false;
|
|
|
+ uses_half_res = false;
|
|
|
+ uses_quarter_res = false;
|
|
|
+ uses_position = false;
|
|
|
+ uses_light = false;
|
|
|
+
|
|
|
+ actions.render_mode_flags["use_half_res_pass"] = &uses_half_res;
|
|
|
+ actions.render_mode_flags["use_quarter_res_pass"] = &uses_quarter_res;
|
|
|
+
|
|
|
+ actions.usage_flag_pointers["TIME"] = &uses_time;
|
|
|
+ actions.usage_flag_pointers["POSITION"] = &uses_position;
|
|
|
+ actions.usage_flag_pointers["LIGHT0_ENABLED"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light;
|
|
|
+ actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light;
|
|
|
+
|
|
|
+ actions.uniforms = &uniforms;
|
|
|
+
|
|
|
+ Error err = MaterialStorage::get_singleton()->shaders.compiler_sky.compile(RS::SHADER_SKY, code, &actions, path, gen_code);
|
|
|
+ ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
|
|
|
+
|
|
|
+ if (version.is_null()) {
|
|
|
+ version = MaterialStorage::get_singleton()->shaders.sky_shader.version_create();
|
|
|
+ }
|
|
|
+
|
|
|
+#if 0
|
|
|
+ print_line("**compiling shader:");
|
|
|
+ print_line("**defines:\n");
|
|
|
+ for (int i = 0; i < gen_code.defines.size(); i++) {
|
|
|
+ print_line(gen_code.defines[i]);
|
|
|
+ }
|
|
|
+ print_line("\n**uniforms:\n" + gen_code.uniforms);
|
|
|
+ // print_line("\n**vertex_globals:\n" + gen_code.vertex_global);
|
|
|
+ // print_line("\n**vertex_code:\n" + gen_code.vertex);
|
|
|
+ print_line("\n**fragment_globals:\n" + gen_code.fragment_global);
|
|
|
+ print_line("\n**fragment_code:\n" + gen_code.fragment);
|
|
|
+ print_line("\n**light_code:\n" + gen_code.light);
|
|
|
+#endif
|
|
|
+
|
|
|
+ Vector<StringName> texture_uniform_names;
|
|
|
+ for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
|
|
|
+ texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
|
|
|
+ }
|
|
|
+
|
|
|
+ MaterialStorage::get_singleton()->shaders.sky_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
|
|
|
+ ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.sky_shader.version_is_valid(version));
|
|
|
+
|
|
|
+ ubo_size = gen_code.uniform_total_size;
|
|
|
+ ubo_offsets = gen_code.uniform_offsets;
|
|
|
+ texture_uniforms = gen_code.texture_uniforms;
|
|
|
+
|
|
|
+ valid = true;
|
|
|
+}
|
|
|
+
|
|
|
+void SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
|
|
|
+ if (!p_texture.is_valid()) {
|
|
|
+ if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) {
|
|
|
+ default_texture_params[p_name].erase(p_index);
|
|
|
+
|
|
|
+ if (default_texture_params[p_name].is_empty()) {
|
|
|
+ default_texture_params.erase(p_name);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!default_texture_params.has(p_name)) {
|
|
|
+ default_texture_params[p_name] = Map<int, RID>();
|
|
|
+ }
|
|
|
+ default_texture_params[p_name][p_index] = p_texture;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
|
|
|
+ Map<int, StringName> order;
|
|
|
+
|
|
|
+ for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
|
|
|
+ if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (E.value.texture_order >= 0) {
|
|
|
+ order[E.value.texture_order + 100000] = E.key;
|
|
|
+ } else {
|
|
|
+ order[E.value.order] = E.key;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const KeyValue<int, StringName> &E : order) {
|
|
|
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
|
|
|
+ pi.name = E.value;
|
|
|
+ p_param_list->push_back(pi);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
|
|
|
+ for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
|
|
|
+ if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ RendererMaterialStorage::InstanceShaderParam p;
|
|
|
+ p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
|
|
+ p.info.name = E.key; //supply name
|
|
|
+ p.index = E.value.instance_index;
|
|
|
+ p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint);
|
|
|
+ p_param_list->push_back(p);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool SkyShaderData::is_param_texture(const StringName &p_param) const {
|
|
|
+ if (!uniforms.has(p_param)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return uniforms[p_param].texture_order >= 0;
|
|
|
+}
|
|
|
+
|
|
|
+bool SkyShaderData::is_animated() const {
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool SkyShaderData::casts_shadows() const {
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+Variant SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
|
|
|
+ if (uniforms.has(p_parameter)) {
|
|
|
+ ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
|
|
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
|
|
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
|
|
|
+ }
|
|
|
+ return Variant();
|
|
|
+}
|
|
|
+
|
|
|
+RS::ShaderNativeSourceCode SkyShaderData::get_native_source_code() const {
|
|
|
+ return MaterialStorage::get_singleton()->shaders.sky_shader.version_get_native_source_code(version);
|
|
|
+}
|
|
|
+
|
|
|
+SkyShaderData::SkyShaderData() {
|
|
|
+ valid = false;
|
|
|
+}
|
|
|
+
|
|
|
+SkyShaderData::~SkyShaderData() {
|
|
|
+ if (version.is_valid()) {
|
|
|
+ MaterialStorage::get_singleton()->shaders.sky_shader.version_free(version);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+GLES3::ShaderData *GLES3::_create_sky_shader_func() {
|
|
|
+ SkyShaderData *shader_data = memnew(SkyShaderData);
|
|
|
+ return shader_data;
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
|
+// Sky material
|
|
|
+
|
|
|
+void SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
|
|
|
+ return update_parameters_internal(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size);
|
|
|
+}
|
|
|
+
|
|
|
+SkyMaterialData::~SkyMaterialData() {
|
|
|
+}
|
|
|
+GLES3::MaterialData *GLES3::_create_sky_material_func(ShaderData *p_shader) {
|
|
|
+ SkyMaterialData *material_data = memnew(SkyMaterialData);
|
|
|
+ material_data->shader_data = static_cast<SkyShaderData *>(p_shader);
|
|
|
+ //update will happen later anyway so do nothing.
|
|
|
+ return material_data;
|
|
|
+}
|
|
|
+
|
|
|
+void SkyMaterialData::bind_uniforms() {
|
|
|
+ // Bind Material Uniforms
|
|
|
+ glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
|
|
|
+
|
|
|
+ RID *textures = texture_cache.ptrw();
|
|
|
+ ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
|
|
+ for (int ti = 0; ti < texture_cache.size(); ti++) {
|
|
|
+ Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
|
|
|
+ glActiveTexture(GL_TEXTURE0 + ti);
|
|
|
+ glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
|
|
|
+
|
|
|
+ // Set sampler state here as the same texture can be used in multiple places with different flags
|
|
|
+ // Need to convert sampler state from ShaderLanguage::Texture* to RS::CanvasItemTexture*
|
|
|
+ RS::CanvasItemTextureFilter filter = RS::CanvasItemTextureFilter((int(texture_uniforms[ti].filter) + 1) % RS::CANVAS_ITEM_TEXTURE_FILTER_MAX);
|
|
|
+ RS::CanvasItemTextureRepeat repeat = RS::CanvasItemTextureRepeat((int(texture_uniforms[ti].repeat) + 1) % RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
|
|
|
+ texture->gl_set_filter(filter);
|
|
|
+ texture->gl_set_repeat(repeat);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
|
+// Scene SHADER
|
|
|
+
|
|
|
+void SceneShaderData::set_code(const String &p_code) {
|
|
|
+ //compile
|
|
|
+
|
|
|
+ code = p_code;
|
|
|
+ valid = false;
|
|
|
+ ubo_size = 0;
|
|
|
+ uniforms.clear();
|
|
|
+ uses_screen_texture = false;
|
|
|
+
|
|
|
+ if (code.is_empty()) {
|
|
|
+ return; //just invalid, but no error
|
|
|
+ }
|
|
|
+
|
|
|
+ ShaderCompiler::GeneratedCode gen_code;
|
|
|
+
|
|
|
+ int blend_modei = BLEND_MODE_MIX;
|
|
|
+ int depth_testi = DEPTH_TEST_ENABLED;
|
|
|
+ int alpha_antialiasing_modei = ALPHA_ANTIALIASING_OFF;
|
|
|
+ int cull_modei = CULL_BACK;
|
|
|
+ int depth_drawi = DEPTH_DRAW_OPAQUE;
|
|
|
+
|
|
|
+ uses_point_size = false;
|
|
|
+ uses_alpha = false;
|
|
|
+ uses_alpha_clip = false;
|
|
|
+ uses_blend_alpha = false;
|
|
|
+ uses_depth_pre_pass = false;
|
|
|
+ uses_discard = false;
|
|
|
+ uses_roughness = false;
|
|
|
+ uses_normal = false;
|
|
|
+ wireframe = false;
|
|
|
+
|
|
|
+ unshaded = false;
|
|
|
+ uses_vertex = false;
|
|
|
+ uses_position = false;
|
|
|
+ uses_sss = false;
|
|
|
+ uses_transmittance = false;
|
|
|
+ uses_screen_texture = false;
|
|
|
+ uses_depth_texture = false;
|
|
|
+ uses_normal_texture = false;
|
|
|
+ uses_time = false;
|
|
|
+ writes_modelview_or_projection = false;
|
|
|
+ uses_world_coordinates = false;
|
|
|
+ uses_particle_trails = false;
|
|
|
+
|
|
|
+ ShaderCompiler::IdentifierActions actions;
|
|
|
+ actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
|
|
|
+ actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT;
|
|
|
+ actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT;
|
|
|
+
|
|
|
+ actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_modei, BLEND_MODE_ADD);
|
|
|
+ actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_modei, BLEND_MODE_MIX);
|
|
|
+ actions.render_mode_values["blend_sub"] = Pair<int *, int>(&blend_modei, BLEND_MODE_SUB);
|
|
|
+ actions.render_mode_values["blend_mul"] = Pair<int *, int>(&blend_modei, BLEND_MODE_MUL);
|
|
|
+
|
|
|
+ actions.render_mode_values["alpha_to_coverage"] = Pair<int *, int>(&alpha_antialiasing_modei, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE);
|
|
|
+ actions.render_mode_values["alpha_to_coverage_and_one"] = Pair<int *, int>(&alpha_antialiasing_modei, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE);
|
|
|
+
|
|
|
+ actions.render_mode_values["depth_draw_never"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_DISABLED);
|
|
|
+ actions.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_OPAQUE);
|
|
|
+ actions.render_mode_values["depth_draw_always"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_ALWAYS);
|
|
|
+
|
|
|
+ actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_testi, DEPTH_TEST_DISABLED);
|
|
|
+
|
|
|
+ actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, CULL_DISABLED);
|
|
|
+ actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, CULL_FRONT);
|
|
|
+ actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, CULL_BACK);
|
|
|
+
|
|
|
+ actions.render_mode_flags["unshaded"] = &unshaded;
|
|
|
+ actions.render_mode_flags["wireframe"] = &wireframe;
|
|
|
+ actions.render_mode_flags["particle_trails"] = &uses_particle_trails;
|
|
|
+
|
|
|
+ actions.usage_flag_pointers["ALPHA"] = &uses_alpha;
|
|
|
+ actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip;
|
|
|
+ actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
|
|
|
+
|
|
|
+ actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
|
|
|
+ actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
|
|
|
+
|
|
|
+ actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
|
|
|
+ actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture;
|
|
|
+ actions.usage_flag_pointers["NORMAL_TEXTURE"] = &uses_normal_texture;
|
|
|
+ actions.usage_flag_pointers["DISCARD"] = &uses_discard;
|
|
|
+ actions.usage_flag_pointers["TIME"] = &uses_time;
|
|
|
+ actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
|
|
|
+ actions.usage_flag_pointers["NORMAL"] = &uses_normal;
|
|
|
+ actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal;
|
|
|
+
|
|
|
+ actions.usage_flag_pointers["POINT_SIZE"] = &uses_point_size;
|
|
|
+ actions.usage_flag_pointers["POINT_COORD"] = &uses_point_size;
|
|
|
+
|
|
|
+ actions.write_flag_pointers["MODELVIEW_MATRIX"] = &writes_modelview_or_projection;
|
|
|
+ actions.write_flag_pointers["PROJECTION_MATRIX"] = &writes_modelview_or_projection;
|
|
|
+ actions.write_flag_pointers["VERTEX"] = &uses_vertex;
|
|
|
+ actions.write_flag_pointers["POSITION"] = &uses_position;
|
|
|
+
|
|
|
+ actions.usage_flag_pointers["TANGENT"] = &uses_tangent;
|
|
|
+ actions.usage_flag_pointers["BINORMAL"] = &uses_tangent;
|
|
|
+ actions.usage_flag_pointers["COLOR"] = &uses_color;
|
|
|
+ actions.usage_flag_pointers["UV"] = &uses_uv;
|
|
|
+ actions.usage_flag_pointers["UV2"] = &uses_uv2;
|
|
|
+ actions.usage_flag_pointers["CUSTOM0"] = &uses_custom0;
|
|
|
+ actions.usage_flag_pointers["CUSTOM1"] = &uses_custom1;
|
|
|
+ actions.usage_flag_pointers["CUSTOM2"] = &uses_custom2;
|
|
|
+ actions.usage_flag_pointers["CUSTOM3"] = &uses_custom3;
|
|
|
+ actions.usage_flag_pointers["BONE_INDICES"] = &uses_bones;
|
|
|
+ actions.usage_flag_pointers["BONE_WEIGHTS"] = &uses_weights;
|
|
|
+
|
|
|
+ actions.uniforms = &uniforms;
|
|
|
+
|
|
|
+ Error err = MaterialStorage::get_singleton()->shaders.compiler_scene.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
|
|
|
+ ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
|
|
|
+
|
|
|
+ if (version.is_null()) {
|
|
|
+ version = MaterialStorage::get_singleton()->shaders.scene_shader.version_create();
|
|
|
+ }
|
|
|
+
|
|
|
+ depth_draw = DepthDraw(depth_drawi);
|
|
|
+ depth_test = DepthTest(depth_testi);
|
|
|
+ cull_mode = Cull(cull_modei);
|
|
|
+ blend_mode = BlendMode(blend_modei);
|
|
|
+ alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
|
|
|
+ vertex_input_mask = uint32_t(uses_normal);
|
|
|
+ vertex_input_mask |= uses_tangent << 1;
|
|
|
+ vertex_input_mask |= uses_color << 2;
|
|
|
+ vertex_input_mask |= uses_uv << 3;
|
|
|
+ vertex_input_mask |= uses_uv2 << 4;
|
|
|
+ vertex_input_mask |= uses_custom0 << 5;
|
|
|
+ vertex_input_mask |= uses_custom1 << 6;
|
|
|
+ vertex_input_mask |= uses_custom2 << 7;
|
|
|
+ vertex_input_mask |= uses_custom3 << 8;
|
|
|
+ vertex_input_mask |= uses_bones << 9;
|
|
|
+ vertex_input_mask |= uses_weights << 10;
|
|
|
+
|
|
|
+#if 0
|
|
|
+ print_line("**compiling shader:");
|
|
|
+ print_line("**defines:\n");
|
|
|
+ for (int i = 0; i < gen_code.defines.size(); i++) {
|
|
|
+ print_line(gen_code.defines[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, String>::Element *el = gen_code.code.front();
|
|
|
+ while (el) {
|
|
|
+ print_line("\n**code " + el->key() + ":\n" + el->value());
|
|
|
+
|
|
|
+ el = el->next();
|
|
|
+ }
|
|
|
+
|
|
|
+ print_line("\n**uniforms:\n" + gen_code.uniforms);
|
|
|
+ print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
|
|
|
+ print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
|
|
|
+#endif
|
|
|
+
|
|
|
+ Vector<StringName> texture_uniform_names;
|
|
|
+ for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
|
|
|
+ texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
|
|
|
+ }
|
|
|
+
|
|
|
+ MaterialStorage::get_singleton()->shaders.scene_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
|
|
|
+ ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.scene_shader.version_is_valid(version));
|
|
|
+
|
|
|
+ ubo_size = gen_code.uniform_total_size;
|
|
|
+ ubo_offsets = gen_code.uniform_offsets;
|
|
|
+ texture_uniforms = gen_code.texture_uniforms;
|
|
|
+
|
|
|
+ // if any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage
|
|
|
+ if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) {
|
|
|
+ blend_mode = BLEND_MODE_ALPHA_TO_COVERAGE;
|
|
|
+ }
|
|
|
+
|
|
|
+ valid = true;
|
|
|
+}
|
|
|
+
|
|
|
+void SceneShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
|
|
|
+ if (!p_texture.is_valid()) {
|
|
|
+ if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) {
|
|
|
+ default_texture_params[p_name].erase(p_index);
|
|
|
+
|
|
|
+ if (default_texture_params[p_name].is_empty()) {
|
|
|
+ default_texture_params.erase(p_name);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!default_texture_params.has(p_name)) {
|
|
|
+ default_texture_params[p_name] = Map<int, RID>();
|
|
|
+ }
|
|
|
+ default_texture_params[p_name][p_index] = p_texture;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void SceneShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
|
|
|
+ Map<int, StringName> order;
|
|
|
+
|
|
|
+ for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
|
|
|
+ if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (E.value.texture_order >= 0) {
|
|
|
+ order[E.value.texture_order + 100000] = E.key;
|
|
|
+ } else {
|
|
|
+ order[E.value.order] = E.key;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const KeyValue<int, StringName> &E : order) {
|
|
|
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
|
|
|
+ pi.name = E.value;
|
|
|
+ p_param_list->push_back(pi);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void SceneShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
|
|
|
+ for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
|
|
|
+ if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ RendererMaterialStorage::InstanceShaderParam p;
|
|
|
+ p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
|
|
+ p.info.name = E.key; //supply name
|
|
|
+ p.index = E.value.instance_index;
|
|
|
+ p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint);
|
|
|
+ p_param_list->push_back(p);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool SceneShaderData::is_param_texture(const StringName &p_param) const {
|
|
|
+ if (!uniforms.has(p_param)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return uniforms[p_param].texture_order >= 0;
|
|
|
+}
|
|
|
+
|
|
|
+bool SceneShaderData::is_animated() const {
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool SceneShaderData::casts_shadows() const {
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+Variant SceneShaderData::get_default_parameter(const StringName &p_parameter) const {
|
|
|
+ if (uniforms.has(p_parameter)) {
|
|
|
+ ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
|
|
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
|
|
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
|
|
|
+ }
|
|
|
+ return Variant();
|
|
|
+}
|
|
|
+
|
|
|
+RS::ShaderNativeSourceCode SceneShaderData::get_native_source_code() const {
|
|
|
+ return MaterialStorage::get_singleton()->shaders.scene_shader.version_get_native_source_code(version);
|
|
|
+}
|
|
|
+
|
|
|
+SceneShaderData::SceneShaderData() {
|
|
|
+ valid = false;
|
|
|
+ uses_screen_texture = false;
|
|
|
+}
|
|
|
+
|
|
|
+SceneShaderData::~SceneShaderData() {
|
|
|
+ if (version.is_valid()) {
|
|
|
+ MaterialStorage::get_singleton()->shaders.scene_shader.version_free(version);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+GLES3::ShaderData *GLES3::_create_scene_shader_func() {
|
|
|
+ SceneShaderData *shader_data = memnew(SceneShaderData);
|
|
|
+ return shader_data;
|
|
|
+}
|
|
|
+
|
|
|
+void SceneMaterialData::set_render_priority(int p_priority) {
|
|
|
+ priority = p_priority - RS::MATERIAL_RENDER_PRIORITY_MIN; //8 bits
|
|
|
+}
|
|
|
+
|
|
|
+void SceneMaterialData::set_next_pass(RID p_pass) {
|
|
|
+ next_pass = p_pass;
|
|
|
+}
|
|
|
+
|
|
|
+void SceneMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
|
|
|
+ return update_parameters_internal(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size);
|
|
|
+}
|
|
|
+
|
|
|
+SceneMaterialData::~SceneMaterialData() {
|
|
|
+}
|
|
|
+
|
|
|
+GLES3::MaterialData *GLES3::_create_scene_material_func(ShaderData *p_shader) {
|
|
|
+ SceneMaterialData *material_data = memnew(SceneMaterialData);
|
|
|
+ material_data->shader_data = static_cast<SceneShaderData *>(p_shader);
|
|
|
+ //update will happen later anyway so do nothing.
|
|
|
+ return material_data;
|
|
|
+}
|
|
|
+
|
|
|
+void SceneMaterialData::bind_uniforms() {
|
|
|
+ // Bind Material Uniforms
|
|
|
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
|
|
|
+
|
|
|
+ RID *textures = texture_cache.ptrw();
|
|
|
+ ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
|
|
+ for (int ti = 0; ti < texture_cache.size(); ti++) {
|
|
|
+ Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
|
|
|
+ glActiveTexture(GL_TEXTURE0 + ti);
|
|
|
+ glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
|
|
|
+
|
|
|
+ // Set sampler state here as the same texture can be used in multiple places with different flags
|
|
|
+ // Need to convert sampler state from ShaderLanguage::Texture* to RS::CanvasItemTexture*
|
|
|
+ RS::CanvasItemTextureFilter filter = RS::CanvasItemTextureFilter((int(texture_uniforms[ti].filter) + 1) % RS::CANVAS_ITEM_TEXTURE_FILTER_MAX);
|
|
|
+ RS::CanvasItemTextureRepeat repeat = RS::CanvasItemTextureRepeat((int(texture_uniforms[ti].repeat) + 1) % RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
|
|
|
+ texture->gl_set_filter(filter);
|
|
|
+ texture->gl_set_repeat(repeat);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#endif // !GLES3_ENABLED
|