Re: [osg-users] problem setting texture min/mag filter
Hi Robertos, setting "texture->setResizeNonPowerOfTwoHint(false);" fixed the problem After being stuck on this problem for more than a week I can safely say that I would never have found that without your help. I checked the data after generating the image at which point it was still OK, but found problems when it was sampled in the shader, which is why expected a problem with the sampling. Being new to OSG (and used to pure openGL) I hadn't realized that OSG would be modifying the data before it got to the graphics card so I was looking in the wrong place. So, thanks again! You saved me many more days of hitting my head against the wall! Cheers, antiro -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=72974#72974 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] problem setting texture min/mag filter
HI Antiro, Thanks for the code example. I don't have the time to test right away. A quick code review and I spotted that the image is 10x10 which will be rescalled to nearest power of two with the default construction of osg::Texture2D. Most modern hardware supports non power of two textures so it should be safe to enable this via: texture->setResizeNonPowerOfTwoHint(false); Could you try this and let us know how you get on. Robert. On 20 February 2018 at 17:10, antiro blackwrote: > Hi, > > I made an executable example based on the osgtexture2D example. I removed the > code to render the different walls of the cube with the exception of the > filter wall. I kept the rest as close to the original as possible. changes to > the code have been marked using comments. > > Essentially all I'm doing is generating an input image instead of loading one. > > > Code: > > #include > #include > #include > #include > #include > #include > #include > #include > > #include > #include > > #include > > #include > > /// > // > // filter wall and animation callback. > // > > class FilterCallback : public osg::NodeCallback > { > public: > > FilterCallback(osg::Texture2D* texture,osgText::Text* text,double > delay=1.0): > _texture(texture), > _text(text), > _delay(delay), > _currPos(0), > _prevTime(0.0) > { > // start with a mip mapped mode to ensure that > _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_LINEAR); > _magFilterList.push_back(osg::Texture2D::LINEAR); > _textList.push_back("Tri-linear mip mapping (default > filtering)\nsetFilter(MIN_FILTER,LINEAR_MIP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)"); > > _minFilterList.push_back(osg::Texture2D::NEAREST); > _magFilterList.push_back(osg::Texture2D::NEAREST); > _textList.push_back("Nearest > filtering\nsetFilter(MIN_FILTER,NEAREST)\nsetFilter(MAG_FILTER,NEAREST)"); > > _minFilterList.push_back(osg::Texture2D::LINEAR); > _magFilterList.push_back(osg::Texture2D::LINEAR); > _textList.push_back("Linear > filtering\nsetFilter(MIN_FILTER,LINEAR)\nsetFilter(MAG_FILTER,LINEAR)"); > > _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_NEAREST); > _magFilterList.push_back(osg::Texture2D::LINEAR); > _textList.push_back("nearest mip mapping (default > filtering)\nsetFilter(MIN_FILTER,)\nsetFilter(MAG_FILTER,LINEAR)"); > > _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_NEAREST); > _magFilterList.push_back(osg::Texture2D::LINEAR); > _textList.push_back("bi-linear mip > mapping\nsetFilter(MIN_FILTER,LINEAR_MIPMAP_NEAREST)\nsetFilter(MAG_FILTER,LINEAR)"); > > _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_LINEAR); > _magFilterList.push_back(osg::Texture2D::LINEAR); > _textList.push_back("bi-linear mip > mapping\nsetFilter(MIN_FILTER,NEAREST_MIPMAP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)"); > > > setValues(); > } > > virtual void operator()(osg::Node*, osg::NodeVisitor* nv) > { > if (nv->getFrameStamp()) > { > double currTime = nv->getFrameStamp()->getSimulationTime(); > if (currTime-_prevTime>_delay) > { > // update filter modes and text. > setValues(); > > // advance the current position, wrap round if required. > _currPos++; > if (_currPos>=_minFilterList.size()) _currPos=0; > > // record time > _prevTime = currTime; > } > } > } > > void setValues() > { > > _texture->setFilter(osg::Texture2D::MIN_FILTER,_minFilterList[_currPos]); > > _texture->setFilter(osg::Texture2D::MAG_FILTER,_magFilterList[_currPos]); > > _text->setText(_textList[_currPos]); > } > > protected: > > typedef std::vector FilterList; > typedef std::vectorTextList; > > osg::ref_ptr_texture; > osg::ref_ptr _text; > double _delay; > > FilterList _minFilterList; > FilterList _magFilterList; > TextList_textList; > > unsigned int_currPos; > double _prevTime; > > }; > > osg::Node* createFilterWall(osg::BoundingBox& bb,osg::Image *img) > { > osg::Group* group = new osg::Group; > > // left hand side of bounding box. > osg::Vec3 top_left(bb.xMin(),bb.yMin(),bb.zMax()); > osg::Vec3 bottom_left(bb.xMin(),bb.yMin(),bb.zMin()); > osg::Vec3 bottom_right(bb.xMin(),bb.yMax(),bb.zMin()); > osg::Vec3 top_right(bb.xMin(),bb.yMax(),bb.zMax()); > osg::Vec3 >
Re: [osg-users] problem setting texture min/mag filter
Hi, I made an executable example based on the osgtexture2D example. I removed the code to render the different walls of the cube with the exception of the filter wall. I kept the rest as close to the original as possible. changes to the code have been marked using comments. Essentially all I'm doing is generating an input image instead of loading one. Code: #include #include #include #include #include #include #include #include #include #include #include #include /// // // filter wall and animation callback. // class FilterCallback : public osg::NodeCallback { public: FilterCallback(osg::Texture2D* texture,osgText::Text* text,double delay=1.0): _texture(texture), _text(text), _delay(delay), _currPos(0), _prevTime(0.0) { // start with a mip mapped mode to ensure that _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_LINEAR); _magFilterList.push_back(osg::Texture2D::LINEAR); _textList.push_back("Tri-linear mip mapping (default filtering)\nsetFilter(MIN_FILTER,LINEAR_MIP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)"); _minFilterList.push_back(osg::Texture2D::NEAREST); _magFilterList.push_back(osg::Texture2D::NEAREST); _textList.push_back("Nearest filtering\nsetFilter(MIN_FILTER,NEAREST)\nsetFilter(MAG_FILTER,NEAREST)"); _minFilterList.push_back(osg::Texture2D::LINEAR); _magFilterList.push_back(osg::Texture2D::LINEAR); _textList.push_back("Linear filtering\nsetFilter(MIN_FILTER,LINEAR)\nsetFilter(MAG_FILTER,LINEAR)"); _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_NEAREST); _magFilterList.push_back(osg::Texture2D::LINEAR); _textList.push_back("nearest mip mapping (default filtering)\nsetFilter(MIN_FILTER,)\nsetFilter(MAG_FILTER,LINEAR)"); _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_NEAREST); _magFilterList.push_back(osg::Texture2D::LINEAR); _textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,LINEAR_MIPMAP_NEAREST)\nsetFilter(MAG_FILTER,LINEAR)"); _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_LINEAR); _magFilterList.push_back(osg::Texture2D::LINEAR); _textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,NEAREST_MIPMAP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)"); setValues(); } virtual void operator()(osg::Node*, osg::NodeVisitor* nv) { if (nv->getFrameStamp()) { double currTime = nv->getFrameStamp()->getSimulationTime(); if (currTime-_prevTime>_delay) { // update filter modes and text. setValues(); // advance the current position, wrap round if required. _currPos++; if (_currPos>=_minFilterList.size()) _currPos=0; // record time _prevTime = currTime; } } } void setValues() { _texture->setFilter(osg::Texture2D::MIN_FILTER,_minFilterList[_currPos]); _texture->setFilter(osg::Texture2D::MAG_FILTER,_magFilterList[_currPos]); _text->setText(_textList[_currPos]); } protected: typedef std::vector FilterList; typedef std::vectorTextList; osg::ref_ptr_texture; osg::ref_ptr _text; double _delay; FilterList _minFilterList; FilterList _magFilterList; TextList_textList; unsigned int_currPos; double _prevTime; }; osg::Node* createFilterWall(osg::BoundingBox& bb,osg::Image *img) { osg::Group* group = new osg::Group; // left hand side of bounding box. osg::Vec3 top_left(bb.xMin(),bb.yMin(),bb.zMax()); osg::Vec3 bottom_left(bb.xMin(),bb.yMin(),bb.zMin()); osg::Vec3 bottom_right(bb.xMin(),bb.yMax(),bb.zMin()); osg::Vec3 top_right(bb.xMin(),bb.yMax(),bb.zMax()); osg::Vec3 center(bb.xMin(),(bb.yMin()+bb.yMax())*0.5f,(bb.zMin()+bb.zMax())*0.5f); float height = bb.zMax()-bb.zMin(); // create the geometry for the wall. osg::Geometry* geom = new osg::Geometry; osg::Vec3Array* vertices = new osg::Vec3Array(4); (*vertices)[0] = top_left; (*vertices)[1] = bottom_left; (*vertices)[2] = bottom_right; (*vertices)[3] = top_right; geom->setVertexArray(vertices); osg::Vec2Array* texcoords = new osg::Vec2Array(4); (*texcoords)[0].set(0.0f,1.0f); (*texcoords)[1].set(0.0f,0.0f); (*texcoords)[2].set(1.0f,0.0f); (*texcoords)[3].set(1.0f,1.0f); geom->setTexCoordArray(0,texcoords); osg::Vec3Array* normals = new osg::Vec3Array(1); (*normals)[0].set(1.0f,0.0f,0.0f);
Re: [osg-users] problem setting texture min/mag filter
Hi Antiro, Without screenshots and a working example that illustrates what you think is a problem there isn't much we can do to help you. Filtering has worked from the very early days of the OSG, it's not something that is known to be problematic, you just set the filter values and you're done. FYI, the OSG example osgtexture2D creates a partial cube rendered with textures and steps through different filter modes on the left hand side wall where the brown/black terrain texture is rendered. When it cycles through to NEAREST, NEAREST you will see a highly pixelated result - zoom into this wall to see texels more clearly. Robert. ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] problem setting texture min/mag filter
Hi, As far as I can tell it does not seem to be rendering related, the shader is really sampling data from the texture that was never in the original image. A summary of my experiments: Input is an image which is half red (255,0,0) and half black (0,0,0) and it is set as a texture for the shader. min/mag filter is set to nearest. 1: Shader sampling this texture and coloring a bigger output texture with whatever it samples -> result: half red, half black output but the halves are separated by a dark red line (as if locations sampled in between the red and black pixels have returned an _unweighted_ average of the two colors) 2: Same shader, but input texture uses min/mag filter of linear -> result half red/half black output but now separated by a gradient (the expected _weighted_ linear interplation when sampling in between black/red pixels) 3: min/mag filter back at nearest now. To verify that it is not a rendering artifact I changed the shader to output red/black when the input is red/black but purple if the input is something else -> result: the output now has a purple line separating the red/black halves, so clearly I am sampling data that is not in the original image. It is my understanding that a nearest filter should result in the value of the _single_ nearest pixel being returned when sampling a location in a texture, but my experiments seem to point at an unweighted average of the neighboring pixels values? Thank you! Cheers, antiro -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=72966#72966 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] problem setting texture min/mag filter
Hi, The half red half black pixels may come from some kind of anti-aliasing. Check your frame buffer settings. My 2 cents. On 19/02/2018 15:18, antiro black wrote: Hi, Thank you for response robertos, I've been playing around with the code the last few days and it seems like the filters are doing something, it is just not what I expected. I'm wondering if I misinterpreted the meaning of a "NEAREST" filter. As I understand it, putting both the min and mag filters on nearest means that, when sampling a location on your texture it will return the color of the nearest pixel. In other words: you will always get a value back that is present in the pixeldata from the image. However, as far as I can see from my test, this is not the case: I created an image with red pixels on one half (255,0,0) and black pixels on the other half (0,0,0). When sampling the texture to which this image was set and simply drawing the sampled values onto a bigger texture for debugging purposes, I see a red half, a black half and a line of dark red "pixels" separating them. As if the values have been interpolated when sampling. If i turn off the "nearest" filters this line becomes a gradient, so clearly the filtering is doing something. Am I just completely misinterpreting the intended behavior of the "nearest" filters? or is there something wrong in the implementation? Thank you! Cheers, antiro -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=72964#72964 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] problem setting texture min/mag filter
Hi, Thank you for response robertos, I've been playing around with the code the last few days and it seems like the filters are doing something, it is just not what I expected. I'm wondering if I misinterpreted the meaning of a "NEAREST" filter. As I understand it, putting both the min and mag filters on nearest means that, when sampling a location on your texture it will return the color of the nearest pixel. In other words: you will always get a value back that is present in the pixeldata from the image. However, as far as I can see from my test, this is not the case: I created an image with red pixels on one half (255,0,0) and black pixels on the other half (0,0,0). When sampling the texture to which this image was set and simply drawing the sampled values onto a bigger texture for debugging purposes, I see a red half, a black half and a line of dark red "pixels" separating them. As if the values have been interpolated when sampling. If i turn off the "nearest" filters this line becomes a gradient, so clearly the filtering is doing something. Am I just completely misinterpreting the intended behavior of the "nearest" filters? or is there something wrong in the implementation? Thank you! Cheers, antiro -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=72964#72964 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] problem setting texture min/mag filter
HI Antiro, You code looks fine, there isn't anything else you need to do to set up filter modes. I haven't heard of issues with setting the filter modes so would expect it to work. Perhaps what is amiss is either something higher up - such as the texture not being used in the subgraph that you think it is being used - or that the filtering is working and you are just mis-interpreting the results. Robert. On 12 February 2018 at 07:51, antiro blackwrote: > Hi, > > I'm trying to use a texture to get some data to a shader. The texure is > created by first creating an osg::Image, setting its pixel values manually > and then assigning the image to a texture. I have verified that the image is > created correctly by writing it to a file. > > As for the actual texture generation I use the following code: > > > Code: > > osg::ref_ptr m_tileDataImg=nullptr; > > // some code to create the osg::image > // ... > // ... > > auto tileDataTexture=new osg::Texture2D(); > > tileDataTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT); > tileDataTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT); > tileDataTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); > tileDataTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); > tileDataTexture->setImage(m_tileDataImg); > > drawableNode->getStateSet()->setTextureAttributeAndModes(0,tileDataTexture,osg::StateAttribute::ON); > > > > > > In my shader I rendered the texture for debugging purposes and realized that > the data was changed. After a closer inspection it turned out that the data > had been interpolated, hence my suspicion that the "setFilter" code did not > work correctly. > > My question is whether there is some other thing I need to do to ensure that > no interpolation happens when sampling the texture in my shader? > > Any help would be greatly appreciated. > Thank you! > > Cheers, > antiro > > -- > Read this topic online here: > http://forum.openscenegraph.org/viewtopic.php?p=72956#72956 > > > > > > ___ > osg-users mailing list > osg-users@lists.openscenegraph.org > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org