Added support for uniform arrays in shaders
This commit is contained in:
parent
a8f53dcced
commit
6873ecaaf9
@ -373,7 +373,7 @@ void SceneShaderForwardClustered::ShaderData::get_instance_param_list(List<Rende
|
|||||||
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
||||||
p.info.name = E.key; //supply name
|
p.info.name = E.key; //supply name
|
||||||
p.index = E.value.instance_index;
|
p.index = E.value.instance_index;
|
||||||
p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint);
|
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);
|
p_param_list->push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,7 +398,7 @@ Variant SceneShaderForwardClustered::ShaderData::get_default_parameter(const Str
|
|||||||
if (uniforms.has(p_parameter)) {
|
if (uniforms.has(p_parameter)) {
|
||||||
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
||||||
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
||||||
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
|
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
|
||||||
}
|
}
|
||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ void SceneShaderForwardMobile::ShaderData::get_instance_param_list(List<Renderer
|
|||||||
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
||||||
p.info.name = E.key; //supply name
|
p.info.name = E.key; //supply name
|
||||||
p.index = E.value.instance_index;
|
p.index = E.value.instance_index;
|
||||||
p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint);
|
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);
|
p_param_list->push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -390,7 +390,7 @@ Variant SceneShaderForwardMobile::ShaderData::get_default_parameter(const String
|
|||||||
if (uniforms.has(p_parameter)) {
|
if (uniforms.has(p_parameter)) {
|
||||||
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
||||||
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
||||||
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
|
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
|
||||||
}
|
}
|
||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
@ -2161,7 +2161,7 @@ void RendererCanvasRenderRD::ShaderData::get_instance_param_list(List<RendererSt
|
|||||||
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
||||||
p.info.name = E.key; //supply name
|
p.info.name = E.key; //supply name
|
||||||
p.index = E.value.instance_index;
|
p.index = E.value.instance_index;
|
||||||
p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint);
|
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);
|
p_param_list->push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2186,7 +2186,7 @@ Variant RendererCanvasRenderRD::ShaderData::get_default_parameter(const StringNa
|
|||||||
if (uniforms.has(p_parameter)) {
|
if (uniforms.has(p_parameter)) {
|
||||||
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
||||||
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
||||||
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
|
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
|
||||||
}
|
}
|
||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererSto
|
|||||||
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
p.info = ShaderLanguage::uniform_to_property_info(E.value);
|
||||||
p.info.name = E.key; //supply name
|
p.info.name = E.key; //supply name
|
||||||
p.index = E.value.instance_index;
|
p.index = E.value.instance_index;
|
||||||
p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint);
|
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);
|
p_param_list->push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringNam
|
|||||||
if (uniforms.has(p_parameter)) {
|
if (uniforms.has(p_parameter)) {
|
||||||
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
|
||||||
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
|
||||||
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
|
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
|
||||||
}
|
}
|
||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -91,7 +91,7 @@ static int _get_datatype_size(SL::DataType p_type) {
|
|||||||
case SL::TYPE_VEC4:
|
case SL::TYPE_VEC4:
|
||||||
return 16;
|
return 16;
|
||||||
case SL::TYPE_MAT2:
|
case SL::TYPE_MAT2:
|
||||||
return 32; //4 * 4 + 4 * 4
|
return 32; // 4 * 4 + 4 * 4
|
||||||
case SL::TYPE_MAT3:
|
case SL::TYPE_MAT3:
|
||||||
return 48; // 4 * 4 + 4 * 4 + 4 * 4
|
return 48; // 4 * 4 + 4 * 4 + 4 * 4
|
||||||
case SL::TYPE_MAT4:
|
case SL::TYPE_MAT4:
|
||||||
@ -608,7 +608,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
continue; // Instances are indexed directly, don't need index uniforms.
|
continue; // Instances are indexed directly, don't need index uniforms.
|
||||||
}
|
}
|
||||||
if (SL::is_sampler_type(uniform.type)) {
|
if (SL::is_sampler_type(uniform.type)) {
|
||||||
ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_order) + ") uniform ";
|
ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_binding) + ") uniform ";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_buffer_global = !SL::is_sampler_type(uniform.type) && uniform.scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL;
|
bool is_buffer_global = !SL::is_sampler_type(uniform.type) && uniform.scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL;
|
||||||
@ -622,6 +622,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
}
|
}
|
||||||
|
|
||||||
ucode += " " + _mkid(uniform_name);
|
ucode += " " + _mkid(uniform_name);
|
||||||
|
if (uniform.array_size > 0) {
|
||||||
|
ucode += "[";
|
||||||
|
ucode += itos(uniform.array_size);
|
||||||
|
ucode += "]";
|
||||||
|
}
|
||||||
ucode += ";\n";
|
ucode += ";\n";
|
||||||
if (SL::is_sampler_type(uniform.type)) {
|
if (SL::is_sampler_type(uniform.type)) {
|
||||||
for (int j = 0; j < STAGE_MAX; j++) {
|
for (int j = 0; j < STAGE_MAX; j++) {
|
||||||
@ -635,6 +640,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
texture.filter = uniform.filter;
|
texture.filter = uniform.filter;
|
||||||
texture.repeat = uniform.repeat;
|
texture.repeat = uniform.repeat;
|
||||||
texture.global = uniform.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL;
|
texture.global = uniform.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL;
|
||||||
|
texture.array_size = uniform.array_size;
|
||||||
if (texture.global) {
|
if (texture.global) {
|
||||||
r_gen_code.uses_global_textures = true;
|
r_gen_code.uses_global_textures = true;
|
||||||
}
|
}
|
||||||
@ -650,7 +656,16 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
uniform_sizes.write[uniform.order] = _get_datatype_size(ShaderLanguage::TYPE_UINT);
|
uniform_sizes.write[uniform.order] = _get_datatype_size(ShaderLanguage::TYPE_UINT);
|
||||||
uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT);
|
uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT);
|
||||||
} else {
|
} else {
|
||||||
uniform_sizes.write[uniform.order] = _get_datatype_size(uniform.type);
|
if (uniform.array_size > 0) {
|
||||||
|
int size = _get_datatype_size(uniform.type) * uniform.array_size;
|
||||||
|
int m = (16 * uniform.array_size);
|
||||||
|
if ((size % m) != 0) {
|
||||||
|
size += m - (size % m);
|
||||||
|
}
|
||||||
|
uniform_sizes.write[uniform.order] = size;
|
||||||
|
} else {
|
||||||
|
uniform_sizes.write[uniform.order] = _get_datatype_size(uniform.type);
|
||||||
|
}
|
||||||
uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type);
|
uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1074,10 +1089,32 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
if (p_default_actions.renames.has(anode->name)) {
|
if (p_default_actions.renames.has(anode->name)) {
|
||||||
code = p_default_actions.renames[anode->name];
|
code = p_default_actions.renames[anode->name];
|
||||||
} else {
|
} else {
|
||||||
if (use_fragment_varying) {
|
if (shader->uniforms.has(anode->name)) {
|
||||||
code = "frag_to_light.";
|
//its a uniform!
|
||||||
|
const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[anode->name];
|
||||||
|
if (u.texture_order >= 0) {
|
||||||
|
code = _mkid(anode->name); //texture, use as is
|
||||||
|
} else {
|
||||||
|
//a scalar or vector
|
||||||
|
if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
|
||||||
|
code = actions.base_uniform_string + _mkid(anode->name); //texture, use as is
|
||||||
|
//global variable, this means the code points to an index to the global table
|
||||||
|
code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type);
|
||||||
|
} else if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
|
||||||
|
//instance variable, index it as such
|
||||||
|
code = "(" + p_default_actions.instance_uniform_index_variable + "+" + itos(u.instance_index) + ")";
|
||||||
|
code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type);
|
||||||
|
} else {
|
||||||
|
//regular uniform, index from UBO
|
||||||
|
code = actions.base_uniform_string + _mkid(anode->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (use_fragment_varying) {
|
||||||
|
code = "frag_to_light.";
|
||||||
|
}
|
||||||
|
code += _mkid(anode->name);
|
||||||
}
|
}
|
||||||
code += _mkid(anode->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anode->call_expression != nullptr) {
|
if (anode->call_expression != nullptr) {
|
||||||
@ -1193,46 +1230,63 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
|
|||||||
code += ", ";
|
code += ", ";
|
||||||
}
|
}
|
||||||
String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
if (is_texture_func && i == 1 && onode->arguments[i]->type == SL::Node::TYPE_VARIABLE) {
|
if (is_texture_func && i == 1 && (onode->arguments[i]->type == SL::Node::TYPE_VARIABLE || onode->arguments[i]->type == SL::Node::TYPE_OPERATOR)) {
|
||||||
//need to map from texture to sampler in order to sample
|
//need to map from texture to sampler in order to sample
|
||||||
const SL::VariableNode *varnode = static_cast<const SL::VariableNode *>(onode->arguments[i]);
|
StringName texture_uniform;
|
||||||
|
bool correct_texture_uniform = false;
|
||||||
|
|
||||||
StringName texture_uniform = varnode->name;
|
if (onode->arguments[i]->type == SL::Node::TYPE_VARIABLE) {
|
||||||
is_screen_texture = (texture_uniform == "SCREEN_TEXTURE");
|
const SL::VariableNode *varnode = static_cast<const SL::VariableNode *>(onode->arguments[i]);
|
||||||
|
texture_uniform = varnode->name;
|
||||||
String sampler_name;
|
correct_texture_uniform = true;
|
||||||
|
} else { // array indexing operator handling
|
||||||
if (actions.custom_samplers.has(texture_uniform)) {
|
const SL::OperatorNode *opnode = static_cast<const SL::OperatorNode *>(onode->arguments[i]);
|
||||||
sampler_name = actions.custom_samplers[texture_uniform];
|
if (opnode->op == SL::Operator::OP_INDEX && opnode->arguments[0]->type == SL::Node::TYPE_ARRAY) {
|
||||||
} else {
|
const SL::ArrayNode *anode = static_cast<const SL::ArrayNode *>(opnode->arguments[0]);
|
||||||
if (shader->uniforms.has(texture_uniform)) {
|
texture_uniform = anode->name;
|
||||||
sampler_name = _get_sampler_name(shader->uniforms[texture_uniform].filter, shader->uniforms[texture_uniform].repeat);
|
correct_texture_uniform = true;
|
||||||
} else {
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (int j = 0; j < function->arguments.size(); j++) {
|
|
||||||
if (function->arguments[j].name == texture_uniform) {
|
|
||||||
if (function->arguments[j].tex_builtin_check) {
|
|
||||||
ERR_CONTINUE(!actions.custom_samplers.has(function->arguments[j].tex_builtin));
|
|
||||||
sampler_name = actions.custom_samplers[function->arguments[j].tex_builtin];
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (function->arguments[j].tex_argument_check) {
|
|
||||||
sampler_name = _get_sampler_name(function->arguments[j].tex_argument_filter, function->arguments[j].tex_argument_repeat);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
//function was most likely unused, so use anything (compiler will remove it anyway)
|
|
||||||
sampler_name = _get_sampler_name(ShaderLanguage::FILTER_DEFAULT, ShaderLanguage::REPEAT_DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code += ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype()) + "(" + node_code + ", " + sampler_name + ")";
|
if (correct_texture_uniform) {
|
||||||
|
is_screen_texture = (texture_uniform == "SCREEN_TEXTURE");
|
||||||
|
|
||||||
|
String sampler_name;
|
||||||
|
|
||||||
|
if (actions.custom_samplers.has(texture_uniform)) {
|
||||||
|
sampler_name = actions.custom_samplers[texture_uniform];
|
||||||
|
} else {
|
||||||
|
if (shader->uniforms.has(texture_uniform)) {
|
||||||
|
sampler_name = _get_sampler_name(shader->uniforms[texture_uniform].filter, shader->uniforms[texture_uniform].repeat);
|
||||||
|
} else {
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (int j = 0; j < function->arguments.size(); j++) {
|
||||||
|
if (function->arguments[j].name == texture_uniform) {
|
||||||
|
if (function->arguments[j].tex_builtin_check) {
|
||||||
|
ERR_CONTINUE(!actions.custom_samplers.has(function->arguments[j].tex_builtin));
|
||||||
|
sampler_name = actions.custom_samplers[function->arguments[j].tex_builtin];
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (function->arguments[j].tex_argument_check) {
|
||||||
|
sampler_name = _get_sampler_name(function->arguments[j].tex_argument_filter, function->arguments[j].tex_argument_repeat);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
//function was most likely unused, so use anything (compiler will remove it anyway)
|
||||||
|
sampler_name = _get_sampler_name(ShaderLanguage::FILTER_DEFAULT, ShaderLanguage::REPEAT_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code += ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype()) + "(" + node_code + ", " + sampler_name + ")";
|
||||||
|
} else {
|
||||||
|
code += node_code;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
code += node_code;
|
code += node_code;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
ShaderLanguage::TextureFilter filter;
|
ShaderLanguage::TextureFilter filter;
|
||||||
ShaderLanguage::TextureRepeat repeat;
|
ShaderLanguage::TextureRepeat repeat;
|
||||||
bool global;
|
bool global;
|
||||||
|
int array_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector<Texture> texture_uniforms;
|
Vector<Texture> texture_uniforms;
|
||||||
|
@ -1078,6 +1078,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
|
|||||||
if (r_data_type) {
|
if (r_data_type) {
|
||||||
*r_data_type = shader->uniforms[p_identifier].type;
|
*r_data_type = shader->uniforms[p_identifier].type;
|
||||||
}
|
}
|
||||||
|
if (r_array_size) {
|
||||||
|
*r_array_size = shader->uniforms[p_identifier].array_size;
|
||||||
|
}
|
||||||
if (r_type) {
|
if (r_type) {
|
||||||
*r_type = IDENTIFIER_UNIFORM;
|
*r_type = IDENTIFIER_UNIFORM;
|
||||||
}
|
}
|
||||||
@ -2921,86 +2924,294 @@ bool ShaderLanguage::is_sampler_type(DataType p_type) {
|
|||||||
p_type == TYPE_SAMPLERCUBEARRAY;
|
p_type == TYPE_SAMPLERCUBEARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
|
Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
|
||||||
|
int array_size = p_array_size;
|
||||||
|
|
||||||
if (p_value.size() > 0) {
|
if (p_value.size() > 0) {
|
||||||
Variant value;
|
Variant value;
|
||||||
switch (p_type) {
|
switch (p_type) {
|
||||||
case ShaderLanguage::TYPE_BOOL:
|
case ShaderLanguage::TYPE_BOOL:
|
||||||
value = Variant(p_value[0].boolean);
|
if (array_size > 0) {
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].boolean);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(p_value[0].boolean);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_BVEC2:
|
case ShaderLanguage::TYPE_BVEC2:
|
||||||
|
array_size *= 2;
|
||||||
|
|
||||||
|
if (array_size > 0) {
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].boolean);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(p_value[0].boolean);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ShaderLanguage::TYPE_BVEC3:
|
case ShaderLanguage::TYPE_BVEC3:
|
||||||
|
array_size *= 3;
|
||||||
|
|
||||||
|
if (array_size > 0) {
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].boolean);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(p_value[0].boolean);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ShaderLanguage::TYPE_BVEC4:
|
case ShaderLanguage::TYPE_BVEC4:
|
||||||
|
array_size *= 4;
|
||||||
|
|
||||||
|
if (array_size > 0) {
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].boolean);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(p_value[0].boolean);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ShaderLanguage::TYPE_INT:
|
case ShaderLanguage::TYPE_INT:
|
||||||
value = Variant(p_value[0].sint);
|
if (array_size > 0) {
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].sint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(p_value[0].sint);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_IVEC2:
|
case ShaderLanguage::TYPE_IVEC2:
|
||||||
value = Variant(Vector2(p_value[0].sint, p_value[1].sint));
|
if (array_size > 0) {
|
||||||
|
array_size *= 2;
|
||||||
|
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].sint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Vector2(p_value[0].sint, p_value[1].sint));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_IVEC3:
|
case ShaderLanguage::TYPE_IVEC3:
|
||||||
value = Variant(Vector3(p_value[0].sint, p_value[1].sint, p_value[2].sint));
|
if (array_size > 0) {
|
||||||
|
array_size *= 3;
|
||||||
|
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].sint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Vector3(p_value[0].sint, p_value[1].sint, p_value[2].sint));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_IVEC4:
|
case ShaderLanguage::TYPE_IVEC4:
|
||||||
value = Variant(Plane(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
|
if (array_size > 0) {
|
||||||
|
array_size *= 4;
|
||||||
|
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].sint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Plane(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_UINT:
|
case ShaderLanguage::TYPE_UINT:
|
||||||
value = Variant(p_value[0].uint);
|
if (array_size > 0) {
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].uint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(p_value[0].uint);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_UVEC2:
|
case ShaderLanguage::TYPE_UVEC2:
|
||||||
value = Variant(Vector2(p_value[0].uint, p_value[1].uint));
|
if (array_size > 0) {
|
||||||
|
array_size *= 2;
|
||||||
|
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].uint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Vector2(p_value[0].uint, p_value[1].uint));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_UVEC3:
|
case ShaderLanguage::TYPE_UVEC3:
|
||||||
value = Variant(Vector3(p_value[0].uint, p_value[1].uint, p_value[2].uint));
|
if (array_size > 0) {
|
||||||
|
array_size *= 3;
|
||||||
|
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].uint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Vector3(p_value[0].uint, p_value[1].uint, p_value[2].uint));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_UVEC4:
|
case ShaderLanguage::TYPE_UVEC4:
|
||||||
value = Variant(Plane(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
|
if (array_size > 0) {
|
||||||
|
array_size *= 4;
|
||||||
|
|
||||||
|
PackedInt32Array array = PackedInt32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].uint);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Plane(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_FLOAT:
|
case ShaderLanguage::TYPE_FLOAT:
|
||||||
value = Variant(p_value[0].real);
|
if (array_size > 0) {
|
||||||
|
PackedFloat32Array array = PackedFloat32Array();
|
||||||
|
for (int i = 0; i < array_size; i++) {
|
||||||
|
array.push_back(p_value[i].real);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(p_value[0].real);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_VEC2:
|
case ShaderLanguage::TYPE_VEC2:
|
||||||
value = Variant(Vector2(p_value[0].real, p_value[1].real));
|
if (array_size > 0) {
|
||||||
|
array_size *= 2;
|
||||||
|
|
||||||
|
PackedVector2Array array = PackedVector2Array();
|
||||||
|
for (int i = 0; i < array_size; i += 2) {
|
||||||
|
array.push_back(Vector2(p_value[i].real, p_value[i + 1].real));
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Vector2(p_value[0].real, p_value[1].real));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_VEC3:
|
case ShaderLanguage::TYPE_VEC3:
|
||||||
value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
|
if (array_size > 0) {
|
||||||
|
array_size *= 3;
|
||||||
|
|
||||||
|
PackedVector3Array array = PackedVector3Array();
|
||||||
|
for (int i = 0; i < array_size; i += 3) {
|
||||||
|
array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_VEC4:
|
case ShaderLanguage::TYPE_VEC4:
|
||||||
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
if (array_size > 0) {
|
||||||
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
array_size *= 4;
|
||||||
|
|
||||||
|
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
||||||
|
PackedColorArray array = PackedColorArray();
|
||||||
|
for (int i = 0; i < array_size; i += 4) {
|
||||||
|
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
PackedFloat32Array array = PackedFloat32Array();
|
||||||
|
for (int i = 0; i < array_size; i += 4) {
|
||||||
|
array.push_back(p_value[i].real);
|
||||||
|
array.push_back(p_value[i + 1].real);
|
||||||
|
array.push_back(p_value[i + 2].real);
|
||||||
|
array.push_back(p_value[i + 3].real);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
value = Variant(Plane(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
||||||
|
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
||||||
|
} else {
|
||||||
|
value = Variant(Plane(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_MAT2:
|
case ShaderLanguage::TYPE_MAT2:
|
||||||
value = Variant(Transform2D(p_value[0].real, p_value[2].real, p_value[1].real, p_value[3].real, 0.0, 0.0));
|
if (array_size > 0) {
|
||||||
|
array_size *= 4;
|
||||||
|
|
||||||
|
PackedFloat32Array array = PackedFloat32Array();
|
||||||
|
for (int i = 0; i < array_size; i += 4) {
|
||||||
|
array.push_back(p_value[i].real);
|
||||||
|
array.push_back(p_value[i + 1].real);
|
||||||
|
array.push_back(p_value[i + 2].real);
|
||||||
|
array.push_back(p_value[i + 3].real);
|
||||||
|
}
|
||||||
|
value = Variant(array);
|
||||||
|
} else {
|
||||||
|
value = Variant(Transform2D(p_value[0].real, p_value[2].real, p_value[1].real, p_value[3].real, 0.0, 0.0));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_MAT3: {
|
case ShaderLanguage::TYPE_MAT3: {
|
||||||
Basis p;
|
if (array_size > 0) {
|
||||||
p[0][0] = p_value[0].real;
|
array_size *= 9;
|
||||||
p[0][1] = p_value[1].real;
|
|
||||||
p[0][2] = p_value[2].real;
|
PackedFloat32Array array = PackedFloat32Array();
|
||||||
p[1][0] = p_value[3].real;
|
for (int i = 0; i < array_size; i += 9) {
|
||||||
p[1][1] = p_value[4].real;
|
for (int j = 0; j < 9; j++) {
|
||||||
p[1][2] = p_value[5].real;
|
array.push_back(p_value[i + j].real);
|
||||||
p[2][0] = p_value[6].real;
|
}
|
||||||
p[2][1] = p_value[7].real;
|
}
|
||||||
p[2][2] = p_value[8].real;
|
value = Variant(array);
|
||||||
value = Variant(p);
|
} else {
|
||||||
|
Basis p;
|
||||||
|
p[0][0] = p_value[0].real;
|
||||||
|
p[0][1] = p_value[1].real;
|
||||||
|
p[0][2] = p_value[2].real;
|
||||||
|
p[1][0] = p_value[3].real;
|
||||||
|
p[1][1] = p_value[4].real;
|
||||||
|
p[1][2] = p_value[5].real;
|
||||||
|
p[2][0] = p_value[6].real;
|
||||||
|
p[2][1] = p_value[7].real;
|
||||||
|
p[2][2] = p_value[8].real;
|
||||||
|
value = Variant(p);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ShaderLanguage::TYPE_MAT4: {
|
case ShaderLanguage::TYPE_MAT4: {
|
||||||
Basis p;
|
if (array_size > 0) {
|
||||||
p[0][0] = p_value[0].real;
|
array_size *= 16;
|
||||||
p[0][1] = p_value[1].real;
|
|
||||||
p[0][2] = p_value[2].real;
|
PackedFloat32Array array = PackedFloat32Array();
|
||||||
p[1][0] = p_value[4].real;
|
for (int i = 0; i < array_size; i += 16) {
|
||||||
p[1][1] = p_value[5].real;
|
for (int j = 0; j < 16; j++) {
|
||||||
p[1][2] = p_value[6].real;
|
array.push_back(p_value[i + j].real);
|
||||||
p[2][0] = p_value[8].real;
|
}
|
||||||
p[2][1] = p_value[9].real;
|
}
|
||||||
p[2][2] = p_value[10].real;
|
value = Variant(array);
|
||||||
Transform3D t = Transform3D(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real));
|
} else {
|
||||||
value = Variant(t);
|
Basis p;
|
||||||
|
p[0][0] = p_value[0].real;
|
||||||
|
p[0][1] = p_value[1].real;
|
||||||
|
p[0][2] = p_value[2].real;
|
||||||
|
p[1][0] = p_value[4].real;
|
||||||
|
p[1][1] = p_value[5].real;
|
||||||
|
p[1][2] = p_value[6].real;
|
||||||
|
p[2][0] = p_value[8].real;
|
||||||
|
p[2][1] = p_value[9].real;
|
||||||
|
p[2][2] = p_value[10].real;
|
||||||
|
Transform3D t = Transform3D(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real));
|
||||||
|
value = Variant(t);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
|
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
|
||||||
@ -3036,31 +3247,50 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
|
|||||||
pi.type = Variant::NIL;
|
pi.type = Variant::NIL;
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_BOOL:
|
case ShaderLanguage::TYPE_BOOL:
|
||||||
pi.type = Variant::BOOL;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::PACKED_INT32_ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::BOOL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_BVEC2:
|
case ShaderLanguage::TYPE_BVEC2:
|
||||||
pi.type = Variant::INT;
|
if (p_uniform.array_size > 0) {
|
||||||
pi.hint = PROPERTY_HINT_FLAGS;
|
pi.type = Variant::PACKED_INT32_ARRAY;
|
||||||
pi.hint_string = "x,y";
|
} else {
|
||||||
|
pi.type = Variant::INT;
|
||||||
|
pi.hint = PROPERTY_HINT_FLAGS;
|
||||||
|
pi.hint_string = "x,y";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_BVEC3:
|
case ShaderLanguage::TYPE_BVEC3:
|
||||||
pi.type = Variant::INT;
|
if (p_uniform.array_size > 0) {
|
||||||
pi.hint = PROPERTY_HINT_FLAGS;
|
pi.type = Variant::PACKED_INT32_ARRAY;
|
||||||
pi.hint_string = "x,y,z";
|
} else {
|
||||||
|
pi.type = Variant::INT;
|
||||||
|
pi.hint = PROPERTY_HINT_FLAGS;
|
||||||
|
pi.hint_string = "x,y,z";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_BVEC4:
|
case ShaderLanguage::TYPE_BVEC4:
|
||||||
pi.type = Variant::INT;
|
if (p_uniform.array_size > 0) {
|
||||||
pi.hint = PROPERTY_HINT_FLAGS;
|
pi.type = Variant::PACKED_INT32_ARRAY;
|
||||||
pi.hint_string = "x,y,z,w";
|
} else {
|
||||||
|
pi.type = Variant::INT;
|
||||||
|
pi.hint = PROPERTY_HINT_FLAGS;
|
||||||
|
pi.hint_string = "x,y,z,w";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_UINT:
|
case ShaderLanguage::TYPE_UINT:
|
||||||
case ShaderLanguage::TYPE_INT: {
|
case ShaderLanguage::TYPE_INT: {
|
||||||
pi.type = Variant::INT;
|
if (p_uniform.array_size > 0) {
|
||||||
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
pi.type = Variant::PACKED_INT32_ARRAY;
|
||||||
pi.hint = PROPERTY_HINT_RANGE;
|
} else {
|
||||||
pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
pi.type = Variant::INT;
|
||||||
|
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
||||||
|
pi.hint = PROPERTY_HINT_RANGE;
|
||||||
|
pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ShaderLanguage::TYPE_IVEC2:
|
case ShaderLanguage::TYPE_IVEC2:
|
||||||
case ShaderLanguage::TYPE_IVEC3:
|
case ShaderLanguage::TYPE_IVEC3:
|
||||||
@ -3071,59 +3301,106 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
|
|||||||
pi.type = Variant::PACKED_INT32_ARRAY;
|
pi.type = Variant::PACKED_INT32_ARRAY;
|
||||||
} break;
|
} break;
|
||||||
case ShaderLanguage::TYPE_FLOAT: {
|
case ShaderLanguage::TYPE_FLOAT: {
|
||||||
pi.type = Variant::FLOAT;
|
if (p_uniform.array_size > 0) {
|
||||||
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
||||||
pi.hint = PROPERTY_HINT_RANGE;
|
} else {
|
||||||
pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
pi.type = Variant::FLOAT;
|
||||||
|
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
|
||||||
|
pi.hint = PROPERTY_HINT_RANGE;
|
||||||
|
pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ShaderLanguage::TYPE_VEC2:
|
case ShaderLanguage::TYPE_VEC2:
|
||||||
pi.type = Variant::VECTOR2;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::PACKED_VECTOR2_ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::VECTOR2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_VEC3:
|
case ShaderLanguage::TYPE_VEC3:
|
||||||
pi.type = Variant::VECTOR3;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::PACKED_VECTOR3_ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::VECTOR3;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_VEC4: {
|
case ShaderLanguage::TYPE_VEC4: {
|
||||||
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
if (p_uniform.array_size > 0) {
|
||||||
pi.type = Variant::COLOR;
|
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
||||||
|
pi.type = Variant::PACKED_COLOR_ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pi.type = Variant::PLANE;
|
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
||||||
|
pi.type = Variant::COLOR;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::PLANE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case ShaderLanguage::TYPE_MAT2:
|
case ShaderLanguage::TYPE_MAT2:
|
||||||
pi.type = Variant::TRANSFORM2D;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::TRANSFORM2D;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_MAT3:
|
case ShaderLanguage::TYPE_MAT3:
|
||||||
pi.type = Variant::BASIS;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::BASIS;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_MAT4:
|
case ShaderLanguage::TYPE_MAT4:
|
||||||
pi.type = Variant::TRANSFORM3D;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::PACKED_FLOAT32_ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::TRANSFORM3D;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ShaderLanguage::TYPE_SAMPLER2D:
|
case ShaderLanguage::TYPE_SAMPLER2D:
|
||||||
case ShaderLanguage::TYPE_ISAMPLER2D:
|
case ShaderLanguage::TYPE_ISAMPLER2D:
|
||||||
case ShaderLanguage::TYPE_USAMPLER2D: {
|
case ShaderLanguage::TYPE_USAMPLER2D: {
|
||||||
pi.type = Variant::OBJECT;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::OBJECT;
|
||||||
|
}
|
||||||
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
||||||
pi.hint_string = "Texture2D";
|
pi.hint_string = "Texture2D";
|
||||||
} break;
|
} break;
|
||||||
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
|
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
|
||||||
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
|
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
|
||||||
case ShaderLanguage::TYPE_USAMPLER2DARRAY: {
|
case ShaderLanguage::TYPE_USAMPLER2DARRAY: {
|
||||||
pi.type = Variant::OBJECT;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::OBJECT;
|
||||||
|
}
|
||||||
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
||||||
pi.hint_string = "TextureLayered";
|
pi.hint_string = "TextureLayered";
|
||||||
} break;
|
} break;
|
||||||
case ShaderLanguage::TYPE_SAMPLER3D:
|
case ShaderLanguage::TYPE_SAMPLER3D:
|
||||||
case ShaderLanguage::TYPE_ISAMPLER3D:
|
case ShaderLanguage::TYPE_ISAMPLER3D:
|
||||||
case ShaderLanguage::TYPE_USAMPLER3D: {
|
case ShaderLanguage::TYPE_USAMPLER3D: {
|
||||||
pi.type = Variant::OBJECT;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::OBJECT;
|
||||||
|
}
|
||||||
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
||||||
pi.hint_string = "Texture3D";
|
pi.hint_string = "Texture3D";
|
||||||
} break;
|
} break;
|
||||||
case ShaderLanguage::TYPE_SAMPLERCUBE:
|
case ShaderLanguage::TYPE_SAMPLERCUBE:
|
||||||
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
|
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
|
||||||
pi.type = Variant::OBJECT;
|
if (p_uniform.array_size > 0) {
|
||||||
|
pi.type = Variant::ARRAY;
|
||||||
|
} else {
|
||||||
|
pi.type = Variant::OBJECT;
|
||||||
|
}
|
||||||
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
|
||||||
pi.hint_string = "TextureLayered";
|
pi.hint_string = "TextureLayered";
|
||||||
} break;
|
} break;
|
||||||
@ -6694,6 +6971,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
|
|
||||||
int texture_uniforms = 0;
|
int texture_uniforms = 0;
|
||||||
|
int texture_binding = 0;
|
||||||
int uniforms = 0;
|
int uniforms = 0;
|
||||||
int instance_index = 0;
|
int instance_index = 0;
|
||||||
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
|
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
|
||||||
@ -6903,6 +7181,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool precision_defined = false;
|
||||||
DataPrecision precision = PRECISION_DEFAULT;
|
DataPrecision precision = PRECISION_DEFAULT;
|
||||||
DataInterpolation interpolation = INTERPOLATION_SMOOTH;
|
DataInterpolation interpolation = INTERPOLATION_SMOOTH;
|
||||||
DataType type;
|
DataType type;
|
||||||
@ -6911,15 +7190,34 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
|
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
if (is_token_interpolation(tk.type)) {
|
if (is_token_interpolation(tk.type)) {
|
||||||
|
if (uniform) {
|
||||||
|
_set_error("Interpolation qualifiers are not supported for uniforms!");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
interpolation = get_token_interpolation(tk.type);
|
interpolation = get_token_interpolation(tk.type);
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_token_precision(tk.type)) {
|
if (is_token_precision(tk.type)) {
|
||||||
precision = get_token_precision(tk.type);
|
precision = get_token_precision(tk.type);
|
||||||
|
precision_defined = true;
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shader->structs.has(tk.text)) {
|
||||||
|
if (uniform) {
|
||||||
|
if (precision_defined) {
|
||||||
|
_set_error("Precision modifier cannot be used on structs.");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
_set_error("struct datatype is not yet supported for uniforms!");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
} else {
|
||||||
|
_set_error("struct datatype not allowed here");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_token_datatype(tk.type)) {
|
if (!is_token_datatype(tk.type)) {
|
||||||
_set_error("Expected datatype. ");
|
_set_error("Expected datatype. ");
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
@ -6996,12 +7294,47 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
}
|
}
|
||||||
ShaderNode::Uniform uniform2;
|
ShaderNode::Uniform uniform2;
|
||||||
|
|
||||||
|
uniform2.type = type;
|
||||||
|
uniform2.scope = uniform_scope;
|
||||||
|
uniform2.precision = precision;
|
||||||
|
uniform2.array_size = array_size;
|
||||||
|
|
||||||
|
tk = _get_token();
|
||||||
|
if (tk.type == TK_BRACKET_OPEN) {
|
||||||
|
if (uniform2.array_size > 0) {
|
||||||
|
_set_error("Array size is already defined!");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
tk = _get_token();
|
||||||
|
|
||||||
|
if (tk.type == TK_INT_CONSTANT && tk.constant > 0) {
|
||||||
|
uniform2.array_size = (int)tk.constant;
|
||||||
|
|
||||||
|
tk = _get_token();
|
||||||
|
if (tk.type == TK_BRACKET_CLOSE) {
|
||||||
|
tk = _get_token();
|
||||||
|
} else {
|
||||||
|
_set_error("Expected ']'");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_set_error("Expected integer constant > 0");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is_sampler_type(type)) {
|
if (is_sampler_type(type)) {
|
||||||
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
|
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
|
||||||
_set_error("Uniforms with 'instance' qualifiers can't be of sampler type.");
|
_set_error("Uniforms with 'instance' qualifiers can't be of sampler type.");
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
uniform2.texture_order = texture_uniforms++;
|
uniform2.texture_order = texture_uniforms++;
|
||||||
|
uniform2.texture_binding = texture_binding;
|
||||||
|
if (uniform2.array_size > 0) {
|
||||||
|
texture_binding += uniform2.array_size;
|
||||||
|
} else {
|
||||||
|
++texture_binding;
|
||||||
|
}
|
||||||
uniform2.order = -1;
|
uniform2.order = -1;
|
||||||
if (_validate_datatype(type) != OK) {
|
if (_validate_datatype(type) != OK) {
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
@ -7011,19 +7344,22 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
_set_error("Uniforms with 'instance' qualifiers can't be of matrix type.");
|
_set_error("Uniforms with 'instance' qualifiers can't be of matrix type.");
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
uniform2.texture_order = -1;
|
uniform2.texture_order = -1;
|
||||||
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
|
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
|
||||||
uniform2.order = uniforms++;
|
uniform2.order = uniforms++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uniform2.type = type;
|
|
||||||
uniform2.scope = uniform_scope;
|
|
||||||
uniform2.precision = precision;
|
|
||||||
|
|
||||||
//todo parse default value
|
if (uniform2.array_size > 0) {
|
||||||
|
if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
|
||||||
tk = _get_token();
|
_set_error("'SCOPE_GLOBAL' qualifier is not yet supported for uniform array!");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
|
||||||
|
_set_error("'SCOPE_INSTANCE' qualifier is not yet supported for uniform array!");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int custom_instance_index = -1;
|
int custom_instance_index = -1;
|
||||||
|
|
||||||
@ -7031,6 +7367,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
//hint
|
//hint
|
||||||
do {
|
do {
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
|
|
||||||
|
if (uniform2.array_size > 0) {
|
||||||
|
if (tk.type != TK_HINT_COLOR) {
|
||||||
|
_set_error("This hint is not yet supported for uniform arrays!");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tk.type == TK_HINT_WHITE_TEXTURE) {
|
if (tk.type == TK_HINT_WHITE_TEXTURE) {
|
||||||
uniform2.hint = ShaderNode::Uniform::HINT_WHITE;
|
uniform2.hint = ShaderNode::Uniform::HINT_WHITE;
|
||||||
} else if (tk.type == TK_HINT_BLACK_TEXTURE) {
|
} else if (tk.type == TK_HINT_BLACK_TEXTURE) {
|
||||||
@ -7221,6 +7565,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
//reset scope for next uniform
|
//reset scope for next uniform
|
||||||
|
|
||||||
if (tk.type == TK_OP_ASSIGN) {
|
if (tk.type == TK_OP_ASSIGN) {
|
||||||
|
if (uniform2.array_size > 0) {
|
||||||
|
_set_error("Setting default value to a uniform array is not yet supported!");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
|
Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
@ -7265,7 +7614,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
|
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
|
if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
|
||||||
_set_error("Expected ';' or '['");
|
if (array_size == 0) {
|
||||||
|
_set_error("Expected ';' or '['");
|
||||||
|
} else {
|
||||||
|
_set_error("Expected ';'");
|
||||||
|
}
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7290,7 +7643,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_set_error("Expected single integer constant > 0");
|
_set_error("Expected integer constant > 0");
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -692,8 +692,10 @@ public:
|
|||||||
|
|
||||||
int order = 0;
|
int order = 0;
|
||||||
int texture_order = 0;
|
int texture_order = 0;
|
||||||
|
int texture_binding = 0;
|
||||||
DataType type = TYPE_VOID;
|
DataType type = TYPE_VOID;
|
||||||
DataPrecision precision = PRECISION_DEFAULT;
|
DataPrecision precision = PRECISION_DEFAULT;
|
||||||
|
int array_size = 0;
|
||||||
Vector<ConstantNode::Value> default_value;
|
Vector<ConstantNode::Value> default_value;
|
||||||
Scope scope = SCOPE_LOCAL;
|
Scope scope = SCOPE_LOCAL;
|
||||||
Hint hint = HINT_NONE;
|
Hint hint = HINT_NONE;
|
||||||
@ -776,7 +778,7 @@ public:
|
|||||||
static bool is_scalar_type(DataType p_type);
|
static bool is_scalar_type(DataType p_type);
|
||||||
static bool is_float_type(DataType p_type);
|
static bool is_float_type(DataType p_type);
|
||||||
static bool is_sampler_type(DataType p_type);
|
static bool is_sampler_type(DataType p_type);
|
||||||
static Variant constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE);
|
static Variant constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE);
|
||||||
static PropertyInfo uniform_to_property_info(const ShaderNode::Uniform &p_uniform);
|
static PropertyInfo uniform_to_property_info(const ShaderNode::Uniform &p_uniform);
|
||||||
static uint32_t get_type_size(DataType p_type);
|
static uint32_t get_type_size(DataType p_type);
|
||||||
|
|
||||||
|
@ -125,23 +125,28 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
|
|||||||
ucode += _prestr(E.value.precision);
|
ucode += _prestr(E.value.precision);
|
||||||
ucode += _typestr(E.value.type);
|
ucode += _typestr(E.value.type);
|
||||||
ucode += " " + String(E.key);
|
ucode += " " + String(E.key);
|
||||||
|
if (E.value.array_size > 0) {
|
||||||
|
ucode += "[";
|
||||||
|
ucode += itos(E.value.array_size);
|
||||||
|
ucode += "]";
|
||||||
|
} else {
|
||||||
|
if (E.value.default_value.size()) {
|
||||||
|
ucode += " = " + get_constant_text(E.value.type, E.value.default_value);
|
||||||
|
}
|
||||||
|
|
||||||
if (E.value.default_value.size()) {
|
static const char *hint_name[SL::ShaderNode::Uniform::HINT_MAX] = {
|
||||||
ucode += " = " + get_constant_text(E.value.type, E.value.default_value);
|
"",
|
||||||
}
|
"color",
|
||||||
|
"range",
|
||||||
|
"albedo",
|
||||||
|
"normal",
|
||||||
|
"black",
|
||||||
|
"white"
|
||||||
|
};
|
||||||
|
|
||||||
static const char *hint_name[SL::ShaderNode::Uniform::HINT_MAX] = {
|
if (E.value.hint) {
|
||||||
"",
|
ucode += " : " + String(hint_name[E.value.hint]);
|
||||||
"color",
|
}
|
||||||
"range",
|
|
||||||
"albedo",
|
|
||||||
"normal",
|
|
||||||
"black",
|
|
||||||
"white"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (E.value.hint) {
|
|
||||||
ucode += " : " + String(hint_name[E.value.hint]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
code += ucode + "\n";
|
code += ucode + "\n";
|
||||||
|
Loading…
Reference in New Issue
Block a user