Skip to content

Commit

Permalink
Backported ORMSpatialMaterial from Godot 3.x without any breaking cha…
Browse files Browse the repository at this point in the history
…nges.
  • Loading branch information
Relintai committed Apr 6, 2024
1 parent efcdf40 commit 4f93164
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 46 deletions.
1 change: 1 addition & 0 deletions scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ void register_scene_types() {
ClassDB::register_class<PointMesh>();
ClassDB::register_virtual_class<Material>();
ClassDB::register_class<SpatialMaterial>();
ClassDB::register_class<ORMSpatialMaterial>();
SceneTree::add_idle_callback(SpatialMaterial::flush_changes);
SpatialMaterial::init_shaders();

Expand Down
152 changes: 107 additions & 45 deletions scene/resources/material/spatial_material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ void SpatialMaterial::init_shaders() {
shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask";
shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo";
shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal";
shader_names->texture_names[TEXTURE_ORM] = "texture_orm";
}

HashMap<uint64_t, Ref<SpatialMaterial>> SpatialMaterial::materials_for_2d;
Expand Down Expand Up @@ -286,15 +287,31 @@ void SpatialMaterial::_update_shader() {
code += "uniform float roughness : hint_range(0,1);\n";
code += "uniform float point_size : hint_range(0,128);\n";

if (textures[TEXTURE_METALLIC] != nullptr) {
code += "uniform sampler2D texture_metallic : hint_white;\n";
code += "uniform vec4 metallic_texture_channel;\n";
}
if (orm) {
if (textures[TEXTURE_ORM] != nullptr) {
code += "uniform sampler2D texture_orm : hint_white;\n";
if (features[FEATURE_AMBIENT_OCCLUSION]) {
code += "uniform float ao_light_affect;\n";
}
}
} else {
if (textures[TEXTURE_METALLIC] != nullptr) {
code += "uniform sampler2D texture_metallic : hint_white;\n";
code += "uniform vec4 metallic_texture_channel;\n";
}

if (textures[TEXTURE_ROUGHNESS] != nullptr) {
code += "uniform sampler2D texture_roughness : hint_white;\n";
code += "uniform vec4 roughness_texture_channel;\n";
}

if (textures[TEXTURE_ROUGHNESS] != nullptr) {
code += "uniform sampler2D texture_roughness : hint_white;\n";
code += "uniform vec4 roughness_texture_channel;\n";
if (features[FEATURE_AMBIENT_OCCLUSION]) {
code += "uniform sampler2D texture_ambient_occlusion : hint_white;\n";
code += "uniform vec4 ao_texture_channel;\n";
code += "uniform float ao_light_affect;\n";
}
}

if (billboard_mode == BILLBOARD_PARTICLES) {
code += "uniform int particles_anim_h_frames;\n";
code += "uniform int particles_anim_v_frames;\n";
Expand Down Expand Up @@ -331,11 +348,6 @@ void SpatialMaterial::_update_shader() {
code += "uniform float anisotropy_ratio : hint_range(0,256);\n";
code += "uniform sampler2D texture_flowmap : hint_aniso;\n";
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
code += "uniform sampler2D texture_ambient_occlusion : hint_white;\n";
code += "uniform vec4 ao_texture_channel;\n";
code += "uniform float ao_light_affect;\n";
}

if (features[FEATURE_DETAIL]) {
code += "uniform sampler2D texture_detail_albedo : hint_albedo;\n";
Expand Down Expand Up @@ -593,26 +605,75 @@ void SpatialMaterial::_update_shader() {
}
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";

if (textures[TEXTURE_METALLIC] != nullptr) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n";

if (orm) {
if (textures[TEXTURE_ORM] != nullptr) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tvec4 orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
code += "\tvec4 orm_tex = texture(texture_orm,base_uv);\n";
}
code += "\tMETALLIC = orm_tex.b;\n";
code += "\tROUGHNESS = orm_tex.g;\n";
} else {
code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
code += "\tMETALLIC = metallic;\n";
code += "\tROUGHNESS = roughness;\n";
}

// AO
if (features[FEATURE_AMBIENT_OCCLUSION]) {
if (flags[FLAG_AO_ON_UV2]) {
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
code += "\tAO = triplanar_texture(texture_orm,uv2_power_normal,uv2_triplanar_pos).r;\n";
} else {
code += "\tAO = texture(texture_orm,base_uv2).r;\n";
}
} else {
code += "\tAO = orm_tex.r;\n";
}

code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n";
}
code += "\tMETALLIC = metallic_tex * metallic;\n";
} else {
code += "\tMETALLIC = metallic;\n";
}
if (textures[TEXTURE_METALLIC] != nullptr) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n";
} else {
code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
}
code += "\tMETALLIC = metallic_tex * metallic;\n";
} else {
code += "\tMETALLIC = metallic;\n";
}

