osgEarth的Rex引擎原理分析(四十九)rex引擎的着色器如何区分顶点和片段

目标:(四十五)中的问题115osgEarth组织着色器是有一套流程的,这套流程可以让用户很方便地添加自定义的着色器函数:1、在构建场景图阶段,加载着色器文件,这些文件只包含不同管线阶段的处理函数,并没有main函数,从文件中#pragma vp_location可以解析出来是顶点或者片段着色器,比如vertex_model、vertex_view、vertex_clip对应顶点着色器中的...
摘要由CSDN通过智能技术生成

目标:(四十五)中的问题115

每个着色器文件中都有一个vp_location,rex引擎是根据这个来判断是属于那种着色器类型,如果没有设置vp_location那么该着色器文件将安装在所有管线阶段。

osgEarth/ShaderLoader.cpp
bool
ShaderLoader::load(VirtualProgram*       vp,
                   const std::string&    filename,
                   const ShaderPackage&  package,
                   const osgDB::Options* dbOptions)
{
        std::string loc = getPragmaValue(source, "vp_location");
        ShaderComp::FunctionLocation location;
        bool locationSet = true;

        if      ( ciEquals(loc, "vertex_model") )
            location = ShaderComp::LOCATION_VERTEX_MODEL;
        else if ( ciEquals(loc, "vertex_view") )
            location = ShaderComp::LOCATION_VERTEX_VIEW;
        else if ( ciEquals(loc, "vertex_clip") )
            location = ShaderComp::LOCATION_VERTEX_CLIP;
        else if ( ciEquals(loc, "tess_control") || ciEquals(loc, "tessellation_control") )
            location = ShaderComp::LOCATION_TESS_CONTROL;
        else if ( ciEquals(loc, "tess_eval") || ciEquals(loc, "tessellation_eval") || ciEquals(loc, "tessellation_evaluation") || ciEquals(loc, "tess_evaluation") )
            location = ShaderComp::LOCATION_TESS_EVALUATION;
        else if ( ciEquals(loc, "vertex_geometry") || ciEquals(loc, "geometry") )
            location = ShaderComp::LOCATION_GEOMETRY;
        else if ( ciEquals(loc, "fragment" ) )
            location = ShaderComp::LOCATION_FRAGMENT_COLORING;
        else if ( ciEquals(loc, "fragment_coloring") )
            location = ShaderComp::LOCATION_FRAGMENT_COLORING;
        else if ( ciEquals(loc, "fragment_lighting") )
            location = ShaderComp::LOCATION_FRAGMENT_LIGHTING;
        else if ( ciEquals(loc, "fragment_output") )
            location = ShaderComp::LOCATION_FRAGMENT_OUTPUT;
        else
        {
            locationSet = false;
        }

                osg::Shader::Type type =
                    location == ShaderComp::LOCATION_VERTEX_MODEL || 
location == ShaderComp::LOCATION_VERTEX_VIEW || 
location == ShaderComp::LOCATION_VERTEX_CLIP ? 
osg::Shader::VERTEX:osg::Shader::FRAGMENT;

                osg::Shader* shader = new osg::Shader(type, source);
                shader->setName( filename );
                vp->setShader( filename, shader );
}

osgEarth组织着色器是有一套流程的,这套流程可以让用户很方便地添加自定义的着色器函数:

1、在构建场景图阶段,加载着色器文件,这些文件只包含不同管线阶段的处理函数,并没有main函数,从文件中#pragma vp_location可以解析出来是顶点或者片段着色器,比如vertex_model、vertex_view、vertex_clip对应顶点着色器中的函数,tess_control、tessellation_control、tess_eval、tessellation_eval、tessellation_eval、tess_evaluation对应细分着色器的函数,vertex_geometry、geometry对应几何着色器,fragment、fragment_coloring、fragment_lighting、fragment_output对应片段着色器。

Rex引擎包含以下着色器文件:

RexEngine.vert.glsl  ENGINE_VERT_MODEL  顶点着色器中的获取顶点位置的函数,

RexEngine.frag.glsl ENGINE_FRAG 是片段着色器,

RexEngine.elevation.glsl ENGINE_ELEVATION_MODEL 顶点着色器中获取

RexEngine.gs.glsl ENGINE_GEOM 是几何着色器

RexEngine.Morphing.vert.glsl MORPHING_VERT

RexEngine.NormalMap.frag.glsl NORMAL_MAP_FRAG

