Jump to content

Shadow quality issues/settings


exc_html5
 Share

Recommended Posts

Hi guys, trying to wrap my head around how shadows are working inside of BJS, and have a few questions. First off, I have this scene here:

http://client.elementxcreative.com/public/bjs/fog_test/index.html

You can move around the scene with the mouse/arrow keys.

You can see the shadows looked a bit jacked up. Not only are the shadows low rez looking (despite having the resolution cranked up in BJS) but there is weird self shadowing on the objects themselves? Attached below is an image of the scene I'm exporting from Unity, what I'm expecting shadows to look closer to. It's just a single directional light. I'm manually fiddling with the filtering options on the BJS to try and get closer to this, but I'm not having much luck. Attached is code were using:

var engine, scene;
var mouseX,mouseY,dx,dz;
var cameraTarget = new BABYLON.Vector3(0,0,0);
var renderPlane, renderTarget;
var DEBUG = true;
var showstats = false;




  
// Get the canvas element from our HTML above
var canvas = document.querySelector("#render");
// var stats = document.querySelector("#stats");

// Load the BABYLON 3D engine
engine = new BABYLON.Engine(canvas, true);
engine.enableOfflineSupport = false; //this stops the manifest errors in the console

BABYLON.SceneLoader.Load("assets/","fog_test.unity.babylon",engine,function(newScene){
scene = newScene;
	   
		//CAMERA
		doCamera(newScene,canvas);
		// FOG
		doFog(newScene,canvas);
		// SHADOWS
		doShadows(newScene);
		
		// RENDER LOOP
		engine.runRenderLoop(function(){
		newScene.render();
		update();
		});
		
});
        


function doShadows(newScene){
  for (var i = 0; i < newScene.lights.length; i++){
    var shadowGenerator = new BABYLON.ShadowGenerator(8192, newScene.lights[i]);
    newScene.meshes.forEach(function(mesh) {
      shadowGenerator.getShadowMap().renderList.push(mesh);
      shadowGenerator.bias = 0.0000001;
      //shadowGenerator.useVarianceShadowMap = true;
	  shadowGenerator.usePoissonSampling = true;
    });
  };
  newScene.meshes.forEach(function(mesh) {
    mesh.receiveShadows = true;
  });
}

function doCamera(newScene,canvas){
  //new camera
  var newCamera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 0, 0), newScene);

  newCamera.position = newScene.cameras[0].position;
  newCamera.rotation = newScene.cameras[0].rotation;
  newCamera.target =  newScene.cameras[0].target;
  newCamera.fov =  newScene.cameras[0].fov;
  newCamera.inertia =  newScene.cameras[0].inertia;
  newCamera.mode =  newScene.cameras[0].mode;
  newCamera.speed = 0.1;

  newCamera.attachControl(canvas,false);
  newScene.activeCamera = newCamera;
  //newScene.activeCamera.wheelPrecision = 90;
  //newScene.activeCamera.minZ = .01;

  // Define z key to rotate object z axis left
  newScene.actionManager = new BABYLON.ActionManager(newScene);
  newScene.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnKeyDownTrigger, function (evt) {
    if (evt.sourceEvent.keyCode == 90) {
      console.log("z key pressed");
      newScene.meshes.forEach(function(mesh) {
        //mesh.rotation = new BABYLON.Vector3(0, 0, 1);
        mesh.rotate(BABYLON.Axis.Z, 0.06, BABYLON.Space.Local)
      }); 
    }	  
  }));

  // Define x key to rotate object z axis right
  newScene.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnKeyDownTrigger, function (evt) {
    if (evt.sourceEvent.keyCode == 88) {
      console.log("x key pressed");
      newScene.meshes.forEach(function(mesh) {
        mesh.rotate(BABYLON.Axis.Z, -0.06, BABYLON.Space.Local)
      });
    }	  
  }));
  
}

function doFog(newScene,canvas){
  newScene.meshes.forEach(function(mesh) {
    mesh.applyFog = true; // allow all meshes to be effected by fog
  });
  // newScene.fogMode = 2;
  // newScene.fogColor = new BABYLON.Color3(1, 1, 0.85);
  // newScene.fogDensity = .0075;             
}


function update(){
  if (renderPlane){
    //console.log('hey');
    var v1 = new BABYLON.Vector3(1,0,0);
    var v2 = scene.cameras[1].target.subtract(scene.cameras[1].position);
    var vec = math.cross([v1.x,v1.y,v1.z],[v2.x,v2.y,v2.z]);
    var w = math.sqrt(v1.lengthSquared()*v2.lengthSquared()) + math.dot([v1.x,v1.y,v1.z],[v2.x,v2.y,v2.z]);

    var q = new BABYLON.Quaternion(vec[0], vec[1], vec[2], w);
    // Quaternion q;
    // vector a = crossproduct(v1, v2)
    // q.xyz = a;
    // q.w = sqrt((v1.Length ^ 2) * (v2.Length ^ 2)) + dotproduct(v1, v2)

    renderPlane.rotation = q.toEulerAngles();
    //console.log(q.toEulerAngles());
    }
  
}

