So my problem is the samplerCube in the fragment shader is like empty in my case (I tried to sample from it and pass the color into gl_FragColor, it just outputs always a black color). However, I tried to draw2DImage() each texture from shadow_cubemap array, it looks as expected.
What I do:
1. create 6 render target textures of video::ECF_A16B16G16R16F color format, cube surfaces and cameras:
Code: Select all
video::ITexture* shadow_t = nullptr;
core::array<video::ITexture*> shadow_cubemap(6);
shadow_cubemap.push_back(vdrv->addRenderTargetTexture(wnd_size, "ShadowSide1RT", video::ECF_A16B16G16R16F));
shadow_cubemap.push_back(vdrv->addRenderTargetTexture(wnd_size, "ShadowSide2RT", video::ECF_A16B16G16R16F));
shadow_cubemap.push_back(vdrv->addRenderTargetTexture(wnd_size, "ShadowSide3RT", video::ECF_A16B16G16R16F));
shadow_cubemap.push_back(vdrv->addRenderTargetTexture(wnd_size, "ShadowSide4RT", video::ECF_A16B16G16R16F));
shadow_cubemap.push_back(vdrv->addRenderTargetTexture(wnd_size, "ShadowSide5RT", video::ECF_A16B16G16R16F));
shadow_cubemap.push_back(vdrv->addRenderTargetTexture(wnd_size, "ShadowSide6RT", video::ECF_A16B16G16R16F));
core::array<video::E_CUBE_SURFACE> shadow_cubemap_surfaces(6);
shadow_cubemap_surfaces.push_back(video::ECS_POSX);
shadow_cubemap_surfaces.push_back(video::ECS_POSY);
shadow_cubemap_surfaces.push_back(video::ECS_POSZ);
shadow_cubemap_surfaces.push_back(video::ECS_NEGX);
shadow_cubemap_surfaces.push_back(video::ECS_NEGY);
shadow_cubemap_surfaces.push_back(video::ECS_NEGZ);
scene::ICameraSceneNode* shadow_cams[] = {
createCameraForCubemap(lights[0]->pos, video::ECS_POSX),
createCameraForCubemap(lights[0]->pos, video::ECS_POSY),
createCameraForCubemap(lights[0]->pos, video::ECS_POSZ),
createCameraForCubemap(lights[0]->pos, video::ECS_NEGX),
createCameraForCubemap(lights[0]->pos, video::ECS_NEGY),
createCameraForCubemap(lights[0]->pos, video::ECS_NEGZ)
};
Code: Select all
// in while loop:
rt->setTexture(shadow_cubemap, depth_t, shadow_cubemap_surfaces);
vdrv->setRenderTargetEx(rt, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255, 0, 0, 0));
table->setMaterialType((video::E_MATERIAL_TYPE)shadow_mat);
skybox->setVisible(false); // skybox shouldn't be rendered to the shadow map as it is not shadowed
for (u16 i = 0; i < 6; i++)
{
smgr->setActiveCamera(shadow_cams[i]);
smgr->drawAll();
}
Code: Select all
// in while loop:
shadow_t = vdrv->addTextureCubemap(
"ShadowRT",
convertTextureToImage(shadow_cubemap[0]),
convertTextureToImage(shadow_cubemap[1]),
convertTextureToImage(shadow_cubemap[2]),
convertTextureToImage(shadow_cubemap[3]),
convertTextureToImage(shadow_cubemap[4]),
convertTextureToImage(shadow_cubemap[5])
);
vdrv->setRenderTargetEx(0, 0);
smgr->setActiveCamera(camera); // set main camera
table->setMaterialType((video::E_MATERIAL_TYPE)lighting_mat);
table->setMaterialTexture(2, shadow_t); // set as second layer the resulted shadow map that will be sent to 'light_mat' shader
skybox->setVisible(true);
smgr->drawAll();
Code: Select all
video::IImage* convertTextureToImage(video::ITexture* tex)
{
video::IVideoDriver* vdrv = device->getVideoDriver();
video::IImage* img = vdrv->createImageFromData(tex->getColorFormat(), tex->getSize(), tex->lock(), false);
tex->unlock();
return img;
}
Code: Select all
s32 base_tex = 0;
s32 normaltex_id = 1;
s32 depthtex_id = 2;
services->setPixelShaderConstant("mBaseTex", &base_tex, 1);
services->setPixelShaderConstant("mNormalTex", &normaltex_id, 1);
services->setPixelShaderConstant("mDepthTex", &depthtex_id, 1); // uniform samplerCube mDepthTex in the fragment shader