• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            eryar

            PipeCAD - Plant Piping Design Software.
            RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
            posts - 603, comments - 590, trackbacks - 0, articles - 0

            A Simple OpenGL Shader Example

            Posted on 2015-06-27 21:38 eryar 閱讀(5091) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            A Simple OpenGL Shader Example

            eryar@163.com

            Abstract. OpenGL Shading Language, the high-level programming language defined to allow application writers to write programs that execute on the programmable processors defined within OpenGL. Informally the language is sometimes referred to as GLSL. The GLSL has been made part of the OpenGL standard as of OpenGL2.0. The paper focus on a simple example of OpenGL Shader, which can be used as a guide of GLSL.

            Key Words. OpenGL, OpenGL Shading Language, GLSL, Shader, Qt


            1. Introduction

            很早之前,從網(wǎng)上下載到這么一本書《OpenGL Shading Language》,翻看了幾遍,終不得要領(lǐng)。后來看到一本由仇德元編寫的《GPGPU編程技術(shù)—從GLSL、CUDA到OpenCL》,對(duì)GPU的了新的認(rèn)識(shí),對(duì)其性能刮目相看。書中給出的一個(gè)簡(jiǎn)單例子,也便于對(duì)Shader的入門。

            wps_clip_image-22807 wps_clip_image-16315

            Figure 1.1 OpenGL Shading Language and GPGPU

            從OpenGL Shading Language的出現(xiàn)可以發(fā)現(xiàn)程序員的一個(gè)特點(diǎn),那就是不喜歡一成不變的東西,希望自己有更多的控制權(quán),有個(gè)性,向往自由。如果要有個(gè)性,那就要引入這個(gè)新的東西GLSL了,增加了學(xué)習(xí)成本。不過從OpenGL2.0之后,Shader已經(jīng)成了OpenGL標(biāo)準(zhǔn)的一部分,新版的OpenGL的書籍中都少不了shader的內(nèi)容。Shader成了真實(shí)感圖形、高性能計(jì)算中不可或缺的技術(shù),學(xué)習(xí)掌握新的工具是為了生活更輕松。

            為了讓例子簡(jiǎn)單,本文在Qt中實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的Shader示例,通過這個(gè)例子入門后,再結(jié)合《OpenGL Shading Language》去實(shí)現(xiàn)更炫的效果。再者就是去理解OpenCASCADE中的shader應(yīng)用。

            2.OpenGL operation pipeline

            原來有個(gè)問題一直困擾著我,那就是三維的模型怎么在二維的計(jì)算機(jī)屏幕上顯示的。現(xiàn)在明白了這個(gè)就其實(shí)是顯卡的主要工作,并按一定的流水線來實(shí)現(xiàn)的。圖形流水線(pipeline)是GPU工作的通用模型,它以某種形式表示的三維場(chǎng)景為輸入,輸出二維的光柵圖像(raster images),也就是位圖。這樣三維的模型就可以在二維的屏幕上進(jìn)行顯示了。下面依次解釋流水線中的關(guān)鍵步驟:

            v 圖形流水線的起點(diǎn)是一個(gè)三維模型。這個(gè)三維模型可以是用軟件設(shè)計(jì)出的三維游戲人物,也可以是逆向工程(Reverse Engineering)中用激光掃描儀(Laser Scanner)設(shè)備采集的頂點(diǎn),也可以是幾何造型內(nèi)核(如OpenCASCADE)將模型網(wǎng)格化生成的頂點(diǎn)等。不論何種模型,在計(jì)算機(jī)處理之前都一定要經(jīng)過采樣而得到有限的離散頂點(diǎn),每個(gè)頂點(diǎn)都可以被一個(gè)向量描述為一個(gè)三維坐標(biāo)系里的點(diǎn)。這些可用來描述三維頂點(diǎn)組成了點(diǎn)云(Point Cloud)。如果采樣頻率足夠高,得到的頂點(diǎn)就可以細(xì)致地描述模型的表面。點(diǎn)云中的點(diǎn)可以由一個(gè)列表表示,列表中每一項(xiàng)是某點(diǎn)的三維坐標(biāo)值。同時(shí),列表中每一點(diǎn)都帶有該點(diǎn)的顏色信息。這個(gè)頂點(diǎn)列表即是流水線的輸入數(shù)據(jù),從起點(diǎn)進(jìn)入流水線。

            v 頂點(diǎn)可以用來形成多邊形,從而擬合出近似的表面。由頂點(diǎn)形成多邊形最常用的一種方法是三角化(triangulation),即每相鄰的三個(gè)點(diǎn)組成一個(gè)三角形。接下來每個(gè)頂點(diǎn)要經(jīng)過一系列的逐頂點(diǎn)操作(per-vertex operation),比如計(jì)算每個(gè)頂點(diǎn)的光照、坐標(biāo)變換等。

            v 由于顯示輸出的需要,用戶會(huì)定義一個(gè)視口(viewport),即觀察模型的位置和角度。然后,模型被投影到與視口觀察方向垂直的平面上。這個(gè)投影變換也是硬件加速的。根據(jù)視口的大小,投影結(jié)果有可能被裁剪(clipping)掉一部分。

            v 接受模型投影的平面是一個(gè)幀緩存(frame buffer),它是一個(gè)由像素(pixels)定義的光柵化平面。光柵化(rasterization)的過程,實(shí)際上就是決定幀緩存上的哪些像素該取怎么樣的值。通過采樣和插值,光柵化器(rasterizer)會(huì)決定一幅最接近原投影圖像的位圖。

            v 這些像素或者由像素連成的片段還須經(jīng)歷一些逐片段操作(per-fragment operation),也就是說它們的顏色也可以根據(jù)算法改變。另外紋理映射(texturing or texture mapping)在這一階段也會(huì)覆蓋某些像素的值。對(duì)于投影和光柵化的結(jié)果,還要判斷片段的可見性,也就是遮擋探測(cè)(occlusion detection)。

            v 最后幀緩存里面的結(jié)果被刷新到顯示器上。該過程以較高的頻率重復(fù),因?yàn)槿说囊曨l延遲,感覺到的就是連續(xù)的。

            wps_clip_image-15682

            Figure 2.1 A simplified version of the OpenGL pipeline

            wps_clip_image-24778

            Figure 2.2 Overview of OpenGL operation

            可以將上述OpenGL的渲染管線想成有兩個(gè)機(jī)器來完成主要的工作:一個(gè)機(jī)器處理頂點(diǎn);一個(gè)處理片段。對(duì)于早期的OpenGL而言,只是兩個(gè)機(jī)器是內(nèi)置的,程序員不能改變他們的工作方式。

            wps_clip_image-20622

            Figure 2.3 The OpenGL Fixed-Function Pipeline[3]

            然而可編程的Shader(programmable shader)則是可以對(duì)這兩個(gè)機(jī)器的工作進(jìn)行干預(yù)。

            3.Using GLSL Shaders

            當(dāng)你想在程序中使用一個(gè)頂點(diǎn)Shader或片段Shader時(shí),需要按如下步驟進(jìn)行:

            v 創(chuàng)建一個(gè)Shader對(duì)象;

            v 將Shader的源文件編譯到這個(gè)對(duì)象;

            v 驗(yàn)證源文件是否編譯成功;

            然后將這些shader鏈接到一個(gè)Shader程序:

            v 創(chuàng)建一個(gè)Shader程序;

            v 將創(chuàng)建的Shader對(duì)象綁定到這個(gè)Shader程序;

            v 鏈接Shader程序;

            v 驗(yàn)證鏈接是否成功;

            v 將shader對(duì)象應(yīng)用到頂點(diǎn)及片段的處理;

            如下圖所示:

            wps_clip_image-9757

            Figure 3.1 Shader Creation Flowchart

            4.The simplest Shader Example

            本來想用glut來寫個(gè)簡(jiǎn)單的例子的,但是識(shí)別不了glCreateShader這種函數(shù),發(fā)現(xiàn)要下載一些第三方庫才可以,如glew。看到Qt中已經(jīng)有封裝好的QGLShader和QGLShaderProgram,所以還是決定用Qt來寫個(gè)簡(jiǎn)單的例子,從而來對(duì)OpenGL的shader有個(gè)感性的認(rèn)識(shí)。其中關(guān)于Shader部分的主要是這個(gè)函數(shù):

            void ShaderWidget::setShader()
            {
                
            if (!isValid())
                {
                    
            return;
                }

                
            const QGLContext* aGlContext = context();

                QGLShaderProgram
            * aShaderProgram = new QGLShaderProgram(aGlContext);

                aShaderProgram
            ->addShaderFromSourceFile(QGLShader::Vertex, "vertex.vert");
                aShaderProgram
            ->addShaderFromSourceFile(QGLShader::Fragment, "fragment.frag");

                aShaderProgram
            ->link();
                aShaderProgram
            ->bind();
                QString aLog 
            = aShaderProgram->log();
            }

            先看一下沒有使用Shader之前的程序的效果圖:

            wps_clip_image-23309

            Figure 4.1 A teapot model without shader

            其中添加兩個(gè)shader,一個(gè)是vertex shader: vertex.vert,一個(gè)是fragment shader:fragment.frag。在vertex shader中對(duì)頂點(diǎn)的坐標(biāo)進(jìn)行變換,代碼如下所示:

            void main()
            {
                vec4 a 
            = gl_ModelViewProjectionMatrix * gl_Vertex;
                gl_Position.x 
            = 0.4 * a.x;
                gl_Position.y 
            = 0.1 * a.y;
            }

            OpenGL內(nèi)置變量gl_Position保存了當(dāng)前頂點(diǎn)的位置信息,上面的頂點(diǎn)著色器修改了每個(gè)頂點(diǎn)的X坐標(biāo)和Y坐標(biāo),使得輸出了一個(gè)扭曲的teapot。

            片段著色器當(dāng)前片段的顏色改成紫色,片段著色器代碼如下:

            void main()
            {
                gl_FragColor 
            = vec4(0.6270.1250.9411.0);
            }

            為了驗(yàn)證程序是使用了著色器,運(yùn)行程序得到如下圖所示:

            wps_clip_image-28370

            Figure 4.2 A Teapot with shader

            在不重新編譯程序的情況下,只修改片段著色器中的代碼,改成如下所示內(nèi)容:

            void main()
            {
                gl_FragColor 
            = vec4(0.6270.1250.01.0);
            }

            保存片段著色器代碼后直接運(yùn)行程序,可得到如下圖所示的紅色teapot:

            wps_clip_image-24948

            Figure 4.3 Change Fragment Shader

            可以看到shader的確是起了作用。本文最后將給出程序的完整代碼及shader的代碼,便于測(cè)試。

            5.Conclusion

            OpenGL的Shader給了程序員對(duì)OpenGL的更多的控制權(quán),可對(duì)其頂點(diǎn)處理和片段處理進(jìn)行更個(gè)性化的配置以達(dá)到炫酷的效果。

            Shader的使用步驟是先創(chuàng)建shader對(duì)象,再將源碼編譯到shader對(duì)象。最后通過shader程序,將shader添加并編譯、鏈接和使用。

            最后在Qt中以一個(gè)簡(jiǎn)單的例子來驗(yàn)證了shader的效果,入門之后便于理解GLSL更詳細(xì)的功能,以使自己的可視化程序具有更高的性能,更酷的效果。

            6. References

            1. 仇德元. GPGPU編程技術(shù)—從GLSL、CUDA到OpenCL. 機(jī)械工業(yè)出版社. 2012

            2. Randi J. Rost. OpenGL Shading Language. Addison Wesley. 2006

            3. Dave Shreiner. OpenGL Programming Guide(7th). Addison-Wesley. 2009

             

            Source Code and PDF Version: A Simple OpenGL Shader Example

            久久久久99精品成人片欧美| jizzjizz国产精品久久| 久久午夜综合久久| 久久亚洲sm情趣捆绑调教| 午夜精品久久久久久毛片| 国产综合精品久久亚洲| 久久久久亚洲AV成人网人人网站 | 久久精品成人国产午夜| 久久国产成人午夜AV影院| 色婷婷久久综合中文久久蜜桃av| 国产AV影片久久久久久| 一本一本久久aa综合精品| 久久久久久毛片免费看| 久久久精品2019免费观看| 久久久久18| 91久久成人免费| 国产精品九九九久久九九| 一本一本久久A久久综合精品 | 久久国产热精品波多野结衣AV| 久久天天躁狠狠躁夜夜2020| aaa级精品久久久国产片| 无码国内精品久久人妻| 久久久久久曰本AV免费免费| 久久精品国产只有精品66| 久久精品国产精品青草app| 无码日韩人妻精品久久蜜桃| 久久精品人妻中文系列| 伊人久久大香线蕉成人| 久久久噜噜噜久久中文字幕色伊伊| 久久亚洲国产精品一区二区| 久久99国产乱子伦精品免费| 中文无码久久精品| 久久久无码精品亚洲日韩按摩| 7777久久久国产精品消防器材| 久久精品中文无码资源站| 三级三级久久三级久久| 亚洲午夜无码久久久久小说| 99久久免费国产精品特黄| 国产精品久久久久久久久久影院| 一级做a爰片久久毛片免费陪| 久久综合久久鬼色|