Browse Source

Rework renderpath quad commands to use same quad transform as deferred directional lights, with the camera projection set correctly. Set quad command's shader parameters last to allow overriding any engine shader parameter (except the quad's model transform.) Remove unused function parameters. Closes #1370.

Lasse Öörni 9 years ago
parent
commit
97bb1769d0

+ 1 - 1
Source/Urho3D/Graphics/Batch.cpp

@@ -235,7 +235,7 @@ void Batch::Prepare(View* view, Camera* camera, bool setModelTransform, bool all
     unsigned viewportHash = (unsigned)(viewSize.x_ | (viewSize.y_ << 16));
     if (graphics->NeedParameterUpdate(SP_CAMERA, reinterpret_cast<const void*>(cameraHash + viewportHash)))
     {
-        view->SetCameraShaderParameters(camera, true);
+        view->SetCameraShaderParameters(camera);
         // During renderpath commands the G-Buffer or viewport texture is assumed to always be viewport-sized
         view->SetGBufferShaderParameters(viewSize, IntRect(0, 0, viewSize.x_, viewSize.y_));
     }

+ 12 - 9
Source/Urho3D/Graphics/Light.cpp

@@ -422,15 +422,7 @@ const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
     switch (lightType_)
     {
     case LIGHT_DIRECTIONAL:
-        {
-            Matrix3x4 quadTransform;
-            Vector3 near, far;
-            // Position the directional light quad in halfway between far & near planes to prevent depth clipping
-            camera->GetFrustumSize(near, far);
-            quadTransform.SetTranslation(Vector3(0.0f, 0.0f, (camera->GetNearClip() + camera->GetFarClip()) * 0.5f));
-            quadTransform.SetScale(Vector3(far.x_, far.y_, 1.0f)); // Will be oversized, but doesn't matter (gets frustum clipped)
-            volumeTransform_ = camera->GetEffectiveWorldTransform() * quadTransform;
-        }
+        volumeTransform_ = GetFullscreenQuadTransform(camera);
         break;
 
     case LIGHT_SPOT:
@@ -573,4 +565,15 @@ void Light::SetLightQueue(LightBatchQueue* queue)
     lightQueue_ = queue;
 }
 
+Matrix3x4 Light::GetFullscreenQuadTransform(Camera* camera)
+{
+    Matrix3x4 quadTransform;
+    Vector3 near, far;
+    // Position the directional light quad in halfway between far & near planes to prevent depth clipping
+    camera->GetFrustumSize(near, far);
+    quadTransform.SetTranslation(Vector3(0.0f, 0.0f, (camera->GetNearClip() + camera->GetFarClip()) * 0.5f));
+    quadTransform.SetScale(Vector3(far.x_, far.y_, 1.0f)); // Will be oversized, but doesn't matter (gets frustum clipped)
+    return camera->GetEffectiveWorldTransform() * quadTransform;
+}
+
 }

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

@@ -304,6 +304,9 @@ public:
     /// Return shape texture attribute.
     ResourceRef GetShapeTextureAttr() const;
 
+    /// Return a transform for deferred fullscreen quad (directional light) rendering.
+    static Matrix3x4 GetFullscreenQuadTransform(Camera* camera);
+
 protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();

+ 2 - 2
Source/Urho3D/Graphics/Renderer.cpp

@@ -1947,7 +1947,7 @@ void Renderer::BlurShadowMap(View* view, Texture2D* shadowMap)
     graphics_->SetShaderParameter(blurOffsetParam, Vector2(shadowSoftness_ / shadowMap->GetWidth(), 0.0f));
 
     graphics_->SetTexture(TU_DIFFUSE, shadowMap);
-    view->DrawFullscreenQuad(false);
+    view->DrawFullscreenQuad(true);
 
     // Vertical blur
     graphics_->SetRenderTarget(0, shadowMap);
@@ -1956,6 +1956,6 @@ void Renderer::BlurShadowMap(View* view, Texture2D* shadowMap)
     graphics_->SetShaderParameter(blurOffsetParam, Vector2(0.0f, shadowSoftness_ / shadowMap->GetHeight()));
 
     graphics_->SetTexture(TU_DIFFUSE, tmpBuffer);
-    view->DrawFullscreenQuad(false);
+    view->DrawFullscreenQuad(true);
 }
 }

+ 32 - 25
Source/Urho3D/Graphics/View.cpp

@@ -706,7 +706,7 @@ void View::SetGlobalShaderParameters()
     }
 }
 
-void View::SetCameraShaderParameters(Camera* camera, bool setProjection)
+void View::SetCameraShaderParameters(Camera* camera)
 {
     if (!camera)
         return;
@@ -750,18 +750,15 @@ void View::SetCameraShaderParameters(Camera* camera, bool setProjection)
     camera->GetFrustumSize(nearVector, farVector);
     graphics_->SetShaderParameter(VSP_FRUSTUMSIZE, farVector);
 
-    if (setProjection)
-    {
-        Matrix4 projection = camera->GetProjection();
+    Matrix4 projection = camera->GetProjection();
 #ifdef URHO3D_OPENGL
-        // Add constant depth bias manually to the projection matrix due to glPolygonOffset() inconsistency
-        float constantBias = 2.0f * graphics_->GetDepthConstantBias();
-        projection.m22_ += projection.m32_ * constantBias;
-        projection.m23_ += projection.m33_ * constantBias;
+    // Add constant depth bias manually to the projection matrix due to glPolygonOffset() inconsistency
+    float constantBias = 2.0f * graphics_->GetDepthConstantBias();
+    projection.m22_ += projection.m32_ * constantBias;
+    projection.m23_ += projection.m33_ * constantBias;
 #endif
 
-        graphics_->SetShaderParameter(VSP_VIEWPROJ, projection * camera->GetView());
-    }
+    graphics_->SetShaderParameter(VSP_VIEWPROJ, projection * camera->GetView());
 }
 
 void View::SetGBufferShaderParameters(const IntVector2& texSize, const IntRect& viewRect)
