Closed coramat closed 2 years ago
Nit: You are not using a HDR environment map in your fiddle. Try using RGBELoader
or EXRLoader
.
Updated fiddle: https://jsfiddle.net/c5hjnpzm/1/
If you copy the code from MeshStandardMaterial
to a custom shader, you should know that the GLSL is not compatible with an environment map in the cube map or equirectangular format. Only the cubeUV format works which is generated by using PMREMGenerator
.
I suggest you only create shader materials from built-in material shader code if you really know the internals. Otherwise I recommend to use onBeforeCompile()
and extend a built-in material with custom logic. This also requires knowledge about the shader source however less things can break.
If you need more help, please use the forum.
Nit: You are not using a HDR environment map in your fiddle. Try using
RGBELoader
orEXRLoader
.
You are right, I am using an HDR in my project and I forgot to update that part in the fiddle.
Thanks a lot for the quick help!
@Mugen87 would it be possible to direct use the scene.enviroment Texture for a ShaderMaterial? updated the example https://jsfiddle.net/rudcsb16/3/
@arpu I'm also trying to create a shader including scene.environment (or scene.background) as envMap. @Mugen87 can you explain a bit on how defines get automatically passed in your initial updated fiddle (https://jsfiddle.net/c5hjnpzm/1/) ? The one OP provided included defines but yours doesn't and it works.. How can that also be applied for ShaderMaterial + scene.environment as envMap. Thanks!
would it be possible to direct use the scene.enviroment Texture for a ShaderMaterial?
No, that does not work since Scene.environment
only affects PBR materials. And you can not guarantee that a custom shader material is always PBR conform.
can you explain a bit on how defines get automatically passed in your initial updated fiddle
The environment map defines are automatically generated when the renderer encounters the envMap
property when processing a material. IIRC, the original fiddle did not work since the env map type was wrong (so it was unrelated to defines).
I, like @max-sym, am interested in writing a ShaderMaterial that can use the scene's environment when the material's envMap property is not defined. Just to clarify @Mugen87, are you saying that is not possible? If it is possible what would we need to do in fragment code to make that happen? I'm having a hard time reverse engineering how it works on the built in materials.
Just to clarify @Mugen87, are you saying that is not possible?
No it isn't. You have to apply hacks and modifications to your project to make this work which I do not recommend. Consider to use onBeforeCompile()
and modify an instance of MeshStandardMaterial
or MeshPhysicalMaterial
.
Please use the forum if you need more guidance in this context.
Hi Everyone,
I am having issues using an environment map with ShaderMaterial.
I am loading the envMap using
THREE.CubeTextureLoader
, which works perfectly withMeshStandardMaterial
but has no effect if I use insteadShaderMaterial
, as you can see in this fiddle example: https://jsfiddle.net/3jo6Ldpf/2/ .The cube on the right has a ShaderMaterial applied and the HDRI is not showing up. In the same example, I tried using the option: (line 51)
and I get the following error:
There is a function in WebGLProgram.js called
generateCubeUVSize
that is suppose to compute the values of CUBEUV_MAX_MIP, CUBEUV_TEXEL_WIDTH, and CUBEUV_TEXEL_HEIGHT, and then automatically generating the corresponding definitions(defines), so I was puzzled why it was not working in this case.When I tried manually defining those options by adding in the same fiddle example these lines of code:
I got this error:
regarding the shader chunk
envmap_physical_pars_fragment.glsl.js
.This gave me the hint that
envMap
passed in the functiontextureCubeUV
is not the sampler2D uniform expected by the function but something else. The type of envmap seems to derive from the shaderChunkenvmap_common_pars_fragment.glsl.js
, which define envmap asuniform samplerCube envMap;
rather thanuniform sampler2D envMap;
ifENVMAP_TYPE_CUBE
has been defined.So I wanted to understand who defines
ENVMAP_TYPE_CUBE
, since in the fiddle code I definedENVMAP_TYPE_CUBE_UV
, and in WebGLPrograms.js I found this piece of code:where it seems that if you do not have a
MeshStandardMaterial
you cannot have cubeuvmaps.This code could also explain why I was getting the error about CUBEUV_MAX_MIP etc not being defined, because those defines are happening only if
envMapCubeUVHeight
is not null.Is there a way to have an HDRI working with
ShaderMaterial
?I am not a threejs expert so I might be not considering something trivial. I just tried to debug as much as I could until I got stuck to avoid bothering you folks <3