Browse Source

Merge branch 'master' into vertexdeclaration

Lasse Öörni 9 years ago
parent
commit
c003af1114

+ 0 - 1
.travis.yml

@@ -352,7 +352,6 @@ env:
     - MAKEFILE=1    URHO3D_LIB_TYPE=SHARED URHO3D_DEPLOYMENT_TARGET=generic
     - XCODE=1       URHO3D_LIB_TYPE=STATIC CMAKE_OSX_DEPLOYMENT_TARGET=10.11 SF_DEFAULT=mac:OSX-64bit-STATIC.tar.gz
     - XCODE=1       URHO3D_LIB_TYPE=SHARED CMAKE_OSX_DEPLOYMENT_TARGET=10.11
-    - XCODE=1 IOS=1 URHO3D_LIB_TYPE=STATIC IPHONEOS_DEPLOYMENT_TARGET=9.1 sdk=iphonesimulator URHO3D_64BIT=0
     - XCODE=1 IOS=1 URHO3D_LIB_TYPE=STATIC IPHONEOS_DEPLOYMENT_TARGET=9.1 sdk=iphonesimulator
 matrix:
   fast_finish: true

+ 2 - 5
CMake/Modules/Urho3D-CMake-common.cmake

@@ -1028,11 +1028,8 @@ macro (setup_target)
         unset (TARGET_PROPERTIES)
     endif ()
 
-    if (DEFINED ENV{TRAVIS})
-        # Workaround to avoid technical error due to Travis CI build time limit
-        add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND rake ci_timeup WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-    else ()
-        # Workaround CMake/Xcode generator bug where it always appends '/build' path element to SYMROOT attribute and as such the items in Products are always rendered as red in the Xcode IDE as if they are not yet built
+    # Workaround CMake/Xcode generator bug where it always appends '/build' path element to SYMROOT attribute and as such the items in Products are always rendered as red in the Xcode IDE as if they are not yet built
+    if (NOT DEFINED ENV{TRAVIS})
         if (XCODE AND NOT CMAKE_PROJECT_NAME MATCHES ^Urho3D-ExternalProject-)
             file (MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/build)
             get_target_property (LOCATION ${TARGET_NAME} LOCATION)

+ 1 - 1
CMakeLists.txt

