…tried it, but it did not work unfortunately. Maybe some other texture/material is interfering?
Here is my planet implementation:
export class Planet {
constructor(scene, {
camera: camera,
light: light,
x: x,
y: y,
z: z,
ox: ox,
oy: oy,
oz: oz,
radius: radius,
biome: biome,
}) {
var options = {
biomes: "earth",
clouds: true,
mapSize: 1024,
upperColor: new BABYLON.Color3(2, 1, 0),
lowerColor: new BABYLON.Color3(0, .2, 1),
haloColor: new BABYLON.Color3(0, .2, 1),
maxResolution: 64,
seed: .3,
cloudSeed: .55,
lowerClamp: new BABYLON.Vector2(.6, 1),
groundAlbedo: 1.2,
cloudAlbedo: 1,
directNoise: false,
lowerClip: new BABYLON.Vector2(0, 0),
range: new BABYLON.Vector2(.3, .35)
}
var terrain = new BABYLON.DynamicTexture("random", 128, scene, false, BABYLON.Texture.NEAREST_SAMPLINGMODE);
var clouds = new BABYLON.DynamicTexture("random", 128, scene, false, BABYLON.Texture.NEAREST_SAMPLINGMODE);
var updateRandomSurface = function (random) {
var context = random.getContext();
var data = context.getImageData(0, 0, 512, 512);
for (var i = 0; i < 512 * 512 * 4; i++) {
data.data[i] = Math.random() * 256 | 0
}
context.putImageData(data, 0, 0);
random.update()
};
var noiseTexture;
var cloudTexture;
var diameter = radius * 2;
var cx = (ox > 0) ? ox * Math.cos(0): x;
var cy = (oy > 0) ? oy * Math.cos(0): y;
var cz = (oz > 0) ? oz * Math.sin(0): z;
var planetShell = BABYLON.Mesh.CreateSphere("planet", 64, diameter, scene, false, BABYLON.Mesh.FRONTSIDE);
planetShell.position.x = cx;
planetShell.position.y = cy;
planetShell.position.z = cz;
planetShell.receiveShadows = true;
// the diameter should be 3 less than the shell
var planetBody = BABYLON.Mesh.CreateSphere("planetBody", 32, diameter-3, scene);
planetBody.isBlocker = true;
planetBody.checkCollisions = true;
planetBody.position.x = cx;
planetBody.position.y = cy;
planetBody.position.z = cz;
var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
vertex: "./space/planet",
fragment: "./space/planet"
}, {
attributes: ["position", "normal", "uv"],
uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"],
needAlphaBlending: true
});
shaderMaterial.setVector3("cameraPosition", camera.position);
shaderMaterial.setVector3("lightPosition", light.position);
planetShell.material = shaderMaterial;
var angle = 0;
scene.registerBeforeRender(function () {
var ratio = scene.getAnimationRatio();
planetShell.rotation.y += .001 * ratio;
shaderMaterial.setMatrix("rotation", BABYLON.Matrix.RotationY(angle));
angle -= 4e-4 * ratio;
shaderMaterial.setVector3("options", new BABYLON.Vector3(options.clouds, options.groundAlbedo, options.cloudAlbedo))
});
var generateBiome = function(biome) {
switch (biome) {
case "earth":
//earthSetup();
break;
case "volcanic":
options.upperColor = new BABYLON.Color3(.9, .45, .45);
options.lowerColor = new BABYLON.Color3(.6, 0, 0);
options.haloColor = new BABYLON.Color3(1, 0, .3);
options.seed = .3;
options.cloudSeed = .6;
options.clouds = false;
options.lowerClamp = new BABYLON.Vector2(0, 1);
options.maxResolution = 256;
options.cloudAlbedo = 0;
options.groundAlbedo = 1;
options.rings = false;
options.directNoise = false;
options.lowerClip = new BABYLON.Vector2(0, 0);
options.range = new BABYLON.Vector2(.3, .4);
break;
case "jungle":
options.upperColor = new BABYLON.Color3(.1, .6, .4);
options.lowerColor = new BABYLON.Color3(0, 1, .1);
options.haloColor = new BABYLON.Color3(.5, 1, .5);
options.seed = .4;
options.cloudSeed = .7;
options.clouds = true;
options.lowerClamp = new BABYLON.Vector2(0, 1);
options.maxResolution = 512;
options.cloudAlbedo = 1;
options.groundAlbedo = 1.1;
options.rings = false;
options.directNoise = false;
options.lowerClip = new BABYLON.Vector2(0, 0);
options.range = new BABYLON.Vector2(.2, .4);
break;
case "icy":
options.upperColor = new BABYLON.Color3(1, 1, 1);
options.lowerColor = new BABYLON.Color3(.7, .7, .9);
options.haloColor = new BABYLON.Color3(1, 1, 1);
options.seed = .8;
options.cloudSeed = .4;
options.clouds = true;
options.lowerClamp = new BABYLON.Vector2(0, 1);
options.maxResolution = 256;
options.cloudAlbedo = 1;
options.groundAlbedo = 1.1;
options.rings = true;
options.ringsColor = new BABYLON.Color3(.6, .6, .6);
options.directNoise = false;
options.lowerClip = new BABYLON.Vector2(0, 0);
options.range = new BABYLON.Vector2(.3, .4);
break;
case "desert":
options.upperColor = new BABYLON.Color3(.9, .3, 0);
options.lowerColor = new BABYLON.Color3(1, .5, .1);
options.haloColor = new BABYLON.Color3(1, .5, .1);
options.seed = .18;
options.cloudSeed = .6;
options.clouds = false;
options.lowerClamp = new BABYLON.Vector2(.3, 1);
options.maxResolution = 512;
options.cloudAlbedo = 1;
options.groundAlbedo = 1;
options.rings = false;
options.directNoise = false;
options.lowerClip = new BABYLON.Vector2(0, 0);
options.range = new BABYLON.Vector2(.3, .4);
break;
case "islands":
options.upperColor = new BABYLON.Color3(.4, 2, .4);
options.lowerColor = new BABYLON.Color3(0, .2, 2);
options.haloColor = new BABYLON.Color3(0, .2, 2);
options.seed = .15;
options.cloudSeed = .6;
options.clouds = true;
options.lowerClamp = new BABYLON.Vector2(.6, 1);
options.maxResolution = 512;
options.cloudAlbedo = 1;
options.groundAlbedo = 1.2;
options.rings = false;
options.directNoise = false;
options.lowerClip = new BABYLON.Vector2(0, 0);
options.range = new BABYLON.Vector2(.2, .3);
break;
case "moon":
options.haloColor = new BABYLON.Color3(0, 0, 0);
options.seed = .5;
options.clouds = false;
options.maxResolution = 256;
options.groundAlbedo = .7;
options.rings = false;
options.directNoise = true;
options.lowerClip = new BABYLON.Vector2(.5, .9);
break
}
if (noiseTexture) {
noiseTexture.dispose();
cloudTexture.dispose()
}
updateRandomSurface(terrain);
updateRandomSurface(clouds);
noiseTexture = new BABYLON.ProceduralTexture("noise", options.mapSize, "./space/noise", scene, null, true, true);
noiseTexture.setColor3("upperColor", options.upperColor);
noiseTexture.setColor3("lowerColor", options.lowerColor);
noiseTexture.setFloat("mapSize", options.mapSize);
noiseTexture.setFloat("maxResolution", options.maxResolution);
noiseTexture.setFloat("seed", options.seed);
noiseTexture.setVector2("lowerClamp", options.lowerClamp);
noiseTexture.setTexture("randomSampler", terrain);
noiseTexture.setVector2("range", options.range);
noiseTexture.setVector3("options", new BABYLON.Vector3(options.directNoise ? 1 : 0, options.lowerClip.x, options.lowerClip.y));
shaderMaterial.setTexture("textureSampler", noiseTexture);
cloudTexture = new BABYLON.ProceduralTexture("cloud", options.mapSize, "./space/noise", scene, null, true, true);
cloudTexture.setTexture("randomSampler", clouds);
cloudTexture.setFloat("mapSize", options.mapSize);
cloudTexture.setFloat("maxResolution", 256);
cloudTexture.setFloat("seed", options.cloudSeed);
cloudTexture.setVector3("options", new BABYLON.Vector3(1, 0, 1));
shaderMaterial.setTexture("cloudSampler", cloudTexture);
shaderMaterial.setColor3("haloColor", options.haloColor);
};
generateBiome(biome);
var cx = ox * Math.cos(0);
var cy = oy * Math.cos(0);
var cz = oz * Math.sin(0);
this.orbitCenter = new BABYLON.Vector3(ox, oy, oz);
this.planetShell = planetShell;
this.planetBody = planetBody;
this.scene = scene;
this.planetShell.animations = [];
this.planetBody.animations = [];
this.radian = 0;
}
}
This is how I’m using the planet class.
var sun = new BABYLON.PointLight("sun", new BABYLON.Vector3(100, 100, 100), scene);
var planet = new Planet(scene, {camera: camera, light: sun, x: -40, y: -20, z: -100, radius: 30, biome: "earth"});
var moon1 = new Planet(scene, {camera: camera, light: sun, x: -60, y: -10, z: -10, ox: -40, oy: -20, oz: -100, radius: 5, biome: "moon"});
var moon2 = new Planet(scene, {camera: camera, light: sun, x: -60, y: -10, z: -20, ox: -30, oy: -10, oz: -60, radius: 2, biome: "volcanic"});
var shadowGenerator = new BABYLON.ShadowGenerator(1024, sun);
shadowGenerator.transparencyShadow = true;
shadowGenerator.getShadowMap().renderList.push(planet.planetShell);
shadowGenerator.getShadowMap().renderList.push(moon1.planetShell);
shadowGenerator.getShadowMap().renderList.push(moon2.planetShell);
shadowGenerator.usePoissonSampling = true;
shadowGenerator.addShadowCaster(planet.planetShell);
shadowGenerator.addShadowCaster(moon1.planetShell);
shadowGenerator.addShadowCaster(moon2.planetShell);
Note: I also tried to use the planetBody as well (i.e “addShadowCaster(planet.planetBody) and shadowGenerator.getShadowMap().renderList.push(planet.planetBody)”. I don’t even know why the planetBody/planetImposter mesh is even needed in the original demo but I left it in there. Of course I renamed planetImposter -> planetBody in my code. When I comment out “planetShell.material = shaderMaterial” in the code above the shadow appears as expected, but then I don’t have the fancy biome. I wondering if casting a shadow upon the actual shaderMaterial is even suppose to work. I noticed that shaderMaterial.receiveShadows = true also does not work.