1
0
mirror of https://github.com/godotengine/godot synced 2024-07-08 18:10:44 +00:00

Several fixes related to PBR and Environment

This commit is contained in:
Juan Linietsky 2017-05-29 22:11:33 -03:00
parent 0a6faeb4f5
commit 5567e898d1
21 changed files with 132 additions and 97 deletions

View File

@ -43,7 +43,7 @@ bool ImageFormatLoader::recognize(const String &p_extension) const {
return false;
}
Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom) {
Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear) {
ERR_FAIL_COND_V(p_image.is_null(), ERR_INVALID_PARAMETER);
FileAccess *f = p_custom;
@ -62,7 +62,7 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
if (!loader[i]->recognize(extension))
continue;
Error err = loader[i]->load_image(p_image, f);
Error err = loader[i]->load_image(p_image, f, p_force_linear);
if (err != ERR_FILE_UNRECOGNIZED) {

View File

@ -56,7 +56,7 @@ class ImageFormatLoader {
friend class ImageLoader;
protected:
virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess) = 0;
virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear) = 0;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
bool recognize(const String &p_extension) const;
@ -75,7 +75,7 @@ class ImageLoader {
protected:
public:
static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL);
static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false);
static void get_recognized_extensions(List<String> *p_extensions);
static bool recognize(const String &p_extension);

View File

@ -2120,7 +2120,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
}
}
void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale) {
void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy) {
if (!p_sky)
return;
@ -2188,13 +2188,16 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
glBindVertexArray(state.sky_array);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, true);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, true);
storage->shaders.copy.bind();
storage->shaders.copy.set_uniform(CopyShaderGLES3::MULTIPLIER, p_energy);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
glColorMask(1, 1, 1, 1);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, false);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, false);
}
@ -3885,7 +3888,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); //switch to alpha fbo for sky, only diffuse/ambient matters
*/
_draw_sky(sky, p_cam_projection, p_cam_transform, storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP], env->sky_scale);
_draw_sky(sky, p_cam_projection, p_cam_transform, storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP], env->sky_scale, env->bg_energy);
}
//_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true);
@ -4832,7 +4835,7 @@ void RasterizerSceneGLES3::initialize() {
glGenTextures(1, &e.color);
glBindTexture(GL_TEXTURE_2D, e.color);
#ifdef IPHONE_ENABLED
///@TODO ugly hack to get around iOS not supporting 32bit single channel floating point textures...
///@TODO ugly hack to get around iOS not supporting 32bit single channel floating point textures...
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, max_exposure_shrink_size, max_exposure_shrink_size, 0, GL_RED, GL_FLOAT, NULL);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, max_exposure_shrink_size, max_exposure_shrink_size, 0, GL_RED, GL_FLOAT, NULL);

View File

@ -131,8 +131,6 @@ public:
struct EnvironmentRadianceUBO {
float transform[16];
float box_min[4]; //unused for now
float box_max[4];
float ambient_contribution;
} env_radiance_data;
@ -700,7 +698,7 @@ public:
_FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow);
void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale);
void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy);
void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform);
void _setup_directional_light(int p_index, const Transform &p_camera_inverse_transformm, bool p_use_shadows);

View File

