PSSM Shadow Shader Problems

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

PSSM Shadow Shader Problems

Post by DGENXP »

Ok I am completely new to shader programming in irrlicht even though i have used code samples found here to make them

This maybe starting really big for someone just starting out with Pixel/vertex shaders and i am aware that this may not even work with irrlicht, but i am trying to use PSSM Shadow mapping for my project, i have found this one

ShadowMap.fx

Code: Select all

// Shader global data

float4x4 viewProjection;
float4x4 world;
float3 lightDirection;
float3 lightColor;
float3 ambientColor;
float shadowMapSize;
float4x4 shadowMapMatrix;

texture shadowTexture;

sampler2D shadowMapSampler = sampler_state
{
	Texture = <shadowTexture>;
	MinFilter = Point;
	MagFilter = Point;
	MipFilter = None;
	AddressU = Border;
	AddressV = Border;
	BorderColor = 0xFFFFFFFF;
}; 

texture objectTexture;

sampler2D objectTextureSampler = sampler_state
{
    Texture = <objectTexture>;
    MinFilter = Anisotropic;
    MagFilter = Anisotropic;
    MipFilter = Linear;
	AddressU = Wrap;
	AddressV = Wrap;
};




// --- Render Shadow Map Technique ---


void VS_RenderShadowMap(float4 pos : POSITION, out float4 outPos : POSITION, out float3 outPixelPos : TEXCOORD0)
{
	float4 posWorld; 
	
	posWorld = mul(pos, world);            
	outPos = mul(posWorld, viewProjection); 
	
	outPixelPos = outPos.xyz;
}


float4 PS_RenderShadowMap(float3 pixelPos : TEXCOORD0): COLOR
{
	// write z coordinate to texture
	return pixelPos.z;
}


technique RenderShadowMap
{
	pass p0
	{
		CullMode = CW;   
		VertexShader = compile vs_2_0 VS_RenderShadowMap();
		PixelShader = compile ps_2_0 PS_RenderShadowMap();
	}
}



// --- Render Shadowed Geometry Technique ---


void VS_Shadowed(in float4 pos : POSITION, in float3 normal : NORMAL,
	float2 texCoord : TEXCOORD0, 
	out float4 outPos : POSITION,
	out float2 outTexCoord : TEXCOORD0,
	out float4 outShadowTexCoord : TEXCOORD1, 
	out float3 outDiffuse : COLOR0)
{
	float4 posWorld;
  
	posWorld = mul(pos, world);           
	outPos = mul(posWorld, viewProjection); 
  
	outDiffuse = lightColor * saturate(dot(-lightDirection, normal));

	outShadowTexCoord = mul(posWorld, shadowMapMatrix);
  
	outTexCoord = texCoord;
}


float4 PS_Shadowed(float2 texCoord : TEXCOORD0, float4 shadowTexCoord : TEXCOORD1, 
	float4 diffuse : COLOR0) : COLOR
{
	float texelSize = 1.0f / shadowMapSize;

	shadowTexCoord.xy /= shadowTexCoord.w;
  
	float4 shadow;

	shadow[0] = (shadowTexCoord.z < tex2D(shadowMapSampler, shadowTexCoord).r);
	shadow[1] = (shadowTexCoord.z < tex2D(shadowMapSampler, shadowTexCoord + float2(texelSize, 0)).r);
	shadow[2] = (shadowTexCoord.z < tex2D(shadowMapSampler, shadowTexCoord + float2(0, texelSize)).r);
	shadow[3] = (shadowTexCoord.z < tex2D(shadowMapSampler, shadowTexCoord + float2(texelSize, texelSize)).r);
  
	float2 lerpFactor = frac(shadowMapSize * shadowTexCoord);

	float lightingFactor = lerp(lerp(shadow[0], shadow[1], lerpFactor.x),
                                 lerp(shadow[2], shadow[3], lerpFactor.x),
                                 lerpFactor.y);

	diffuse *= lightingFactor;
  
	float4 outColor = 1;
	
	outColor.rgb = tex2D(objectTextureSampler, texCoord) * saturate(ambientColor + diffuse).rgb;
		
	return outColor;
}


technique Shadowed
{
	pass p0
	{
		CullMode = CCW;
		VertexShader = compile vs_2_0 VS_Shadowed();
		PixelShader = compile ps_2_0 PS_Shadowed();
	}
}
now i know that this effect is achievable as i have seen wing64 use this in his project, he did not respond when i asked him how to add it so i am turning to the rest of the community, I would be very greatful if you can help me out with this

ok the code i am using to try and test this out is basically the shader tutorial sample 10 in irrlicht 1.4.1

