Page 1 of 1

Creating projected shadows with RenderTargetTexture/Manip.

Posted: Tue May 16, 2006 11:17 am
by Robat
I want to have cheap shadows for my bicycle model and so I created a camera fixed to the sunlight that renders the bicycle model in a second render pass to a texture attached to a plane below the bicycle. But the rendered image is colored and sharp (naturally :). The shadow plane has transparency as well.
Does anyone know how to manipulate the rendertarget-Texture to make the colored texture-parts black and to blur the projected image a bit? I searched in the forum and didn't find a real solution. Is it at all possible to show the manipulations in the texture after the image is rendered? Can I access the buffer directly before rendering it to the texture? Telling the camera it should see everything black?

Please note I am a newbie in both c++ programming and Irrlicht :D.
Thank you so far.

This is the code I have so far:

//creation of shadow plane
IAnimatedMesh* pShdMesh = pSmgr->getMesh("../media/shadowPlane.X");
IAnimatedMeshSceneNode* mShdNode = pSmgr->addAnimatedMeshSceneNode(pShadowMesh);
mShdNode ->setPosition(pBikeNode->getPosition());
mShdNode ->setRotation(vector3df(0,-90,0));
mShdNode ->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL);

//render target texture creation
ITexture* pRtTexture = pDriver->createRenderTargetTexture(dimension2d<s32>(256,256));
mShdNode ->setMaterialTexture(0, pRtTexture);

//projectionCam
ICameraSceneNode* pFixedCam = pSmgr->addCameraSceneNode(pSmgr->getRootSceneNode(), (pBicycleNode->getPosition() + vector3df(200,200,0)), pBicycleNode->getPosition(), 1);

//drawing scene
while(pDevice->run()){

if(pRtTexture){
pDriver->beginScene(true, true, 0);
pDriver->setRenderTarget(pRtTexture , true, true, SColor(0,0,0,0));
pSmgr->setActiveCamera(pFixedCam);
pSmgr->drawAll();

//Here I wanted to manipulate the texture
colorizeShadow();

// set back old render target
pDriver->setRenderTarget(0);
pSmgr->setActiveCamera(pCameraNode);
}
}

pSmgr->drawAll();
pGuienv->drawAll();
pDriver->endScene();



void colorizeShadow(){
//locking works because of the fix of TURBOFERRET
u32* pixel = (u32*)pRtTexture->lock();
int pitch = mrtTexture->getPitch();
for (int y=0; y < 256; y++){
for (int x=0; x < 256; x++) {
//this doesn't work really, doesn't show result, A8R8G8B8
pixel[y * pitch/4 + x] = 16164555;
}
}
pRtTexture->unlock();
}

Is this a cheap method at all? I mainly do it because the bicycle has a high poly count and Stencil buffer shadows are so slow.

Posted: Tue May 16, 2006 11:52 am
by JP
You could probably make the bicycle black in the rendered texture by turning the lighting off or something similar when you render to the shadow texture? Then turn it back on for rendering the whole scene.

Posted: Tue May 16, 2006 12:15 pm
by Robat
Sounds good, thanks, and it works :). The only thing I try now is to chnnge the vertex colors from white to black, because switching EMF_LIGHTING to false lights the model with the vertex colors(?). Or am I wrong?

Robert

Posted: Tue May 16, 2006 12:28 pm
by hybrid
Better switch off all lights and leave the models with EMF_LIGHTING==true. This will render all objects in black and only requires little changes to your scene.

Posted: Tue May 16, 2006 1:03 pm
by Robat
Thanks hybrid, this is really good. It works, I switched the one light off with the following code:

lightData.DiffuseColor = SColorf(0.0f, 0.0f, 0.0f);
lightData.AmbientColor = SColorf(0.0f, 0.0f, 0.0f);

So if there is simpler code, like a flag for visible or not, please tell me, I didn't find any adjustable flag.

Robert

Posted: Tue May 16, 2006 3:21 pm
by hybrid
Just make the ILightSceneNode invisible and it is not rendered anymore.

Posted: Wed May 17, 2006 8:38 am
by Robat
Thanks :). Perfekt.