osg+shader光照半透明

news2025/1/14 18:32:42

先记录下,免得时间久了忘了。
对于光照,光源有点光源,聚光灯,方向光。每种光源又有ambient,diffuse,specular,emission几个属性。

这里用点光源(不考虑衰减)

1,diffuse是入射光与物体法线之间的余弦起作用
2,specular是半矢量与物体法线之间的余弦起作用。
3,在learn opengl中,是在逆转置矩阵乘以法线转换到投影坐标系;而osg中,也可以使用摄像机坐标系下的法线,转换到摄像机坐标系。本质都是一样的。同理,点光源的位置,也可以转换到投影坐标系或者摄像机坐标系。
4,这里考虑到点云可能是黑色的(0,0,0,0),相乘也是0,所以做了些处理。

代码如下:

//通过Liblas读取.las文件,并在osg中显示出来,用shader
#include <liblas/liblas.hpp>
#include
#include

#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>

#include <osg/Switch>
#include <osg/Types>
#include <osgText/Text>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>

#include <osgGA/Device>

#include
#include <osg/Shader>

osg::ref_ptrosg::Geode getGeodeFromLas(std::string strLasFileName)
{

std::ifstream ifs;
ifs.open(strLasFileName, std::ios::in | std::ios::binary);

liblas::ReaderFactory f;

liblas::Reader reader = f.CreateWithStream(ifs);
liblas::Header const& header = reader.GetHeader();
int pointCount = header.GetPointRecordsCount();
std::cout << "pointCount:" << pointCount << std::endl;

osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
for (int i = 0; i < pointCount; i++)
{
	bool readSuccess = reader.ReadPointAt(i);
	if (!readSuccess)
	{
		continue;
	}
	liblas::Point const& p = reader.GetPoint();
	float red = p.GetColor().GetRed() * 1.0 / 65535;
	float green = p.GetColor().GetGreen()* 1.0 / 65535;
	//float green = 1.0;
	float blue = p.GetColor().GetBlue()* 1.0 / 65535;
	//	std::cout << "red =" << red << ";green=" << green << ";blue=" << blue << std::endl;
	colors->push_back(osg::Vec4(red, green, blue, 1.0));
	double x = p.GetX();
	double y = p.GetY();
	double z = p.GetZ();
	//	std::cout << "x =" << x << ";y=" << y << ";z=" << z << std::endl;
	vertices->push_back(osg::Vec3(x, y, z));
}
geom->setVertexAttribArray(10, colors, osg::Array::BIND_PER_VERTEX);
geom->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
geom->setVertexArray(vertices);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, vertices->size()));
geode->addDrawable(geom);
return geode.release();

}