@@ -83,7 +83,7 @@ set (DEST_PKGCONFIG_DIR lib${LIB_SUFFIX}/pkgconfig)
 file (GLOB APP_SCRIPTS ${CMAKE_SOURCE_DIR}/bin/*${SCRIPT_EXT})
 install (PROGRAMS ${APP_SCRIPTS} DESTINATION ${DEST_RUNTIME_DIR})   # DEST_RUNTIME_DIR variable is set by the set_output_directories() macro call in the Urho3D-CMake-common module
 # Install resource directories required by applications built with Urho3D library
-install (DIRECTORY ${CMAKE_SOURCE_DIR}/bin/CoreData ${CMAKE_SOURCE_DIR}/bin/Data DESTINATION ${DEST_SHARE_DIR}/Resources)
+install (DIRECTORY ${CMAKE_SOURCE_DIR}/bin/Autoload ${CMAKE_SOURCE_DIR}/bin/CoreData ${CMAKE_SOURCE_DIR}/bin/Data DESTINATION ${DEST_SHARE_DIR}/Resources)
 # Install CMake modules and toolchains provided by and for Urho3D
 install (DIRECTORY ${CMAKE_SOURCE_DIR}/CMake/ DESTINATION ${DEST_SHARE_DIR}/CMake)    # Note: the trailing slash is significant
 # Install CMake build scripts

+ 22 - 25
Rakefile

@@ -350,14 +350,11 @@ task :ci do
     system 'rake ci_push_bindings' or abort
     next
   end
-  # Enable more granular timeup check for Xcode
-  system 'touch enabled_time_check.log' if ENV['XCODE']
-  if !system "bash -c 'rake make'"
+  if !wait_for_block { system "bash -c 'rake make'" }
     abort 'Failed to build Urho3D library' unless File.exists?('already_timeup.log')
     $stderr.puts "Skipped the rest of the CI processes due to insufficient time"
     next
   end
-  File.delete 'enabled_time_check.log' if ENV['XCODE']
   if ENV['URHO3D_TESTING'] && !timeup
     # Multi-config CMake generators use different test target name than single-config ones for no good reason
     test = "rake make target=#{ENV['OS'] || ENV['XCODE'] ? 'RUN_TESTS' : 'test'}"
@@ -370,13 +367,11 @@ task :ci do
   unless ENV['CI'] && (ENV['IOS'] || ENV['WEB']) && ENV['PACKAGE_UPLOAD'] || ENV['XCODE_64BIT_ONLY'] || timeup
     # Staged-install Urho3D SDK when on Travis-CI; normal install when on AppVeyor
     ENV['DESTDIR'] = ENV['HOME'] || Dir.home unless ENV['APPVEYOR']
-    system 'touch enabled_time_check.log' if ENV['XCODE']
-    if wait_for_block("Installing Urho3D SDK to #{ENV['DESTDIR'] ? "#{ENV['DESTDIR']}/usr/local" : 'default system-wide location'}...") { system "bash -c 'rake make target=install >/dev/null'"; Thread.current[:exit_code] = $?.exitstatus } != 0
+    if !wait_for_block("Installing Urho3D SDK to #{ENV['DESTDIR'] ? "#{ENV['DESTDIR']}/usr/local" : 'default system-wide location'}...") { system "bash -c 'rake make target=install >/dev/null'" }
       abort 'Failed to install Urho3D SDK' unless File.exists?('already_timeup.log')
       $stderr.puts "Skipped the rest of the CI processes due to insufficient time"
       next
     end
-    File.delete 'enabled_time_check.log' if ENV['XCODE']
     # Alternate to use in-the-source build tree for test coverage
     ENV['build_tree'] = '.' unless ENV['APPVEYOR']
     # Ensure the following variables are auto-discovered during scaffolding test
@@ -394,7 +389,7 @@ task :ci do
     next if timeup
     # Second test - create a new project on the fly that uses newly built Urho3D library in the build tree
     Dir.chdir scaffolding "#{ENV['APPVEYOR'] ? '' : '../Build/'}UsingBuildTree" do
-      puts "\nConfiguring downstream project using Urho3D library in its build tree...\n\n"; $stdout.flush
+      puts "Configuring downstream project using Urho3D library in its build tree...\n\n"; $stdout.flush
       system "bash -c 'rake cmake #{generator} URHO3D_HOME=#{ENV['APPVEYOR'] ? '../../Build' : '..'} URHO3D_LUA=1 && rake make #{test}'" or abort 'Failed to configure/build/test temporary downstream project using Urho3D as external library'
     end
   end
@@ -651,14 +646,8 @@ task :ci_timer do
   timeup
 end
 
-# Usage: NOT Intended to be used manually
-desc 'Check if the time is up when the time check is enabled'
-task :ci_timeup do
-  abort "Time up!" if File.exists?('enabled_time_check.log') && timeup(true)
-end
-
 # Always call this function last in the multiple conditional check so that the checkpoint message does not being echoed unnecessarily
-def timeup quiet = false
+def timeup quiet = false, cutoff_time = 40.0
   unless File.exists?('start_time.log')
     system 'touch start_time.log split_time.log'
     return nil
@@ -670,7 +659,7 @@ def timeup quiet = false
     system 'touch split_time.log'
     puts "\n=== elapsed time: #{elapsed_time.to_i} minutes #{((elapsed_time - elapsed_time.to_i) * 60.0).round} seconds, lap time: #{lap_time.to_i} minutes #{((lap_time - lap_time.to_i) * 60.0).round} seconds ===\n\n" unless File.exists?('already_timeup.log'); $stdout.flush
   end
-  return system('touch already_timeup.log') if elapsed_time > 40.0
+  return system('touch already_timeup.log') if elapsed_time > cutoff_time
 end
 
 def scaffolding dir, project = 'Scaffolding', target = 'Main'
@@ -831,24 +820,32 @@ EOF") { |stdout| echo = false; while output = stdout.gets do if echo && /#\s#/ !
   end
 end
 
-# Usage: wait_for_block("This is a long function call...") { Thread.current[:exit_code] = call_a_func } or abort
-#        wait_for_block("This is a long system call...") { system "do_something"; Thread.current[:exit_code] = $?.exitstatus } or abort
-def wait_for_block comment = '', retries = -1, retry_interval = 60, exit_code_sym = 'exit_code', &block
+# Usage: wait_for_block('This is a long function call...') { call_a_func } or abort
+#        wait_for_block('This is a long system call...') { system 'do_something' } or abort
+def wait_for_block comment = '', retries = -1, retry_interval = 60
+  # When not using Xcode, execute the code block in full speed
+  unless ENV['XCODE']
+    puts comment; $stdout.flush
+    return yield
+  end
+
   # Wait until the code block is completed or it is killed externally by user via Ctrl+C or when it exceeds the number of retries (if the retries parameter is provided)
-  thread = Thread.new &block
+  thread = Thread.new { rc = yield; Thread.main.wakeup; rc }
+  thread.priority = 1   # Make the worker thread has higher priority than the main thread
   str = comment
   retries = retries * 60 / retry_interval unless retries == -1
-  until retries == 0
-    if thread.status == false
-      thread.join
+  until thread.status == false
+    if retries == 0 || timeup(true, 45.0)
+      thread.kill   # TODO: also kill the child subproceses spawned by the worker thread
       break
     end
     print str; str = '.'; $stdout.flush   # Flush the standard output stream in case it is buffered to prevent Travis-CI into thinking that the build/test has stalled
-    sleep retry_interval
     retries -= 1 if retries > 0
+    sleep retry_interval
   end
   puts "\n" if str == '.'; $stdout.flush
-  return retries == 0 ? nil : (exit_code_sym ? thread[exit_code_sym] : 0)
+  thread.join
+  return thread.value
 end
 
 def append_new_release release, filename = '../urho3d.github.io/_data/urho3d.json'

+ 36 - 0
Source/Urho3D/AngelScript/ScriptFile.cpp

@@ -769,6 +769,42 @@ void ScriptFile::SetParameters(asIScriptContext* context, asIScriptFunction* fun
                     context->SetArgObject(i, (void*)&parameters[i].GetString());
                     break;
 
+                case VAR_VARIANTMAP:
+                    context->SetArgObject(i, (void*)&parameters[i].GetVariantMap());
+                    break;
+
+                case VAR_INTRECT:
+                    context->SetArgObject(i, (void*)&parameters[i].GetIntRect());
+                    break;
+
+                case VAR_INTVECTOR2:
+                    context->SetArgObject(i, (void*)&parameters[i].GetIntVector2());
+                    break;
+
+                case VAR_COLOR:
+                    context->SetArgObject(i, (void*)&parameters[i].GetColor());
+                    break;
+
+                case VAR_MATRIX3:
+                    context->SetArgObject(i, (void*)&parameters[i].GetMatrix3());
+                    break;
+
+                case VAR_MATRIX3X4:
+                    context->SetArgObject(i, (void*)&parameters[i].GetMatrix3x4());
+                    break;
+
+                case VAR_MATRIX4:
+                    context->SetArgObject(i, (void*)&parameters[i].GetMatrix4());
+                    break;
+
+                case VAR_RESOURCEREF:
+                    context->SetArgObject(i, (void*)&parameters[i].GetResourceRef());
+                    break;
+
+                case VAR_RESOURCEREFLIST:
+                    context->SetArgObject(i, (void*)&parameters[i].GetResourceRefList());
+                    break;
+
                 case VAR_VOIDPTR:
                     context->SetArgObject(i, parameters[i].GetVoidPtr());
                     break;

+ 3 - 3
Source/Urho3D/Graphics/Light.h

@@ -195,7 +195,7 @@ public:
     void SetShadowCascade(const CascadeParameters& parameters);
     /// Set shadow map focusing parameters.
     void SetShadowFocus(const FocusParameters& parameters);
-    /// Set shadow intensity between 0.0 - 1.0. 0.0 (the default) gives fully dark shadows.
+    /// Set light intensity in shadow between 0.0 - 1.0. 0.0 (the default) gives fully dark shadows.
     void SetShadowIntensity(float intensity);
     /// Set shadow resolution between 0.25 - 1.0. Determines the shadow map to use.
     void SetShadowResolution(float resolution);
@@ -251,7 +251,7 @@ public:
     /// Return shadow map focus parameters.
     const FocusParameters& GetShadowFocus() const { return shadowFocus_; }
 
-    /// Return shadow intensity.
+    /// Return light intensity in shadow.
     float GetShadowIntensity() const { return shadowIntensity_; }
 
     /// Return shadow resolution.
@@ -338,7 +338,7 @@ private:
     float fadeDistance_;
     /// Shadow fade start distance.
     float shadowFadeDistance_;
-    /// Shadow intensity.
+    /// Light intensity in shadow.
     float shadowIntensity_;
     /// Shadow resolution.
     float shadowResolution_;

+ 3 - 0
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -2468,6 +2468,9 @@ void Graphics::Restore()
             URHO3D_LOGERROR("OpenGL 2.0 is required");
             return;
         }
+
+        // Enable seamless cubemap if possible
+        glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
 #endif
 
         // Set up texture data read/write alignment. It is important that this is done before uploading any texture data

+ 60 - 52
Source/Urho3D/Graphics/Renderer.cpp

@@ -639,60 +639,17 @@ void Renderer::Update(float timeStep)
     for (unsigned i = viewports_.Size() - 1; i < viewports_.Size(); --i)
         QueueViewport(0, viewports_[i]);
 
-    // Gather other render surfaces that are autoupdated
-    SendEvent(E_RENDERSURFACEUPDATE);
-
-    // Process gathered views. This may queue further views (render surfaces that are only updated when visible)
-    for (unsigned i = 0; i < queuedViewports_.Size(); ++i)
-    {
-        WeakPtr<RenderSurface>& renderTarget = queuedViewports_[i].first_;
-        WeakPtr<Viewport>& viewport = queuedViewports_[i].second_;
-
-        // Null pointer means backbuffer view. Differentiate between that and an expired rendersurface
-        if ((renderTarget.NotNull() && renderTarget.Expired()) || viewport.Expired())
-            continue;
-
-        // (Re)allocate the view structure if necessary
-        if (!viewport->GetView() || resetViews_)
-            viewport->AllocateView();
-
-        View* view = viewport->GetView();
-        assert(view);
-        // Check if view can be defined successfully (has either valid scene, camera and octree, or no scene passes)
-        if (!view->Define(renderTarget, viewport))
-            continue;
+    // Update main viewports. This may queue further views
+    unsigned numMainViewports = queuedViewports_.Size();
+    for (unsigned i = 0; i < numMainViewports; ++i)
+        UpdateQueuedViewport(i);
 
-        views_.Push(WeakPtr<View>(view));
-
-        const IntRect& viewRect = viewport->GetRect();
-        Scene* scene = viewport->GetScene();
-        if (!scene)
-            continue;
-
-        Octree* octree = scene->GetComponent<Octree>();
-
-        // Update octree (perform early update for drawables which need that, and reinsert moved drawables.)
-        // However, if the same scene is viewed from multiple cameras, update the octree only once
-        if (!updatedOctrees_.Contains(octree))
-        {
-            frame_.camera_ = viewport->GetCamera();
-            frame_.viewSize_ = viewRect.Size();
-            if (frame_.viewSize_ == IntVector2::ZERO)
-                frame_.viewSize_ = IntVector2(graphics_->GetWidth(), graphics_->GetHeight());
-            octree->Update(frame_);
-            updatedOctrees_.Insert(octree);
-
-            // Set also the view for the debug renderer already here, so that it can use culling
-            /// \todo May result in incorrect debug geometry culling if the same scene is drawn from multiple viewports
-            DebugRenderer* debug = scene->GetComponent<DebugRenderer>();
-            if (debug && viewport->GetDrawDebug())
-                debug->SetView(viewport->GetCamera());
-        }
+    // Gather queued & autoupdated render surfaces
+    SendEvent(E_RENDERSURFACEUPDATE);
 
-        // Update view. This may queue further views. View will send update begin/end events once its state is set
-        ResetShadowMapAllocations(); // Each view can reuse the same shadow maps
-        view->Update(frame_);
-    }
+    // Update viewports that were added as result of the event above
+    for (unsigned i = numMainViewports; i < queuedViewports_.Size(); ++i)
+        UpdateQueuedViewport(i);
 
     queuedViewports_.Clear();
     resetViews_ = false;
@@ -1471,6 +1428,57 @@ const Rect& Renderer::GetLightScissor(Light* light, Camera* camera)
     }
 }
 
+void Renderer::UpdateQueuedViewport(unsigned index)
+{
+    WeakPtr<RenderSurface>& renderTarget = queuedViewports_[index].first_;
+    WeakPtr<Viewport>& viewport = queuedViewports_[index].second_;
+
+    // Null pointer means backbuffer view. Differentiate between that and an expired rendersurface
+    if ((renderTarget.NotNull() && renderTarget.Expired()) || viewport.Expired())
+        return;
+
+    // (Re)allocate the view structure if necessary
+    if (!viewport->GetView() || resetViews_)
+        viewport->AllocateView();
+
+    View* view = viewport->GetView();
+    assert(view);
+    // Check if view can be defined successfully (has either valid scene, camera and octree, or no scene passes)
+    if (!view->Define(renderTarget, viewport))
+        return;
+
+    views_.Push(WeakPtr<View>(view));
+
+    const IntRect& viewRect = viewport->GetRect();
+    Scene* scene = viewport->GetScene();
+    if (!scene)
+        return;
+
+    Octree* octree = scene->GetComponent<Octree>();
+
+    // Update octree (perform early update for drawables which need that, and reinsert moved drawables.)
+    // However, if the same scene is viewed from multiple cameras, update the octree only once
+    if (!updatedOctrees_.Contains(octree))
+    {
+        frame_.camera_ = viewport->GetCamera();
+        frame_.viewSize_ = viewRect.Size();
+        if (frame_.viewSize_ == IntVector2::ZERO)
+            frame_.viewSize_ = IntVector2(graphics_->GetWidth(), graphics_->GetHeight());
+        octree->Update(frame_);
+        updatedOctrees_.Insert(octree);
+
+        // Set also the view for the debug renderer already here, so that it can use culling
+        /// \todo May result in incorrect debug geometry culling if the same scene is drawn from multiple viewports
+        DebugRenderer* debug = scene->GetComponent<DebugRenderer>();
+        if (debug && viewport->GetDrawDebug())
+            debug->SetView(viewport->GetCamera());
+    }
+
+    // Update view. This may queue further views. View will send update begin/end events once its state is set
+    ResetShadowMapAllocations(); // Each view can reuse the same shadow maps
+    view->Update(frame_);
+}
+
 void Renderer::PrepareViewRender()
 {
     ResetScreenBufferAllocations();

+ 3 - 1
Source/Urho3D/Graphics/Renderer.h

@@ -411,6 +411,8 @@ private:
     void CreateInstancingBuffer();
     /// Create point light shadow indirection texture data.
     void SetIndirectionTextureData();
+    /// Update a queued viewport for rendering.
+    void UpdateQueuedViewport(unsigned index);
     /// Prepare for rendering of a new view.
     void PrepareViewRender();
     /// Remove unused occlusion and screen buffers.
@@ -429,7 +431,7 @@ private:
     void HandleScreenMode(StringHash eventType, VariantMap& eventData);
     /// Handle render update event.
     void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
-    /// Blur the shadow map
+    /// Blur the shadow map.
     void BlurShadowMap(View* view, Texture2D* shadowMap);
 
     /// Graphics subsystem.

+ 51 - 62
bin/CoreData/Shaders/GLSL/IBL.glsl

@@ -1,39 +1,40 @@
 #line 10001
 #ifdef COMPILEPS
-    #define PBRFAST
-
     vec3 ImportanceSampleSimple(in vec2 Xi, in float roughness, in vec3 T, in vec3 B, in vec3 N)
     {
-      float a = roughness * roughness;
-      mat3 tbn = mat3(T, B, N);
-      #ifdef PBRFAST
-          const float blurFactor = 0.0;
-      #else
-          const float blurFactor = 5.0;
-      #endif
-      vec3 Xi3 = mix(vec3(0,0,1), normalize(vec3(Xi.xy * blurFactor , 1)), a);
-      vec3 XiWS = tbn * Xi3;
-      return normalize(N + XiWS);
+        float a = roughness * roughness;
+        mat3 tbn = mat3(T, B, N);
+        #ifdef IBLFAST
+            const float blurFactor = 0.0;
+        #else
+            const float blurFactor = 5.0;
+        #endif
+        vec2 xx = Xi.xy * blurFactor;
+        xx = xx - 1.0 * trunc(xx/1.0); // hlsl style modulo
+        vec3 Xi3 = mix(vec3(0,0,1), normalize(vec3(xx, 1.0)), a);
+        vec3 XiWS = tbn * Xi3;
+        return normalize(N + XiWS);
     }
 
     // Karis '13
-    vec3 ImportanceSampleGGX(in vec2 Xi, in float roughness, in vec3 N)
+    vec3 ImportanceSampleGGX(in vec2 Xi, in float roughness, in vec3 T, in vec3 B, in vec3 N)
     {
-       float a = roughness * roughness;
-       float Phi = 2.0 * M_PI * Xi.x;
-       float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
-       float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
-       vec3 H = vec3(0,0,0);
-       H.x = SinTheta * cos(Phi);
-       H.y = SinTheta * sin(Phi);
-       H.z = CosTheta;
-
-       vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
-       vec3 TangentX = normalize(cross(UpVector, N));
-       vec3 TangentY = cross(N, TangentX);
-       // Tangent to world space
-       return TangentX * H.x + TangentY * H.y + N * H.z;
+        float a = roughness * roughness;
+        float Phi = 2.0 * M_PI * Xi.x;
+        float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
+        float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
+        vec3 H = vec3(0,0,0);
+        H.x = SinTheta * cos(Phi);
+        H.y = SinTheta * sin(Phi);
+        H.z = CosTheta;
+
+        vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+        vec3 TangentX = normalize(cross(UpVector, N));
+        vec3 TangentY = cross(N, TangentX);
+        // Tangent to world space
+        return TangentX * H.x + TangentY * H.y + N * H.z;
     }
+
     /// Determine reflection vector based on surface roughness, rougher uses closer to the normal and smoother uses closer to the reflection vector
     ///     normal: surface normal
     ///     reflection: vector of reflection off of the surface
@@ -45,8 +46,14 @@
         return mix(normal, reflection, lerpFactor);
     }
 
-    #define IMPORTANCE_SAMPLES 16
-    vec2 IMPORTANCE_KERNEL[IMPORTANCE_SAMPLES] = vec2[] (
+    #ifdef IBLFAST
+        #define IMPORTANCE_SAMPLES 1
+    #else
+        #define IMPORTANCE_SAMPLES 4
+    #endif
+
+    #define IMPORTANCE_KERNEL_SIZE 16
+    vec2 IMPORTANCE_KERNEL[IMPORTANCE_KERNEL_SIZE] = vec2[] (
         vec2(-0.0780436, 0.0558389),
         vec2(0.034318, -0.0635879),
         vec2(0.00230821, 0.0807279),
@@ -110,15 +117,12 @@
                 float ndh = clamp(abs(dot(N, H)), 0.0, 1.0);
                 float ndl = clamp(abs(dot(N, L)), 0.0, 1.0);
 
-                //if (ndl > 0.0)
-                {
-                    vec3 sampledColor = textureLod(sZoneCubeMap, L, mipLevel).rgb;
+                vec3 sampledColor = textureLod(sZoneCubeMap, L, mipLevel).rgb;
 
-                    vec3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
-                    vec3 lightTerm = sampledColor;
+                vec3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
+                vec3 lightTerm = sampledColor;
 
-                    diffuseFactor = lightTerm * diffuseTerm;
-                }
+                diffuseFactor = lightTerm * diffuseTerm;
             }
 
             {
@@ -134,30 +138,15 @@
                 float ndh = clamp(abs(dot(N, H)), 0.0, 1.0);
                 float ndl = clamp(abs(dot(N, L)), 0.0, 1.0);
 
-                vec3 specularTerm = vec3(0,0,0);
-                float pdf = 1.0;
-                vec3 lightTerm = vec3(0,0,0);
-
-                if (ndl > 0.05)
-                {
-                    vec3 fresnelTerm = Fresnel(specColor, vdh);
-                    float distTerm = 1.0; // Optimization, this term is mathematically cancelled out  -- Distribution(ndh, roughness);
-                    float visTerm = Visibility(ndl, ndv, rough);
-
-                    lightTerm = sampledColor * ndl;
-                    specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv);
-                    pdf = ImportanceSamplePDF(distTerm, ndh, vdh);
-                }
-                else // reduce artifacts at extreme grazing angles
-                {
-                    vec3 fresnelTerm = Fresnel(specColor, vdh);
-                    float distTerm = 1.0;//Distribution(ndh_, roughness);
-                    float visTerm = Visibility(ndl, ndv, rough);
-
-                    lightTerm = sampledColor * ndl;
-                    specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndl);
-                    pdf = 4.0;//ImportanceSamplePDF(distTerm, ndh, vdh);
-                }
+                vec3 fresnelTerm = Fresnel(specColor, vdh);
+                float distTerm = 1.0; // Optimization, this term is mathematically cancelled out  -- Distribution(ndh, roughness);
+                float visTerm = Visibility(ndl, ndv, rough);
+
+                vec3 lightTerm = sampledColor * ndl;
+
+                float pdf = ndl > 0.05 ? ImportanceSamplePDF(distTerm, ndh, vdh) : 4.0; // reduce artifacts at extreme grazing angles
+
+                vec3 specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv);
 
                 // energy conservation:
                 // Specular conservation:
@@ -201,7 +190,7 @@
                 const float rough = 1.0;
                 const float mipLevel = 9.0;
 
-                vec3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, wsNormal);
+                vec3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, wsNormal);
                 vec3 sampleVec = wsNormal + perturb; //perturb by the sample vector
 
                 vec3 sampledColor = textureLod(sZoneCubeMap, sampleVec, mipLevel).rgb;
@@ -218,7 +207,7 @@
                 float rough = roughness;
                 float mipLevel =  GetMipFromRougness(rough);
 
-                vec3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, reflectVec);
+                vec3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, reflectVec);
                 vec3 sampleVec = reflectVec + perturb; //perturb by the sample vector
 
                 vec3 sampledColor = textureCube(sZoneCubeMap, sampleVec, mipLevel).rgb;

+ 9 - 9
bin/CoreData/Shaders/GLSL/PBRDeferred.glsl

@@ -73,11 +73,11 @@ void PS()
         vec4 specularInput = texture2DProj(sSpecMap, vScreenPos);
     #endif
 
-    vec3 normal = normalize(normalInput.rgb);
-    float roughness = depthInput.a;//length(normal);
-    //normal = normalize(normal);
+    vec3 normal = normalInput.rgb;
+    float roughness = length(normal);
+    normal = normalize(normal);
 
-    vec3 specColor = vec3(specularInput.a, albedoInput.a, normalInput.a);
+    vec3 specColor = specularInput.rgb;
 
     vec4 projWorldPos = vec4(worldPos, 1.0);
 
@@ -99,13 +99,13 @@ void PS()
     #endif
 
     vec3 toCamera = normalize(-worldPos);
-    vec3 lightVec = lightDir;
+    vec3 lightVec = normalize(lightDir);
 
     vec3 Hn = normalize(toCamera + lightVec);
-    float vdh = max(M_EPSILON, dot(toCamera, Hn));
-    float ndh = max(M_EPSILON, dot(normal, Hn));
-    float ndl = max(M_EPSILON, dot(normal, lightVec));
-    float ndv = max(M_EPSILON, dot(normal, toCamera));
+    float vdh = clamp(abs(dot(toCamera, Hn)), M_EPSILON, 1.0);
+    float ndh = clamp(abs(dot(normal, Hn)), M_EPSILON, 1.0);
+    float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
+    float ndv = clamp(abs(dot(normal, toCamera)), M_EPSILON, 1.0);
 
     vec3 diffuseFactor = BurleyDiffuse(albedoInput.rgb, roughness, ndv, ndl, vdh);
     vec3 specularFactor = vec3(0,0,0);

+ 10 - 9
bin/CoreData/Shaders/GLSL/PBRLitSolid.glsl

@@ -178,12 +178,13 @@ void PS()
         #endif
 
         vec3 toCamera = normalize(cCameraPosPS - vWorldPos.xyz);
+        vec3 lightVec = normalize(lightDir);
 
         vec3 Hn = normalize(toCamera + lightDir);
-        float vdh = max(M_EPSILON, dot(toCamera, Hn));
-        float ndh = max(M_EPSILON, dot(normal, Hn));
-        float ndl = max(M_EPSILON, dot(normal, lightDir));
-        float ndv = max(M_EPSILON, dot(normal, toCamera));
+        float vdh = clamp(abs(dot(toCamera, Hn)), M_EPSILON, 1.0);
+        float ndh = clamp(abs(dot(normal, Hn)), M_EPSILON, 1.0);
+        float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
+        float ndv = clamp(abs(dot(normal, toCamera)), M_EPSILON, 1.0);
 
         vec3 diffuseFactor = BurleyDiffuse(diffColor.rgb, roughness, ndv, ndl, vdh);
         vec3 specularFactor = vec3(0,0,0);
@@ -206,12 +207,12 @@ void PS()
             gl_FragColor = vec4(GetLitFog(finalColor, fogFactor), diffColor.a);
         #endif
     #elif defined(DEFERRED)
-        // Fill deferred G-buffer'
+        // Fill deferred G-buffer
         const vec3 spareData = vec3(0,0,0); // Can be used to pass more data to deferred renderer
-        gl_FragData[0] = vec4(spareData, specColor.r);
-        gl_FragData[1] = vec4(diffColor.rgb, specColor.g);
-        gl_FragData[2] = vec4(normal, specColor.b);
-        gl_FragData[3] = vec4(EncodeDepth(vWorldPos.w), roughness);
+        gl_FragData[0] = vec4(specColor, spareData.r);
+        gl_FragData[1] = vec4(diffColor.rgb, spareData.g);
+        gl_FragData[2] = vec4(normal * roughness, spareData.b);
+        gl_FragData[3] = vec4(EncodeDepth(vWorldPos.w), 0);
     #else
         // Ambient & per-vertex lighting
         vec3 finalColor = vVertexLight * diffColor.rgb;

+ 29 - 41
bin/CoreData/Shaders/HLSL/IBL.hlsl

@@ -1,20 +1,22 @@
 #ifdef COMPILEPS
+    //#define IBLFAST
+
     float3 ImportanceSampleSimple(in float2 Xi, in float roughness, in float3 T, in float3 B, in float3 N)
     {
         const float a = roughness * roughness;
         const float3x3 tbn = float3x3(T, B, N);
-        #if defined(PBRFAST)
+        #ifdef IBLFAST
             const float blurFactor = 0.0;
         #else
             const float blurFactor = 5.0;
         #endif
-        const float3 Xi3 = lerp(float3(0,0,1), normalize(float3(Xi.xy * blurFactor , 1)), a);
+        const float3 Xi3 = lerp(float3(0,0,1), normalize(float3(Xi.xy * blurFactor % 1.0 , 1.0)), a);
         const float3 XiWS = mul(Xi3, tbn);
         return normalize(N + XiWS);
     }
 
     // Karis '13
-    float3 ImportanceSampleGGX(in float2 Xi, in float roughness, in float3 N)
+    float3 ImportanceSampleGGX(in float2 Xi, in float roughness, in float3 T, in float3 B, in float3 N)
     {
         float a = roughness * roughness;
         float Phi = 2.0 * M_PI * Xi.x;
@@ -43,8 +45,14 @@
         return lerp(normal, reflection, lerpFactor);
     }
 
-    #define IMPORTANCE_SAMPLES 16
-    static const float2 IMPORTANCE_KERNEL[IMPORTANCE_SAMPLES] =
+    #ifdef IBLFAST
+        #define IMPORTANCE_SAMPLES 1
+    #else
+        #define IMPORTANCE_SAMPLES 16
+    #endif
+
+    #define IMPORTANCE_KERNEL_SIZE 16
+    static const float2 IMPORTANCE_KERNEL[IMPORTANCE_KERNEL_SIZE] =
     {
         float2(-0.0780436, 0.0558389),
         float2(0.034318, -0.0635879),
@@ -110,15 +118,12 @@
                 const float ndh = saturate(abs(dot(N, H)));
                 const float ndl = saturate(abs(dot(N, L)));
 
-                //if (ndl > 0.0)
-                {
-                    const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(L, mipLevel));
+                const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(L, mipLevel));
 
-                    const float3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
-                    const float3 lightTerm = sampledColor;
+                const float3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
+                const float3 lightTerm = sampledColor;
 
-                    diffuseFactor = lightTerm * diffuseTerm;
-                }
+                diffuseFactor = lightTerm * diffuseTerm;
             }
 
             {
@@ -134,38 +139,21 @@
                 const float ndh = saturate(abs(dot(N, H)));
                 const float ndl = saturate(abs(dot(N, L)));
 
-                float3 specularTerm = 0.0;
-                float pdf = 1.0;
-                float3 lightTerm = 0.0;
-
-                if (ndl > 0.05)
-                {
-                    const float3 fresnelTerm = Fresnel(specColor, vdh);
-                    const float distTerm = 1.0; // Optimization, this term is mathematically cancelled out  -- Distribution(ndh, roughness);
-                    const float visTerm = Visibility(ndl, ndv, rough);
-
-                    lightTerm = sampledColor * ndl;
-                    specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv);
-                    pdf = ImportanceSamplePDF(distTerm, ndh, vdh);
-                }
-                else // reduce artifacts at extreme grazing angles
-                {
-                    const float3 fresnelTerm = Fresnel(specColor, vdh);
-                    const float distTerm = 1.0;//Distribution(ndh_, roughness);
-                    const float visTerm = Visibility(ndl, ndv, rough);
-
-                    lightTerm = sampledColor * ndl;
-                    specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndl);
-                    pdf = 4.0;//ImportanceSamplePDF(distTerm, ndh, vdh);
-                }
-
-                // energy conservation:
+                const float3 fresnelTerm = Fresnel(specColor, vdh);
+                const float distTerm = 1.0;//Distribution(ndh_, roughness);
+                const float visTerm = Visibility(ndl, ndv, rough);
+                const float3 lightTerm = sampledColor * ndl;
+
+                const float pdf = ndl > 0.05 ? ImportanceSamplePDF(distTerm, ndh, vdh) : 4.0; // reduce artifacts at extreme grazing angles
+
+                const float3 specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv);
+
+                // Energy conservation:
                 // Specular conservation:
                 specularFactor = lightTerm * specularTerm / pdf;
                 specularFactor = max(saturate(normalize(specularFactor) * (length(sampledColor * specColor))), specularFactor);
 
                 // Diffuse conservation:
-                //kd = (sampledColor * specColor)/specularFactor; //energy conservation
                 kd = 1.0 - specularFactor;
             }
 
@@ -199,7 +187,7 @@
                 const float rough = 1.0;
                 const float mipLevel = 9.0;
 
-                const float3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, wsNormal);
+                const float3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, wsNormal);
                 const float3 sampleVec = wsNormal + perturb; //perturb by the sample vector
 
                 const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(sampleVec, mipLevel));
@@ -216,7 +204,7 @@
                 const float rough = roughness;
                 const float mipLevel =  GetMipFromRougness(rough);
 
-                const float3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, reflectVec);
+                const float3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, reflectVec);
                 const float3 sampleVec = reflectVec + perturb; //perturb by the sample vector
 
                 const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(sampleVec, mipLevel));

+ 5 - 5
bin/CoreData/Shaders/HLSL/PBRDeferred.hlsl

@@ -84,7 +84,7 @@ void PS(
     const float roughness = length(normal);
     normal = normalize(normal);
 
-    const float3 specColor = float3(specularInput.a, albedoInput.a, normalInput.a);
+    const float3 specColor = specularInput.rgb;
 
     const float4 projWorldPos = float4(worldPos, 1.0);
 
@@ -108,10 +108,10 @@ void PS(
     const float3 lightVec = normalize(lightDir);
 
     const float3 Hn = normalize(toCamera + lightVec);
-    const float vdh = max(M_EPSILON, dot(toCamera, Hn));
-    const float ndh = max(M_EPSILON, dot(normal, Hn));
-    const float ndl = max(M_EPSILON, dot(normal, lightVec));
-    const float ndv = max(M_EPSILON, dot(normal, toCamera));
+    const float vdh = clamp(abs(dot(toCamera, Hn)), M_EPSILON, 1.0);
+    const float ndh = clamp(abs(dot(normal, Hn)), M_EPSILON, 1.0);
+    const float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
+    const float ndv = clamp(abs(dot(normal, toCamera)), M_EPSILON, 1.0);
 
     const float3 diffuseFactor = BurleyDiffuse(albedoInput.rgb, roughness, ndv, ndl, vdh);
     float3 specularFactor = 0;

+ 8 - 7
bin/CoreData/Shaders/HLSL/PBRLitSolid.hlsl

@@ -263,12 +263,13 @@ void PS(
         #endif
 
         const float3 toCamera = normalize(cCameraPosPS - iWorldPos.xyz);
+        const float3 lightVec = normalize(lightDir);
 
         const float3 Hn = normalize(toCamera + lightDir);
-        const float vdh = max(M_EPSILON, dot(toCamera, Hn));
-        const float ndh = max(M_EPSILON, dot(normal, Hn));
-        const float ndl = max(M_EPSILON, dot(normal, lightDir));
-        const float ndv = max(M_EPSILON, dot(normal, toCamera));
+        const float vdh = clamp(abs(dot(toCamera, Hn)), M_EPSILON, 1.0);
+        const float ndh = clamp(abs(dot(normal, Hn)), M_EPSILON, 1.0);
+        const float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
+        const float ndv = clamp(abs(dot(normal, toCamera)), M_EPSILON, 1.0);
 
         const float3 diffuseFactor = BurleyDiffuse(diffColor.rgb, roughness, ndv, ndl, vdh);
         float3 specularFactor = 0;
@@ -293,9 +294,9 @@ void PS(
     #elif defined(DEFERRED)
         // Fill deferred G-buffer
         const float3 spareData = 0; // Can be used to pass more data to deferred renderer
-        oColor = float4(spareData, specColor.r);
-        oAlbedo = float4(diffColor.rgb, specColor.g);
-        oNormal = float4(normalize(normal) * roughness, specColor.b);
+        oColor = float4(specColor, spareData.r);
+        oAlbedo = float4(diffColor.rgb, spareData.g);
+        oNormal = float4(normalize(normal) * roughness, spareData.b);
         oDepth = iWorldPos.w;
     #else
         // Ambient & per-vertex lighting

+ 5 - 6
bin/CoreData/Techniques/PBR/DiffNormalSpecEmissive.xml

@@ -1,9 +1,8 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP">
-    <pass name="base" psdefines="EMISSIVEMAP" />
-    <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP SPECMAP" depthtest="equal" depthwrite="false" blend="add" />
-    <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP SPECMAP" />
-    <pass name="material" psdefines="MATERIAL SPECMAP EMISSIVEMAP" depthtest="equal" depthwrite="false" />
-    <pass name="deferred" vsdefines="NORMALMAP" psdefines="DEFERRED NORMALMAP SPECMAP EMISSIVEMAP" />
+<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP NORMALMAP SPECMAP EMISSIVEMAP">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />>
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" />
     <pass name="depth" vs="Depth" ps="Depth" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>

+ 3 - 3
bin/CoreData/Techniques/PBR/DiffNormalSpecEmissiveAlpha.xml

@@ -1,5 +1,5 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP">
-    <pass name="alpha" psdefines="EMISSIVEMAP" depthwrite="false" blend="alpha" />
-    <pass name="litalpha" vsdefines="NORMALMAP" psdefines="NORMALMAP SPECMAP" depthwrite="false" blend="addalpha" />
+<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP SPECMAP EMISSIVEMAP NORMALMAP">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>

+ 2 - 2
bin/CoreData/Techniques/PBR/PBRDiffNormal.xml

@@ -1,6 +1,6 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP PBR IBL">
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP NORMALMAP PBR IBL">
     <pass name="base" />
-    <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
     <pass name="deferred" psdefines="DEFERRED" blend="add" />
     <pass name="depth" vs="Depth" ps="Depth" />

+ 2 - 2
bin/CoreData/Techniques/PBR/PBRDiffNormalAlpha.xml

@@ -1,5 +1,5 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP PBR IBL">
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP NORMALMAP PBR IBL">
     <pass name="alpha" depthwrite="false" blend="alpha" />
-    <pass name="litalpha" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthwrite="false" blend="addalpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>

+ 4 - 4
bin/CoreData/Techniques/PBR/PBRDiffNormalEmissive.xml

@@ -1,7 +1,7 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid"  vsdefines="IBL" psdefines="DIFFMAP PBR IBL">
-    <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthtest="equal" depthwrite="false" blend="add" />
-    <pass name="material" psdefines="MATERIAL EMISSIVEMAP" depthtest="equal" depthwrite="false" />
-    <pass name="deferred" psdefines="DEFERRED EMISSIVEMAP" blend="add" />
+<technique vs="PBRLitSolid" ps="PBRLitSolid"  vsdefines="IBL" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP PBR IBL">
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add" />
     <pass name="depth" vs="Depth" ps="Depth" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>

+ 3 - 3
bin/CoreData/Techniques/PBR/PBRDiffNormalEmissiveAlpha.xml

@@ -1,5 +1,5 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid"  vsdefines="IBL" psdefines="DIFFMAP PBR IBL">
-    <pass name="alpha" psdefines="EMISSIVEMAP" depthwrite="false" blend="alpha" />
-    <pass name="litalpha" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthwrite="false" blend="addalpha" />
+<technique vs="PBRLitSolid" ps="PBRLitSolid"  vsdefines="IBL" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP PBR IBL">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>

+ 2 - 2
bin/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpec.xml

@@ -1,7 +1,7 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="NORMALMAP IBL" psdefines="NORMALMAP DIFFMAP METALLIC ROUGHNESS PBR IBL">
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="NORMALMAP DIFFMAP METALLIC ROUGHNESS PBR IBL">
     <pass name="base" />
     <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
-    <pass name="material" psdefines="MATERIAL NORMALMAP" depthtest="equal" depthwrite="false" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
     <pass name="deferred" psdefines="DEFERRED" blend="add"/>
     <pass name="depth" vs="Depth" ps="Depth" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />

+ 5 - 5
bin/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissive.xml

@@ -1,8 +1,8 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="NORMALMAP IBL" psdefines="NORMALMAP DIFFMAP METALLIC ROUGHNESS PBR IBL">
-    <pass name="base" psdefines="EMISSIVEMAP"/>
-    <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthtest="equal" depthwrite="false" blend="add" />
-    <pass name="material" psdefines="MATERIAL EMISSIVEMAP NORMALMAP" depthtest="equal" depthwrite="false" />
-    <pass name="deferred" psdefines="DEFERRED EMISSIVEMAP NORMALMAP" blend="add"/>
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP METALLIC ROUGHNESS PBR IBL">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add"/>
     <pass name="depth" vs="Depth" ps="Depth" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>

+ 3 - 3
bin/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissiveAlpha.xml

@@ -1,5 +1,5 @@
-<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP PBR IBL METALLIC ROUGHNESS">
-    <pass name="alpha" psdefines="EMISSIVEMAP" depthwrite="false" blend="alpha" />
-    <pass name="litalpha" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthwrite="false" blend="addalpha" />
+<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP PBR IBL METALLIC ROUGHNESS">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>

+ 1 - 1
bin/CoreData/Techniques/PBR/PBRMetallicRoughDiffSpecAlpha.xml

@@ -1,5 +1,5 @@
 <technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP PBR IBL METALLIC ROUGHNESS">
     <pass name="alpha" depthwrite="false" blend="alpha" />
-    <pass name="litalpha" psdefines="METALLIC ROUGHNESS" depthwrite="false" blend="addalpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
     <pass name="shadow" vs="Shadow" ps="Shadow" />
 </technique>