osgEarth的Rex引擎原理分析(九十一)晕眩图的制作与实现

本文详细介绍了如何利用osgEarth的Rex引擎制作晕眩图,通过修改片段着色器,根据高程值赋予不同颜色。讲解了如何创建自定义的片段着色器文件,并将其注入到引擎中,以实现基于高程的着色方案,即晕渲图的制作。同时,提到了一些注意事项,如避免在glsl文件中使用{}注释和禁止出现中文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目标:(七十八)中的问题152

先上效果图:

思路是:不同的高程采用不同的颜色进行着色,需要对rex引擎现有的片段着色器进行修改。默认的片段着色器是这样的(见osgEarth的Rex引擎原理分析(五十四)rex引擎默认的几个着色器功能分析):

#version 330 compatibility
 
#pragma vp_name VP Fragment Shader Main
#extension GL_ARB_gpu_shader5 : enable 
 
// Fragment output
out vec4 vp_FragColor;
 
// Fragment stage inputs:
in VP_PerVertex { 
    float oe_layer_rangeOpacity; 
    float oe_rex_morphFactor; 
    vec2 oe_normalMapCoords; 
    vec3 oe_UpVectorView; 
    vec3 oe_normalMapBinormal; 
    vec3 vp_Normal; 
    vec4 oe_layer_texc; 
    vec4 oe_layer_texcParent; 
    vec4 oe_layer_tilec; 
    vec4 vp_Color; 
    vec4 vp_Vertex; 
} vp_in; 
 
// Fragment stage globals:
float oe_layer_rangeOpacity;
float oe_rex_morphFactor;
vec2 oe_normalMapCoords;
vec3 oe_UpVectorView;
vec3 oe_normalMapBinormal;
vec3 vp_Normal;
vec4 oe_layer_texc;
vec4 oe_layer_texcParent;
vec4 oe_layer_tilec;
vec4 vp_Color;
vec4 vp_Vertex;
 
// Function declarations:
void oe_normalMapFragment(inout vec4 color); 
void oe_rexEngine_frag(inout vec4 color); 
 
void main(void) 
{ 
    oe_layer_rangeOpacity = vp_in.oe_layer_rangeOpacity; 
    oe_rex_morphFactor = vp_in.oe_rex_morphFactor; 
    oe_normalMapCoords = vp_in.oe_normalMapCoords; 
    oe_UpVectorView = vp_in.oe_UpVectorView; 
    oe_normalMapBinormal = vp_in.oe_normalMapBinormal; 
    vp_Normal = vp_in.vp_Normal; 
    oe_layer_texc = vp_in.oe_layer_texc; 
    oe_layer_texcParent = vp_in.oe_layer_texcParent; 
    oe_layer_tilec = vp_in.oe_layer_tilec; 
    vp_Color = vp_in.vp_Color; 
    vp_Vertex = vp_in.vp_Vertex; 
    vp_Normal = normalize(vp_Normal); 
    oe_normalMapFragment( vp_Color ); 
    oe_rexEngine_frag( vp_Color ); 
    vp_FragColor = vp_Color;
}

注意这里有一个oe_layer_tilec,其中的st分量记录的是片段的纹理坐标,根据这个坐标就可以获取高程值,根据这个高程值给vp_Color赋不同值,就可以不渲染影像数据,而是采用基于高程的着色方案,也就是晕渲图的制作。这里需要生成一个片段着色器文件,其中有一个函数负责根据oe_layer_tilec.st来修改vp_Color,这个着色器文件函数顺序一定要放在最后,否则他的效果会被其他着色器函数修改,也就是vp_order要大。

写好这个片段着色器文件后,要将其注入到rex引擎的着色器程序中,注入方法为:

    osg::Group* container=dynamic_cast<osg::Group*>(mapNode->getChild(1));
    osgEarth::OverlayDecorator* deco= dynamic_cast<osgEarth::OverlayDecorator*>(container->getChild(0));
    osgEarth::Drivers::RexTerrainEngine::RexTerrainEngineNode* Rexter=dynamic_cast<osgEarth::Drivers::RexTerrainEngine::RexTerrainEngineNode*>(deco->getChild(0));

    //加入自定义的着色器
    osg::StateSet* surfaceStateSet = Rexter->getSurfaceStateSet();
    osgEarth::VirtualProgram* surfaceVP = osgEarth::VirtualProgram::getOrCreate(surfaceStateSet);
    osgEarth::ShaderPackage package;
    //package.load(surfaceVP, package.ENGINE_VERT_VIEW);
    package.load(surfaceVP, "elevation.frag.glsl");

着色器文件elevation.frag.glsl内容为:

#version $GLSL_VERSION_STR
$GLSL_DEFAULT_PRECISION_FLOAT

#pragma vp_name       REX Engine - Fragment
#pragma vp_entryPoint elevation_last_frag
#pragma vp_location   fragment_coloring
#pragma vp_order      0.9

// SDK functions:
float oe_terrain_getElevation();

void elevation_last_frag(inout vec4 color)
{	
  vec4 vec4ColorArray[64];
  vec4ColorArray[ 0] = vec4(0.00000, 0.00000,   0.56250,     1.0);
  vec4ColorArray[ 1] = vec4(0.00000, 0.00000,   0.62500,     1.0);
  vec4ColorArray[ 2] = vec4(0.00000, 0.00000,   0.68750,     1.0);
  vec4ColorArray[ 3] = vec4(0.00000, 0.00000,   0.75000,     1.0);
  vec4ColorArray[ 4] = vec4(0.00000, 0.00000,   0.81250,     1.0);
  vec4ColorArray[ 5] = vec4(0.00000, 0.00000,   0.87500,     1.0);
  vec4ColorArray[ 6] = vec4(0.00000, 0.00000,   0.93750,     1.0);
  vec4ColorArray[ 7] = vec4(0.00000, 0.00000,   1.00000,     1.0);
  vec4ColorArray[ 8] = vec4(0.00000, 0.06250,   1.00000,     1.0);
  vec4ColorArray[ 9] = vec4(0.00000, 0.12500,   1.00000,     1.0);
  vec4ColorArray[10] = vec4(0.00000, 0.18750,   1.00000,     1.0);
  vec4ColorArray[11] = vec4(0.00000, 0.25000,   1.00000,     1.0);
  v
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值