here is my code:

Code: Select all

#include <irrlicht.h>
#include <iostream>


using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

IrrlichtDevice* device = 0;
bool UseHighLevelShaders = false;

class MyShadowDataCallBack : public video::IShaderConstantSetCallBack
{
public:

	virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
	{
		video::IVideoDriver* driver = services->getVideoDriver();


		core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
		invWorld.makeInverse();

		if (UseHighLevelShaders)
			services->setVertexShaderConstant("world", invWorld.pointer(), 16);
		else
			services->setVertexShaderConstant(invWorld.pointer(), 0, 4);

		// set clip matrix

		core::matrix4 worldViewProj;
		worldViewProj = driver->getTransform(video::ETS_PROJECTION);			
		worldViewProj *= driver->getTransform(video::ETS_VIEW);
		worldViewProj *= driver->getTransform(video::ETS_WORLD);

		if (UseHighLevelShaders)
			services->setVertexShaderConstant("viewProjection", worldViewProj.pointer(), 16);
		else
			services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4);		





	}
};

class MyShadowMapCallback : public video::IShaderConstantSetCallBack
{
public:

	virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
	{
		video::IVideoDriver* driver = services->getVideoDriver();


		core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
		invWorld.makeInverse();

		if (UseHighLevelShaders)
			services->setVertexShaderConstant("world", invWorld.pointer(), 16);
		else
			services->setVertexShaderConstant(invWorld.pointer(), 0, 4);

		// set clip matrix

		core::matrix4 worldViewProj;
		worldViewProj = driver->getTransform(video::ETS_PROJECTION);			
		worldViewProj *= driver->getTransform(video::ETS_VIEW);
		worldViewProj *= driver->getTransform(video::ETS_WORLD);

		if (UseHighLevelShaders)
			services->setVertexShaderConstant("viewProjection", worldViewProj.pointer(), 16);
		else
			services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4);		



		core::matrix4 worldShadowMatrix;
		worldShadowMatrix = driver->getTransform(video::ETS_PROJECTION);			
		worldShadowMatrix *= driver->getTransform(video::ETS_VIEW);
		worldShadowMatrix *= driver->getTransform(video::ETS_WORLD);

	}
};

