I recently found a bug when you enable additive blending and Fog with another color than black.
The additive blending of the fogged texture will result in a "doubled" colorvalue. For better understanding I made some snapshots:
bigger screenshot
Pic 1: This is my testapp: notice the billboard which is flying above the terrain.. nothing special to discover.. but ..
bigger screenshot
..if the billboard moves into the fog, there are nasty artefacts appearing..
I made a picture from a distance to show the bug very clear:
bigger screenshot
Explanation:
When drawing a fogged additive blended material, the color values will be blend into the fogcolor and then added to the screen. If fogcolor is not black,this procedure will result into a doubled fog color value as the fog color will be on screen and on the polygon and then added together.
Solution
Additive blending materials have to set the fogcolor to black and after render themselve they need to reset to current fog color.
This has to be done in CXXXDriver.cpp for each Videodriver. I would fix it, but unfortunately I cannot test implement DirectXrenderers.
So I hope a fix will make it into a next release.
Thanx in advance. And keep up the good work!
Peter
Transparent Bug when additive blending and FOG enabled
-
- Posts: 11
- Joined: Mon Nov 28, 2005 5:00 am
- Location: N.Y.
Hi,
I've made a quick fix but in the SceneManager not in the VideoDriver:
Please add/change the following lines:
CNullDriver.h
AFTER:
ADD:
CNullDriver.cpp
AFTER:
ADD:
IVideoDriver.h
AFTER:
ADD:
CSceneManager.cpp
in CSceneManager::drawAll()
REPLACE:
WITH:
Regards - Xaron
I've made a quick fix but in the SceneManager not in the VideoDriver:
Please add/change the following lines:
CNullDriver.h
AFTER:
Code: Select all
virtual void setFog(SColor color=SColor(0,255,255,255), bool linearFog=true,
f32 start=50.0f, f32 end=100.0f,
f32 density=0.01f, bool pixelFog=false, bool rangeFog=false);
Code: Select all
virtual void getFog(SColor& color, bool& linearFog, f32& start, f32& end,
f32& density, bool& pixelFog, bool& rangeFog);
AFTER:
Code: Select all
//! Sets the fog mode.
void CNullDriver::setFog(SColor color, bool linearFog, f32 start, f32 end, f32 density,
bool pixelFog, bool rangeFog)
{
FogColor = color;
LinearFog = linearFog;
FogStart = start;
FogEnd = end;
FogDensity = density;
PixelFog = pixelFog;
RangeFog = rangeFog;
}
Code: Select all
//! Gets the current fog settings
void CNullDriver::getFog(SColor& color, bool& linearFog, f32& start, f32& end,
f32& density, bool& pixelFog, bool& rangeFog)
{
color = FogColor;
linearFog = LinearFog;
start = FogStart;
end = FogEnd;
density = FogDensity;
pixelFog = PixelFog;
rangeFog = RangeFog;
}
AFTER:
Code: Select all
virtual void setFog(SColor color=SColor(0,255,255,255), bool linearFog=true, f32 start=50.0f, f32 end=100.0f,
f32 density=0.01f, bool pixelFog=false, bool rangeFog=false) = 0;
Code: Select all
virtual void getFog(SColor& color, bool& linearFog, f32& start, f32& end,
f32& density, bool& pixelFog, bool& rangeFog) = 0;
in CSceneManager::drawAll()
REPLACE:
Code: Select all
// render transparent objects.
CurrentRendertime = ESNRP_TRANSPARENT;
TransparentNodeList.sort(); // sort by distance from camera
for (i=0; i<TransparentNodeList.size(); ++i)
TransparentNodeList[i].node->render();
TransparentNodeList.clear();
Code: Select all
// render transparent objects.
CurrentRendertime = ESNRP_TRANSPARENT;
TransparentNodeList.sort(); // sort by distance from camera
// save the current fog settings
video::SColor fogColor;
bool linearFog, pixelFog, rangeFog;
f32 fogStart, fogEnd, fogDensity;
Driver->getFog(fogColor, linearFog, fogStart, fogEnd, fogDensity, pixelFog, rangeFog);
for (i=0; i<TransparentNodeList.size(); ++i)
{
video::SMaterial mat = TransparentNodeList[i].node->getMaterial(0);
// set the fog color to black to get transparent things work correctly
if (mat.MaterialType == video::EMT_TRANSPARENT_ADD_COLOR)
Driver->setFog(video::SColor(0,0,0,0), linearFog, fogStart, fogEnd, fogDensity, pixelFog, rangeFog);
else
Driver->setFog(fogColor, linearFog, fogStart, fogEnd, fogDensity, pixelFog, rangeFog);
TransparentNodeList[i].node->render();
}
// set the fog color back to the original one
Driver->setFog(fogColor, linearFog, fogStart, fogEnd, fogDensity, pixelFog, rangeFog);
TransparentNodeList.clear();
Fog bug still in irrlicht 1.3
It looks like peterparker's right (BTW, that's a cool nick, especially this weekend!).
Here's a pic with fog off (looks normal):
http://panther.110mb.com/misc/compass_no_fog.jpg
When I am using Irrlicht v1.3 with fog on, you can see it's not transparent anymore (looks like frosted glass):
http://panther.110mb.com/misc/compass_fog.jpg
I have not yet made the changes that Xaron suggested. It would be really great if this fix could go into Irrlicht v1.4!
Here's a pic with fog off (looks normal):
http://panther.110mb.com/misc/compass_no_fog.jpg
When I am using Irrlicht v1.3 with fog on, you can see it's not transparent anymore (looks like frosted glass):
http://panther.110mb.com/misc/compass_fog.jpg
I have not yet made the changes that Xaron suggested. It would be really great if this fix could go into Irrlicht v1.4!
Code correction for transparency
Be careful when you copy Xaron's CSceneManager.cpp code above. After the "//Render transparent objects" line, there is a Begin "{" and after the code there is an End "}".
I rebuilt Irrlicht, and Xaron's patch does fix the transparency problem!
However, I am getting a repetitive message:
I rebuilt Irrlicht, and Xaron's patch does fix the transparency problem!
However, I am getting a repetitive message:
Not sure what is causing this! The error message is from the file CD3D9ParallaxMapRenderer.cpp.Error: parallax map renderer only supports vertices of type EVT_TANGENTS