@ -5553,7 +5553,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
Image::Format image_format;
bool hdr = rt->flags[RENDER_TARGET_HDR] && config.hdr_supported;
hdr = false;
//hdr = false;
if (!hdr || rt->flags[RENDER_TARGET_NO_3D]) {
@ -6403,6 +6403,8 @@ void RasterizerStorageGLES3::initialize() {
config.etc2_supported = true;
config.hdr_supported = false;
#endif
print_line("hdr supported: " + itos(config.hdr_supported));
config.pvrtc_supported = config.extensions.has("GL_IMG_texture_compression_pvrtc");
config.srgb_decode_supported = config.extensions.has("GL_EXT_texture_sRGB_decode");

View File

@ -45,6 +45,11 @@ uniform samplerCube source_cube; //texunit:0
uniform sampler2D source; //texunit:0
#endif
#ifdef USE_MULTIPLIER
uniform float multiplier;
#endif
#ifdef USE_PANORAMA
vec4 texturePanorama(vec3 normal,sampler2D pano ) {
@ -130,7 +135,9 @@ void main() {
color+=texture( source, uv_interp+vec2( 0.0,-2.0)*pixel_size )*0.06136;
#endif
#ifdef USE_MULTIPLIER
color.rgb*=multiplier;
#endif
frag_color = color;
}

View File

@ -380,8 +380,6 @@ uniform sampler2D radiance_map; //texunit:-2
layout(std140) uniform Radiance { //ubo:2
mat4 radiance_inverse_xform;
vec3 radiance_box_min;
vec3 radiance_box_max;
float radiance_ambient_contribution;
};
@ -1133,6 +1131,23 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, vec3 specular, in
#endif
vec3 textureDualParabolod(sampler2D p_tex, vec3 p_vec,float p_lod) {
vec3 norm = normalize(p_vec);
float y_ofs=0.0;
if (norm.z>=0.0) {
norm.z+=1.0;
y_ofs+=0.5;
} else {
norm.z=1.0 - norm.z;
norm.y=-norm.y;
}
norm.xy/=norm.z;
norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs);
return textureLod(p_tex, norm.xy, p_lod).xyz;
}
void main() {
@ -1264,6 +1279,8 @@ FRAGMENT_SHADER_CODE
float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy;
brdf.x=1.0;
brdf.y=0.0;
#endif
#ifdef USE_RADIANCE_MAP
@ -1274,28 +1291,15 @@ FRAGMENT_SHADER_CODE
{
float lod = roughness * 5.0;
#define RADIANCE_MAX_LOD 5.0
float lod = roughness * RADIANCE_MAX_LOD;
{ //read radiance from dual paraboloid
vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz);
vec3 norm = normalize(ref_vec);
float y_ofs=0.0;
if (norm.z>=0.0) {
norm.z+=1.0;
y_ofs+=0.5;
} else {
norm.z=1.0 - norm.z;
norm.y=-norm.y;
}
norm.xy/=norm.z;
norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs);
specular_light = textureLod(radiance_map, norm.xy, lod).xyz * brdf.x + brdf.y;
ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz);
vec3 radiance = textureDualParabolod(radiance_map,ref_vec,lod) * bg_energy;
specular_light = radiance * brdf.x + brdf.y;
}
//no longer a cubemap
@ -1305,11 +1309,11 @@ FRAGMENT_SHADER_CODE
{
/*vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
vec3 env_ambient=textureLod(radiance_cube, ambient_dir, 5.0).xyz;
vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
vec3 env_ambient=textureDualParabolod(radiance_map,ambient_dir,RADIANCE_MAX_LOD) * bg_energy;
ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution);*/
ambient_light=vec3(0.0,0.0,0.0);
ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution);
//ambient_light=vec3(0.0,0.0,0.0);
}
}
@ -1322,6 +1326,7 @@ FRAGMENT_SHADER_CODE
}
#endif
ambient_light*=ambient_energy;
#ifdef USE_LIGHT_DIRECTIONAL

View File

