Shaders and Mipmapping

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.

Shaders and Mipmapping

Postby Klunk » Fri Apr 27, 2012 8:41 am

when I, say, on terrain have a road texture (uvcoord1) blended to a terrain texture (uvcoord2) the mipmapping on the terrain texture seems to be controlled by the mipmapping on the road texture. So if the road texture is much smaller than the terrain texture, the terrain will be in the a much lower mip than adjacent non blended terrain. Obviously I can make all textures the same size so they all mip at the same rate but that makes getting a constant pixel density tricky. Is there any other way round this ? sorry this is in openGL btw.

Image
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm

Re: Shaders and Mipmapping

Postby REDDemon » Fri Apr 27, 2012 9:25 am

Interesting. try to enable anisotropic filtering only on the road texture and see if that still happens.
OpenGL says that every texture unit should behave according to glTexParameters. so it can be both a bug in mipmap settings of Irrlicht or a wrong implementation of GL of your video card. Have you tried on different PCs? You can still write a sader using a specific mipmap level but that is even trickier.
OpenGL is not hard. What you have to do is just explained in specifications. What is hard is dealing with poor OpenGL implementations.
User avatar
REDDemon
 
Posts: 832
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: Shaders and Mipmapping

Postby hendu » Fri Apr 27, 2012 10:16 am

You can tell it to use a given mip level (texture2dLod), or add a bias.
hendu
 
Posts: 1619
Joined: Sat Dec 18, 2010 12:53 pm

Re: Shaders and Mipmapping

Postby Klunk » Fri Apr 27, 2012 10:34 am

it seems to be a bug either in my code or irrlicht, something to do with call driver->getTexture(filename) on a previously loaded texture leaves the previous texture with no mipmaps (hence the terrain in the image the terrain isn't mipping out but the new terrain in the blend is). It works ok if I duplicate the terrain texture and load the copy in the blend.
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm

Re: Shaders and Mipmapping

Postby Klunk » Fri Apr 27, 2012 12:38 pm

it seems to be an issue when the new terrain is set as a different texture index on the new material that is

if on the terrain material it would be

mat.setTexture(0,texture);

on the blending material the same texture is set as

mat.setTexture(1,texture);

this will cause loss of mipmaps on the original terrain material

if the terrain texture is set as

mat.setTexture(0,texture);

on the blend there's no loss of mipmaps :?

Image

the only difference between the two is the top right hand sphere has the displayed texture in the second texture slot. There is a very obvious and easy work around for me (i just need to swap two lines in the max shader, so the terrain texture is defined first). But this sort thing will bug me for ages :D
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm

Re: Shaders and Mipmapping

Postby hendu » Fri Apr 27, 2012 12:56 pm

That does rather sound like an Irrlicht bug.
hendu
 
Posts: 1619
Joined: Sat Dec 18, 2010 12:53 pm

Re: Shaders and Mipmapping

Postby hybrid » Fri Apr 27, 2012 1:46 pm

Could you please provide a test case which we can use to debug and fix this issue? So do you have a texture set in slot 0 as well? Because right now Irrlicht it might be required to use the texture slots consecutively. IIRC, we break at the first empty slot.
hybrid
Admin
 
Posts: 13970
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany

Re: Shaders and Mipmapping

Postby Klunk » Fri Apr 27, 2012 2:00 pm

yes there is texture in slot 0 as well. the test case may be a quite a bit of work as It's all custom file format and non standard loader :oops:
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm

Re: Shaders and Mipmapping

Postby hybrid » Fri Apr 27, 2012 2:26 pm

Uh, I thought you just created two spheres, a teexture and a plane, and just need to attack the shaders there... As we don't need the terrain obviously, and the spheres can be created with one Irrlicht call, without any loaders.
hybrid
Admin
 
Posts: 13970
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany

Re: Shaders and Mipmapping

Postby Klunk » Fri Apr 27, 2012 2:40 pm

no the spheres were exported from max, the exporter exports Directx (.fx files) materials assigned to the spheres, along with all params. the loader then finds the appropriate glsl shader and reads out the params which are then passed to the correct extended shadercall back. works really well gives me a perfect wysiwyg between max and irrlicht unfortunately doesn't make for quick and easy test cases for you. I'll try and get round to creating a stand alone test case.
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm

Re: Shaders and Mipmapping

Postby Klunk » Fri Apr 27, 2012 8:51 pm

this will generate the same error, I copied straight over "HelloWorld" example with main.cpp and the 4 shaders go in the media folder.

main.cpp

cpp Code: Select all
#include <irrlicht.h>
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
 
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
 
//***********************************************************************
 
class CCamSpaceLightAnim : public ISceneNodeAnimator
{
public:
 
        CCamSpaceLightAnim(ICameraSceneNode* cam, float offset, bool left)
                : camera(cam), csoffset(0.5f * sin(PI/6.0f), 0.5f * cos(PI/6.0f),-cos(PI/6.0f)), doffset(offset)
        {
                if(left)  
                        csoffset.X *= -1.0f;
        }
        virtual void animateNode(ISceneNode* node, u32 timeMs)
        {
                matrix4 camTM, lightTM;
                vector3df wsoffset;
                camera->getViewMatrix().getInverse(camTM);
                camTM.zeroTranslation();
                camTM.transformVect(wsoffset,csoffset);
                TransformFromDirVector(-wsoffset,  lightTM);
                node->setRotation(lightTM.getRotationDegrees());
                node->setPosition(wsoffset * doffset);
        }
        virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const {}
        virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) {}
        virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_UNKNOWN; }
        virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0)
        {
                return new CCamSpaceLightAnim(camera,doffset,false);
        }
 
