I guess I'm just missing something very basic, but I just can't get a HLSL shader to make a terrain transparent.
What I want is to be able to "hide" a terrain partially by using a pixel shader and making it partially transparent. But it seems like the alpha channel is being ignored or something...
Now i broke down the problem, so the shader should only set the color of the terrain to RED (which it does), and the alpha channel to 0 (invisible) which it doesn't. It just shows a solid red terrain, although I used EMT_TRANSPARENT_ADD_COLOR as base material.
This is my HLSL shader code:
Code: Select all
float4x4 matViewProjection : ViewProjection;
struct VS_INPUT
{
float4 Position : POSITION0;
float2 alphamap : TEXCOORD0;
float2 tex : TEXCOORD1;
float4 vertexcolor : COLOR0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 alphamap : TEXCOORD0;
float2 tex : TEXCOORD1;
float4 vertexcolor : COLOR0;
};
struct PS_OUTPUT
{
float4 col : COLOR0;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul( Input.Position, matViewProjection );
Output.alphamap = Input.alphamap;
Output.tex = Input.tex;
Output.vertexcolor = Input.vertexcolor;
return( Output );
}
PS_OUTPUT ps_main(in VS_OUTPUT input)
{
PS_OUTPUT output = (PS_OUTPUT)0;
output.col.r = 255;
output.col.g = 0;
output.col.b = 0;
output.col.a = 0;// seems to be ignored
return output;
}And this is the C++-Irrlicht-Code:
Code: Select all
irr::video::SMaterial TerrainMaterial;
class CAlphaShaderCallBack : public irr::video::IShaderConstantSetCallBack
{
void OnSetConstants(irr::video::IMaterialRendererServices* services, irr::s32 userData)
{
irr::video::IVideoDriver* tmpVideoDriver = services->getVideoDriver();
irr::core::matrix4 worldViewProj;
worldViewProj = tmpVideoDriver->getTransform(irr::video::ETS_PROJECTION);
worldViewProj *= tmpVideoDriver->getTransform(irr::video::ETS_VIEW);
worldViewProj *= tmpVideoDriver->getTransform(irr::video::ETS_WORLD);
services->setVertexShaderConstant("matViewProjection", worldViewProj.pointer(), 16);
}
};
int main()
{
irr::SIrrlichtCreationParameters params;
params.DriverType= irr::video::EDT_DIRECT3D9;
params.WindowSize = core::dimension2d<u32>(800, 600);
IrrlichtDevice* device = createDeviceEx(params);
if (device == 0)
return 1;
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
// add camera
scene::ICameraSceneNode* camera =
smgr->addCameraSceneNodeFPS(0,100.0f,1.2f);
camera->setPosition(irr::core::vector3df(0,10,0));
// add terrain scene node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode("terrain-heightmap.bmp");
irr::io::path shaderFileName ="shader.hlsl";
CAlphaShaderCallBack* tmpShaderCallback = new CAlphaShaderCallBack();
irr::video::IGPUProgrammingServices* tmpGpu = driver->getGPUProgrammingServices();
TerrainMaterial.MaterialType = (irr::video::E_MATERIAL_TYPE)(tmpGpu->addHighLevelShaderMaterialFromFiles(
shaderFileName, "vs_main", irr::video::EVST_VS_2_0,
shaderFileName, "ps_main", irr::video::EPST_PS_2_0,
tmpShaderCallback, irr::video::EMT_TRANSPARENT_ADD_COLOR));
tmpShaderCallback->drop();
terrain->getMaterial(0) = TerrainMaterial;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, video::SColor(255, 0, 0, 100));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}