@ -201,7 +201,7 @@ Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Ref<Image> p_i
return OK;
}
Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f) {
Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
Error err = _load_image(f, _read_png_data, p_image);
f->close();

View File

@ -43,7 +43,7 @@ class ImageLoaderPNG : public ImageFormatLoader {
public:
static Error _load_image(void *rf_up, png_rw_ptr p_func, Ref<Image> p_image);
virtual Error load_image(Ref<Image> p_image, FileAccess *f);
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderPNG();
};

View File

@ -1380,7 +1380,7 @@ void EditorNode::_property_editor_back() {
void EditorNode::_save_default_environment() {
Ref<Environment> fallback = get_scene_root()->get_world()->get_fallback_environment();
Ref<Environment> fallback = get_tree()->get_root()->get_world()->get_fallback_environment();
if (fallback.is_valid() && fallback->get_path().is_resource_file()) {
Map<RES, bool> processed;

View File

@ -177,6 +177,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/srgb", PROPERTY_HINT_ENUM, "Disable,Enable,Detect"), 2));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D ? true : false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "stream"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "detect_3d"), p_preset == PRESET_DETECT));
@ -327,10 +328,11 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool stream = p_options["stream"];
int size_limit = p_options["size_limit"];
bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1;
bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
Ref<Image> image;
image.instance();
Error err = ImageLoader::load_image(p_source_file, image);
Error err = ImageLoader::load_image(p_source_file, image, NULL, hdr_as_srgb);
if (err != OK)
return err;

View File

@ -34,17 +34,23 @@
#include "thirdparty/tinyexr/tinyexr.h"
Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f) {
Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
String header = f->get_token();
print_line("HEADER: " + header);
ERR_FAIL_COND_V(header != "#?RADIANCE", ERR_FILE_UNRECOGNIZED);
ERR_FAIL_COND_V(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED);
String format = f->get_token();
print_line("FORMAT: " + format);
ERR_FAIL_COND_V(format != "FORMAT=32-bit_rle_rgbe", ERR_FILE_UNRECOGNIZED);
while (true) {
String format = f->get_token();
ERR_FAIL_COND_V(f->eof_reached(), ERR_FILE_UNRECOGNIZED);
if (format.begins_with("FORMAT=") && format != "FORMAT=32-bit_rle_rgbe") {
ERR_EXPLAIN("Only 32-bit_rle_rgbe is supported for .hdr files.");
return ERR_FILE_UNRECOGNIZED;
}
if (format == "FORMAT=32-bit_rle_rgbe")
break;
}
String token = f->get_token();
@ -132,6 +138,10 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f) {
ptr[1] * exp / 255.0,
ptr[2] * exp / 255.0);
if (p_force_linear) {
c = c.to_linear();
}
*(uint32_t *)ptr = c.to_rgbe9995();
ptr += 4;
}

View File

@ -38,7 +38,7 @@
class ImageLoaderHDR : public ImageFormatLoader {
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f);
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderHDR();
};

View File

@ -89,7 +89,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
return OK;
}
Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f) {
Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
PoolVector<uint8_t> src_image;
int src_image_len = f->get_len();

View File

@ -38,7 +38,7 @@
class ImageLoaderJPG : public ImageFormatLoader {
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f);
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderJPG();
};

View File

@ -34,7 +34,7 @@
#include "thirdparty/tinyexr/tinyexr.h"
Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f) {
Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
PoolVector<uint8_t> src_image;
int src_image_len = f->get_len();
@ -133,9 +133,17 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f) {
// Assume `out_rgba` have enough memory allocated.
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
*iw++ = Math::make_half_float(reinterpret_cast<float **>(exr_image.images)[idxR][i]);
*iw++ = Math::make_half_float(reinterpret_cast<float **>(exr_image.images)[idxG][i]);
*iw++ = Math::make_half_float(reinterpret_cast<float **>(exr_image.images)[idxB][i]);
Color color(
reinterpret_cast<float **>(exr_image.images)[idxR][i],
reinterpret_cast<float **>(exr_image.images)[idxG][i],
reinterpret_cast<float **>(exr_image.images)[idxB][i]);
if (p_force_linear)
color = color.to_linear();
*iw++ = Math::make_half_float(color.r);
*iw++ = Math::make_half_float(color.g);
*iw++ = Math::make_half_float(color.b);
if (idxA > 0) {
*iw++ = Math::make_half_float(reinterpret_cast<float **>(exr_image.images)[idxA][i]);

View File

@ -38,7 +38,7 @@
class ImageLoaderTinyEXR : public ImageFormatLoader {
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f);
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderTinyEXR();
};

View File

@ -115,7 +115,7 @@ static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
return img;
}
Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f) {
Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
uint32_t size = f->get_len();
PoolVector<uint8_t> src_image;

View File

@ -38,7 +38,7 @@
class ImageLoaderWEBP : public ImageFormatLoader {
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f);
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderWEBP();
};

View File