private:
 
        void TransformFromDirVector(const vector3df& dir, matrix4& mat)
        {
                vector3df up(0.0f,1.0f,0.0f), zaxis, xaxis, yaxis;
        zaxis = dir;
        zaxis.normalize();
        xaxis = up.crossProduct(zaxis);
        xaxis.normalize();
        yaxis = zaxis.crossProduct(xaxis);
        mat[0] = xaxis.X; mat[1] = xaxis.Y; mat[2] = xaxis.Z; mat[3] = 0;
        mat[4] = yaxis.X; mat[5] = yaxis.Y; mat[6] = yaxis.Z; mat[7] = 0;
        mat[8] = zaxis.X; mat[9] = zaxis.Y; mat[10] = zaxis.Z; mat[11] = 0;
        mat[12] = 0; mat[13] = 0; mat[14] = 0; mat[15] = 1;
        }
        vector3df                       csoffset;
        float                           doffset;
        ICameraSceneNode*       camera;
};
 
//***********************************************************************
 
#define LIGHT_INDEX             "glight"
#define AMBIENTCOLOUR   "gAmbient"
#define DIFFUSECOLOUR   "gDiffuse"
#define DIFFUSEMAP              "diffuseMapTexture"
#define BLENDTOMAP              "blendtoMapTexture"
 
class Terrain_Shader : public IShaderConstantSetCallBack
{
        u32                     light;
        SColorf         ambient;
        SColorf         diffuse;
        int                     diffuse_sampler;
 
public:
 
        Terrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f), diffuse(1.0f,1.0f,1.0f), diffuse_sampler(0) {}
        virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData)
        {
                services->setVertexShaderConstant(LIGHT_INDEX, (float*)(&light), 1);
                services->setVertexShaderConstant(AMBIENTCOLOUR, (float*)(&ambient), 4);
                services->setVertexShaderConstant(DIFFUSECOLOUR, (float*)(&diffuse), 4);
                services->setPixelShaderConstant(DIFFUSEMAP,(float*)(&diffuse_sampler),1);
        }
};
 
//***********************************************************************
 
class BlendToTerrain_Shader : public IShaderConstantSetCallBack
{
        u32                     light;
        SColorf         ambient;
        SColorf         diffuse;
        int                     diffuse_sampler;
        int                     blend_sampler;
       
 
public:
 
        BlendToTerrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f),
                        diffuse(1.0f,1.0f,1.0f), diffuse_sampler(0) , blend_sampler(1) {}
 
        virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData)
        {
                services->setVertexShaderConstant(LIGHT_INDEX, (float*)(&light), 1);
                services->setVertexShaderConstant(AMBIENTCOLOUR, (float*)(&ambient), 4);
                services->setVertexShaderConstant(DIFFUSECOLOUR, (float*)(&diffuse), 4);
                services->setPixelShaderConstant(DIFFUSEMAP,(float*)(&diffuse_sampler),1);
                services->setPixelShaderConstant(BLENDTOMAP,(float*)(&blend_sampler),1);
        }
};
 
//***********************************************************************
 
int main()
{
        IrrlichtDevice *device = createDevice( video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, false, false, 0);
 
        if (!device)
                return 1;
 
        device->setWindowCaption(L"Test mipmap");
 
        IVideoDriver* driver = device->getVideoDriver();
        ISceneManager* smgr = device->getSceneManager();
 
// add spheres
 
        IMeshSceneNode* sphereNode1 = smgr->addSphereSceneNode(50,16,smgr->getRootSceneNode(),999,vector3df(100.0f,0.0,0.0));
        IMeshSceneNode* sphereNode2 = smgr->addSphereSceneNode(50,16,smgr->getRootSceneNode(),1000,vector3df(-100.0f,0.0,0.0));
 
// add camera
 
        ICameraSceneNode* cameraNode = smgr->addCameraSceneNodeMaya();;
 
// add a light
 
        ILightSceneNode* lightNode = smgr->addLightSceneNode(smgr->getRootSceneNode(),vector3df(0,0,0));
        lightNode->setLightType(ELT_DIRECTIONAL);
 
// add camera space animator
 
        ISceneNodeAnimator* anim = new CCamSpaceLightAnim(cameraNode,100.0f,false);
        if(anim)
        {
                lightNode->addAnimator(anim);
                anim->drop();
        }
 
        path blendtoVSfname = "../../media/blend_to_terrain.vert";
        path blendtoPSfname = "../../media/blend_to_terrain.frag";
 
        path terrainVSfname = "../../media/terrain.vert";
        path terrainPSfname = "../../media/terrain.frag";
       
        if (!driver->queryFeature(EVDF_PIXEL_SHADER_1_1) && !driver->queryFeature(EVDF_ARB_FRAGMENT_PROGRAM_1))
        {
                device->getLogger()->log("WARNING: Pixel shaders disabled ");
                blendtoPSfname = "";
                terrainVSfname = "";
        }
        if (!driver->queryFeature(EVDF_VERTEX_SHADER_1_1) && !driver->queryFeature(EVDF_ARB_VERTEX_PROGRAM_1))
        {
                device->getLogger()->log("WARNING: Vertex shaders disabled ");
                blendtoVSfname = "";
                terrainPSfname = "";
        }
 
        IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
        s32 terrainShaderMat = 0;
        s32 blendtoShaderMat = 0;
        if (gpu)
        {
                Terrain_Shader* ts = new Terrain_Shader();
                terrainShaderMat = gpu->addHighLevelShaderMaterialFromFiles( terrainVSfname, "main",
                                                EVST_VS_1_1, terrainPSfname, "main", EPST_PS_1_1, ts, EMT_SOLID);
                ts->drop();
 
                BlendToTerrain_Shader* bts = new BlendToTerrain_Shader();
                blendtoShaderMat = gpu->addHighLevelShaderMaterialFromFiles( blendtoVSfname, "main",
                                                EVST_VS_1_1, blendtoPSfname, "main", EPST_PS_1_1, bts, EMT_SOLID);
                bts->drop();
        }
 
        sphereNode1->setMaterialType((E_MATERIAL_TYPE)terrainShaderMat);
        sphereNode2->setMaterialType((E_MATERIAL_TYPE)blendtoShaderMat);
 
        ITexture* texture;
        driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS,  true);
 
        texture = driver->getTexture("../../media/wall.jpg");
        sphereNode1->setMaterialTexture(0, texture);
 
        texture = driver->getTexture("../../media/wall.bmp");
        sphereNode2->setMaterialTexture(0, texture);
 
        texture = driver->getTexture("../../media/wall.jpg");
        sphereNode2->setMaterialTexture(1, texture);
 
