osgPBR(十五)镜面IBL--查看不同级别的HDR环境贴图

news2024/11/17 14:45:26

首先,设置可以使用Mipmap,启用三线性过滤,设置最大级别和最小级别

osg::ref_ptr<osg::TextureCubeMap> tcm = new osg::TextureCubeMap;
tcm->setTextureSize(128, 128);

tcm->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
tcm->setUseHardwareMipMapGeneration(true);
tcm->setMinLOD(0);
tcm->setMaxLOD(4	);

然后在shader中,用textureLod分别查看各个级别
“gl_FragColor = textureLod(tex0,dir,4);\n”//0,1,2,3,4
运行如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码如下:
#include <osg/TextureCubeMap>
#include <osg/TexGen>
#include <osg/TexEnvCombine>
#include <osgUtil/ReflectionMapGenerator>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/NodeVisitor>
#include <osg/ShapeDrawable>

static const char * vertexShader =
{
“in vec3 aPos;\n”
“varying vec3 outPos;”
“void main(void)\n”
“{\n”
“outPos = aPos;\n”
" gl_Position = ftransform();\n"
“}\n”
};

static const char *psShader =
{
“varying vec3 outPos;”
“uniform samplerCube tex0;”
“void main(void)\n”
“{\n”
“float x = outPos.r;\n”
“float y = outPos.g;\n”
“float z = outPos.b;\n”
“vec3 dir = vec3(x,y,z);\n”
//“gl_FragColor = vec4(x,y,z,1);\n”
//“gl_FragColor = texture(tex0,dir);\n”
“gl_FragColor = textureLod(tex0,dir,2);\n”//0,1,2,3,4
“}\n”
};
class MyNodeVisitor : public osg::NodeVisitor
{
public:
MyNodeVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{

}
void apply(osg::Geode& geode)
{
	int count = geode.getNumDrawables();
	for (int i = 0; i < count; i++)
	{
		osg::ref_ptr<osg::Geometry> geometry = geode.getDrawable(i)->asGeometry();
		if (!geometry.valid())
		{
			continue;
		}
		osg::Array* vertexArray = geometry->getVertexArray();
		geometry->setVertexAttribArray(1, vertexArray);

	}
	traverse(geode);
}

};

int main()
{
osg::ref_ptrosg::TextureCubeMap tcm = new osg::TextureCubeMap;
tcm->setTextureSize(128, 128);
tcm->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
tcm->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
tcm->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
tcm->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
tcm->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);

std::string strImagePosX = "D:/hdr/Right face camera.bmp";
osg::ref_ptr<osg::Image> imagePosX = osgDB::readImageFile(strImagePosX);
tcm->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
std::string strImageNegX = "D:/hdr/Left face camera.bmp";
osg::ref_ptr<osg::Image> imageNegX = osgDB::readImageFile(strImageNegX);
tcm->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);

std::string strImagePosY = "D:/hdr/Front face camera.bmp";;
osg::ref_ptr<osg::Image> imagePosY = osgDB::readImageFile(strImagePosY);
tcm->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
std::string strImageNegY = "D:/hdr/Back face camera.bmp";;
osg::ref_ptr<osg::Image> imageNegY = osgDB::readImageFile(strImageNegY);
tcm->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);

std::string strImagePosZ = "D:/hdr/Top face camera.bmp";
osg::ref_ptr<osg::Image> imagePosZ = osgDB::readImageFile(strImagePosZ);
tcm->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);

std::string strImageNegZ = "D:/hdr/Bottom face camera.bmp";
osg::ref_ptr<osg::Image> imageNegZ = osgDB::readImageFile(strImageNegZ);
tcm->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);
tcm->setUseHardwareMipMapGeneration(true);
tcm->setMinLOD(0);
tcm->setMaxLOD(4);

osg::ref_ptr<osg::Box> box = new osg::Box(osg::Vec3(0, 0, 0), 10);
osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(box);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(drawable);
MyNodeVisitor nv;
geode->accept(nv);
osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, tcm, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

//shader