Any thoughts on what we could do to improve the shadows?

thanks!

shadows_unity.png

Link to comment
Share on other sites

Okay, still having some issues here. First, just to make sure, I took the sample shadows scene and turned off the spotlight so we only see the directional shadow:

http://www.babylonjs-playground.com/#PHUZL

Next, I took our own custom scene, and made an area the same size as the ground plane in the BJS sample scene (100 units wide/across), also at the origin like the sample scene. Also, this scene has a directional light, with the same shadow settings as the BJS sample scene. You can see this scene below (use the arrow keys to move around). 

http://client.elementxcreative.com/public/bjs/fog_test/index.html

My scene shows up completely black tho. The BJS scene file is here:

http://client.elementxcreative.com/public/bjs/fog_test/assets/fog_test.unity.babylon - Size: 0.26 MB

I have another JS file that runs the shadow loops like this:

function doShadows(newScene){
  for (var i = 0; i < newScene.lights.length; i++){
    var shadowGenerator = new BABYLON.ShadowGenerator(1024, newScene.lights[i]);
    newScene.meshes.forEach(function(mesh) {
      shadowGenerator.getShadowMap().renderList.push(mesh);
      //shadowGenerator.bias = 0.00001;
      shadowGenerator.useVarianceShadowMap = true;
    });
  };
  newScene.meshes.forEach(function(mesh) {
    mesh.receiveShadows = true;
  });
}

If I disable the doShadows function the scenes shows up as expected, but no shadows. Since the size of my scene is exactly the same as your sample scene on the playground, as well as the shadow settings, i'm at a loss why it looks so diff :( 

Link to comment
Share on other sites

Hey there,

if you want your meshes to drop and receive shadows at the same time you cannot use variance shadow maps (neither blurred nor normal). You will have to stick to shadowGenerator.usePoissonSampling in that case.

On another side note, the shadowGenerator properties are per generator, so you can set these outside your forEach loop.

Link to comment
Share on other sites

Thanks for the tip! Change the code to this:

function doShadows(newScene){
  for (var i = 0; i < newScene.lights.length; i++){
    var shadowGenerator = new BABYLON.ShadowGenerator(1024, newScene.lights[i]);
    newScene.meshes.forEach(function(mesh) {
      shadowGenerator.getShadowMap().renderList.push(mesh);
      //shadowGenerator.bias = 0.00001;
	  shadowGenerator.usePoissonSampling = true;
      //shadowGenerator.useVarianceShadowMap = true;
    });
  };
  newScene.meshes.forEach(function(mesh) {
    mesh.receiveShadows = true;
  });
}

And now I get this:

http://client.elementxcreative.com/public/bjs/fog_test/index.html

Which is better, but the shadows still look pretty funky, compared to the BJS sample scene?

Link to comment
Share on other sites

Funky is a good way to describe it :D

Well looking at your babylon file, there already seems to be a shadowGenerator included with a shadowMap size of 1536. So you are loading the scene which already has the light and the shadowGenerator for it, and afterwards you create a new shadowGenerator for that light. Since you are doing all this in the "onLoad" callBack maybe this causes some side effects? (Just a wild guess, I don't know if that is really a problem)

So one thing you could try is to call all your setup functions (doShadows, doCamera, etc.) in a newScene.executeWhenReady(function(){ .. });

I don't know if this solves any problems, but that way at least you can be sure that everything is loaded from your babylon file into the scene before you finish setting it up with your code.

Just to make clear what I mean:

BABYLON.SceneLoader.Load("assets/","fog_test.unity.babylon",engine,function(newScene){
scene = newScene;
	
    newScene.executeWhenReady(function(){  
    	//CAMERA
        doCamera(newScene,canvas);
    	// FOG
        doFog(newScene,canvas);
    	// SHADOWS
        doShadows(newScene);
		
	    // RENDER LOOP
    	engine.runRenderLoop(function(){
            newScene.render();
            update();
        });
    });
		
});

 

Link to comment
Share on other sites

@lesterhaus- Yeah, i forgot to mention we did the execute when ready in the code on the last pass, didn't really do much. 

For whoever is watching, I can get the shadows to look a little better by cranking the resolution up, but I'm sure that's going to have performance consequences. This is a 4k shadow map:

http://client.elementxcreative.com/public/bjs/fog_test/index.html

Given my scene is the same as the bablyon playground test scene (size wise), i'm baffled how the shadows in that one are crisp at 1024 and mine are still chunky at 4k. 

Link to comment
Share on other sites

Yeah, better. Looks like the cylinders have a weird dark stripe on them from self shadowing? So I guess I'd need to turn off recieve shadows on the cylinders if I want that to go away? If I comment out the shadowGenerator.useBlurVarianceShadowMap = true; line, then the shadows go back to being jaggy, but they shade correctly on the objects.  

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...