diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/SCsub | 9 | ||||
-rw-r--r-- | drivers/coreaudio/SCsub | 8 | ||||
-rw-r--r-- | drivers/coreaudio/audio_driver_coreaudio.cpp | 315 | ||||
-rw-r--r-- | drivers/coreaudio/audio_driver_coreaudio.h | 89 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 51 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 8 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 11 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 12 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 41 | ||||
-rw-r--r-- | drivers/png/SCsub | 2 |
10 files changed, 494 insertions, 52 deletions
diff --git a/drivers/SCsub b/drivers/SCsub index b8bba91378..34d6254578 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -4,7 +4,7 @@ Import('env') env.drivers_sources = [] -if ("builtin_zlib" in env and env["builtin_zlib"] == "yes"): +if 'builtin_zlib' in env and env['builtin_zlib']: SConscript("zlib/SCsub") # OS drivers @@ -13,11 +13,12 @@ SConscript('windows/SCsub') # Sounds drivers SConscript('alsa/SCsub') +SConscript('coreaudio/SCsub') SConscript('pulseaudio/SCsub') if (env["platform"] == "windows"): SConscript("rtaudio/SCsub") SConscript("wasapi/SCsub") -if (env["xaudio2"] == "yes"): +if env['xaudio2']: SConscript("xaudio2/SCsub") # Graphics drivers @@ -29,10 +30,10 @@ SConscript("png/SCsub") # Tools override # FIXME: Should likely be integrated in the tools/ codebase -if (env["tools"] == "yes"): +if env['tools']: SConscript("convex_decomp/SCsub") -if env['vsproj'] == "yes": +if env['vsproj']: env.AddToVSProject(env.drivers_sources) if env.split_drivers: diff --git a/drivers/coreaudio/SCsub b/drivers/coreaudio/SCsub new file mode 100644 index 0000000000..233593b0f9 --- /dev/null +++ b/drivers/coreaudio/SCsub @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +Import('env') + +# Driver source files +env.add_source_files(env.drivers_sources, "*.cpp") + +Export('env') diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp new file mode 100644 index 0000000000..c531d6af9d --- /dev/null +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -0,0 +1,315 @@ +/*************************************************************************/ +/* audio_driver_coreaudio.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifdef COREAUDIO_ENABLED + +#include "audio_driver_coreaudio.h" +#include "core/project_settings.h" +#include "os/os.h" + +#define kOutputBus 0 + +#ifdef OSX_ENABLED +static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *__nullable inClientData) { + AudioDriverCoreAudio *driver = (AudioDriverCoreAudio *)inClientData; + + driver->reopen(); + + return noErr; +} +#endif + +Error AudioDriverCoreAudio::initDevice() { + AudioComponentDescription desc; + zeromem(&desc, sizeof(desc)); + desc.componentType = kAudioUnitType_Output; +#ifdef OSX_ENABLED + desc.componentSubType = kAudioUnitSubType_HALOutput; +#else + desc.componentSubType = kAudioUnitSubType_RemoteIO; +#endif + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + + AudioComponent comp = AudioComponentFindNext(NULL, &desc); + ERR_FAIL_COND_V(comp == NULL, FAILED); + + OSStatus result = AudioComponentInstanceNew(comp, &audio_unit); + ERR_FAIL_COND_V(result != noErr, FAILED); + + AudioStreamBasicDescription strdesc; + + zeromem(&strdesc, sizeof(strdesc)); + UInt32 size = sizeof(strdesc); + result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &strdesc, &size); + ERR_FAIL_COND_V(result != noErr, FAILED); + + switch (strdesc.mChannelsPerFrame) { + case 2: // Stereo + case 4: // Surround 3.1 + case 6: // Surround 5.1 + case 8: // Surround 7.1 + channels = strdesc.mChannelsPerFrame; + break; + + default: + // Unknown number of channels, default to stereo + channels = 2; + break; + } + + mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); + + zeromem(&strdesc, sizeof(strdesc)); + strdesc.mFormatID = kAudioFormatLinearPCM; + strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; + strdesc.mChannelsPerFrame = channels; + strdesc.mSampleRate = mix_rate; + strdesc.mFramesPerPacket = 1; + strdesc.mBitsPerChannel = 16; + strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8; + strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket; + + result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc)); + ERR_FAIL_COND_V(result != noErr, FAILED); + + int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) + buffer_frames = closest_power_of_2(latency * mix_rate / 1000); + +#ifdef OSX_ENABLED + result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32)); + ERR_FAIL_COND_V(result != noErr, FAILED); +#endif + + buffer_size = buffer_frames * channels; + samples_in.resize(buffer_size); + + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("CoreAudio: detected " + itos(channels) + " channels"); + print_line("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); + } + + AURenderCallbackStruct callback; + zeromem(&callback, sizeof(AURenderCallbackStruct)); + callback.inputProc = &AudioDriverCoreAudio::output_callback; + callback.inputProcRefCon = this; + result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback)); + ERR_FAIL_COND_V(result != noErr, FAILED); + + result = AudioUnitInitialize(audio_unit); + ERR_FAIL_COND_V(result != noErr, FAILED); + + return OK; +} + +Error AudioDriverCoreAudio::finishDevice() { + OSStatus result; + + if (active) { + result = AudioOutputUnitStop(audio_unit); + ERR_FAIL_COND_V(result != noErr, FAILED); + + active = false; + } + + result = AudioUnitUninitialize(audio_unit); + ERR_FAIL_COND_V(result != noErr, FAILED); + + return OK; +} + +Error AudioDriverCoreAudio::init() { + OSStatus result; + + mutex = Mutex::create(); + active = false; + channels = 2; + +#ifdef OSX_ENABLED + outputDeviceAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; + outputDeviceAddress.mScope = kAudioObjectPropertyScopeGlobal; + outputDeviceAddress.mElement = kAudioObjectPropertyElementMaster; + + result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this); + ERR_FAIL_COND_V(result != noErr, FAILED); +#endif + + return initDevice(); +}; + +Error AudioDriverCoreAudio::reopen() { + bool restart = false; + + lock(); + + if (active) { + restart = true; + } + + Error err = finishDevice(); + if (err != OK) { + ERR_PRINT("finishDevice failed"); + unlock(); + return err; + } + + err = initDevice(); + if (err != OK) { + ERR_PRINT("initDevice failed"); + unlock(); + return err; + } + + if (restart) { + start(); + } + + unlock(); + + return OK; +} + +OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, UInt32 inNumberFrames, + AudioBufferList *ioData) { + + AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon; + + if (!ad->active || !ad->try_lock()) { + for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) { + AudioBuffer *abuf = &ioData->mBuffers[i]; + zeromem(abuf->mData, abuf->mDataByteSize); + }; + return 0; + }; + + for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) { + + AudioBuffer *abuf = &ioData->mBuffers[i]; + int frames_left = inNumberFrames; + int16_t *out = (int16_t *)abuf->mData; + + while (frames_left) { + + int frames = MIN(frames_left, ad->buffer_frames); + ad->audio_server_process(frames, ad->samples_in.ptr()); + + for (int j = 0; j < frames * ad->channels; j++) { + + out[j] = ad->samples_in[j] >> 16; + } + + frames_left -= frames; + out += frames * ad->channels; + }; + }; + + ad->unlock(); + + return 0; +}; + +void AudioDriverCoreAudio::start() { + if (!active) { + OSStatus result = AudioOutputUnitStart(audio_unit); + if (result != noErr) { + ERR_PRINT("AudioOutputUnitStart failed"); + } else { + active = true; + } + } +}; + +int AudioDriverCoreAudio::get_mix_rate() const { + return mix_rate; +}; + +AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const { + return get_speaker_mode_by_total_channels(channels); +}; + +void AudioDriverCoreAudio::lock() { + if (mutex) + mutex->lock(); +}; + +void AudioDriverCoreAudio::unlock() { + if (mutex) + mutex->unlock(); +}; + +bool AudioDriverCoreAudio::try_lock() { + if (mutex) + return mutex->try_lock() == OK; + return true; +} + +void AudioDriverCoreAudio::finish() { + OSStatus result; + + finishDevice(); + +#ifdef OSX_ENABLED + result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this); + if (result != noErr) { + ERR_PRINT("AudioObjectRemovePropertyListener failed"); + } +#endif + + AURenderCallbackStruct callback; + zeromem(&callback, sizeof(AURenderCallbackStruct)); + result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback)); + if (result != noErr) { + ERR_PRINT("AudioUnitSetProperty failed"); + } + + if (mutex) { + memdelete(mutex); + mutex = NULL; + } +}; + +AudioDriverCoreAudio::AudioDriverCoreAudio() { + active = false; + mutex = NULL; + + mix_rate = 0; + channels = 2; + + buffer_size = 0; + buffer_frames = 0; + + samples_in.clear(); +}; + +AudioDriverCoreAudio::~AudioDriverCoreAudio(){}; + +#endif diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h new file mode 100644 index 0000000000..33b3ba93ec --- /dev/null +++ b/drivers/coreaudio/audio_driver_coreaudio.h @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* audio_driver_coreaudio.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifdef COREAUDIO_ENABLED + +#ifndef AUDIO_DRIVER_COREAUDIO_H +#define AUDIO_DRIVER_COREAUDIO_H + +#include "servers/audio_server.h" + +#include <AudioUnit/AudioUnit.h> +#ifdef OSX_ENABLED +#include <CoreAudio/AudioHardware.h> +#endif + +class AudioDriverCoreAudio : public AudioDriver { + + AudioComponentInstance audio_unit; +#ifdef OSX_ENABLED + AudioObjectPropertyAddress outputDeviceAddress; +#endif + bool active; + Mutex *mutex; + + int mix_rate; + unsigned int channels; + unsigned int buffer_frames; + unsigned int buffer_size; + + Vector<int32_t> samples_in; + + static OSStatus output_callback(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, UInt32 inNumberFrames, + AudioBufferList *ioData); + + Error initDevice(); + Error finishDevice(); + +public: + const char *get_name() const { + return "CoreAudio"; + }; + + virtual Error init(); + virtual void start(); + virtual int get_mix_rate() const; + virtual SpeakerMode get_speaker_mode() const; + virtual void lock(); + virtual void unlock(); + virtual void finish(); + + bool try_lock(); + Error reopen(); + + AudioDriverCoreAudio(); + ~AudioDriverCoreAudio(); +}; + +#endif + +#endif diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 98a9211d0c..eaf0b06664 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "rasterizer_scene_gles3.h" - +#include "math_funcs.h" #include "os/os.h" #include "project_settings.h" #include "rasterizer_canvas_gles3.h" @@ -799,12 +799,12 @@ void RasterizerSceneGLES3::environment_set_sky(RID p_env, RID p_sky) { env->sky = p_sky; } -void RasterizerSceneGLES3::environment_set_sky_scale(RID p_env, float p_scale) { +void RasterizerSceneGLES3::environment_set_sky_custom_fov(RID p_env, float p_scale) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); - env->sky_scale = p_scale; + env->sky_custom_fov = p_scale; } void RasterizerSceneGLES3::environment_set_bg_color(RID p_env, const Color &p_color) { @@ -2319,7 +2319,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G } } -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) { +void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) { if (!p_sky) return; @@ -2365,16 +2365,28 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C //sky uv vectors float vw, vh, zn; - p_projection.get_viewport_size(vw, vh); - zn = p_projection.get_z_near(); + CameraMatrix camera; + + if (p_custom_fov) { + + float near_plane = p_projection.get_z_near(); + float far_plane = p_projection.get_z_far(); + float aspect = p_projection.get_aspect(); + + camera.set_perspective(p_custom_fov, aspect, near_plane, far_plane); - float scale = p_scale; + } else { + camera = p_projection; + } + + camera.get_viewport_size(vw, vh); + zn = p_projection.get_z_near(); for (int i = 0; i < 4; i++) { Vector3 uv = vertices[i * 2 + 1]; - uv.x = (uv.x * 2.0 - 1.0) * vw * scale; - uv.y = -(uv.y * 2.0 - 1.0) * vh * scale; + uv.x = (uv.x * 2.0 - 1.0) * vw; + uv.y = -(uv.y * 2.0 - 1.0) * vh; uv.z = -zn; vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized(); vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z; @@ -2522,9 +2534,10 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform float sign = li->light_ptr->negative ? -1 : 1; Color linear_col = li->light_ptr->color.to_linear(); - ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; - ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; - ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; + //compensate normalized diffuse range by multiplying by PI + ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; + ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; + ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; ubo_data.light_color_energy[3] = 0; //omni, keep at 0 @@ -2662,9 +2675,9 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c float sign = li->light_ptr->negative ? -1 : 1; Color linear_col = li->light_ptr->color.to_linear(); - ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; - ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; - ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; + ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; + ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; + ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; ubo_data.light_color_energy[3] = 0; Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin); @@ -2748,9 +2761,9 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c float sign = li->light_ptr->negative ? -1 : 1; Color linear_col = li->light_ptr->color.to_linear(); - ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; - ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; - ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; + ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; + ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; + ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI; ubo_data.light_color_energy[3] = 0; Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin); @@ -4258,7 +4271,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, false, env->sky_scale, env->bg_energy); + _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_custom_fov, env->bg_energy); } //_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 04cb3597da..28a5cef0ee 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -352,7 +352,7 @@ public: VS::EnvironmentBG bg_mode; RID sky; - float sky_scale; + float sky_custom_fov; Color bg_color; float bg_energy; @@ -435,7 +435,7 @@ public: Environment() { bg_mode = VS::ENV_BG_CLEAR_COLOR; - sky_scale = 1.0; + sky_custom_fov = 0.0; bg_energy = 1.0; sky_ambient = 0; ambient_energy = 1.0; @@ -520,7 +520,7 @@ public: virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg); virtual void environment_set_sky(RID p_env, RID p_sky); - virtual void environment_set_sky_scale(RID p_env, float p_scale); + virtual void environment_set_sky_custom_fov(RID p_env, float p_scale); virtual void environment_set_bg_color(RID p_env, const Color &p_color); virtual void environment_set_bg_energy(RID p_env, float p_energy); virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer); @@ -811,7 +811,7 @@ public: _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass); - 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 _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, 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_transform, bool p_use_shadows); diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 9a5b53c84b..91159e3381 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -700,9 +700,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { /** CANVAS ITEM SHADER **/ - actions[VS::SHADER_CANVAS_ITEM].renames["SRC_VERTEX"] = "vertex"; actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy"; - actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX_COLOR"] = "vertex_color"; actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp"; actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize"; @@ -711,6 +709,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] == "extra_matrix"; actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time"; actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass"; + actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom"; actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal"; @@ -720,6 +719,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE"] = "color_texture"; actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size"; + actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL_TEXTURE"] = "normal_texture"; actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_UV"] = "screen_uv"; actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_TEXTURE"] = "screen_texture"; actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size"; @@ -798,6 +798,13 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side"; actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; + //for light + actions[VS::SHADER_SPATIAL].renames["VIEW"] = "view"; + actions[VS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color"; + actions[VS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation"; + actions[VS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light"; + actions[VS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; + actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; actions[VS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n"; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index bf8eaf601d..731d6968ce 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -105,13 +105,16 @@ VERTEX_SHADER_GLOBALS void main() { - vec4 vertex_color = color_attrib; + vec4 color = color_attrib; #ifdef USE_INSTANCING mat4 extra_matrix2 = extra_matrix * transpose(mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0))); - vertex_color*=instance_color; + color*=instance_color; + vec4 instance_custom = instance_custom_data; + #else mat4 extra_matrix2 = extra_matrix; + vec4 instance_custom = vec4(0.0); #endif #ifdef USE_TEXTURE_RECT @@ -135,7 +138,7 @@ void main() { //compute h and v frames and adjust UV interp for animation int total_frames = h_frames * v_frames; - int frame = min(int(float(total_frames) *instance_custom_data.z),total_frames-1); + int frame = min(int(float(total_frames) *instance_custom.z),total_frames-1); float frame_w = 1.0/float(h_frames); float frame_h = 1.0/float(v_frames); uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames); @@ -146,7 +149,6 @@ void main() { #define extra_matrix extra_matrix2 { - vec2 src_vtx=outvec.xy; VERTEX_SHADER_CODE @@ -165,7 +167,7 @@ VERTEX_SHADER_CODE #undef extra_matrix - color_interp = vertex_color; + color_interp = color; #ifdef USE_PIXEL_SNAP diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 25115bc18a..41d5ef5bc9 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1,5 +1,6 @@ [vertex] +#define M_PI 3.14159265359 /* from VisualServer: @@ -166,7 +167,7 @@ out vec4 specular_light_interp; void light_compute(vec3 N, vec3 L,vec3 V, vec3 light_color,float roughness,inout vec3 diffuse, inout vec3 specular) { float dotNL = max(dot(N,L), 0.0 ); - diffuse += dotNL * light_color; + diffuse += dotNL * light_color / M_PI; if (roughness > 0.0) { @@ -589,7 +590,7 @@ vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) { norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); // we need to lie the derivatives (normg) and assume that DP side is always the same - // to get proper texure filtering + // to get proper texture filtering vec2 normg=norm.xy; if (norm.z>0.0) { norm.y=0.5-norm.y+0.5; @@ -894,6 +895,10 @@ void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 at #if defined(USE_LIGHT_SHADER_CODE) //light is written by the light shader + vec3 normal = N; + vec3 albedo = diffuse_color; + vec3 light = L; + vec3 view = V; LIGHT_SHADER_CODE @@ -916,6 +921,7 @@ LIGHT_SHADER_CODE #elif defined(DIFFUSE_OREN_NAYAR) { + // see http://mimosa-pudica.net/improved-oren-nayar.html float LdotV = dot(L, V); float NdotL = dot(L, N); float NdotV = dot(N, V); @@ -924,10 +930,10 @@ LIGHT_SHADER_CODE float t = mix(1.0, max(NdotL, NdotV), step(0.0, s)); float sigma2 = roughness * roughness; - vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33)); + vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) ); float B = 0.45 * sigma2 / (sigma2 + 0.09); - light_amount = max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI; + light_amount = dotNL * (A + vec3(B) * s / t) / M_PI; } #elif defined(DIFFUSE_TOON) @@ -941,13 +947,13 @@ LIGHT_SHADER_CODE vec3 H = normalize(V + L); float NoL = max(0.0,dot(N, L)); - float VoH = max(0.0,dot(L, H)); + float LoH = max(0.0,dot(L, H)); float NoV = max(0.0,dot(N, V)); - float FD90 = 0.5 + 2.0 * VoH * VoH * roughness; - float FdV = 1.0 + (FD90 - 1.0) * pow( 1.0 - NoV, 5.0 ); - float FdL = 1.0 + (FD90 - 1.0) * pow( 1.0 - NoL, 5.0 ); - light_amount = ( (1.0 / M_PI) * FdV * FdL ); + float FD90 = 0.5 + 2.0 * LoH * LoH * roughness; + float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(NoV); + float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(NoL); + light_amount = ( (1.0 / M_PI) * FdV * FdL ) * NoL; /* float energyBias = mix(roughness, 0.0, 0.5); float energyFactor = mix(roughness, 1.0, 1.0 / 1.51); @@ -960,11 +966,11 @@ LIGHT_SHADER_CODE } #else //lambert - light_amount = dotNL; + light_amount = dotNL / M_PI; #endif #if defined(TRANSMISSION_USED) - diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission) * attenuation; + diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(M_PI),transmission) * attenuation; #else diffuse += light_color * diffuse_color * light_amount * attenuation; #endif @@ -1939,18 +1945,19 @@ FRAGMENT_SHADER_CODE //simplify for toon, as specular_light *= specular * metallic * albedo * 2.0; #else - //brdf approximation (Lazarov 2013) - float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); - vec3 dielectric = vec3(0.034) * specular * 2.0; //energy conservation - vec3 f0 = mix(dielectric, albedo, metallic); + vec3 dielectric = vec3(0.034) * specular * 2.0; + vec3 specular_color = mix(dielectric, albedo, metallic); + // Environment brdf approximation (Lazarov 2013) + // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04); vec4 r = roughness * c0 + c1; + float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); float a004 = min( r.x * r.x, exp2( -9.28 * ndotv ) ) * r.x + r.y; - vec2 brdf = vec2( -1.04, 1.04 ) * a004 + r.zw; + vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; - specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0; + specular_light *= AB.x * specular_color + AB.y; #endif } diff --git a/drivers/png/SCsub b/drivers/png/SCsub index 6684e36b20..39480351a6 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -5,7 +5,7 @@ Import('env') env_png = env.Clone() # Thirdparty source files -if (env['builtin_libpng'] != 'no'): +if env['builtin_libpng']: thirdparty_dir = "#thirdparty/libpng/" thirdparty_sources = [ "png.c", |