osg::ref_ptr<osg::Shader> vs1 = new osg::Shader(osg::Shader::VERTEX, vertexShader);
osg::ref_ptr<osg::Shader> ps1 = new osg::Shader(osg::Shader::FRAGMENT, psShader);
osg::ref_ptr<osg::Program> program1 = new osg::Program;
program1->addShader(vs1);
program1->addShader(ps1);
program1->addBindAttribLocation("aPos", 1);

osg::ref_ptr<osg::Uniform> tex0Uniform = new osg::Uniform("tex0", 0);
stateset->addUniform(tex0Uniform);
stateset->setAttribute(program1, osg::StateAttribute::ON);

osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(geode);
viewer->realize();
return viewer->run();

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1047358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

吃鸡达人分享顶级作战干货,让你的战斗力爆表!

大家好&#xff01;作为一位专业吃鸡行家&#xff0c;我将为大家分享一些热门话题和实用干货&#xff0c;帮助你提高游戏的战斗力&#xff0c;让你在绝地求生中立于不败之地&#xff01; 首先&#xff0c;让我们来谈谈绝地求生作图工具推荐。我们推荐使用一款专业的作图工具&am…

信息安全第三周++

公钥加密算法 公钥加密算法&#xff0c;也被称为非对称加密算法&#xff0c;是现代加密技术的核心概念。与传统的对称加密算法不同&#xff0c;非对称加密使用一对密钥&#xff1a;一个公钥和一个私钥。以下是公钥加密算法的基本思想和工作原理&#xff1a; 密钥对&#xff1a…

英语——谐音篇——单词——单词密码

记忆即联结&#xff0c;只要能建立有效的联结&#xff0c;就能很好地记住。在现实生活中&#xff0c;声音的联结模式能很好地帮助我们记忆。几乎每个学生都曾用谐音的方法记忆一些事物&#xff0c;但很多人都没有意识到&#xff0c;我们每个人都可以通过一定的练习&#xff0c;…

rust生命期

一、生命期是什么 生命期&#xff0c;又叫生存期&#xff0c;就是变量的有效期。 实例1 {let r;{let x 5;r &x;}println!("r: {}", r); }编译错误&#xff0c;原因是r所引用的值已经被释放。 上图中的绿色范围’a表示r的生命期&#xff0c;蓝色范围’b表示…

解决方案 | 法大大电子签赋能电力交易全流程电子化

随着电子签名技术的不断发展和完善&#xff0c;其在各个领域都得到了广泛的应用。尤其在电力交易场景中&#xff0c;电子签的应用能为电力交易带来极大的便利&#xff0c;带来多重价值点。与此同时&#xff0c;国家也出台了相应政策&#xff0c;全面推动各行各业的数字化转型建…

好看的货架效果(含3D效果)

搭配thymeleaf layui合成 货架一 1. css #gudinghuojia2F .layui-row { display: flex; justify-content: space-between; height: 100%;} #gudinghuojia2F .layui-col-xs10 {margin-right: 4%;} #gudinghuojia2F .layui-col-xs10:last-child {margin-right: 0;} .inner-ti…

C语言-变量与数据类型

一、基本语法 1、注释 注释&#xff08;Comments&#xff09;可以出现在代码中的任何位置&#xff0c;用来向用户提示或解释代码的含义。程序编译时&#xff0c;会忽略注释&#xff0c;不做任何处理。 C 语言有两种注释方式&#xff1a; &#xff08;1&#xff09;单行注释 …

【Verilog 教程】6.4Verilog竞争与冒险

关键字&#xff1a;竞争&#xff0c;冒险&#xff0c;书写规范 产生原因 数字电路中&#xff0c;信号传输与状态变换时都会有一定的延时。 在组合逻辑电路中&#xff0c;不同路径的输入信号变化传输到同一点门级电路时&#xff0c;在时间上有先有后&#xff0c;这种先后所形成…

面试题:Java8 lambda 表达式 forEach 如何提前终止?