if (textures[TEXTURE_ROUGHNESS] != nullptr) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n";
if (textures[TEXTURE_ROUGHNESS] != nullptr) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n";
} else {
code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
}
code += "\tROUGHNESS = roughness_tex * roughness;\n";
} else {
code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
code += "\tROUGHNESS = roughness;\n";
}

if (features[FEATURE_AMBIENT_OCCLUSION]) {
if (flags[FLAG_AO_ON_UV2]) {
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
} else {
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
}
} else {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
} else {
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
}
}

code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n";
}
code += "\tROUGHNESS = roughness_tex * roughness;\n";
} else {
code += "\tROUGHNESS = roughness;\n";
}

code += "\tSPECULAR = specular;\n";
Expand Down Expand Up @@ -735,24 +796,6 @@ void SpatialMaterial::_update_shader() {
code += "\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n";
}

if (features[FEATURE_AMBIENT_OCCLUSION]) {
if (flags[FLAG_AO_ON_UV2]) {
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
} else {
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
}
} else {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
} else {
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
}
}

code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n";
}

if (features[FEATURE_SUBSURACE_SCATTERING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
Expand Down Expand Up @@ -1264,6 +1307,20 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
}

if (orm) {
if (property.name == "shading_mode") {
// Vertex not supported in ORM mode, since no individual roughness.
property.hint_string = "Unshaded,Per-Pixel";
}
if (property.name.begins_with("roughness") || property.name.begins_with("metallic") || property.name.begins_with("ao_texture")) {
property.usage = 0;
}
} else {
if (property.name == "orm_texture") {
property.usage = 0;
}
}
}

void SpatialMaterial::set_line_width(float p_line_width) {
Expand Down Expand Up @@ -1857,6 +1914,9 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO);

ADD_GROUP("ORM", "orm_");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orm_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM);

ADD_GROUP("Metallic", "metallic_");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular");
Expand Down Expand Up @@ -2067,8 +2127,10 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(ASYNC_MODE_HIDDEN);
}

SpatialMaterial::SpatialMaterial() :
SpatialMaterial::SpatialMaterial(bool p_orm) :
element(this) {
orm = p_orm;

// Initialize to the same values as the shader
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
set_specular(0.5);
Expand Down
11 changes: 10 additions & 1 deletion scene/resources/material/spatial_material.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class SpatialMaterial : public Material {
TEXTURE_DETAIL_MASK,
TEXTURE_DETAIL_ALBEDO,
TEXTURE_DETAIL_NORMAL,
TEXTURE_ORM,
TEXTURE_MAX

};
Expand Down Expand Up @@ -311,6 +312,7 @@ class SpatialMaterial : public Material {
_FORCE_INLINE_ bool _is_shader_dirty() const;

bool is_initialized = false;
bool orm;
Color albedo;
float specular;
float metallic;
Expand Down Expand Up @@ -578,7 +580,7 @@ class SpatialMaterial : public Material {

virtual Shader::Mode get_shader_mode() const;

SpatialMaterial();
SpatialMaterial(bool p_orm = false);
virtual ~SpatialMaterial();
};

Expand All @@ -599,4 +601,11 @@ VARIANT_ENUM_CAST(SpatialMaterial::AsyncMode)

//////////////////////

class ORMSpatialMaterial : public SpatialMaterial {
GDCLASS(ORMSpatialMaterial, SpatialMaterial)
public:
ORMSpatialMaterial() :
SpatialMaterial(true) {}
};

#endif

0 comments on commit 4f93164

Please sign in to comment.