Jump to content

receiveShadows not working on imported meshes


Recommended Posts


How receive shadow actually works? i'v been trying to get it work on imported meshes without success. the weird part is that it works on plain plane just well :S

I'v been trying something like this for hours and just can't get it work.

EDIT: the plan was to get the mesh to receive shadows from itself.

		var light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(-1, -2, -1), scene);
		light.position = new BABYLON.Vector3(20, 40, 20);
		light.intensity = 1;

		var shadowGenerator = new BABYLON.ShadowGenerator(2048, light);
		shadowGenerator.useVarianceShadowMap = true;
		shadowGenerator.usePoissonSampling = true; 
		shadowGenerator.bias = 0.01;

		BABYLON.SceneLoader.ImportMesh("", "assets/models/sample/", "house1.babylon", scene, function (newMesh){
			newMesh[0].material.specularPower = 0;
			newMesh[0].material.specularColor = new BABYLON.Color3(0, 0, 0);
			newMesh[0].material.diffuseColor = new BABYLON.Color3(1, 1, 1);
			newMesh[0].material.emissiveColor = new BABYLON.Color3(1, 1, 1);
			newMesh[0].position.x = -4;
			newMesh[0].position.z = 6;
			newMesh[0].position.y = -0.05;
			newMesh[0].rotation.y = Math.random()*(2*Math.PI);
			newMesh[0].receiveShadows = true;

		var material1 = new BABYLON.StandardMaterial("texture1", scene);
		material1.emissiveColor = new BABYLON.Color3(0,0,0)
		material1.diffuseTexture = new BABYLON.Texture("assets/models/sample/sand.png", scene);
		material1.diffuseTexture.uScale = 500.0;
		material1.diffuseTexture.vScale = 500.0;

		var plane = BABYLON.Mesh.CreatePlane("plane", 1000.0, scene);
		plane.rotation.x += Math.PI / 2;
		plane.material = material1;
		plane.receiveShadows = true;

Anyone knows what i'm doing wrong?

- regards, eljuko


Link to comment
Share on other sites

Hi @eljuko, good to see you again.  Have you tried putting the s-gen creation... inside the onSuccess callback?  Might work.

Let's try a playground.  Yeah, we got some shadows happening there.  Hmm.  Seeing some quality inconsistency.

Not sure why creating shadowGen OUTSIDE-OF callback... would fail... but maybe.  Use this playground to test stuff, as wanted.  Talk soon, be well.

Link to comment
Share on other sites

I just noticed that you wanted the model to receive shadows from itself.  Perhaps I need to use a different model... something with some bends.  I'll sniff around for a better test model.

Update:  http://www.babylonjs-playground.com/#1CMD3G#21

Using "dude" model, setting .receiveShadows on all mesh, with light positioned -x and +y (high left), aimed... (1, -1, 0) (equal amounts of down and right?)

I think I see SOME shadow on inside of +X (right) leg.  But -X (left) arm should be casting a shadow on the side of the torso.  I don't see it.  Turning on Poisson or VSM makes things... pretty ugly.  Head should also cast shadow onto top of right shoulder.

If I understood what DK once said, directional light .position is not important to lighting, but IS important and used for origin point of the shadowMap camera.  Does that make sense?  Anyway, directionLight.position should be considered in these tests.

Let's increase the directionalLight Y position... a lot...


Looking better at Y = 150 in line 10.  Good arm shadow, good head shadow, good ground shadow.  Our Dude is about 100 units tall.  Getting that light elevated...  for use in the shadow generator... was super important.  *shrug*  Its .position == shadowMap point-of-perspective... seemingly.

Not sure what the problems are, if any exist.  I'm just making test playgrounds.  This one is better prepared for testing cast-on-self issues.  :)

Link to comment
Share on other sites

Nice demo, you definitely made something i couldn't :D

With http://www.babylonjs-playground.com/#1CMD3G#23 that setup it actually starts to look pretty good!

What if i had like hundreds of imported scenes from blender, do i have to make different shadowGen and light for each of them? I'm still breaking everything in my project but at least your demos gave me hope.

I'v been working on this projects backend now, and to be honest i'v been trying avoid this 3d part for far too long :D So pardon me if i present stupid questions.


Link to comment
Share on other sites

Hi again, and no, you didn't ask any stupid questions. 

Generally, there's only one "scene" but there can be many mesh,  loadable from one or many .babylon files or using one of our mesh importer extensions (for .obj, .gItf, and .stl, I believe).

And generally speaking, one shadowGenerator per light, but many mesh can be pushed into each shadowMap.renderList array.  Also, our lights have "excludedMeshes" and "includedMeshes" settings, and all our light-types EXCEPT the HemisphericLight... can be used as shadowGenerator lights.

I'm rather inexperienced myself.  I don't know much about variance shadow maps (VSM), nor about Poisson, nor about bias settings.  Some of these things are webGL-based and not necessarily BabylonJS-based.  I think webGL has no "native" lights or shadows... so it is Deltakosh and the Core Team who have borrowed/coded our lights and shadows... probably using "approved techniques" that can be learned on the web.

Note:  Notice that VSM is now "deprecated" and now ESM is recommended.

I've heard shadows are performance soaks... a little heavy on the frame rates.  I think they might use something like renderTargetTextures for attaining the shadowMap (like a screengrab snapshot from a temp camera located at the light's position).  Therefore, in SOME cases, the BJS framework tries to avoid updating the shadow's primary light... for every frame.  There is an adjustment on lights... for this reason.  light.needRefreshPerFrame()  (see source for more info).

In fact, while you are "touring" the shadowGenerator's TypeScript code... relax and tour.  Notice all the caching attempts.  These "cachings" are some of the reasons why BJS out-performs the other frameworks.  Core programmers, constantly trying to accelerate potential slow-down points.  When you say "hundreds of imported scenes"... that is not realistic, and that won't happen.  Hundreds of mesh... perhaps... but that too, is not overly realistic.  You will likely use incremental loading, instead.  And you may find that JS can generate some mesh... easier/faster than you can import Blender models.

So, in other words... you're in a browser, in JS.  Don't expect to have the power to take over the world.  :)  But... use the horsepower that you DO have.... wisely, and often with trickery and visual foolery... and you will win the perf wars as well as anyone.  Look carefully at that shadowGenerator code that Deltakosh and his team coded.  It's pretty nice.  Learn to work WITH-IT... and you will have good success with many-mesh shadows.  Do playground searches for shadowGenerator... see what others have done... check their playground's performance numbers, use browser's dev-tools "profiling" system... to see "performance strangulation points".  :)  (bog points)

