Jump to content

PointLight shadow generator uses activeCamera.maxZ instead of light.range -- bug?


BeanstalkBlue
 Share

Recommended Posts

I noticed that the shadow generator for point lights sets the shadow generator camera matrix using the activeCamera.maxZ (in .setShadowProjectionMatrix()).

It should really use the point light's range, to have better depth z accuracy since there are no shadows further than the light's range anyway.

It is also using the activeCamera.minZ, which is too far (at least in my case) for the shadows, and causes light bleeding.

Can I set this or do I need to override the setShadowProjectionMatrix function like this:

        BABYLON.PointLight.prototype.setShadowProjectionMatrix = function (){
            [...]
        }

Or is there a better way?

If I am right then I would submit a PR but I am new to Babylon (and Javascript and Typescript) so I thought it is better to ask here instead and let you guys fix it since it is a 1 line change in BabylonJS code.

Link to comment
Share on other sites

What I am trying to say is that the Babylon.js function here:

        public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): PointLight {
            var activeCamera = this.getScene().activeCamera;
            Matrix.PerspectiveFovLHToRef(Math.PI / 2, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
            return this;
        }

 

Should be this:

        public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): PointLight {
            Matrix.PerspectiveFovLHToRef(Math.PI / 2, 1.0, this.range/1000.0, this.range, matrix);
            return this;
        }

 

Unless I am missing something?

"activeCamera" is not the shadow generator's camera, it is the camera that the player sees the world through, right?

Link to comment
Share on other sites

I think you are right:
Just patched my version of babylon with your code, and shadows become much clearer. Much better now! Thanks!
(My camera MaxZ was 20000)

This is not the only problem with point light shadows btw.
It does not work with instanced meshes:
Look at the wrong shadows here. They are coming from the characters behind me.
 

pointlights.jpg

Link to comment
Share on other sites

I have point shadows on SPS particles (which I guess are instanced meshes), and it works fine. Maybe there is something going on with the meshes you are adding to the shadowGenerator renderList?

 

Did your instanced mesh error occur after using my code? If so then just to check, set minZ and maxZ in setShadowProjectionMatrix() to something sensible manually (like 0.1 and 100.0) and see if that changes anything.

Link to comment
Share on other sites

Well, I dont know what is wrong now.
Tried a few bias values (and I realy do not know what is the correct bias, as it should be one texel above the  shadowed surface, but what size is that? only guessing!)
http://www.babylonjs-playground.com/#EZCUT#20

grey boxes are normal meshes (have some wrong shadow, only in the distance, and only at the right bias setting)
reds are clones (have shadows too)
blues are instances (have no shadows)

Your code does not help if I comment it out.
Edit:
This playground scene is with default camera maxZ... In my scene, it does help!

Link to comment
Share on other sites

Hey I've just added a new property to each light: light.customProjectionMatrixBuilder

here is how the code looks like:

public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): SpotLight {
            if (this.customProjectionMatrixBuilder) {
                this.customProjectionMatrixBuilder(viewMatrix, renderList, matrix);
            } else {
                var activeCamera = this.getScene().activeCamera;
                Matrix.PerspectiveFovLHToRef(this.angle, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
            }
            return this;
        }

So basically you can now write:

light.customProjectionMatrixBuilder = function(viewMatrix, renderList, output) {

     BABYLON.Matrix.PerspectiveFovLHToRef(Math.PI / 2, 1.0, light.range/1000.0, light.range, output);

}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...