RexEngine.NormalMap.vert.glsl NORMAL_MAP_VERT

RexEngine.SDK.vert.glsl SDK 所有着色器阶段的文件

RexEngine.tcs.glsl 是细分着色器中的细分控制着色器,需要ogl4.x版本支持

RexEngine.tes.glsl 是细分着色器中的细分计算着色器,需要ogl4.x版本支持

RexEngine.vert.view.glsl ENGINE_VERT_VIEW

RexEngine.SDK.vert.glsl

 RexEngine.frag.glsl

 RexEngine.vert.glsl

 RexEngine.vert.view.glsl

RexEngine.elevation.glsl

RexEngine.NormalMap.vert.glsl

 RexEngine.NormalMap.frag.glsl

 RexEngine.Morphing.vert.glsl

2、在场景图渲染阶段,生成各个管线的main函数,并将文件中的函数组织起来,经过编译链接生成着色器程序。

是不是只有顶点和片段着色器有main函数呢,不是的,每个着色器阶段都有main函数。下面的函数负责生成每个着色器阶段的main函数。对于osgEarth2.9还不支持计算着色器。

osgEarth/ShaderFactory.cpp
ShaderComp::StageMask
ShaderFactory::createMains(const ShaderComp::FunctionLocationMap&    functions,
                           const VirtualProgram::ShaderMap&          in_shaders,
                           const VirtualProgram::ExtensionsSet&      in_extensions,
                           std::vector< osg::ref_ptr<osg::Shader> >& out_shaders) const
{
}

osgEarth的着色器框架:

1、顶点着色器框架

// VERTEX SHADER:
#version 330 compatibility

#pragma vp_name VP Vertex Shader Main
#extension GL_ARB_gpu_shader5 : enable 

// Vertex 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; 

// Vertex stage outputs:
out 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_out; 

// Function declarations:
//从其它着色器文件中提取过来的函数
void oe_rexEngine_vert(inout vec4); 
void oe_rexEngine_morph(inout vec4); 
void oe_rexEngine_elevation(inout vec4); 
void oe_rex_elevateVertexAndSetTexCoords(inout vec4); 
void oe_normalMapVertex(inout vec4); 

void main(void) 
{ 
    vp_Vertex = gl_Vertex; 
    vp_Normal = gl_Normal; 
    vp_Color  = gl_Color; 

    // "LOCATION_VERTEX_MODEL" user functions are called here:
    //模型空间的顶点处理过程函数
    oe_rexEngine_vert(vp_Vertex); 
    oe_rexEngine_morph(vp_Vertex); 
    oe_rexEngine_elevation(vp_Vertex); 
    ...

    // "LOCATION_VERTEX_VIEW" user functions are called here:
    //视口空间的顶点处理过程函数
    vp_Vertex = gl_ModelViewMatrix * vp_Vertex; 
    vp_Normal = normalize(gl_NormalMatrix * vp_Normal); 
    oe_rex_elevateVertexAndSetTexCoords(vp_Vertex); 
    oe_normalMapVertex(vp_Vertex); 
    ...

    // "LOCATION_VERTEX_CLIP" user functions are called last:
    //裁剪空间的顶点处理过程函数    
    gl_Position = gl_ProjectionMatrix * vp_Vertex;
    ...
    


    //用于细分、几何、片段着色器使用
    vp_out.oe_layer_rangeOpacity = oe_layer_rangeOpacity; 
    vp_out.oe_rex_morphFactor = oe_rex_morphFactor; 
    vp_out.oe_normalMapCoords = oe_normalMapCoords; 
    vp_out.oe_UpVectorView = oe_UpVectorView; 
    vp_out.oe_normalMapBinormal = oe_normalMapBinormal; 
    vp_out.vp_Normal = vp_Normal; 
    vp_out.oe_layer_texc = oe_layer_texc; 
    vp_out.oe_layer_texcParent = oe_layer_texcParent; 
    vp_out.oe_layer_tilec = oe_layer_tilec; 
    vp_out.vp_Color = vp_Color; 
    vp_out.vp_Vertex = vp_Vertex; 
} 

用户只需要设计好顶点模型、视图、裁剪处理的功能即可,osgEarth着色器框架会将这些函数功能放入main函数的相应位置,进行处理。当然,每一个功能函数的编写要遵守一定的规则,这样osgEarth着色器框架才能争取识别,规则详见osgEarth的Re

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值