文章目录 1.情景展示2.原因分析3.解决方案方案一&#xff1a;使用原始的foreach循环方式一&#xff1a;break方式二&#xff1a;return(不推荐使用) 方案二&#xff1a;抛出异常 1.情景展示 如上图所示&#xff0c;我们想要终止for循环&#xff0c;使用return。 执行结果如下&…

成为吃鸡战场的王者!分享顶级战术干货,助您提高战斗力!

各位吃鸡战场的玩家们&#xff0c;欢迎来到本视频&#xff01;在这里&#xff0c;我将为您呈现一些与众不同的吃鸡干货&#xff0c;帮助您提高战斗力、轻松吃鸡&#xff01; 首先&#xff0c;让我们谈一谈作图工具推荐。绝地求生作图工具是吃鸡玩家们的必备利器。我将给大家推荐…

python+vue电子资源管理系统

能实现不出家门就可以通过网络进行系统管理&#xff0c;交易等&#xff0c;而且过程简单、快捷。同样的&#xff0c;在人们的工作生活中&#xff0c;也就需要互联网技术来方便人们的日常工作生活&#xff0c;实现工作办公的自动化处理&#xff0c;实现信息化&#xff0c;无纸化…

1.物联网射频识别

1.RFID概念 RFID是Radio Frequency Identification的缩写&#xff0c;又称无线射频识别&#xff0c;是一种通信技术&#xff0c;可通过无线电讯号识别特定目标并读写相关数据&#xff0c;而无需与被识别物体建立机械或光学接触。 RFID&#xff08;Radio Frequency Identificati…

传染病学模型 | Python实现基于SIR模型分析Covid19爆发

效果一览 文章概述 传染病学模型 | Python实现基于SIR 模型分析Covid19爆发 源码设计 import jax.numpy as npimport matplotlib.pyplot

向量数据库库Milvus Cloud2.3 运维可靠,秒级故障恢复

Milvus 2.3.0 已经发布有一段时间了,正如二选一的选择题总会让人陷入纠结一般,不少社区用户反馈对于选择 Milvus 2.2.x 还是 Milvus 2.3.x 犹豫不已。 对此,我们的回答是:强烈建议升级至 Milvus 2.3.x 版本。 为什么?在回答此问题之前,先回顾一下近一年来业界发生了哪些变…

RabbitMQ的基本介绍

什么是MQ 本质是一个队列&#xff0c;只不过队列中存放的信息是message罢了&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递信息。在互联网架构中&#xff0c;MQ是一种非常常见的上下游“逻辑解耦物理解耦”的消息通信服务。使用了MQ之后&#xff0c;信息发送…

Flutter笔记:滚动之-无限滚动与动态加载的实现

Flutter笔记 无限滚动与动态加载的实现 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133342307 本文还…

C++的内存管理和模板

文章目录 一、内存管理1.内存的分布2.C中的动态内存管理3.重载new和重载delete4.new和delete的实现原理5.定位new 二、模板1.泛型编程2.函数模板1.定义模板2.实例化模板3.模板类型的参数4.非类型模板参数 3.类模板1.定义模板2.实例化模板3.模板的成员函数 总结 一、内存管理 1…

蓝桥杯每日一题2023.9.27

4408. 李白打酒加强版 - AcWing题库 题目描述 题目分析 对于这题我们发现有三个变量&#xff0c;店&#xff0c;花&#xff0c;酒的数量&#xff0c;对于这种范围我们使用DP来进行分析。 dp[i][j][k]我们表示有i个店&#xff0c;j朵花&#xff0c;k单位酒的集合&#xff0c…

逆向入门及实战

一、逆向工程介绍 1.1 什么是逆向工程 提到逆向工程可能大多数人第一印象就是非道德层面的软件破解&#xff0c;其实不然&#xff0c;逆向工程又称为逆向技术&#xff0c;是一种产品设计技术再现过程&#xff0c;即对一项目产品进行逆向分析及研究&#xff0c;从而演绎并得出该…

git 过滤不需要提交的目录和文件

项目根目录下&#xff08;.git同级目录&#xff09;添加.gitignore文件 .DS_Store .idea npm-debug.log yarn-error.log /node_modules /log/**.log /config.js