• OpenGL(八)使用 subroutine 切换可编程管线


    Subroutine 功能是在OpenGL 4.0 版本号里才添加的。因此对于各种Android手机。这个功能基本跪了。假设你发现你的程序报错:ARB_shader_subroutine。那就说明当前显卡不支持。只是大体思路能够了解一下。由于思路相似的功能有其它的实现方式。

    原理

    在shader中声明一个函数变量,然后定义它的指针,并将其作为一个uniform变量公开出去。最后定义非常多复写函数就可以。

    实现

    由于版本号限制。使用 subroutine 要注意在shader中添加版本号的编译宏:

    #version 400 core

    在shader中编写:

    subroutine vec4 SurfaceColor();
    subroutine uniform SurfaceColor U_SurfaceColor;
    
    subroutine (SurfaceColor) vec4 Ambient()
    {
       //...
    }
    
    subroutine (SurfaceColor) vec4 Diffuse()
    {
        //...
    }
    
    subroutine (SurfaceColor) vec4 Specular()
    {
        //...
    }
    
    void main()
    {
        gl_FragColor = U_SurfaceColor();
    }

    在shader中,每个函数中的代码段代表一种处理函数。

    还有一方面在GL指令中,绑定这个函数指针,并为其指定实现函数的索引值,就可以实现效果的控制。

    surfaceColorLocation = glGetSubroutineUniformLocation(program,GL_FRAGMENT_SHADER,"U_SurfaceColor");
    
    GLuint ambientLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Ambient");
    GLuint diffuseLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Diffuse");
    GLuint specularLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Specular");
    
    //draw
    glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&ambientLightIndex);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
    glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    总结

    本文介绍了OpenGL中的 subroutine 机制,通过它能够切换shader的内容。在Unity3d中使用Shader.maximumLOD技术能够达到相似的效果,相关内容能够參考官方文档


    松阳论道

    关注我的微信公众号,获取很多其它优质内容

  • 相关阅读:
    jQuery使用工具集
    JQuery解决鼠标单双击冲突问题
    线程池
    配置文件application.properties参数详解
    SpringBoot整合SpringDataJPA
    获取数据库的自增主键(六)
    【使用篇二】邮箱自动化配置集成(18)
    Quartz自动化配置集成
    Cron表达式详解
    标准盒模型和怪异盒模型的区别
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7286987.html
Copyright © 2020-2023  润新知