EMF_TRANSPARENT_ALPHA rendering problem
Posted: Sun Dec 21, 2014 22:00
Hello everyone! I write a voxel game and decided to add some transparent materials to it. It leads to many bugs and problems, which can't be solved by me. I'll try to show them in video. So, as you can see, i create two chunks(which are two different meshes and meshbuffers and nodes also). When i try to see them from different angles, i get some strange things. No separating quads there. Node's (0, 0, 0) point is the chunk's corner. I'm really tired and i can't find a solution, please, help.
P.S. For lighting i use my own shader, but i'm pretty sure, that it is not the reason. I tried to turn it off, colored the mesh by irrlicht's methods and got exaclty the same bugs, but, just in case, i'll give a code.
Help me, please, and sorry for my english. The code is below.
P.P.S. I always ask. No one can help. To organize polygons in order of distance from the camera will greatly reduce performance. But minetest, build a world, minecraft have a normal blend transparency (for example, water, color glass). Somebody please explain, what is the secret of such transparency?
Video: http://www.youtube.com/watch?v=Q0dJYQO_Hbc
Code:
Shaders:
light.vert:
light.frag:
P.S. For lighting i use my own shader, but i'm pretty sure, that it is not the reason. I tried to turn it off, colored the mesh by irrlicht's methods and got exaclty the same bugs, but, just in case, i'll give a code.
Help me, please, and sorry for my english. The code is below.
P.P.S. I always ask. No one can help. To organize polygons in order of distance from the camera will greatly reduce performance. But minetest, build a world, minecraft have a normal blend transparency (for example, water, color glass). Somebody please explain, what is the secret of such transparency?
Video: http://www.youtube.com/watch?v=Q0dJYQO_Hbc
Code:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
int main()
{
..............
SIrrlichtCreationParameters* s_IrrlichtCreationParameters = new SIrrlichtCreationParameters;
s_IrrlichtCreationParameters->DeviceType = EIDT_BEST;
s_IrrlichtCreationParameters->DriverType = EDT_OPENGL;
s_IrrlichtCreationParameters->WindowSize = dimension2d<u32>(1280, 720);
s_IrrlichtCreationParameters->Bits = 32;
s_IrrlichtCreationParameters->ZBufferBits = 16;
s_IrrlichtCreationParameters->Fullscreen = false;
s_IrrlichtCreationParameters->Stencilbuffer = false;
s_IrrlichtCreationParameters->Vsync = false;
s_IrrlichtCreationParameters->AntiAlias = 8;
s_IrrlichtCreationParameters->WithAlphaChannel = false;
s_IrrlichtCreationParameters->Doublebuffer = true;
s_IrrlichtCreationParameters->IgnoreInput = false;
s_IrrlichtCreationParameters->Stereobuffer = false;
s_IrrlichtCreationParameters->HighPrecisionFPU = false;
IrrlichtDevice* device = createDeviceEx(*s_IrrlichtCreationParameters);
delete s_IrrlichtCreationParameters;
...............
smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); //Scene manager
// Creating light shaders
MyShaderCallBack* mc = new MyShaderCallBack();
s32 chunkLightMaterialType = driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
"Shaders/light.vert", "vertexMain", video::EVST_VS_1_1,
"Shaders/light.frag", "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_SOLID, 0, EGSL_DEFAULT);
s32 chunkLightTransparentMaterialType = driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
"Shaders/light.vert", "vertexMain", video::EVST_VS_1_1,
"Shaders/light.frag", "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, EGSL_DEFAULT);
..........................
MyFactoryChunkMeshSceneNode* mfcmsn = new MyFactoryChunkMeshSceneNode(device, isve); //Creating factory of nodes
..........................
mfcmsn->setNumberOfMeshesSceneNodeForChunk(3);
mfcmsn->setHardwareMappingHint(0, EHM_STATIC, EBT_VERTEX_AND_INDEX); //First parameter is number mesh
mfcmsn->setMaterialType(0, (E_MATERIAL_TYPE)chunkLightMaterialType);
mfcmsn->setHardwareMappingHint(1, EHM_STATIC, EBT_VERTEX_AND_INDEX); //Glass mesh
mfcmsn->setMaterialType(1, (E_MATERIAL_TYPE)chunkLightTransparentMaterialType);
mfcmsn->setHardwareMappingHint(2, EHM_STATIC, EBT_VERTEX_AND_INDEX); //Water mesh
mfcmsn->setMaterialType(2, (E_MATERIAL_TYPE)chunkLightTransparentMaterialType);
...........................
isve->getFactoryChunkMeshSceneNode()->setMaterialFlag(2, id, EMF_LIGHTING, false); //id - world identificator, 2 - mesh for water, isve - my voxel engine
isve->getFactoryChunkMeshSceneNode()->setMaterialFlag(2, id, EMF_BLEND_OPERATION, true);
isve->getFactoryChunkMeshSceneNode()->setMaterialFlag(2, id, EMF_ZWRITE_ENABLE, false);
isve->getFactoryChunkMeshSceneNode()->setMaterialFlag(2, id, EMF_BACK_FACE_CULLING, false);
isve->getFactoryChunkMeshSceneNode()->setMaterialFlag(2, id, EMF_COLOR_MATERIAL, false);
.........................
isve->stop(); //Stopping engine, waiting all thread
delete isve;
device->drop();
return 0;
}
Shaders:
light.vert:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
uniform float s_StarLightIntensity;
varying vec3 s_PixelColor;
varying float s_StarLight;
void main(void)
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
s_PixelColor = gl_Color.xyz;
s_StarLight = gl_Color[3] * s_StarLightIntensity;
}
light.frag:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
uniform sampler2D s_TextureLayerID;
uniform vec4 s_StarLightColor;
varying vec3 s_PixelColor;
varying float s_StarLight;
vec4 colorDown(in vec4 color)
{
float dist = 0.0;
for(int i = 0; i < 3; i++)
if(color[i] > 1.0 && color[i] - 1.0 > dist) dist = color[i] - 1.0;
for(int i = 0; i < 3; i++) color[i] = color[i] - dist;
return color;
}
vec4 getLight(in vec4 color, in float starlight)
{
return colorDown(color + vec4(s_StarLightColor.xyz, 0.0) * starlight);
}
void main()
{
float starlight = s_StarLight;
vec4 color = texture2D(s_TextureLayerID, vec2(gl_TexCoord[0]));
gl_FragColor = vec4((color * getLight(vec4(s_PixelColor, 1.0), starlight)).xyz, color.a);
}