查看: 359|回复: 0

【多重采样纹理】【后处理】使用Texture2DMultisample作为FBO输出的后处理例子

[复制链接]

该用户从未签到

发表于 2024-5-23 16:20:40 | 显示全部楼层 |阅读模式
本帖最后由 smtKafka 于 2024-5-23 16:42 编辑

国内外论坛搜了一下没有相关的例子,尝试写了一个记录一下。重点说明:颜色和深度纹理都要写,且OSG_GL_TEXTURE_STORAGE设置一致。
  1. #include <osg/Group>
  2. #include <osg/Geode>
  3. #include <osg/Geometry>
  4. #include <osg/Camera>
  5. #include <osgViewer/Viewer>
  6. #include <osgGA/StateSetManipulator>
  7. #include <osg/Texture2D>
  8. #include <osg/Texture2DMultisample>
  9. #include <Windows.h>

  10. int main()
  11. {
  12.     putenv("OSG_GL_TEXTURE_STORAGE=DISABLE");

  13.     const double w = 800;
  14.     const double h = 600;
  15.     // 创建场景图
  16.     osg::ref_ptr<osg::Group> root = new osg::Group;

  17.     // 创建采样相机
  18.     osg::ref_ptr<osg::Camera> renderToTextureCamera = new osg::Camera;
  19.     renderToTextureCamera->setRenderOrder(osg::Camera::PRE_RENDER);

  20.     renderToTextureCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  21.     renderToTextureCamera->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 0.0));
  22.     renderToTextureCamera->setViewport(0, 0, w, h);

  23.     osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  24.     // 创建红色矩形的顶点数组
  25.     osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
  26.     //vertices->push_back(osg::Vec3(-0.5, -0.5, 0.0));
  27.     //vertices->push_back(osg::Vec3(0.5, -0.5, 0.0));
  28.     //vertices->push_back(osg::Vec3(0.5, 0.5, 0.0));
  29.     //vertices->push_back(osg::Vec3(-0.5, 0.5, 0.0));

  30.     vertices->push_back(osg::Vec3(-0.5, 0.0, -0.5));
  31.     vertices->push_back(osg::Vec3(0.5, 0.0, -0.5));
  32.     vertices->push_back(osg::Vec3(0.5, 0.0, 0.5));
  33.     vertices->push_back(osg::Vec3(-0.5, 0.0, 0.5));
  34.     // 创建红色矩形的颜色数组
  35.     osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
  36.     colors->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0)); // 红色

  37.     // 创建Geometry并设置顶点和颜色数组
  38.     osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
  39.     geometry->setVertexArray(vertices);
  40.     geometry->setColorArray(colors, osg::Array::BIND_OVERALL);
  41.     geometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
  42.     geode->addDrawable(geometry);

  43.     // 添加红色球到采样相机
  44.     renderToTextureCamera->addChild(geode);
  45.     root->addChild(renderToTextureCamera);

  46.     // 创建一个纹理用于存储渲染结果
  47.     osg::ref_ptr<osg::Texture2D> textureColor = new osg::Texture2D;
  48.     textureColor->setTextureSize(512, 512);
  49.     textureColor->setInternalFormat(GL_RGBA);

  50.     osg::ref_ptr<osg::Texture2D> textureDepth = new osg::Texture2D;
  51.     textureDepth->setTextureSize(512, 512);
  52.     textureDepth->setInternalFormat(GL_DEPTH_COMPONENT24);

  53.     osg::ref_ptr<osg::Texture2DMultisample> textureMSColor = new osg::Texture2DMultisample(4, true);
  54.     textureMSColor->setTextureSize(512, 512);
  55.     textureMSColor->setInternalFormat(GL_RGBA);

  56.     osg::ref_ptr<osg::Texture2DMultisample> textureMSDepth = new osg::Texture2DMultisample(4, true);
  57.     textureMSDepth->setTextureSize(512, 512);
  58.     textureMSDepth->setInternalFormat(GL_DEPTH_COMPONENT24);

  59.     // 设置渲染到纹理的相机的纹理
  60.     renderToTextureCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
  61.     renderToTextureCamera->setRenderOrder(osg::Camera::POST_RENDER);

  62.     bool isMultisample = true;

  63.     if (isMultisample)
  64.     {
  65.         renderToTextureCamera->attach(osg::Camera::COLOR_BUFFER, textureMSColor);
  66.         renderToTextureCamera->attach(osg::Camera::DEPTH_BUFFER, textureMSDepth);
  67.     }
  68.     else
  69.     {
  70.         renderToTextureCamera->attach(osg::Camera::COLOR_BUFFER, textureColor);
  71.         //renderToTextureCamera->attach(osg::Camera::DEPTH_BUFFER, textureDepth);
  72.     }

  73.     // 创建HUD相机
  74.     osg::ref_ptr<osg::Camera> hudCamera = new osg::Camera;
  75.     hudCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
  76.     hudCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
  77.     hudCamera->setViewMatrix(osg::Matrix::identity());
  78.     hudCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, w, 0, h));
  79.     hudCamera->setRenderOrder(osg::Camera::POST_RENDER);

  80.     hudCamera->setViewport(0, 0, w, h);
  81.     hudCamera->setAllowEventFocus(false);
  82.     hudCamera->setCullingActive(false);

  83.     // 创建顶点着色器
  84.     osg::ref_ptr<osg::Shader> vertShader = new osg::Shader(osg::Shader::VERTEX, R"(
  85.     #version 430
  86.     layout(location = 0) in vec3 VertexPosition;
  87.     out vec2 TexCoord;
  88.     void main()
  89.     {
  90.         TexCoord = (VertexPosition.xy + vec2(1.0)) * 0.5; // 转换到纹理坐标范围 [0, 1]
  91.         gl_Position = vec4(VertexPosition, 1);
  92.     }
  93.     )");

  94.     // 创建带有多重采样支持的片段着色器
  95.     osg::ref_ptr<osg::Shader> fragShaderMS = new osg::Shader(osg::Shader::FRAGMENT, R"(
  96.     #version 430
  97.     #extension GL_ARB_texture_multisample : enable

  98.     in vec2 TexCoord;
  99.     out vec4 FragColor;
  100.     uniform sampler2DMS tex; // 多重采样纹理

  101.     void main()
  102.     {
  103.         ivec2 texSize = textureSize(tex);
  104.         ivec2 coord = ivec2(TexCoord * vec2(texSize));
  105.         vec4 a1 = texelFetch(tex, coord, 0);
  106.         vec4 a2 = texelFetch(tex, coord, 1);
  107.         vec4 a3 = texelFetch(tex, coord, 2);
  108.         vec4 a4 = texelFetch(tex, coord, 3);
  109.         //FragColor = (a1+a2+a3+a4)/4.0;
  110.         FragColor = a1;
  111.     }
  112.     )");

  113.     // 创建不带多重采样的片段着色器
  114.     osg::ref_ptr<osg::Shader> fragShader = new osg::Shader(osg::Shader::FRAGMENT, R"(
  115.     #version 430
  116.     in vec2 TexCoord;
  117.     out vec4 FragColor;
  118.     uniform sampler2D tex;

  119.     void main()
  120.     {
  121.         FragColor = texture(tex, TexCoord);
  122.     }
  123.     )");

  124.     // 创建Program,并将Shader附加到其中
  125.     osg::ref_ptr<osg::Program> program = new osg::Program;
  126.     program->addShader(vertShader);
  127.     if (isMultisample)
  128.     {
  129.         program->addShader(fragShaderMS);
  130.     }
  131.     else
  132.     {
  133.         program->addShader(fragShader);
  134.     }

  135.     // 将Program设置到hudGeometry的StateSet中
  136.     hudCamera->getOrCreateStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON);

  137.     // 创建HUD相机中显示纹理的节点
  138.     osg::ref_ptr<osg::Geode> hudGeode = new osg::Geode;
  139.     osg::ref_ptr<osg::Geometry> hudGeometry = osg::createTexturedQuadGeometry(osg::Vec3(-1.0f, -1.0f, 0.0f), osg::Vec3(2.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 2.0f, 0.0f));
  140.     hudGeode->addDrawable(hudGeometry);

  141.     // 设置HUD相机的纹理
  142.     if (isMultisample)
  143.     {
  144.         hudCamera->getOrCreateStateSet()->setTextureAttributeAndModes(0, textureMSColor, osg::StateAttribute::ON);
  145.     }
  146.     else
  147.     {
  148.         hudCamera->getOrCreateStateSet()->setTextureAttributeAndModes(0, textureColor, osg::StateAttribute::ON);
  149.     }
  150.     hudCamera->getOrCreateStateSet()->addUniform(new osg::Uniform("tex", 0));
  151.     hudGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

  152.     hudCamera->addChild(hudGeode);
  153.     root->addChild(hudCamera);

  154.     // 创建查看器
  155.     osgViewer::Viewer viewer;
  156.     viewer.setSceneData(root);

  157.     // 添加事件处理器
  158.     viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
  159.     viewer.setUpViewInWindow(100, 100, w, h);

  160.     viewer.run();
  161. }
复制代码

微信截图_20240523164226.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表