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();
}
}
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;
}
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
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