Commit 8637f399 authored by hybrid's avatar hybrid

Enhanced D3D9 normalmap shader by RyanClark.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@842 dfc29bdd-3216-0410-991c-e03cc46cb475
parent b004d40f
...@@ -82,7 +82,7 @@ namespace video ...@@ -82,7 +82,7 @@ namespace video
"\n"; "\n";
// Irrlicht Engine D3D9 render path normal map pixel shader // Irrlicht Engine D3D9 render path normal map pixel shader
const char D3D9_NORMAL_MAP_PSH[] = const char D3D9_NORMAL_MAP_PSH_1_1[] =
";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\ ";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\
";Input: \n"\ ";Input: \n"\
";t0: color map texture coord \n"\ ";t0: color map texture coord \n"\
...@@ -108,6 +108,60 @@ namespace video ...@@ -108,6 +108,60 @@ namespace video
"+mov r0.a, v0.a ; write interpolated vertex alpha value \n"\ "+mov r0.a, v0.a ; write interpolated vertex alpha value \n"\
"\n"\ "\n"\
""; "";
// Higher-quality normal map pixel shader (requires PS 2.0)
// uses per-pixel normalization for improved accuracy
const char D3D9_NORMAL_MAP_PSH_2_0[] =
";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\
";Input: \n"\
";t0: color map texture coord \n"\
";t1: normal map texture coords \n"\
";t2: light 1 vector in tangent space \n"\
";v0: light 1 color \n"\
";t3: light 2 vector in tangent space \n"\
";v1: light 2 color \n"\
";v0.a: vertex alpha value \n"\
"ps_2_0 \n"\
"def c0, 0, 0, 0, 0\n"\
"def c1, 1.0, 1.0, 1.0, 1.0\n"\
"def c2, 2.0, 2.0, 2.0, 2.0\n"\
"def c3, -.5, -.5, -.5, -.5\n"\
"dcl t0\n"\
"dcl t1\n"\
"dcl t2\n"\
"dcl t3\n"\
"dcl v1\n"\
"dcl v0\n"\
"dcl_2d s0\n"\
"dcl_2d s1\n"\
"texld r0, t0, s0 ; sample color map into r0 \n"\
"texld r4, t0, s1 ; sample normal map into r4\n"\
"add r4, r4, c3 ; bias the normal vector\n"\
"add r5, t2, c3 ; bias the light 1 vector into r5\n"\
"add r6, t3, c3 ; bias the light 2 vector into r6\n"\
"nrm r1, r4 ; normalize the normal vector into r1\n"\
"nrm r2, r5 ; normalize the light1 vector into r2\n"\
"nrm r3, r6 ; normalize the light2 vector into r3\n"\
"dp3 r2, r2, r1 ; let r2 = normal DOT light 1 vector\n"\
"max r2, r2, c0 ; clamp result to positive numbers\n"\
"mul r2, r2, v0 ; let r2 = luminance1 * light color 1 \n"\
"dp3 r3, r3, r1 ; let r3 = normal DOT light 2 vector\n"\
"max r3, r3, c0 ; clamp result to positive numbers\n"\
"mad r2, r3, v1, r2 ; let r2 = (luminance2 * light color 2) + (luminance2 * light color 1) \n"\
"mul r2, r2, r0 ; let r2 = total luminance * base color\n"\
"mov r2.w, v0.w ; write interpolated vertex alpha value \n"\
"mov oC0, r2 ; copy r2 to the output register \n"\
"\n"\
"";
CD3D9NormalMapRenderer::CD3D9NormalMapRenderer( CD3D9NormalMapRenderer::CD3D9NormalMapRenderer(
IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, IDirect3DDevice9* d3ddev, video::IVideoDriver* driver,
...@@ -151,7 +205,14 @@ namespace video ...@@ -151,7 +205,14 @@ namespace video
else else
{ {
// compile shaders on our own // compile shaders on our own
init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH); if (driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0))
{
init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_2_0);
}
else
{
init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_1_1);
}
} }
} }
......
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
namespace irr namespace irr
{ {
namespace video namespace video
{ {
// 1.1/1.4 Shaders with two lights and vertex based attenuation // 1.1/1.4 Shaders with two lights and vertex based attenuation
// Irrlicht Engine D3D9 render path normal map vertex shader // Irrlicht Engine D3D9 render path normal map vertex shader
const char D3D9_PARALLAX_MAP_VSH[] = const char D3D9_PARALLAX_MAP_VSH[] =
";Irrlicht Engine 0.10 D3D9 render path parallax mapping vertex shader\n"\ ";Irrlicht Engine 0.10 D3D9 render path parallax mapping vertex shader\n"\
"; c0-3: Transposed world matrix \n"\ "; c0-3: Transposed world matrix \n"\
"; c4: Eye position \n"\ "; c4: Eye position \n"\
...@@ -45,7 +45,7 @@ namespace video ...@@ -45,7 +45,7 @@ namespace video
"def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\ "def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\
"\n"\ "\n"\
"m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\
"\n"\ "\n"\
"m3x3 r5, v4, c0 ; transform tangent U\n"\ "m3x3 r5, v4, c0 ; transform tangent U\n"\
"m3x3 r7, v1, c0 ; transform normal W\n"\ "m3x3 r7, v1, c0 ; transform normal W\n"\
"m3x3 r6, v5, c0 ; transform binormal V\n"\ "m3x3 r6, v5, c0 ; transform binormal V\n"\
...@@ -102,7 +102,7 @@ namespace video ...@@ -102,7 +102,7 @@ namespace video
// Irrlicht Engine D3D9 render path normal map pixel shader version 1.4 // Irrlicht Engine D3D9 render path normal map pixel shader version 1.4
const char D3D9_PARALLAX_MAP_PSH[] = const char D3D9_PARALLAX_MAP_PSH[] =
";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\ ";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\
";Input: \n"\ ";Input: \n"\
";t0: color map texture coord \n"\ ";t0: color map texture coord \n"\
...@@ -121,7 +121,7 @@ namespace video ...@@ -121,7 +121,7 @@ namespace video
" \n"\ " \n"\
"texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\ "texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\
"texcrd r4.xyz, t4 ; fetch eye vector \n"\ "texcrd r4.xyz, t4 ; fetch eye vector \n"\
"texcrd r0.xyz, t0 ; color map \n"\ "texcrd r0.xyz, t0 ; color map \n"\
" \n"\ " \n"\
"; original parallax mapping: \n"\ "; original parallax mapping: \n"\
";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\ ";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\
...@@ -150,7 +150,7 @@ namespace video ...@@ -150,7 +150,7 @@ namespace video
"\n"; "\n";
// Irrlicht Engine D3D9 render path normal map pixel shader version 2.0 // Irrlicht Engine D3D9 render path normal map pixel shader version 2.0
const char D3D9_PARALLAX_MAP_PSH_20[] = const char D3D9_PARALLAX_MAP_PSH_20[] =
";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\ ";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\
";Input: \n"\ ";Input: \n"\
" \n"\ " \n"\
...@@ -219,15 +219,15 @@ namespace video ...@@ -219,15 +219,15 @@ namespace video
"mul r0.xyz, r0, r3 ; total luminance * base color \n"\ "mul r0.xyz, r0, r3 ; total luminance * base color \n"\
"mov r0.a, v0.a ; write original alpha value \n"\ "mov r0.a, v0.a ; write original alpha value \n"\
"mov oC0, r0; \n"\ "mov oC0, r0; \n"\
"\n"; "\n";
CD3D9ParallaxMapRenderer::CD3D9ParallaxMapRenderer( CD3D9ParallaxMapRenderer::CD3D9ParallaxMapRenderer(
IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, IDirect3DDevice9* d3ddev, video::IVideoDriver* driver,
s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial)
: CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), : CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial),
CurrentScale(0.0f) CurrentScale(0.0f)
{ {
// set this as callback. We could have done this in // set this as callback. We could have done this in
// the initialization list, but some compilers don't like it. // the initialization list, but some compilers don't like it.
CallBack = this; CallBack = this;
...@@ -244,12 +244,12 @@ namespace video ...@@ -244,12 +244,12 @@ namespace video
return; return;
} }
// check if already compiled parallax map shaders are there. // check if already compiled parallax map shaders are there.
video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID);
if (renderer) if (renderer)
{ {
// use the already compiled shaders // use the already compiled shaders
video::CD3D9ParallaxMapRenderer* nmr = (video::CD3D9ParallaxMapRenderer*)renderer; video::CD3D9ParallaxMapRenderer* nmr = (video::CD3D9ParallaxMapRenderer*)renderer;
VertexShader = nmr->VertexShader; VertexShader = nmr->VertexShader;
if (VertexShader) if (VertexShader)
...@@ -303,17 +303,17 @@ namespace video ...@@ -303,17 +303,17 @@ namespace video
return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype);
} }
void CD3D9ParallaxMapRenderer::OnSetMaterial(video::SMaterial& material, void CD3D9ParallaxMapRenderer::OnSetMaterial(video::SMaterial& material,
const video::SMaterial& lastMaterial, const video::SMaterial& lastMaterial,
bool resetAllRenderstates, video::IMaterialRendererServices* services) bool resetAllRenderstates, video::IMaterialRendererServices* services)
{ {
CD3D9ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, CD3D9ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial,
resetAllRenderstates, services); resetAllRenderstates, services);
CurrentScale = material.MaterialTypeParam; CurrentScale = material.MaterialTypeParam;
} }
//! Returns the render capability of the material. //! Returns the render capability of the material.
s32 CD3D9ParallaxMapRenderer::getRenderCapability() s32 CD3D9ParallaxMapRenderer::getRenderCapability()
{ {
if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) && if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) &&
...@@ -335,8 +335,8 @@ namespace video ...@@ -335,8 +335,8 @@ namespace video
// set eye position // set eye position
// The viewpoint is at (0., 0., 0.) in eye space. // The viewpoint is at (0., 0., 0.) in eye space.
// Turning this into a vector [0 0 0 1] and multiply it by // Turning this into a vector [0 0 0 1] and multiply it by
// the inverse of the view matrix, the resulting vector is the // the inverse of the view matrix, the resulting vector is the
// object space location of the camera. // object space location of the camera.
...@@ -348,7 +348,7 @@ namespace video ...@@ -348,7 +348,7 @@ namespace video
// set transposed worldViewProj matrix // set transposed worldViewProj matrix
core::matrix4 worldViewProj; core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION); worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW); worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD); worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4);
...@@ -357,10 +357,10 @@ namespace video ...@@ -357,10 +357,10 @@ namespace video
// and set them as constants // and set them as constants
int cnt = driver->getDynamicLightCount(); int cnt = driver->getDynamicLightCount();
for (int i=0; i<2; ++i) for (int i=0; i<2; ++i)
{ {
SLight light; SLight light;
if (i<cnt) if (i<cnt)
light = driver->getDynamicLight(i); light = driver->getDynamicLight(i);
...@@ -383,14 +383,14 @@ namespace video ...@@ -383,14 +383,14 @@ namespace video
services->setVertexShaderConstant(c96, 96, 1); services->setVertexShaderConstant(c96, 96, 1);
// set scale factor // set scale factor
f32 factor = 0.02f; // default value f32 factor = 0.02f; // default value
if (CurrentScale != 0) if (CurrentScale != 0)
factor = CurrentScale; factor = CurrentScale;
f32 c6[] = {factor, factor, factor, 0}; f32 c6[] = {factor, factor, factor, 0};
services->setPixelShaderConstant(c6, 6, 1); services->setPixelShaderConstant(c6, 6, 1);
} }
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment