BurningVideo 0.51 - NormalMap

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6101 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
engineer_apple 2020-02-27 00:17:46 +00:00
parent 725391bf50
commit 704c9eec83
5 changed files with 48 additions and 119 deletions

@ -1,13 +1,17 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- BurningVideo: 0.50 - BurningVideo: 0.51
- 10 year anniversary update - 10 year anniversary update
- Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map] - Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map]
- increased internal s4DVertex to support 4 Textures and 4 Colors [switchable] - increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]
- Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption - Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption
- 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D - 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D
- Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE] - Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]
- NormalMap for 1 Light accurate. still all lights are accumulated
- SuperTuxKart 8.0.1 playable - SuperTuxKart 8.0.1 playable
- Known Problems
- Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows
- Triangle MipMap Selection. Wrong for TextureAtlas and Billboards
- Fix CPLYMeshFileLoader checking for wrong vertex count when switching between 16/32 bit. Thanks @randomMesh for reporting. - Fix CPLYMeshFileLoader checking for wrong vertex count when switching between 16/32 bit. Thanks @randomMesh for reporting.
- Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes. - Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes.
- Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function. - Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function.

@ -70,7 +70,7 @@ bool CMainMenu::run()
gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1); gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1);
box->addItem(L"OpenGL 1.5"); box->addItem(L"OpenGL 1.5");
box->addItem(L"Direct3D 9.0c"); box->addItem(L"Direct3D 9.0c");
box->addItem(L"Burning's Video 0.5"); box->addItem(L"Burning's Video 0.51");
box->addItem(L"Irrlicht Software Renderer 1.0"); box->addItem(L"Irrlicht Software Renderer 1.0");
switch (driverType ) switch (driverType )
{ {

@ -145,7 +145,7 @@ inline void rotateVec3Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict
out[3] = 0.f; out[3] = 0.f;
} }
//https://github.com/ekmett/approximate/blob/master/cbits/fast.c powf_fast_precise //based on https://github.com/ekmett/approximate/blob/master/cbits/fast.c powf_fast_precise
static inline float powf_limit(const float a, const float b) static inline float powf_limit(const float a, const float b)
{ {
if (a <= 0.0000001f) return 0.f; if (a <= 0.0000001f) return 0.f;
@ -410,7 +410,6 @@ CBurningVideoDriver::~CBurningVideoDriver()
} }
// delete triangle renderers // delete triangle renderers
for (s32 i=0; i<ETR2_COUNT; ++i) for (s32 i=0; i<ETR2_COUNT; ++i)
{ {
if (BurningShader[i]) if (BurningShader[i])
@ -539,9 +538,6 @@ void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO st
case ETS_VIEW_PROJECTION: case ETS_VIEW_PROJECTION:
ok = flag[ETS_VIEW] & flag[ETS_PROJECTION] & ETF_VALID; ok = flag[ETS_VIEW] & flag[ETS_PROJECTION] & ETF_VALID;
break; break;
//case ETS_VIEW_INVERSE:
// ok = TransformationFlag[ETS_VIEW] & ETF_VALID;
// break;
case ETS_MODEL_VIEW: case ETS_MODEL_VIEW:
ok = flag[ETS_WORLD] & flag[ETS_VIEW] & ETF_VALID; ok = flag[ETS_WORLD] & flag[ETS_VIEW] & ETF_VALID;
break; break;
@ -574,10 +570,6 @@ void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO st
} }
break; break;
//case ETS_VIEW_INVERSE:
// mat44_inverse(matrix[state],matrix[ETS_VIEW]);
// break;
case ETS_VIEW_PROJECTION: case ETS_VIEW_PROJECTION:
matrix[state].setbyproduct_nocheck (matrix[ETS_PROJECTION], matrix[ETS_VIEW]); matrix[state].setbyproduct_nocheck (matrix[ETS_PROJECTION], matrix[ETS_VIEW]);
break; break;
@ -642,7 +634,6 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core:
case ETS_VIEW: case ETS_VIEW:
flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID; flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;
flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID; flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID;
//flag[ETS_VIEW_INVERSE] &= ~ETF_VALID;
flag[ETS_MODEL_VIEW] &= ~ETF_VALID; flag[ETS_MODEL_VIEW] &= ~ETF_VALID;
flag[ETS_NORMAL] &= ~ETF_VALID; flag[ETS_NORMAL] &= ~ETF_VALID;
break; break;
@ -1120,21 +1111,20 @@ inline void CBurningVideoDriver::ndc_2_dc_and_project (s4DVertexPair* dest,const
for ( size_t g = 0; g != vIn; g += sizeof_s4DVertexPairRel) for ( size_t g = 0; g != vIn; g += sizeof_s4DVertexPairRel)
{ {
if ( dest[g].flag & VERTEX4D_PROJECTED ) //cache doesn't work anymore?
continue; //if ( dest[g].flag & VERTEX4D_PROJECTED )
// continue;
//dest[g].flag = source[g].flag | VERTEX4D_PROJECTED;
dest[g].flag = source[g].flag | VERTEX4D_PROJECTED; const f32 iw = reciprocal_zero (source[g].Pos.w);
const f32 w = source[g].Pos.w;
const f32 iw = reciprocal_zero ( w );
// to device coordinates // to device coordinates
dest[g].Pos.x = iw * ( source[g].Pos.x * dc[0] + w * dc[1] ); dest[g].Pos.x = iw * source[g].Pos.x * dc[0] + dc[1];
dest[g].Pos.y = iw * ( source[g].Pos.y * dc[2] + w * dc[3] ); dest[g].Pos.y = iw * source[g].Pos.y * dc[2] + dc[3];
//burning uses direct Z. for OpenGL it should be -Z and texture flip //burning uses direct Z. for OpenGL it should be -Z,[-1;1] and texture flip
#if !defined(SOFTWARE_DRIVER_2_USE_WBUFFER) || 1 #if !defined(SOFTWARE_DRIVER_2_USE_WBUFFER) || 1
dest[g].Pos.z = iw * source[g].Pos.z; dest[g].Pos.z = -iw * source[g].Pos.z * 0.5f + 0.5f;
#endif #endif
dest[g].Pos.w = iw; dest[g].Pos.w = iw;
@ -1234,6 +1224,7 @@ f32 MipmapLevel(const sVec2& uv, const sVec2& textureSize)
attribute need not to follow winding rule from position. attribute need not to follow winding rule from position.
Edge-walking problem Edge-walking problem
Texture Wrapping problem Texture Wrapping problem
Atlas problem
*/ */
REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burning_restrict const face[], REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burning_restrict const face[],
const size_t m, f32 dc_area, f32 lod_bias) const const size_t m, f32 dc_area, f32 lod_bias) const
@ -1731,7 +1722,7 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
Uw Vw 0 0 Uw Vw 0 0
*/ */
const sVec4& u = EyeSpace.cam_dir; const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized
const sVec4& n = EyeSpace.normal; const sVec4& n = EyeSpace.normal;
sVec4 r; sVec4 r;
@ -1741,11 +1732,6 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
// texgen // texgen
if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_SPHERE ) if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_SPHERE )
{ {
//u.x = EyeSpace.vertex.x;
//u.y = EyeSpace.vertex.y;
//u.z = EyeSpace.vertex.z;
//u.normalize_dir_xyz();
//reflect(u,N) u - 2.0 * dot(N, u) * N //reflect(u,N) u - 2.0 * dot(N, u) * N
// cam is (0,0,-1), tex flipped // cam is (0,0,-1), tex flipped
f32 dot = -2.f * n.dot_xyz(u); f32 dot = -2.f * n.dot_xyz(u);
@ -1767,11 +1753,6 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
} }
else if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_REFLECTION ) else if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_REFLECTION )
{ {
//u.x = EyeSpace.vertex.x;
//u.y = EyeSpace.vertex.y;
//u.z = EyeSpace.vertex.z;
//u.normalize_dir_xyz();
//reflect(u,N) u - 2.0 * dot(N, u) * N //reflect(u,N) u - 2.0 * dot(N, u) * N
// cam is (0,0,-1), tex flipped // cam is (0,0,-1), tex flipped
f32 dot = -2.f * n.dot_xyz(u); f32 dot = -2.f * n.dot_xyz(u);
@ -1868,7 +1849,6 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
for ( u32 i = 0; i < 2 && i < EyeSpace.Light.size (); ++i ) for ( u32 i = 0; i < 2 && i < EyeSpace.Light.size (); ++i )
{ {
const SBurningShaderLight &light = EyeSpace.Light[i]; const SBurningShaderLight &light = EyeSpace.Light[i];
if ( !light.LightIsOn ) if ( !light.LightIsOn )
continue; continue;
@ -1876,41 +1856,19 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
vp.y = light.pos4.y - EyeSpace.vertex.y; vp.y = light.pos4.y - EyeSpace.vertex.y;
vp.z = light.pos4.z - EyeSpace.vertex.z; vp.z = light.pos4.z - EyeSpace.vertex.z;
//vp.normalize_dir_xyz(); // lightcolor with standard model
// but shader is brighter and using different normalmatrix
// transform by tangent matrix // transform by tangent matrix
sVec4 l; light_accu.x += (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z );
#if 0 light_accu.y += (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z );
l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z ); light_accu.z += (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z );
l.y = (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z );
l.z = (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z );
#else
l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Binormal.X + vp.z * tangent->Normal.X );
l.y = (vp.x * tangent->Tangent.Y + vp.y * tangent->Binormal.Y + vp.z * tangent->Normal.Y );
l.z = (vp.x * tangent->Tangent.Z + vp.y * tangent->Binormal.Z + vp.z * tangent->Normal.Z );
#endif
/*
f32 scale = 1.f / 128.f;
if ( dest->LightTangent[0].y != 0.f )
scale /= dest->LightTangent[0].y;
// emboss, shift coordinates
dest->Tex[1].x = dest->Tex[0].x + l.r * scale;
dest->Tex[1].y = dest->Tex[0].y + l.g * scale;
*/
dest->Tex[1].x = dest->Tex[0].x;
dest->Tex[1].y = dest->Tex[0].y;
// scale bias
light_accu.x += l.x;
light_accu.y += l.y;
light_accu.z += l.z;
} }
//normalize [-1,+1] to [0,1] //normalize [-1,+1] to [0,1] -> obsolete
light_accu.normalize_pack_xyz(dest->LightTangent[0],0.5f, 0.5f); light_accu.normalize_pack_xyz(dest->LightTangent[0],1.f, 0.f);
dest->Tex[1].x = dest->Tex[0].x;
dest->Tex[1].y = dest->Tex[0].y;
} }
else if (Material.org.Lighting) else if (Material.org.Lighting)
{ {
@ -2483,28 +2441,6 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl)
return EyeSpace.Light.size() - 1; return EyeSpace.Light.size() - 1;
} }
#if 0
/*!
Camera Position in World Space
*/
void CBurningVideoDriver::getCameraPosWorldSpace()
{
transform_calc(ETS_VIEW_INVERSE);
const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer();
/* The viewpoint is at (0., 0., 0.) in eye space.
Turning this into a vector [0 0 0 1] and multiply it by
the inverse of the view matrix, the resulting vector is the
object space location of the camera.
*/
EyeSpace.camworldpos.x = M[12];
EyeSpace.camworldpos.y = M[13];
EyeSpace.camworldpos.z = M[14];
EyeSpace.camworldpos.w = 1.f;
}
#endif
//! Turns a dynamic light on or off //! Turns a dynamic light on or off
void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn) void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn)
@ -2761,8 +2697,6 @@ void CBurningVideoDriver::setMaterial(const SMaterial& material)
} }
//! Sets the fog mode. //! Sets the fog mode.
void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start,
f32 end, f32 density, bool pixelFog, bool rangeFog) f32 end, f32 density, bool pixelFog, bool rangeFog)
@ -2806,8 +2740,7 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex *dest, u32 vertexargb)
for (i = 0; i < EyeSpace.Light.size(); ++i) for (i = 0; i < EyeSpace.Light.size(); ++i)
{ {
const SBurningShaderLight &light = EyeSpace.Light[i]; const SBurningShaderLight& light = EyeSpace.Light[i];
if (!light.LightIsOn) if (!light.LightIsOn)
continue; continue;
@ -2961,6 +2894,7 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex *dest, u32 vertexargb)
dColor.sat(dest->Color[0], vertexargb); dColor.sat(dest->Color[0], vertexargb);
} }
#endif #endif
@ -3542,8 +3476,6 @@ const core::dimension2d<u32>& CBurningVideoDriver::getCurrentRenderTargetSize()
} }
//! Draws a 3d line. //! Draws a 3d line.
void CBurningVideoDriver::draw3DLine(const core::vector3df& start, void CBurningVideoDriver::draw3DLine(const core::vector3df& start,
const core::vector3df& end, SColor color_start) const core::vector3df& end, SColor color_start)
@ -3619,15 +3551,15 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start,
const wchar_t* CBurningVideoDriver::getName() const const wchar_t* CBurningVideoDriver::getName() const
{ {
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
return L"Burning's Video 0.50 beautiful"; return L"Burning's Video 0.51 beautiful";
#elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) #elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST )
return L"Burning's Video 0.50 ultra fast"; return L"Burning's Video 0.51 ultra fast";
#elif defined ( BURNINGVIDEO_RENDERER_FAST ) #elif defined ( BURNINGVIDEO_RENDERER_FAST )
return L"Burning's Video 0.50 fast"; return L"Burning's Video 0.51 fast";
#elif defined ( BURNINGVIDEO_RENDERER_CE ) #elif defined ( BURNINGVIDEO_RENDERER_CE )
return L"Burning's Video 0.50 CE"; return L"Burning's Video 0.51 CE";
#else #else
return L"Burning's Video 0.50"; return L"Burning's Video 0.51";
#endif #endif
} }

@ -299,7 +299,6 @@ namespace video
ETS_MODEL_VIEW, ETS_MODEL_VIEW,
ETS_NORMAL, //3x3 ModelView Tansposed Inverse ETS_NORMAL, //3x3 ModelView Tansposed Inverse
//ETS_VIEW_INVERSE,
ETS_COUNT_BURNING = 16 ETS_COUNT_BURNING = 16
}; };

@ -229,8 +229,11 @@ void CTRNormalMap::fragmentShader()
f32 inversew = FIX_POINT_F32_MUL; f32 inversew = FIX_POINT_F32_MUL;
tFixPoint tx0, tx1; tFixPoint tx0, ty0;
tFixPoint ty0, ty1;
#ifdef IPOL_T1
tFixPoint tx1, ty1;
#endif
tFixPoint r0, g0, b0; tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1; tFixPoint r1, g1, b1;
@ -296,11 +299,10 @@ void CTRNormalMap::fragmentShader()
tx1 = tofix ( line.t[1][0].x,inversew); tx1 = tofix ( line.t[1][0].x,inversew);
ty1 = tofix ( line.t[1][0].y,inversew); ty1 = tofix ( line.t[1][0].y,inversew);
// diffuse map // diffuse map
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
// normal map // normal map ( same texcoord0 but different mipmapping)
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 ); getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );
r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1); r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
@ -313,30 +315,22 @@ void CTRNormalMap::fragmentShader()
lz = tofix ( line.l[0][0].z, inversew ); lz = tofix ( line.l[0][0].z, inversew );
// DOT 3 Normal Map light in tangent space // DOT 3 Normal Map light in tangent space
ndotl = saturateFix ( FIX_POINT_HALF_COLOR + ((imulFix_simple(r1,lx) + imulFix_simple(g1,ly) + imulFix_simple(b1,lz) ) << (COLOR_MAX_LOG2-1)) ); //max(dot(LightVector, Normal), 0.0);
ndotl = clampfix_mincolor( (imulFix_simple(r1,lx) + imulFix_simple(g1,ly) + imulFix_simple(b1,lz) ) );
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
//getSample_color(a3,r3,g3,b3, line.c[0][0],inversew); //LightColor[0]
//a3 = tofix(line.c[0][0].x, inversew);
r3 = tofix(line.c[0][0].y, inversew); r3 = tofix(line.c[0][0].y, inversew);
g3 = tofix(line.c[0][0].z, inversew); g3 = tofix(line.c[0][0].z, inversew);
b3 = tofix(line.c[0][0].w, inversew); b3 = tofix(line.c[0][0].w, inversew);
// N . L // Lambert * LightColor[0] * Diffuse Texture;
r2 = imulFix ( imulFix_tex1 ( r0, ndotl ), r3 ); r2 = imulFix (imulFix_simple( r3, ndotl ), r0 );
g2 = imulFix ( imulFix_tex1 ( g0, ndotl ), g3 ); g2 = imulFix (imulFix_simple( g3, ndotl ), g0 );
b2 = imulFix ( imulFix_tex1 ( b0, ndotl ), b3 ); b2 = imulFix (imulFix_simple( b3, ndotl ), b0 );
/*
// heightmap: (1 - neu ) + alt - 0.5, on_minus_srcalpha + add signed
// emboss bump map
a4 -= a1;
r2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( r0 + a4, r3 ) ) );
g2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( g0 + a4, g3 ) ) );
b2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( b0 + a4, b3 ) ) );
*/
//vertex alpha blend ( and omit depthwrite ,hacky..) //vertex alpha blend ( and omit depthwrite ,hacky..)
if (a3 + 2 < FIX_POINT_ONE) if (a3 + 2 < FIX_POINT_ONE)
{ {