Anyone see something out of place in the shaders, or in the code?
to make a graphical explanation of this:
Here, we see that there should be a little of highlights in the tigh, perhaps but there isn't.
And in this image the light is behind the models, so, little, or no highlight should be present, and there they are.
I've tried some combinations, and none of them gave a satisfactory result, this is the closest stage to what a good phong shader should be, IMO, so, if anyone who knew about shaders a bit could take a peek and say what would be out of place, would be a great help. Thanks!
This is the code.
Code: Select all
#include <iostream>
#include <irrlicht.h>
#pragma comment(lib, "Irrlicht.lib")
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
//a small and pointy tweak, using the "user data" i give the callback full access to all the irrlicht device :)
//god bless that pointers are still good ol' 32 bits integers ^O^
class bumpPhongCNS : public IShaderConstantSetCallBack{
public:
virtual void OnSetConstants (IMaterialRendererServices *services, s32 userData){
IrrlichtDevice *dev=(IrrlichtDevice *) userData;
matrix4 matViewProjection=dev->getSceneManager()->getActiveCamera()->getProjectionMatrix();
matViewProjection*=dev->getVideoDriver()->getTransform(ETS_VIEW);
matViewProjection*=dev->getVideoDriver()->getTransform(ETS_WORLD);
vector3df lightPos = vector3df(100,100,100);
services->setVertexShaderConstant("fvLightPosition",reinterpret_cast<f32*>(&lightPos),3);
vector3df camPos = dev->getSceneManager()->getActiveCamera()->getPosition();
services->setVertexShaderConstant("fvEyePosition",reinterpret_cast<f32*>(&camPos),3);
matrix4 matView=dev->getSceneManager()->getActiveCamera()->getProjectionMatrix();
matView*=dev->getVideoDriver()->getTransform(ETS_WORLD);
services->setVertexShaderConstant("matView",&matView[0],16);
services->setVertexShaderConstant("matViewProjection",&matViewProjection[0],16);
SColorf lightAmbient = SColorf(.1,.1,.1,1);
services->setPixelShaderConstant("fvAmbient",reinterpret_cast<f32*>(&lightAmbient),4);
SColorf lightDiffuse = SColorf(1,1,1,1);
services->setPixelShaderConstant("fvDiffuse",reinterpret_cast<f32*>(&lightDiffuse),4);
float specularPower = 25;
services->setPixelShaderConstant("fSpecularPower",reinterpret_cast<f32*>(&specularPower),1);
return;
}
};
int main(int argc, char *argv[])
{
//We create a small direct3d9 device...
IrrlichtDevice *device=0;
ISceneManager *smgr=0;
IVideoDriver *driver=0;
IAnimatedMeshSceneNode *uni=0;
IAnimatedMeshSceneNode *uni2=0;
ISkinnedMesh *uniMesh=0;
IGPUProgrammingServices *gpu=0;
s32 material;
ICameraSceneNode *camara=0;
bumpPhongCNS *cons = new bumpPhongCNS();
device = createDevice(EDT_DIRECT3D9 , dimension2d<s32>(1024, 768),32,false,true,false,0);
if(device){
smgr=device->getSceneManager();
driver=device->getVideoDriver();
if(!smgr||!driver){ exit(1);}
//add a camera, two lights
camara=smgr->addCameraSceneNodeMaya();
camara->setPosition(vector3df(0,1,3));
smgr->addLightSceneNode(0,
vector3df(100, 100, 100),
SColorf(1, 1, 1),
2000);
smgr->addLightSceneNode(0,
vector3df(-100, -100, -100),
SColorf(.5,.5,.5),
2000);
//We load a tiny cool mesh, perhaps Uni.
gpu = driver->getGPUProgrammingServices();
//We load the Shader...
//While it doesn't blow up, experiments are welcome! ^^
material = gpu->addHighLevelShaderMaterialFromFiles (
"./datos/BumpPhongV.hlsl",
"vs_main",
EVST_VS_2_0,
"./datos/BumpPhongP.hlsl",
"ps_main",
EPST_PS_2_0,
cons,
EMT_SOLID,
(s32)device
);
uniMesh = (ISkinnedMesh *) smgr->getMesh("./datos/uni.X");
uniMesh->convertMeshToTangents();
if (uniMesh){
uni = smgr->addAnimatedMeshSceneNode(uniMesh);
}
uni->setMaterialTexture(1,driver->getTexture("./datos/base.body.universe.normals.png"));
uni->getMaterial(0).MaterialType=(E_MATERIAL_TYPE)material;
uni->getMaterial(1).MaterialType=(E_MATERIAL_TYPE)material;
uni->getMaterial(2).MaterialType=(E_MATERIAL_TYPE)material;
uni->getMaterial(3).MaterialType=(E_MATERIAL_TYPE)material;
uni2=smgr->addAnimatedMeshSceneNode(uniMesh);
uni->setPosition(vector3df(-1,0,0));
uni2->setPosition(vector3df(1,0,0));
//We try to put shaders a go go!
device->getCursorControl()->setVisible(false);
int lastFPS;
while(device->run()){
driver->beginScene(true,true,SColor(0,64,128,160));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"PixelShader tests [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
}
//And That's all folks! :)
return 0;
}
Code: Select all
/////Vertex Shader/////////////////////////////////
float3 fvLightPosition;
float3 fvEyePosition;
float4x4 matView;
float4x4 matViewProjection;
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 Normal : NORMAL0;
float3 Binormal : BINORMAL0;
float3 Tangent : TANGENT0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection: TEXCOORD2;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul( Input.Position, matViewProjection );
Output.Texcoord = Input.Texcoord;
float3 fvObjectPosition = mul( Input.Position, matView );
float3 fvViewDirection = fvEyePosition - fvObjectPosition;
float3 fvLightDirection = fvLightPosition - fvObjectPosition ;
float3 fvNormal = mul( Input.Normal, matView );
float3 fvBinormal = mul( Input.Binormal, matView );
float3 fvTangent = mul( Input.Tangent, matView );
Output.ViewDirection.x = dot( fvTangent, fvViewDirection );
Output.ViewDirection.y = dot( fvBinormal, fvViewDirection );
Output.ViewDirection.z = dot( fvNormal, fvViewDirection );
Output.LightDirection.x = dot( fvTangent, fvLightDirection );
Output.LightDirection.y = dot( fvBinormal, fvLightDirection );
Output.LightDirection.z = dot( fvNormal, fvLightDirection );
return( Output );
}
Code: Select all
//////Pixel Shader//////////////////////////////////////////////
float4 fvAmbient;
float4 fvDiffuse;
float4 fvLightColor;
float fSpecularPower;
sampler2D baseMap;
sampler2D bumpMap;
struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection: TEXCOORD2;
};
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float3 fvLightDirection = normalize( Input.LightDirection );
float3 fvNormal = normalize( ( tex2D( bumpMap, Input.Texcoord ).xyz * 2.0f ) - 1.0f );
float fNDotL = dot( fvNormal, fvLightDirection );
float3 fvReflection = normalize( ( ( 2.0f * fvNormal ) * ( fNDotL ) ) - fvLightDirection );
float3 fvViewDirection = normalize( Input.ViewDirection );
float fRDotV = max( 0.0f, dot( fvReflection, fvViewDirection ) );
float4 fvBaseColor = tex2D( baseMap, Input.Texcoord );
float4 fvTotalAmbient = fvAmbient * fvBaseColor;
float4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor ;
float4 fvTotalSpecular = tex2D( baseMap, Input.Texcoord ) * pow( fRDotV, fSpecularPower ) ;
return( saturate( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular ) );
}