static const char * vertexShader =
{
“uniform vec3 lightWorldPos; \n”
“in vec4 colors;\n”
“varying float NdotL;\n”
“varying float NdotHV;\n”
“varying vec3 ReflectVec;\n”
“varying vec3 ViewVec;\n”
“varying vec4 outColors;”
“void main(void)\n”
“{\n”
“vec3 ecPos = vec3 (gl_ModelViewMatrix * gl_Vertex);\n”
“vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);\n”
“vec4 lightViewPos = gl_ModelViewMatrix * vec4(lightWorldPos,1.0);”
“vec3 lightVec = normalize(lightViewPos.xyz - ecPos);\n”
“ReflectVec = normalize(reflect(-lightVec, tnorm));\n”
“ViewVec = normalize(-ecPos);\n”
“NdotL = max(dot(lightVec, tnorm),0.0);\n”
“vec3 halfVector = normalize(ViewVec + lightVec);”
"NdotHV = max(0,dot(tnorm, halfVector)); "
“outColors = colors;”
“gl_Position = ftransform();\n”
“}\n”
};
static const char *psShader =
{
“uniform float alpha;”
“uniform float shinessValue;”
“uniform float ambientStrength;”
“uniform vec4 ambientLightColor;”
“uniform vec4 diffuseLightColor;”
“uniform vec4 specularLightColor;”
“varying float NdotL;\n”
“varying float NdotHV;\n”
“varying vec3 ReflectVec;\n”
“varying vec3 ViewVec;\n”
“varying vec4 outColors;”
“void main(void)\n”
“{\n”
“vec4 specular = vec4(0.0,0.0,0.0,0.0);”
“if ( NdotL * NdotHV > 0.0 )”
“{”
“specular = specularLightColor * pow( NdotHV, shinessValue);”
“}”
“vec4 diffuse = NdotL * diffuseLightColor;”
“vec4 ambient = ambientStrength * ambientLightColor;”
“vec4 totalLightColor = diffuse + specular + ambient;”
“gl_FragColor = totalLightColor * outColors;\n”
“if(outColors.xyz == vec3(0.0,0.0,0.0))”
“{”
“gl_FragColor = min(totalLightColor,vec4(1.0,1.0,1.0,1.0)) ;\n”
“}”

"gl_FragColor.a = alpha;\n"
"}\n"

};

int main()
{
//std::string strLasFileName = “d:/ddss.las”;
std::string strLasFileName = “d:/test.las”;

osg::ref_ptr<osg::Group> grp = new osg::Group;
osg::ref_ptr<osg::Geode> geode = getGeodeFromLas(strLasFileName);
grp->addChild(geode);
//获取geode中心点,在向上走,罩住整个场景,当做点光源位置
osg::Vec3 center = geode->getBound().center();
center.z() += geode->getBound().radius() *0.5;
osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osg::ref_ptr<osg::Shader> vs = new osg::Shader(osg::Shader::VERTEX, vertexShader);
osg::ref_ptr<osg::Shader> ps = new osg::Shader(osg::Shader::FRAGMENT, psShader);
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(vs);
program->addShader(ps);
program->addBindAttribLocation("colors", 10);
osg::ref_ptr<osg::Uniform> alphaValue = new osg::Uniform("alpha", 0.2f);
osg::ref_ptr<osg::Uniform> shinessValue = new osg::Uniform("shinessValue", 64.0f);
osg::ref_ptr<osg::Uniform> ambientLength = new osg::Uniform("ambientStrength", 0.3f);
osg::ref_ptr<osg::Uniform> ambientLightColor = new osg::Uniform("ambientLightColor", osg::Vec4(0.1f, 0.1f, 0.1f, 0.1f));
osg::ref_ptr<osg::Uniform> diffuseLightColor = new osg::Uniform("diffuseLightColor", osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
osg::ref_ptr<osg::Uniform> specularLightColor = new osg::Uniform("specularLightColor", osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
osg::ref_ptr<osg::Uniform> lightWorldPos = new osg::Uniform("lightWorldPos", center);
stateset->addUniform(alphaValue);
stateset->addUniform(shinessValue);
stateset->addUniform(ambientLength);
stateset->addUniform(ambientLightColor);
stateset->addUniform(diffuseLightColor);
stateset->addUniform(specularLightColor);
stateset->addUniform(lightWorldPos);
stateset->setAttribute(program, osg::StateAttribute::ON);
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->getCamera()->setClearColor(osg::Vec4(0, 0, 0, 1.0));
viewer->setSceneData(grp);
viewer->run();
return 0;

}

运行结果如下:
在这里插入图片描述

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

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

相关文章

R语言raster包计算多个栅格图像平均值、标准差的方法

本文介绍基于R语言中的raster包&#xff0c;批量读取多张栅格图像&#xff0c;对多个栅格图像计算平均值、标准差&#xff0c;并将所得新的栅格结果图像保存的方法。 在文章R语言raster包批量读取单一或大量栅格图像&#xff08;https://blog.csdn.net/zhebushibiaoshifu/artic…

Spring 获取resource下文件路径

两种方式String path "excel/constant.xlsx" &#xff1b;// 直接获取文件1 File file1 new DefaultResourceLoader().getResource(path).getFile(); // 获取路径2 String file Thread.currentThread().getContextClassLoader().getResource(path).getFile(); Inp…

mac xcode工具 配置github 流程

注&#xff1a;这个方法是服务于私有仓库配置&#xff0c;同时建立与之前本机 多端仓库配置的基础上实现&#xff0c;如有疑问&#xff0c;请留言。 这个方法可行&#xff0c;但不一定是最好。 1、初始化一个私有github仓库&#xff0c;初始化github 的token【这里一定记得要…

容器在公有云上的落地姿势

1.容器天生隔离能力不足1.1 容器是一种进程隔离技术&#xff0c;并非虚拟化技术容器&#xff08;container&#xff09;&#xff0c;并不是一种虚拟化&#xff08;virtualization&#xff09;技术&#xff0c;而是一种进程隔离&#xff08;isolation&#xff09;技术&#xff0…

6.6、电子邮件

电子邮件&#xff08;E-mail&#xff09;是因特网上最早流行的一种应用\color{red}最早流行的一种应用最早流行的一种应用&#xff0c;并且仍然是当今因特网上最重要、最实用的应用之一 传统的电话通信属于实时通信&#xff0c;存在以下两个缺点: 电话通信的主叫和被叫双方必须…

Raki的读paper小记:ConTinTin: Continual Learning from Task Instructions

Abstract&Introduction&Related Work 研究任务 Continual Learning from Task Instructions已有方法和相关工作面临挑战创新思路 InstructionSpeak包含两个策略&#xff0c;充分利用task instruction来改善前向转移和后向转移&#xff1a; 一个是从negative的输出中学…

nodejs图片上传/头像上传

项目结构 utils文件夹无用,没文件 前端代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"utf-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport&…

大屏展示项目开发常用属性

图例legend前言&#xff1a;1.[配置项手册](https://echarts.apache.org/zh/option.html#title)2.[使用手册可以快速入门](https://echarts.apache.org/handbook/zh/get-started/)3.4.一、图例legend1.1 设置图例的位置 &#xff08;上下左右&#xff09;1.1.1 上下&#xff08…

【爪洼岛冒险记】第2站:带你学会:Java中三种输出语句,java中基本数据类型,学会变量,常量,类型转换知识点

&#x1f331;博主简介&#xff1a;是瑶瑶子啦&#xff0c;一名大一计科生&#xff0c;目前在努力学习C进阶、数据结构、算法、JavaSE。热爱写博客~正在努力成为一个厉害的开发程序媛&#xff01; &#x1f4dc;所属专栏&#xff1a;爪洼岛冒险记 ✈往期博文回顾&#xff1a;【…

【译】eBPF 和服务网格:还不能丢掉 Sidecar

服务网格以典型的 sidecar 模型为人熟知&#xff0c;将 sidecar 容器与应用容器部署在同一个 Pod 中。虽说 sidecar 并非很新的模型&#xff08;操作系统的 systemd、initd、cron 进程&#xff1b;Java 的多线程&#xff09;&#xff0c;但是以这种与业务逻辑分离的方式来提供服…

主库出问题了,从库怎么办?

在前面的文章中,我和你介绍了 MySQL 主备复制的基础结构,但这些都是一主一备的结构。 大多数的互联网应用场景都是读多写少,因此你负责的业务,在发展过程中很可能先会遇到读性能的问题。而在数据库层解决读性能问题,就要涉及到接下来两篇文章要讨论的架构:一主多从。 今…

Qt之标准对话框(QColorDialog、QInputDialog、QFontDialog)

文章目录QColorDialog使用方式QInputDialog使用方式QFontDialog使用方式提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 QColorDialog QDialog类用于指定颜色的。 使用方式 设置最开始的颜色 setCurrentColor(Qt::red);//其他的颜色Qt::white Qt::…

迪文串口屏(1)-DMG80480C070_03WTC

由于成本缘故&#xff0c;用迪文串口屏去替换项目里的大彩串口屏&#xff0c;样品型号为DMG80480C070_03WTC。不过说句实话&#xff0c;迪文串口屏没有大彩串口屏那么容易上手。产品命名及硬件特性10Pin_1.0mm座子&#xff0c;7.0英寸&#xff0c;800*480分辨率&#xff0c;16.…

机器学习--方差和偏差、Bagging、Boosting、Stacking

目录 一、方差和偏差 数学定义 对公式的解释 减小偏差、方差、噪声 总结 二、Bagging 代码实现 bagging什么时候会变好 不稳定的learner ​总结 三、Boosting Gradient boosting gradient boosting 的代码实现 gradient boosting的效果 ​总结 四、Stacking st…

秒杀项目总结

秒杀就是同一个时刻有大量的请求争抢购买同一个商品&#xff0c;并且完成交易的过程 也就是大量的并发读和并发写 先制作一个增删改查的秒杀系统&#xff0c;但是想让这个系统支持高并发访问就没那么容易了&#xff0c; 如何让这个秒杀系统面对百万级的请求流量不出故障&…

02-final、finally、finalize的区别?

1.final final是java中的修饰符&#xff0c;用于修饰属性&#xff08;变量&#xff09;、方法、类。 1.被final修饰的变量不可以被改变,如果修饰引用,那么表示引用不可变,引用指向的内容可变. 被修饰的常量,在编译阶段会存入常量池中. 2.被final修饰的方法不可以被重写, 被修…

图片播放器的实现1——利用Image2LCD提取图片数据并显示

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考内容 &#xff08;1&#xff09;https://xiefor100.blog.csdn.net/article/details/71941527 &#xff08;2&#xff09;https://xiefor100.blog.csdn.net/article/details/78529519 内容总结 …

2022. 12 青少年软件编程(图形化) 等级考试试卷(四级)

2022年12月 青少年软件编程&#xff08;图形化&#xff09; scratch等级考试试卷&#xff08;四级&#xff09; 分数&#xff1a; 100 题数&#xff1a; 28 一、单选题(共 15题&#xff0c;共 30分) 1.运行下列程序&#xff0c; 变量“结果”的值为&#xff1f; &#xff08; &…

WXSS 如何进行编译?

过往中小企业或技术团队开发一个 App 的时间成本和人力成本居高难下&#xff0c;但是随着微信上线小程序&#xff0c;更像是为这部分群体打开了一扇天窗&#xff0c;此后小程序呈现出井喷式发展的状态&#xff0c;不仅微信&#xff0c;支付宝、百度、抖音等超级 App 都跟上步伐…

【C++核心编程】C++全栈体系(十)

C核心编程 第四章 类和对象 六、继承 继承是面向对象三大特性之一 有些类与类之间存在特殊的关系&#xff0c;例如下图中&#xff1a; 我们发现&#xff0c;定义这些类时&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性。 这个时候我们就可以考…