Hi, i’m trying to render a bunch of scenes with different HDR textures. I tried to render one scene with prefiltered env file created from Babylon sandbox and it looks great. But since i have too many hdr textures and I dont want to export them through babylon sandbox mannully. So is there a repository for babylon sandbox so that i can include it in my project so that i can bake the hdr files through script? Thank you!
The sandbox is here: Babylon.js/sandbox at master · BabylonJS/Babylon.js · GitHub
The loading code is here:
And the export to .env code is part of the inspector here:
Thanks! Can i ask you some questions about i?
1.So the procedure to create an env file is to load an hdr file to scene --> assign it as scene’s environment texture --> call CreateEnvTextureAsync to create an env file from scene’s environment texture, i want to ask can I just create an env file directly from the hdrCubeTexture ?
2. in the document, besides hdr file we also have to drag pbr scene file to the scene. i don’t understand how the env file works, so I want ask is pbr file compulsory in creating env file? Can I create an env file only with hdr file, and then apply the env file to the pbr scene?
By the way i have been asking questions for days, and I really appreciate your quick ans professional responses!
So you do not need pbr to generate it but sandbox is meant for viewing models first so you can do all you said in 1. without pbr materials .
CreateEnvTextureAsync takes a texture in param so you could simple create you hdrTexture and call CreateEnvTextureAsync with it in parameter if it is easier for you.
I tried to create an env file using CreateEnvTextureAsync function, the code is below:
const environment = new HDRCubeTexture(
“…/…/…/shared-assets/environments/lightroom_14b.hdr”, this[$scene], 256, false, true, false, true);
this[$scene].environmentTexture = environment;
EnvironmentTextureTools.CreateEnvTextureAsync(this[$scene].environmentTexture as CubeTexture).then((buffer: ArrayBuffer)=>{
console.log(buffer);
}
).catch((error=>{
console.log(error);
}))
But it gives me an error that “The cube texture is invalid (not prefiltered)”. I tried to use different hdr textures and it still give the same error. I guess there’s something wrong with the hdrCubeTexture I created, but I’m doing exact the same way as in LoadSkyboxPathTexture(). Could you help me with it? Thank you !
I read the source code and I found that the input of CreateEnvTextureAsync have to be prefiltered, right?
So I can’t just hdr–> env file, i should do hdr–> some prefiltered texture --> env file instead , is that true?
If so, could you give me some hints on how to do that? Thank you !
if (!texture._prefiltered) {
return Promise.reject(“The cube texture is invalid (not prefiltered).”);
}
You need to wait for the texture to be loaded and ready before creating the env file after loading the hdr one.
i tried to call createEnvTexture, in excuteWhenReady function, but it’s still giving me the same error : “The cube texture is invalid (not prefiltered)”
this[$scene].executeWhenReady(() => {
EnvironmentTextureTools
.CreateEnvTextureAsync(this[$scene].environmentTexture as CubeTexture)
.then((buffer: ArrayBuffer) => {
console.log(buffer);
console.log('success');
})
.catch((error => {
console.log(error);
}))
});
}
Could you help me with that? Thank you !
This is the same code that we use internally so it should work, to go further, you should create a repro in the sandbox.
This is working:
Thanks for making a repro for me ! One thing I forgot to mention is my project is written in typescript using strict mode, (also, i use babylon’s es6 module) so im guessing it has something to do with typescript for the two reasons:
1.I looked into the code of createEnvAsync, if the input texture’s _prefiltered is null or false, it will yell the same error as mine that “The cube texture is invalid (not prefiltered)”. I saw you use “environment” directly as input of createEnvAsyns function, but in my project it doesn’t let me do so because of type conflict , so I have to use “environment as unknown as CubeTexture” as input , but this way the casted environment’s prefiltered variable is undefined. I tried to set the _prefiltered property of environment variable to be true
and this error is not shown again, but a new error is shown.
2. The new error is “Env texture can only be created when the engine is created with the premultipliedAlpha option set to false.” In the playground it shows the same error if I switch it to typescript
I found this premultipliedAlpha is a read only variable and didn’t find a way to set it to false.
@sebavan Could you help me with that? Thank you !
Yes engine needs to be instantiated with the correct option premultipliedAlpha set to false.
You can do it in your code when you do new Engine(…
“The cube texture is invalid” is raised when texture.getInternalTexture()
returns null
, which it never should if your texture is valid. I suspect you call CreateEnvTextureAsync
too soon and your texture is not created yet.
https://playground.babylonjs.com/#1PMFC3#1
This PG is the same than the previous one but in Typescript: you can see it does work and does not raise any error. Note that I had to do (engine as any).premultipliedAlpha = false;
to get rid of the Env texture can only be created when the engine is created with the premultipliedAlpha option set to false
error because I don’t know how to override the engine creation in a typescript PG, but of course you should not do that in a real project! My point was to demonstrate you should not get any compilation error (related to I saw you use “environment” directly as input of createEnvAsyns function, but in my project it doesn’t let me do so because of type conflict
): CreateEnvTextureAsync
takes a BaseTexture
as a parameter, and HDRCubeTexture
subclasses BaseTexture
.
You may have some setup problems with your typescript environment.
Thanks for you detailed reply and it helps a lot! There’s still two things i don’t understand:
-
I tried as you did : (engine as any).premultipliedAlpha = false; , this did solve the “Env texture can only be created when the engine is created with the premultipliedAlpha option set to false” error. I just want to ask how to set the option when constructing the engine? I didn’t see how to do that in the constructor
-
As for the type conflict, in my project, the input of CreateEnvTextureAsync takes a CubeTexture instead of a BaseTexture. And i saw HDRCubeTexture inherit BaseTexture directly , that’s why it conflicts with CubeTexture, right?
Here are the babylon’s dependencies im using:
Although this code works, but do you think it’s a safe way to so so in a real project? If not, does that have something to do with the specific version of babylonjs Im using?
const environment = new HDRCubeTexture(
scenario.lighting, this[$scene], 256, false, true, false, true);
const castedEnvironment = environment as unknown as CubeTexture;
castedEnvironment._prefiltered = true;
Thank you !
It should not work, you are using our previous version, it is only available in preview of 4.2.
Set the option through the options
parameter:
new BABYLON.Engine(canvas, true, {
preserveDrawingBuffer: true,
stencil: true,
premultipliedAlpha: false
});
As @sebavan said, the change to use BaseTexture
has been done for 4.2.
However, your changes are ok if you can’t switch to 4.2 and must stick with 4.1, as the only changes performed for 4.2 over 4.1 are:
- change
CubeTexture
toBaseTexture
for thetexture
parameter =>HDRCubeTexture
subclassesBaseTexture
so that’s ok - the check that
_prefiltered
must betrue
has been removed in 4.2. So, setting_prefiltered=true
to make the check pass in 4.1 is ok, but you should reset it tofalse
after the call toCreateEnvTextureAsync
, to get back to the right texture state.
I upgrade babylonjs to the latest 4.2 and everything solved, thank you so much!