Generate and load skybox completely by code

Hey guys, so I’m working on a engine-only project and I was wondering how to have skybox completely by code

this example seems to be outdated: PlayCanvas 3D HTML5 Game Engine

My goal is to generate all the required images on the go (512x512, plain color from code) and i have this part working already, can either store it as a png/jpeg both blob and base64 if needed

or perhaps there’s a smarter solution to have all the goodies that skybox brings including reflections and etc by color code?

You can check out how the model viewer sets the skybox:

PS
Its doing a reprojection technique to “move” the floor of the cubemap up, but you can ignore that. The principle is same.

1 Like

with the plain single color faces of a cubemap, don’t expect any decent looking lighting by the way.
What exactly are you trying to do?

I have a gradient sky shader that is applied to huge box, and these colors change quite often, I know that it would not look as good as with normal detailed skybox, but I’ll be able to use metalicness and reflectivitness on materials, which will bring somewhat better looking results that it is now, completely matte.

My suggestion then would be to look at this example:
https://playcanvas.github.io/#/graphics/reflection-cubemap

create an TEXTUREPROJECTION_EQUIRECT texture, which is a 360 2D texture like this:
Screenshot 2023-10-13 at 09.24.19

and fill it with your colors.

Then create TEXTUREPROJECTION_CUBE texture, and copy data from equirect to it like this:

                pc.reprojectTexture(textureEqui, textureCube, {
                    numSamples: 1,
                });

then generate env atlas from it

// cube -> envAtlas
                pc.EnvLighting.generateAtlas(textureCube, {
                    target: textureAtlas,
                });

and use that as your skydome

            app.scene.envAtlas = textureAtlas;
            app.scene.skyboxMip = 0; // use top mipmap level of cubemap (full resolution)
            app.scene.skyboxIntensity = 2; // make it brighter
2 Likes

Works great!

var Skybox = pc.createScript('skybox');

// initialize code called once per entity
Skybox.prototype.initialize = function() {


var textureCube = new pc.Texture(this.app.graphicsDevice, {
    cubemap: true,
    width: 1024, 
    height: 1024
});

var textureAtlas = new pc.Texture(this.app.graphicsDevice, {
    width: 1024, 
    height: 1024
});

console.log(this.app.assets.find("skybox.jpg", "texture").id);

pc.reprojectTexture(this.app.assets.find("skybox.jpg", "texture").resource, textureCube, {
    numSamples: 1,
});

pc.EnvLighting.generateAtlas(textureCube, {
    target: textureAtlas,
});

this.app.scene.envAtlas = textureAtlas;
this.app.scene.skyboxMip = 0;


};


except that texture is very low quality, but I guess that won’t matther since I will be using simple gradient texture, now just uploaded test equir 1500x500 from internet.

Update: I’ve noticed that ambient color has no effect after adding skybox, or is it something else?

Yes, currently we get ambient either from the single color, or from envAtlas, but not both,

Hmm, how come editor can have both ambient and skybox?


Or i need to utilize different method to achieve same look?

Not sure to be honest, maybe there is some way, but I didn’t think there was.

Even though both options are visible, I don’t think both are used at the same time?

Might be both used, or there’s something else

with the code i’ve been using earlier, once you set the EQUIRECT texture to be completely white, ambient also turns to be completely white, which makes shadows not to appear.

in the editor version capture: skybox is transparent image (white) and the shadows still reflecs by ambient color, which is my goal.

I have another example in the works, might get both working soon

nope

1 Like

Bumping one more time

var Skybox = pc.createScript('skybox');

// initialize code called once per entity
Skybox.prototype.initialize = function() {


var textureCube = new pc.Texture(this.app.graphicsDevice, {
    cubemap: true,
    width: 512, 
    height: 512
});

var textureAtlas = new pc.Texture(this.app.graphicsDevice, {
    width: 512, 
    height: 512
});


pc.reprojectTexture(this.app.assets.find("skybox2", "texture").resource, textureCube, {
});

pc.EnvLighting.generateAtlas(textureCube, {
    target: textureAtlas,
});

this.app.scene.envAtlas = textureAtlas;
this.app.scene.skyboxMip = 0;


};

How would I get the equivalent lighting on materials compared to cubemap?
I’ve tried to apply the same identical texture as a cubemap, while the visual sky is identical, reflection is different, less visible with envAtlas

envatlas


cubemap from editor

Hey guys I got all of this working and I’m setting skybox using envAtlas - all over engine-only
But I still need to be able to set custom ambient color, any ideas?

I’m out of ideas

pc.app.scene.skybox = textureAtlas;
  • Can change ambient
  • No reflections
pc.app.scene.envAtlas = textureAtlas;
  • Can’t change ambient
  • Reflections

Still looking for a solution how to set skybox using pc.app.scene.envAtlas and have a custom ambient color