int main()
{
	// let user select driver type

	video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 1;
	}	

	// ask the user if we should use high level shaders for this example
	if (driverType == video::EDT_DIRECT3D9 || 
		 driverType == video::EDT_OPENGL)
	{
		printf("Please press 'y' if you want to use high level shaders.\n");
		std::cin >> i;
		if (i == 'y')
			UseHighLevelShaders = true;
	}

	// create device

	device = createDevice(driverType, core::dimension2d<s32>(640, 480));

	if (device == 0)
		return 1; // could not create selected driver.


	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	gui::IGUIEnvironment* gui = device->getGUIEnvironment();

	c8* vsFileName = 0; // filename for the vertex shader
	c8* psFileName = 0; // filename for the pixel shader

	switch(driverType)
	{
	case video::EDT_DIRECT3D8:
		psFileName = "media/ShadowMap.fx";
		vsFileName = "media/ShadowMap.fx";
		break;
	case video::EDT_DIRECT3D9:
		if (UseHighLevelShaders)
		{
			psFileName = "media/ShadowMap.fx";
			vsFileName = psFileName; // both shaders are in the same file
		}
		else
		{
			psFileName = "media/ShadowMap.fx";
			vsFileName = "media/ShadowMap.fx";
		}
		break;

	case video::EDT_OPENGL:
		if (UseHighLevelShaders)
		{
			psFileName = "media/opengl.frag";
			vsFileName = "media/opengl.vert";
		}
		else
		{
			psFileName = "media/opengl.psh";
			vsFileName = "media/opengl.vsh";
		}
		break;
	}

	if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
		!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
	{
		device->getLogger()->log("WARNING: Pixel shaders disabled "\
			"because of missing driver/hardware support.");
		psFileName = 0;
	}
	
	if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
		!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
	{
		device->getLogger()->log("WARNING: Vertex shaders disabled "\
			"because of missing driver/hardware support.");
		vsFileName = 0;
	}


	video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
	s32 newMaterialType1 = 0;
	s32 newMaterialType2 = 0;

	if (gpu)
	{
		MyShadowMapCallback* SM = new MyShadowMapCallback();
		MyShadowDataCallBack* SD = new MyShadowDataCallBack();



		if (UseHighLevelShaders)
		{
			// create material from high level shaders (hlsl or glsl)

			newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
				vsFileName, "VS_RenderShadowMap", video::EVST_VS_2_0,
				psFileName, "PS_RenderShadowMap", video::EPST_PS_2_0,
				SM, video::EMT_SOLID);

			newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
				vsFileName, "VS_Shadowed", video::EVST_VS_2_0,
				psFileName, "PS_Shadowed", video::EPST_PS_2_0,
				SD, video::EMT_SOLID);
		}
		else
		{
			// create material from low level shaders (asm or arb_asm)

			newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName,
				psFileName, SD, video::EMT_SOLID);

			newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName,
				psFileName, SM, video::EMT_SOLID);
		}

		SD->drop();
		SM->drop();
	}



	// create test scene node 1, with the new created material type 1

	scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("media/MedievalScene.X"));
	node->setPosition(core::vector3df(0,0,0));
	node->setMaterialTexture(0, driver->getTexture("media/wall.bmp"));
	node->setMaterialTexture(1, driver->getTexture("media/wall.bmp"));
	node->setMaterialFlag(video::EMF_LIGHTING, false);

	node->getMaterial(0).MaterialType = (video::E_MATERIAL_TYPE)newMaterialType1;
	node->getMaterial(1).MaterialType = (video::E_MATERIAL_TYPE)newMaterialType2;

	//node->setScale(core::vector3df(30.25,30.25,30.25));
	smgr->addTextSceneNode(gui->getBuiltInFont(), 
			L"PS & VS & EMT_SOLID", 
			video::SColor(255,255,255,255),	node);

	scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
			core::vector3df(0,0.3f,0));
	node->addAnimator(anim);
	anim->drop();


	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

	smgr->addSkyBoxSceneNode(
		driver->getTexture("media/irrlicht2_up.jpg"),
		driver->getTexture("media/irrlicht2_dn.jpg"),
		driver->getTexture("media/irrlicht2_lf.jpg"),
		driver->getTexture("media/irrlicht2_rt.jpg"),
		driver->getTexture("media/irrlicht2_ft.jpg"),
		driver->getTexture("media/irrlicht2_bk.jpg"));

	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

	// add a camera and disable the mouse cursor

	scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
	cam->setPosition(core::vector3df(-100,50,100));
	cam->setTarget(core::vector3df(0,0,0));
	device->getCursorControl()->setVisible(false);

	/*
	Now draw everything. That's all.
	*/

	int lastFPS = -1;

	while(device->run())
		if (device->isWindowActive())
	{
		driver->beginScene(true, true, video::SColor(255,0,0,0));
		smgr->drawAll();
		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
		  core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

		  device->setWindowCaption(str.c_str());
		  lastFPS = fps;
		}
	}

	device->drop();
	
	return 0;
}

I am completely aware that alot of this code is likely to be wrong so no sarcasm please :) i have assmed there needs to be 2 callbacks over 2 materials which is what i have done

now when i try and run the code - it all compiles and runs with no PS or VS Errors but the results are somewhat strange

Image

as you can see from the image there is no shadow at all and even the floor seems to have become a little strange, as in All White which it shouldn't be

Like i said earlier this may be a little enthusiastic for my first self added shader but i really would like this effect for my main project i just need to get it right....

So please please can i get some help
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

The first thing I'd do is check the console. Is the shader not compiling properly? If not an error message would appear in the console.
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

Yeah i did that there is no errors at all
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
wing64
Competition winner
Posts: 242
Joined: Wed Jul 23, 2008 2:35 am
Location: Thailand
Contact:

Post by wing64 »

You can port code from book GPU gem3 - chapter 10 PSSM to irrlicht. :D
(It very easy.)
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

Hmm Like i said i am compleely new to this and that chapter is greek to me, does anyone have a sample of this port as i am not sure where the certain parts of the code need to go lol
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

You can find my PSSM example on this forum and check how it's done in Irrlicht.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

Thats cool m8 could you send us a link so i can check it out there is like 1million posts on this forum - id appreciate it man
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

I see that download link has expired, it was avaiable here:
http://irrlicht.sourceforge.net/phpBB2/ ... &start=135
Currently I don't have access to my PC, so I can't send it to You, but when I will be back at home I can send it.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

thats great thanks
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

You can download PSSM example (binaries) from:
http://www.sendspace.com/file/34wlaa

Sources for it, You can find on irrCg SVN:
http://code.google.com/p/irrcg/source/b ... es/06.PSSM
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

Thanks alot man - the problem is however each time i try to run your CG Code it claims that CG.h cannot be found is there something i am missing as i would really like to use this code for my games....
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

Ok i got the CG pack from nvidia but now im getting linker errors gallore