Scary, and not so scary, right?  That shadowGen is written in TypeScript/JavaScript ... so... that's just a simple programming language that even your dog can learn.  So, if you wanted to do so... you could borrow the current shadowGenerator code... (Deltakosh allows this), and put it into your project, and even put your name on it, and then hack it silly or not.  You can over-ride/over-rule the default shadowGen system.  Anything goes.  Maybe we haven't got the computing horsepower to take over the world, but we DEFINITELY have been given the tools and knowledge to do so. 

Just think of the "worth"... of that shadowGenerator code... use it to steal, use it to learn-from, use it to make great shadows, and use it to learn about... how webGL treats lights and shadows (very rudely).  I really like touring our shadowGenerator source code.  I learn something new every time, and I get stuck in a fun shadow project for 2-3 days, playing, testing, learning.  They're pretty cool, and shadows add MUCH "feel" to almost any scene.  It's a curious "how did they do that?" point of interest, to say the least.  Render on!

Link to comment
Share on other sites

Thanks again for mindblowing set. I'll definitely look into that source once i have the time for it. Maybe after this project.

About hundreds of scenes from blender: my plan was to create something from multiple exports on the fly. And when i speak about a scene from blender it basically means 1-5 rather lowpoly meshes, but not sure if i should dump every single mesh in one scene though.

Can't tell if i can take over the world with javascript but if i'm ever gonna do it; i'm going to do it with JS :]

Anyhow, finally got the time to start working on my game which has been in my head for really long now. I'm super excited about this project and hopefully will make announcement here a bit later this year.

Till i feel dumb again!

Link to comment
Share on other sites

5 hours ago, eljuko said:

but not sure if i should dump every single mesh in one scene though.

*nod*.  Yeah, conditionally loading multiple BJS files could be useful under certain circumstances.  I really have low experience in those areas, and it's very dependent upon how your game operates.  The camera frustum (camera maxZ) will keep the render performance good... if user is out of range of other scenes/mesh.  But just because unneeded mesh aren't being rendered... doesn't mean they are gone from memory/cache.  Still, it seems that BJS low frame rates are mostly caused by rendering bog, and not by memory issues.  Still again, there are garbage collection issues, sometimes.  *scratch scratch*

For ease of talking, let's call each of your scenes... a "set"... as in... a movie set (where a scene is shot).  Let's pretend each "set" has 5 mesh.

Now, must the user have more than one "set" in-view at any time?  Can/will they be spaced some distance apart from each other, and user must travel?  Must they see the targeted set they are traveling-to?  Will you need perhaps 10 of these "hundreds of sets" remaining rendered at the same time?

Nosey, aren't I?  :)  Thinkin'.  "hundreds of" is sort of scary.  heh.

Link to comment
Share on other sites

Hey, sorry for a bit late reply. The "world" or should i say game board / area is rather small and almost fully dynamic depending on some random factors. User can almost see the whole game area in first view.

Nosey, perhaps :D but i don't mind. You actually put me think once again and i sure can clamp environmental meshes with subjects like desert, city, jungle and the list goes on. Originally i was planning to import each individual tree and rock for example which is a bit pointless.

But there are the random and userselect factor that kinda demand either that every single mesh will be loaded in 1 import or import as needed = multiple imports which may raise to rather large numbers, but i think it will pay off; maybe not in the beginning but later on.

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.

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.


  • Recently Browsing   0 members

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