// dooo it
 
        while(device->run())
        {
                driver->beginScene(true, true, SColor(255,127,127,140));
                smgr->drawAll();
                driver->endScene();
        }
 
        device->drop();
 
        return 0;
}
 


blend_to_terrain.vert

cpp Code: Select all
uniform int      glight;       
uniform vec4 gAmbient;                 
uniform vec4 gDiffuse;                         
 
void main()
{
        gl_Position = ftransform();
        vec3 N = gl_NormalMatrix * gl_Normal;  
        vec3 L =  gl_LightSource[glight].position;
        float lambert = 0.5 * dot(N,L) + 0.5;
        gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
        gl_TexCoord[0].zw = gl_MultiTexCoord1.xy;
        gl_FrontColor = gl_Color * gl_LightSource[glight].diffuse * gDiffuse * (gAmbient +  lambert * lambert);
}


blend_to_terrain.frag

cpp Code: Select all
 
uniform sampler2D diffuseMapTexture;
uniform sampler2D blendtoMapTexture;
 
void main()
{
/*      normally this but needs second map channel to work
 
        vec4 col = texture2D(diffuseMapTexture, vec2(gl_TexCoord[0].xy));
        vec4 bld = texture2D(blendtoMapTexture, vec2(gl_TexCoord[0].zw));
    gl_FragColor = gl_Color * lerp(bld,col,gl_Color.a); */

   
// so we've replaced with this    
   
        vec4 bld = texture2D(blendtoMapTexture, vec2(gl_TexCoord[0].xy));
    gl_FragColor = gl_Color * bld;
   
}


terrain.vert

cpp Code: Select all
uniform int      glight;       
uniform vec4 gAmbient;                 
uniform vec4 gDiffuse;                         
 
 
void main()
{
        gl_Position = ftransform();
        vec3 N = gl_NormalMatrix * gl_Normal;  
        vec3 L =  gl_LightSource[glight].position;
        float lambert = 0.5 * dot(N,L) + 0.5;
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_FrontColor = gl_Color * gl_LightSource[glight].diffuse * gDiffuse * (gAmbient +  lambert * lambert);
}


terrain.frag

cpp Code: Select all
uniform sampler2D diffuseMapTexture;
 
void main()
{
        vec4 col = texture2D(diffuseMapTexture, vec2(gl_TexCoord[0]));
    gl_FragColor = col * gl_Color;
}
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm

Re: Shaders and Mipmapping

Postby Klunk » Fri Apr 27, 2012 9:05 pm

btw you can correct the issue by changing

cpp Code: Select all
        texture = driver->getTexture("../../media/wall.bmp");
        sphereNode2->setMaterialTexture(0, texture);
 
        texture = driver->getTexture("../../media/wall.jpg");
        sphereNode2->setMaterialTexture(1, texture);


cpp Code: Select all
        texture = driver->getTexture("../../media/wall.bmp");
        sphereNode2->setMaterialTexture(1, texture);
 
        texture = driver->getTexture("../../media/wall.jpg");
        sphereNode2->setMaterialTexture(0, texture);


and

cpp Code: Select all
BlendToTerrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f),
                        diffuse(1.0f,1.0f,1.0f), diffuse_sampler(0), blend_sampler(1) {}


cpp Code: Select all
BlendToTerrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f),
                        diffuse(1.0f,1.0f,1.0f), diffuse_sampler(1), blend_sampler(0) {}
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm

Re: Shaders and Mipmapping

Postby Klunk » Wed May 30, 2012 2:55 pm

is there a fix for this yet ?
Klunk
 
Posts: 232
Joined: Mon Jan 10, 2011 5:21 pm


Return to Bug reports

Who is online

Users browsing this forum: No registered users and 1 guest