1>main.obj : error LNK2019: unresolved external symbol "int __cdecl IrrCg::addCgShaderMaterialFromFiles(class IrrCg::CG_CListner *,enum CGenum,char const *,char const *,char const *,char const *,char const *,char const *,char const *,char const *,class IrrCg::ICgShaderConstantSetCallBack *,enum irr::video::E_MATERIAL_TYPE)" (?addCgShaderMaterialFromFiles@IrrCg@@YAHPAVCG_CListner@1@W4CGenum@@PBD2222222PAVICgShaderConstantSetCallBack@1@W4E_MATERIAL_TYPE@video@irr@@@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "class IrrCg::CG_CListner * __cdecl IrrCg::CreateCgInterface(class irr::IrrlichtDevice *)" (?CreateCgInterface@IrrCg@@YAPAVCG_CListner@1@PAVIrrlichtDevice@irr@@@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class irr::IrrlichtDevice * __cdecl irr::createDevice(enum irr::video::E_DRIVER_TYPE,class irr::core::dimension2d<int> const &,unsigned int,bool,bool,bool,class irr::IEventReceiver *,char const *)" (__imp_?createDevice@irr@@YAPAVIrrlichtDevice@1@W4E_DRIVER_TYPE@video@1@ABV?$dimension2d@H@core@1@I_N22PAVIEventReceiver@1@PBD@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _cgGetNamedParameter referenced in function "public: virtual void __thiscall NormalMapCallBack::OnSetConstants(class IrrCg::CG_CListner *,struct _CGprogram *,struct _CGprogram *,class irr::video::SMaterial)" (?OnSetConstants@NormalMapCallBack@@UAEXPAVCG_CListner@IrrCg@@PAU_CGprogram@@1VSMaterial@video@irr@@@Z)

i have linked to the IRR_CG Lib as i should have but i still get these
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

Do You use the latest Irrlicht and irrCg versions from SVN? (it looks like that You use very old version of irrCg). If You use irrCg 0.7.1 (or older) You should upgrade it to version from SVN (rev11).
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

Yeah i have your latest Irrcg From SVN but i am still using Irrlicht 1.4.1 as this was the most stable for RPG Builder - Due to a shedload of Problems especially with the MAYAcam Which is heavily used in RPG Builder i have not upgraded to 1.7 upwards and don't intend to untill these issues are fixed.

So will IRRCG Be ale to be modified by me to work with irrlicht 1.4.1 or can i just forget using it in RPG Builder until the devs here realise and fix the Camera problems....

Thanks in advance
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
DGENXP
Posts: 124
Joined: Tue Dec 27, 2005 2:49 am
Contact:

Post by DGENXP »

Hmm I have tried your CG Pack with irrlicht 1.7 and the latest IrrCG from the site you provided version 0.7.1 and still i get these linker errors

1>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall IrrCg::ICgProgrammingServices::addCgShaderMaterialFromFiles(enum CGenum,char const *,char const *,char const *,char const *,char const *,char const *,char const *,char const *,class IrrCg::ICgShaderConstantSetCallBack *,enum irr::video::E_MATERIAL_TYPE,char const * *)" (?addCgShaderMaterialFromFiles@ICgProgrammingServices@IrrCg@@QAEHW4CGenum@@PBD1111111PAVICgShaderConstantSetCallBack@2@W4E_MATERIAL_TYPE@video@irr@@PAPBD@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall IrrCg::ICgProgrammingServices::ICgProgrammingServices(class irr::IrrlichtDevice *,bool,bool,enum CGenum)" (??0ICgProgrammingServices@IrrCg@@QAE@PAVIrrlichtDevice@irr@@_N1W4CGenum@@@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol __imp__createDevice referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _cgGetNamedParameter referenced in function "public: virtual void __thiscall PerVertexLightingCallBack::OnSetConstants(class IrrCg::ICgServices *,struct _CGprogram *,struct _CGprogram *,class irr::video::SMaterial const &)" (?OnSetConstants@PerVertexLightingCallBack@@UAEXPAVICgServices@IrrCg@@PAU_CGprogram@@1ABVSMaterial@video@irr@@@Z)
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall IrrCg::ICgProgrammingServices::~ICgProgrammingServices(void)" (??1ICgProgrammingServices@IrrCg@@QAE@XZ) referenced in function "public: void * __thiscall IrrCg::ICgProgrammingServices::`scalar deleting destructor'(unsigned int)" (??_GICgProgrammingServices@IrrCg@@QAEPAXI@Z)

I made sure that Visual Studio was linked to them but i still get this problem - some help would be appreated this is the first example in your system
Someone once said A Jack of all trades is a master of none.

Join the Community at the RB3D Forums:

http://www.rpbuilder.org/forum
Post Reply