OSG与opengl的shader结合
1.OpenGL(3.3)可编程管线
可编程管线可以理解为一系列的三维顶点经过加工变成二维离散的像素点.并且允许在特定的着色阶段自有配置(顶点着色,几何着色,片源着色).
这里主要介绍一下几何着色,几何着色器是在紧挨着顶点着色器的后面.理论上可以将一些原来在顶点着色器中的计算操作转移到几何着色器中进行,但实际操作中并不建议这么做,因为几何着色器并行调用硬件困难,并行度低,效率和顶点着色器有很大的区别.
顶点着色器是逐顶点进行操作,可以进行坐标变换等操作.
片源着色器是逐片源/片段/像素进行的,主要用于最终颜色的计算.
几何着色器是逐图元的操作,输入的是图元,输出的也是图元,(图元是渲染对象在顶点着色器之后,光栅化之前的一种状态。简单的来说,就是包含点【点Point而不是顶点Vertex】或者线段或者三角形的集合。)
2.osg结合vertex shader和fragment shader
#include <osg/Program>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>static const char* vertSource = {"varying vec3 normal;\n""void main()\n""{\n"" normal = normalize(gl_NormalMatrix * gl_Normal);\n"" gl_Position = ftransform();\n""}\n"
};static const char* fragSource = {"uniform vec4 color1;\n""uniform vec4 color2;\n""uniform vec4 color3;\n""uniform vec4 color4;\n""varying vec3 normal;\n""void main()\n""{\n"" float intensity = dot(vec3(gl_LightSource[0].position), normal);\n"" if (intensity > 0.95) gl_FragColor = color1;\n"" else if (intensity > 0.5) gl_FragColor = color2;\n"" else if (intensity > 0.25) gl_FragColor = color3;\n"" else gl_FragColor = color4;\n""}\n"
};int main( int argc, char** argv )
{osg::ref_ptr<osg::Node> model = osgDB::readNodeFile( "cow.osg" );osg::ref_ptr<osg::Shader> vertShader = new osg::Shader( osg::Shader::VERTEX, vertSource );osg::ref_ptr<osg::Shader> fragShader = new osg::Shader( osg::Shader::FRAGMENT, fragSource );osg::ref_ptr<osg::Program> program = new osg::Program;program->addShader( vertShader.get() );program->addShader( fragShader.get() );osg::StateSet* stateset = model->getOrCreateStateSet();stateset->setAttributeAndModes( program.get() );stateset->addUniform( new osg::Uniform("color1", osg::Vec4(1.0f, 0.5f, 0.5f, 1.0f)) );stateset->addUniform( new osg::Uniform("color2", osg::Vec4(0.5f, 0.2f, 0.2f, 1.0f)) );stateset->addUniform( new osg::Uniform("color3", osg::Vec4(0.2f, 0.1f, 0.1f, 1.0f)) );stateset->addUniform( new osg::Uniform("color4", osg::Vec4(0.1f, 0.05f, 0.05f, 1.0f)) );osgViewer::Viewer viewer;viewer.setSceneData( model.get() );return viewer.run();
}
3.osg结合geometry shader
geometry shader是在Opengl3.2时加入核心代码库的,如果低版本想要使用它,需要在shader code中声明GL_EXT_geometry_shader4.
geometry shader将会根据vertex shader传递给的图元信息,产生新的邻接图元.geometry shader需要指定一些变量来指定对shader的操作.
GL_GEOMETRY_VERTICES_OUT_EXT :vertex shader发送给geometry shader的顶点数.
GL_GEOMETRY_INPUT_TYPE_EXT :定义传送给geometry shader的图元类型
GL_GEOMETRY_OUTPUT_TYPE_EXT :定义从geometry shader传出的图元类型
program->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, 100 );
例子
#include <osg/Program>
#include <osg/LineWidth>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>static const char* vertSource = {"#version 120\n""#extension GL_EXT_geometry_shader4 : enable\n""void main()\n""{ gl_Position = ftransform(); }\n"
};
//贝赛尔曲线方程P(t) = (1-t) 3 *P0 + 3*t*(1-t) 2 *P1 + 3*t 2 *(1-t)*P2 + t 3 *P3
static const char* geomSource = {"#version 120\n""#extension GL_EXT_geometry_shader4 : enable\n""uniform int segments;\n""void main(void)\n""{\n"" float delta = 1.0 / float(segments);\n"" vec4 v;\n"" for ( int i=0; i<=segments; ++i )\n"" {\n"" float t = delta * float(i);\n"" float t2 = t * t;\n"" float one_minus_t = 1.0 - t;\n"" float one_minus_t2 = one_minus_t * one_minus_t;\n"" v = gl_PositionIn[0] * one_minus_t2 * one_minus_t +\n"" gl_PositionIn[1] * 3.0 * t * one_minus_t2 +\n"" gl_PositionIn[2] * 3.0 * t2 * one_minus_t +\n"" gl_PositionIn[3] * t2 * t;\n"" gl_Position = v;\n"" EmitVertex();\n"" }\n"" EndPrimitive();\n""}\n"
};int main( int argc, char** argv )
{osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;vertices->push_back( osg::Vec3(0.0f, 0.0f, 0.0f) );vertices->push_back( osg::Vec3(1.0f, 1.0f, 1.0f) );vertices->push_back( osg::Vec3(2.0f, 1.0f,-1.0f) );vertices->push_back( osg::Vec3(3.0f, 0.0f, 0.0f) );osg::ref_ptr<osg::Geometry> controlPoints = new osg::Geometry;controlPoints->setVertexArray( vertices.get() );controlPoints->addPrimitiveSet( new osg::DrawArrays(GL_LINES_ADJACENCY_EXT, 0, 4) );osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable( controlPoints.get() );int segments = 10;osg::ref_ptr<osg::Program> program = new osg::Program;program->addShader( new osg::Shader(osg::Shader::VERTEX, vertSource) );program->addShader( new osg::Shader(osg::Shader::GEOMETRY, geomSource) );program->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, segments+1 );program->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, GL_LINES_ADJACENCY_EXT );program->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_LINE_STRIP );osg::ref_ptr<osg::LineWidth> lineWidth = new osg::LineWidth;lineWidth->setWidth( 2.0f );osg::StateSet* stateset = geode->getOrCreateStateSet();stateset->setAttributeAndModes( program.get() );stateset->setAttribute( lineWidth.get() );stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );stateset->addUniform( new osg::Uniform("segments", segments) );osgViewer::Viewer viewer;viewer.setSceneData( geode.get() );return viewer.run();
}
OSG与opengl的shader结合相关推荐
- OSG使用OpenGL(以及glad库)绘制自定义图形
简单记录一下在OSG中使用OpenGL函数(以及glad库)绘制自定义图形. 源码: #include <osgViewer/viewer> #include <osg/Geode& ...
- OpenGL Compute Shader计算着色器的实例
OpenGL Compute Shader计算着色器 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 // #define USE_GL3W #include &l ...
- OpenGL Compute Shader Raytracing 计算着色器光线追踪的实例
OpenGL Compute Shader Raytracing 计算着色器光线追踪 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 // #define USE_ ...
- OpenGL Compute Shader Particle System计算着色器粒子系统的实例
OpenGL Compute Shader Particle System计算着色器粒子系统 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include &l ...
- OpenGL Compute Shader Image Processing计算着色器图像处理的实例
OpenGL Compute Shader Image Processing计算着色器图像处理 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include & ...
- OpenGL GLSL Shader Subroutines函数的实例
OpenGL GLSL Shader Subroutines函数 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <shader.h> ...
- 【Modern OpenGL】Shader
Shaders 正如在上一篇教程中提到的,shader是在GPU中运行的小程序.如上一个教程中实现的最简单的vertex shader和fragment shader,一个shader基本上负责图形渲 ...
- android雪花飘落效果,【OpenGL】Shader实例分析(七)- 雪花飘落效果
研究了一个雪花飘落效果.感觉挺不错的.分享给大家,效果例如以下: 代码例如以下: Shader "shadertoy/Flakes" { // https://www.shader ...
- OpenGL Blinn-Phong Shader实例
OpenGL blinnphong 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <vmath.h> #include <sh ...
最新文章
- Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性
- 谷歌推出数据集搜索专用引擎Dataset Search
- 让互联网拥抱移动VR,三星将发布新版VR浏览器
- 纵向导航css设置主要属性,CSS 导航
- 简单安装ELK分析日志及使用心得
- 怎么利用迭代器写入mysql_range()是什么?为什么不生产迭代器?
- Stream操作Collection集合
- [不得不提]国外的一个silverlight for cube的商业组件
- Linux下Shell 备份脚本集合
- linux看是不是db2实例用户,切换到实例用户以后不能执行 db2
- Mac上创建cocos2d-x工程
- Emscripten教程之C++和JavaScript绑定(三)
- 如何使用U盘制作Windows 7安装盘
- python内置函数( )可以返回列表长度_python内置函数总结
- 分布形态的度量-偏度系数与峰度系数的探讨
- 2920集五福_支付宝集五福攻略 ▏顺便学点营销活动传播套路
- R语言C指数,在R中求一致性指数( Harrell'concordance index:C-index)案例
- 手机便签的字体大小怎么调?
- 【色彩管理】YIQ色彩模式详解
- 华硕系列笔记本命名规则以及各型号的差别特点