osg+shader光照半透明

2023-11-13

先记录下,免得时间久了忘了。
对于光照,光源有点光源,聚光灯,方向光。每种光源又有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;

}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

osg+shader光照半透明 的相关文章

随机推荐

  • Cookie和Session 登录

    Cookie 实现免登陆和Session 01 需求说明 完成用户登录功能 登录成功后跳到成功页面 显示用户名 登录失败可以跳回登录页面 登录成功后后续操作均能显示当前登录的用户名 02 完成代码 DologinServlet java O
  • 数据挖掘实验-week8-关联规则挖掘(Association Rule Mining)

    Contents 0 引言 0 1 关联规则挖掘 0 2 Apriori算法 实验 Step 1 Familiarize yourself with the arules package in R 1 1 Load the package
  • python如何输出数字后三位

    想要输出数字的后三位 首先需要了解一些基础知识 在Python中 浮点数可以用round 函数来保留小数位数 这个函数有两个参数 要操作的数字和要保留的小数位数 例如 round 3 1415926 3 将返回3 142 其中第二个参数3表
  • Electron+Vue3+TypeScript+Vite +Vue.Draggable 完成事务拖动

    原文地址 Electron Vue3 TypeScript Vite Vue Draggable 完成事务拖动 前言 有了简单的框架 下面来点实际业务相关的操作吧 集成 Vue Draggable 将每一项任务拖拽任务到每个分类吧 Vue
  • Java连接MySQL数据库并实现增删改查

    首先我们需要连接数据库 我这里选择的是MySQL数据库 我们需要做的第一件事就是加载驱动 采用下列语句加载MySQL驱动 Class forName com mysql jdbc Driver 驱动加载成功后就可以创建连接对象 这里会使用到
  • 斐波那契数列计算 Python编程

    问题描述 斐波那契数列如下 F 0 0 F 1 1 F n F n 1 F n 2 编写一个计算斐波那契数列的函数 采用递归方式 输出不超过n的所有斐波那契数列元素 调用上述函数 完成如下功能 用户输入一个整数n 输出所有不超过n的斐波那契
  • Markdown表格实现合并单元格

    Markdown表格实现合并单元格 markdown基本语法的表格没有办法实现合并单元格功能 但是在实际使用中很多时候需要合并单元格 例如需要写一个这样非连续的寄存器说明 markdown语法的表格 参数 额定值 最大结温 150 C DV
  • Node写博客--用户登录和用cookie保存用户登录状态

    1 首先在index js中加入用户登录的ajax数据传输 登录 loginBox find button on click function 通过ajax提交请求 ajax type post url api user login dat
  • FPGA零基础学习之Vivado-TLC5620驱动教程

    FPGA零基础学习之Vivado TLC5620驱动教程 本系列将带来FPGA的系统性学习 从最基本的数字电路基础开始 最详细操作步骤 最直白的言语描述 手把手的 傻瓜式 讲解 让电子 信息 通信类专业学生 初入职场小白及打算进阶提升的职业
  • 创建Metasploit Payloads

    Often one of the most useful and to the beginner underrated abilities of Metasploit is the msfpayload module Multiple pa
  • 虚拟机后台运行怎么彻底关闭?

    1 首先启动vmware workstation软件 2 打开之后 在虚拟机软件的左侧工具栏中打开 编辑 工具 3 然后在弹出来的下拉菜单中使用鼠标左键点击菜单中的 首选项 4 在 工作区 选项找到 显示托盘图标 把托盘图标默认的 始终 改
  • 索引以及存储过程和存储函数介绍

    目录 索引 创建索引 创建表时创建索引 在已经存在的表中创建索引 使用alter table 语句创建 使用create index语句创建 删除索引 存储过程与函数 创建存储过程和函数 创建存储过程 创建存储函数 调用存储过程和函数 调用
  • Weblogic自动部署与手动部署 异常记录与解决方法

    weblogic在控制台部署项目时提示 The application mycim2Ejb was autodeployed and may only be redeployed by touching REDEPLOY file in t
  • http长连接

    http长连接与短连接 http协议是基于TCP协议的 http长连接即指的是TCP的长连接 TCP协议是一个面向连接 可靠 有着拥塞控制以及流量控制的传输层协议 http长连接问题由来 http是一个无状态的协议 简单点来说 如果同一个浏
  • 生产者―消费者问题算法的实现

    实验目的 掌握进程 线程的概念 熟悉相关的控制语 掌握进程 线程间的同步原理和方法 掌握进程 线程间的互斥原理和方法 掌握使用信号量原语解决进程 线程间互斥和同步方法 实验思路 生产者的主要作用是生成一定量的数据放到缓冲区中 然后重复此过程
  • Android数据加密之Rsa/MD5/Aes/Des加密算法归纳总结

    加密算法 1 加密算法通常分为对称性加密算法和非对称性加密算法 对于对称性加密算法 信息接收双方都需事先知道密匙和加解密算法且其密匙是相同的 之后便是对数据进行 加解密了 非对称算法与之不同 发送双方A B事先均生成一堆密匙 然后A将自己的
  • JS获取日期,浏览器高度

    1 获取当前日期向前推x天或者向后推x天 并已年 月 日 时 分 秒的格式返回值 获取往前后各推x天 function getDateOfDelayOrAdvance delay advance delay 往后推x天 advance 往前
  • ue4 用武器切割物体.

    我们这里使用UE4自带的第三人称的模板开始我们的游戏 切割物体嘛 所以这里我们需要一把武器和人物的武器攻击动画 武器我们可以从官方商城的免费资源获得 人物攻击动画我们可以从下面这个网站获得 这里面有各种人物动画和模型 完全免费 业界良心啊
  • TPshop项目介绍

    熟悉项目的信息来源 组织架构图 作用 整体性的认识被测试的项目 绘制 后台 系统 子系统 模块 子模块 见到具体界面为止 不考虑界面上的模块内容 前台 tpshop购买流程 注册登录 商品展示 购物车 支付 订单管理 前台绘制原则 一个独立
  • osg+shader光照半透明

    先记录下 免得时间久了忘了 对于光照 光源有点光源 聚光灯 方向光 每种光源又有ambient diffuse specular emission几个属性 这里用点光源 不考虑衰减 1 diffuse是入射光与物体法线之间的余弦起作用 2