@@ -1800,12 +1797,8 @@ void View::RenderQuad(RenderPathCommand& command)
     // Set shaders & shader parameters and textures
     graphics_->SetShaders(vs, ps);
 
-    const HashMap<StringHash, Variant>& parameters = command.shaderParameters_;
-    for (HashMap<StringHash, Variant>::ConstIterator k = parameters.Begin(); k != parameters.End(); ++k)
-        graphics_->SetShaderParameter(k->first_, k->second_);
-
     SetGlobalShaderParameters();
-    SetCameraShaderParameters(camera_, false);
+    SetCameraShaderParameters(camera_);
 
     // During renderpath commands the G-Buffer or viewport texture is assumed to always be viewport-sized
     IntRect viewport = graphics_->GetViewport();
@@ -1833,6 +1826,11 @@ void View::RenderQuad(RenderPathCommand& command)
         graphics_->SetShaderParameter(offsetsName, Vector2(pixelUVOffset.x_ / width, pixelUVOffset.y_ / height));
     }
 
+    // Set command's shader parameters last to allow them to override any of the above
+    const HashMap<StringHash, Variant>& parameters = command.shaderParameters_;
+    for (HashMap<StringHash, Variant>::ConstIterator k = parameters.Begin(); k != parameters.End(); ++k)
+        graphics_->SetShaderParameter(k->first_, k->second_);
+
     graphics_->SetBlendMode(command.blendMode_);
     graphics_->SetDepthTest(CMP_ALWAYS);
     graphics_->SetDepthWrite(false);
@@ -2079,27 +2077,36 @@ void View::BlitFramebuffer(Texture* source, RenderSurface* destination, bool dep
     SetGBufferShaderParameters(srcSize, srcRect);
 
     graphics_->SetTexture(TU_DIFFUSE, source);
-    DrawFullscreenQuad(false);
+    DrawFullscreenQuad(true);
 }
 
-void View::DrawFullscreenQuad(bool nearQuad)
+void View::DrawFullscreenQuad(bool setIdentityProjection)
 {
     Geometry* geometry = renderer_->GetQuadGeometry();
 
-    Matrix3x4 model = Matrix3x4::IDENTITY;
-    Matrix4 projection = Matrix4::IDENTITY;
+    // If no camera, no choice but to use identity projection
+    if (!camera_)
+        setIdentityProjection = true;
 
+    if (setIdentityProjection)
+    {
+        Matrix3x4 model = Matrix3x4::IDENTITY;
+        Matrix4 projection = Matrix4::IDENTITY;
 #ifdef URHO3D_OPENGL
-    if (camera_ && camera_->GetFlipVertical())
-        projection.m11_ = -1.0f;
-    model.m23_ = nearQuad ? -1.0f : 1.0f;
+        if (camera_ && camera_->GetFlipVertical())
+            projection.m11_ = -1.0f;
+        model.m23_ = 0.0f;
 #else
-    model.m23_ = nearQuad ? 0.0f : 1.0f;
+        model.m23_ = 0.5f;
 #endif
 
+        graphics_->SetShaderParameter(VSP_MODEL, model);
+        graphics_->SetShaderParameter(VSP_VIEWPROJ, projection);
+    }
+    else
+        graphics_->SetShaderParameter(VSP_MODEL, Light::GetFullscreenQuadTransform(camera_));
+
     graphics_->SetCullMode(CULL_NONE);
-    graphics_->SetShaderParameter(VSP_MODEL, model);
-    graphics_->SetShaderParameter(VSP_VIEWPROJ, projection);
     graphics_->ClearTransformSources();
 
     geometry->Draw(graphics_);

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

@@ -177,12 +177,12 @@ public:
     /// Set global (per-frame) shader parameters. Called by Batch and internally by View.
     void SetGlobalShaderParameters();
     /// Set camera-specific shader parameters. Called by Batch and internally by View.
-    void SetCameraShaderParameters(Camera* camera, bool setProjectionMatrix);
+    void SetCameraShaderParameters(Camera* camera);
     /// Set G-buffer offset and inverse size shader parameters. Called by Batch and internally by View.
     void SetGBufferShaderParameters(const IntVector2& texSize, const IntRect& viewRect);
 
-    /// Draw a fullscreen quad. Shaders and renderstates must have been set beforehand.
-    void DrawFullscreenQuad(bool nearQuad);
+    /// Draw a fullscreen quad. Shaders and renderstates must have been set beforehand. Quad will be drawn to the middle of depth range, similarly to deferred directional lights.
+    void DrawFullscreenQuad(bool setIdentityProjection = false);
 
 private:
     /// Query the octree for drawable objects.