@ -266,19 +266,19 @@ Ref<Texture> Environment::get_adjustment_color_correction() const {
void Environment::_validate_property(PropertyInfo &property) const {
if (property.name == "background/sky" || property.name == "background/sky_scale" || property.name == "ambient_light/sky_contribution") {
if (property.name == "background_sky" || property.name == "background_sky_scale" || property.name == "ambient_light/sky_contribution") {
if (bg_mode != BG_SKY) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
if (property.name == "background/color") {
if (property.name == "background_color") {
if (bg_mode != BG_COLOR) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
if (property.name == "background/canvas_max_layer") {
if (property.name == "background_canvas_max_layer") {
if (bg_mode != BG_CANVAS) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
@ -695,6 +695,41 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution");
ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper);
ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper);
ClassDB::bind_method(D_METHOD("set_tonemap_exposure", "exposure"), &Environment::set_tonemap_exposure);
ClassDB::bind_method(D_METHOD("get_tonemap_exposure"), &Environment::get_tonemap_exposure);
ClassDB::bind_method(D_METHOD("set_tonemap_white", "white"), &Environment::set_tonemap_white);
ClassDB::bind_method(D_METHOD("get_tonemap_white"), &Environment::get_tonemap_white);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure", "auto_exposure"), &Environment::set_tonemap_auto_exposure);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure"), &Environment::get_tonemap_auto_exposure);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_max", "exposure_max"), &Environment::set_tonemap_auto_exposure_max);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_max"), &Environment::get_tonemap_auto_exposure_max);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_min", "exposure_min"), &Environment::set_tonemap_auto_exposure_min);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_min"), &Environment::get_tonemap_auto_exposure_min);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_speed", "exposure_speed"), &Environment::set_tonemap_auto_exposure_speed);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_speed"), &Environment::get_tonemap_auto_exposure_speed);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_grey", "exposure_grey"), &Environment::set_tonemap_auto_exposure_grey);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey);
ADD_GROUP("Tonemap", "tonemap_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reindhart,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
ADD_GROUP("Auto Exposure", "auto_exposure_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_exposure_enabled"), "set_tonemap_auto_exposure", "get_tonemap_auto_exposure");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed");
ClassDB::bind_method(D_METHOD("set_ssr_enabled", "enabled"), &Environment::set_ssr_enabled);
ClassDB::bind_method(D_METHOD("is_ssr_enabled"), &Environment::is_ssr_enabled);
@ -852,41 +887,6 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_bicubic_upscale"), "set_glow_bicubic_upscale", "is_glow_bicubic_upscale_enabled");
ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper);
ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper);
ClassDB::bind_method(D_METHOD("set_tonemap_exposure", "exposure"), &Environment::set_tonemap_exposure);
ClassDB::bind_method(D_METHOD("get_tonemap_exposure"), &Environment::get_tonemap_exposure);
ClassDB::bind_method(D_METHOD("set_tonemap_white", "white"), &Environment::set_tonemap_white);
ClassDB::bind_method(D_METHOD("get_tonemap_white"), &Environment::get_tonemap_white);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure", "auto_exposure"), &Environment::set_tonemap_auto_exposure);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure"), &Environment::get_tonemap_auto_exposure);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_max", "exposure_max"), &Environment::set_tonemap_auto_exposure_max);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_max"), &Environment::get_tonemap_auto_exposure_max);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_min", "exposure_min"), &Environment::set_tonemap_auto_exposure_min);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_min"), &Environment::get_tonemap_auto_exposure_min);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_speed", "exposure_speed"), &Environment::set_tonemap_auto_exposure_speed);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_speed"), &Environment::get_tonemap_auto_exposure_speed);
ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_grey", "exposure_grey"), &Environment::set_tonemap_auto_exposure_grey);
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey);
ADD_GROUP("Tonemap", "tonemap_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reindhart,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
ADD_GROUP("Auto Exposure", "auto_exposure_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_expoure_enabled"), "set_tonemap_auto_exposure", "get_tonemap_auto_exposure");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed");
ClassDB::bind_method(D_METHOD("set_adjustment_enable", "enabled"), &Environment::set_adjustment_enable);
ClassDB::bind_method(D_METHOD("is_adjustment_enabled"), &Environment::is_adjustment_enabled);

View File

@ -510,7 +510,7 @@ void SpatialMaterial::_update_shader() {
} else {
code += "\tvec4 specular_tex = texture(texture_specular,UV);\n";
code += "\tSPECULAR = vec3(ALBEDO.rgb * metalness * specular_tex.r);\n";
code += "\tROUGHNESS = specular_tex.a * roughness;\n";
code += "\tROUGHNESS = specular_tex.g * roughness;\n";
}
code += "}\n";
@ -888,10 +888,10 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
_validate_feature("refraction", FEATURE_REFRACTION, property);
_validate_feature("detail", FEATURE_DETAIL, property);
if (property.name == "specular/color" && specular_mode == SPECULAR_MODE_METALLIC) {
if (property.name == "specular_color" && specular_mode == SPECULAR_MODE_METALLIC) {
property.usage = 0;
}
if (property.name == "specular/metalness" && specular_mode == SPECULAR_MODE_SPECULAR) {
if (property.name == "specular_metalness" && specular_mode == SPECULAR_MODE_SPECULAR) {
property.usage = 0;
}