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;
}
![Smile :)](./images/smilies/icon_smile.gif)
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](http://s1.postimage.org/eo34r.jpg)
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