亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

延遲渲染(Deferred Shading)技術詳解

2019-11-11 03:51:13
字體:
來源:轉載
供稿:網友

一、Deferred shading技術簡介

Deferred shading是這樣一種技術:將光照/渲染計算推遲到第二步進行計算。我們這樣做的目的是為了避免多次(超過1次)渲染同一個像素。

基本思想如下:

1、在第一步中,我們渲染場景,但是與通常情況下應用反射模型計算片斷顏色不同的是,我們只是簡單的將幾何信息(位置坐標,法線向量,紋理坐標,反射系數等等)存儲在中間緩沖區中,這樣的緩沖區我們稱之為g-buffer(g是幾何geometry的縮寫)。

2、在第二步,我們從g-buffer中讀取信息,應用反射模型,計算出每個像素的最終顏色。

 

Deferred shading技術的應用使得我們避免了應用反射模型于最終不可見的片斷上。例如,考慮這樣的像素,它位于兩個多邊形重疊的區域。通常的片斷著色器會讀對每個多邊形分別計算那個像素一次;然而,兩次執行的結果最終只有一個成為該像素的最終顏色(這里基于的一個假設是:混合已被禁用)。這樣,其中的一次計算就是無用的。有了Deferred shading技術,反射模型的計算會推遲到所有幾何體被處理之后,那時候每個像素位置幾何體的可見性也是已知的。這樣,對于屏幕上的每個像素,反射模型的計算只會發生一次。

 

Deferred shading容易懂而且便于使用。它能夠幫助實施很復雜的光照/反射模型。

 

二、結合例子來說明Deferred shading技術

下面的例子采用Deferred shading技術渲染了一個包含一個茶壺和一個圓環的場景。效果如下:

圖一 場景渲染效果圖

在這個例子中,我們將位置坐標、法線以及漫反射因子存儲在g-buffer里。在第二步的時候,我們使用g-buffer里面的數據來進行漫反射光照模型的計算。

g-buffer包含3個紋理:分別用來存儲位置坐標、法線以及漫反射因子。對應的采用了3個uniform變量:PositionTex、NormalTex、ColorTex。

他們均被關聯到一個FBO上。關于FBO使用見:FBO。

 

下面是創建包含g-buffer的FBO的代碼:

 

GLuint depthBuf, posTex, normTex, colorTex;        // Create and bind the FBO       glGenFramebuffers(1, &deferredFBO);      glBindFramebuffer(GL_FRAMEBUFFER, deferredFBO);        // The depth buffer       glGenRenderbuffers(1, &depthBuf);      glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);      glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);        // The position buffer       glActiveTexture(GL_TEXTURE0);   // Use texture unit 0       glGenTextures(1, &posTex);      glBindTexture(GL_TEXTURE_2D, posTex);      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        // The normal buffer       glActiveTexture(GL_TEXTURE1);      glGenTextures(1, &normTex);      glBindTexture(GL_TEXTURE_2D, normTex);      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        // The color buffer       glActiveTexture(GL_TEXTURE2);      glGenTextures(1, &colorTex);      glBindTexture(GL_TEXTURE_2D, colorTex);      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        // Attach the images to the framebuffer       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf);      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, posTex, 0);      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normTex, 0);      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorTex, 0);        GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,                          GL_COLOR_ATTACHMENT2};      glDrawBuffers(4, drawBuffers);        glBindFramebuffer(GL_FRAMEBUFFER, 0);  GLuint depthBuf, posTex, normTex, colorTex;        // Create and bind the FBO      glGenFramebuffers(1, &deferredFBO);      glBindFramebuffer(GL_FRAMEBUFFER, deferredFBO);        // The depth buffer      glGenRenderbuffers(1, &depthBuf);      glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);      glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);        // The position buffer      glActiveTexture(GL_TEXTURE0);   // Use texture unit 0      glGenTextures(1, &posTex);      glBindTexture(GL_TEXTURE_2D, posTex);      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        // The normal buffer      glActiveTexture(GL_TEXTURE1);      glGenTextures(1, &normTex);      glBindTexture(GL_TEXTURE_2D, normTex);      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        // The color buffer      glActiveTexture(GL_TEXTURE2);      glGenTextures(1, &colorTex);      glBindTexture(GL_TEXTURE_2D, colorTex);      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        // Attach the images to the framebuffer      glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf);      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, posTex, 0);      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normTex, 0);      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorTex, 0);        GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,                          GL_COLOR_ATTACHMENT2};      glDrawBuffers(4, drawBuffers);        glBindFramebuffer(GL_FRAMEBUFFER, 0);  

注意:三個紋理分別使用函數glFramebufferTexture2D()關聯到FBO的顏色關聯點0、1、2上面。接著調用函數glDrawBuffers把它們和片斷著色器的輸出變量聯系起來。

 

函數glDrawBuffer指示了FBO成員和片斷著色器輸出變量之間的聯系。FBO中的第i個成員對應片斷著色器中的索引為i的輸出變量。這樣,片斷著色器(下面列出了完整代碼)中相對應的輸出變量分別是PosiutionData,NormalData和ColorData。

 

頂點著色器實現了一個很簡單的功能:將位置坐標和法線轉化到eye sapce中,然后傳遞到片斷著色器中。而紋理坐標則沒有發生變化。

 

片斷著色器如下:

#version 400     struct LightInfo {    vec4 Position;  // Light position in eye coords.     vec3 Intensity; // A,D,S intensity   };  uniform LightInfo Light;    struct MaterialInfo {    vec3 Kd;            // Diffuse reflectivity   };  uniform MaterialInfo Material;    subroutine void RenderPassType();  subroutine uniform RenderPassType RenderPass;    uniform sampler2D PositionTex, NormalTex, ColorTex;    in vec3 Position;  in vec3 Normal;  in vec2 TexCoord;    layout (location = 0) out vec4 FragColor;  layout (location = 1) out vec3 PositionData;  layout (location = 2) out vec3 NormalData;  layout (location = 3) out vec3 ColorData;    vec3 diffuseModel( vec3 pos, vec3 norm, vec3 diff )  {      vec3 s = normalize(vec3(Light.Position) - pos);      float sDotN = max( dot(s,norm), 0.0 );      vec3 diffuse = Light.Intensity * diff * sDotN;        return diffuse;  }    subroutine (RenderPassType)  void pass1()  {      // Store position, normal, and diffuse color in textures       PositionData = Position;      NormalData = Normal;      ColorData = Material.Kd;  }    subroutine(RenderPassType)  void pass2()  {      // Retrieve position and normal information from textures       vec3 pos = vec3( texture( PositionTex, TexCoord ) );      vec3 norm = vec3( texture( NormalTex, TexCoord ) );      vec3 diffColor = vec3( texture(ColorTex, TexCoord) );        FragColor = vec4( diffuseModel(pos,norm,diffColor), 1.0 );  }    void main() {      // This will call either pass1 or pass2       RenderPass();  }  #version 400    struct LightInfo {    vec4 Position;  // Light position in eye coords.    vec3 Intensity; // A,D,S intensity  };  uniform LightInfo Light;    struct MaterialInfo {    vec3 Kd;            // Diffuse reflectivity  };  uniform MaterialInfo Material;    subroutine void RenderPassType();  subroutine uniform RenderPassType RenderPass;    uniform sampler2D PositionTex, NormalTex, ColorTex;    in vec3 Position;  in vec3 Normal;  in vec2 TexCoord;    layout (location = 0) out vec4 FragColor;  layout (location = 1) out vec3 PositionData;  layout (location = 2) out vec3 NormalData;  layout (location = 3) out vec3 ColorData;    vec3 diffuseModel( vec3 pos, vec3 norm, vec3 diff )  {      vec3 s = normalize(vec3(Light.Position) - pos);      float sDotN = max( dot(s,norm), 0.0 );      vec3 diffuse = Light.Intensity * diff * sDotN;        return diffuse;  }    subroutine (RenderPassType)  void pass1()  {      // Store position, normal, and diffuse color in textures      PositionData = Position;      NormalData = Normal;      ColorData = Material.Kd;  }    subroutine(RenderPassType)  void pass2()  {      // Retrieve position and normal information from textures      vec3 pos = vec3( texture( PositionTex, TexCoord ) );      vec3 norm = vec3( texture( NormalTex, TexCoord ) );      vec3 diffColor = vec3( texture(ColorTex, TexCoord) );        FragColor = vec4( diffuseModel(pos,norm,diffColor), 1.0 );  }    void main() {      // This will call either pass1 or pass2      RenderPass();  }  

 

片斷著色器則包含了關于光源、材料的一些信息,都是uniform變量,以用于光照計算。

片斷著色器里面使用了subroutine技術,實現了兩個函數pass1和pass2,分別包含了第一步和第二步的操作。我們在OpenGL應用程序中通過設置uniform變量的值可以選擇使用相應的功能。

 

在OpenGL應用程序里面,

實施第一步的步驟如下:

1、綁定FBO;

2、情況顏色以及深度緩沖區,選擇pass1 subroutine函數,啟用深度測試;

3、渲染場景。

 

實施第二步的步驟是:

1、去除FBO綁定(將其綁定到0),目的是能夠渲染場景到默認緩沖區,而不是FBO里面,它就能顯示到屏幕上;

2、清除顏色緩沖去對象。禁用深度測試;

3、選擇pass2 subroutine函數,渲染一個充滿屏幕的四邊形,帶有紋理坐標,每個方向的紋理坐標的范圍都是從0到1.計算光照模型,得出最后的片斷顏色。

 

三、如何選擇使用Deferred shading技術

在圖形學領域,關于Deferred shading技術的優點和缺陷備受爭議。這種技術并不適用所有的場合,它取決于你的應用程序的需求。因此在覺得是否采用這個技術之前一定要權衡它帶來的優點和缺陷。

Deferred shading技術帶來一個很重要的缺點就是不能使用基于硬件實現的多重采樣抗鋸齒功能。因為渲染過程發生在第二步,所以我們在第二步需要多個樣本。但是,在第二步我們只有每一個像素的一個樣本。

另外一個缺點就是不能使用混合技術。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
九九热这里只有精品6| 大桥未久av一区二区三区| 国产精品视频久久久| 国产欧美日韩中文字幕| 亚洲精品二三区| 全亚洲最色的网站在线观看| 亚洲一区二区三区乱码aⅴ| 欧美一级黑人aaaaaaa做受| 久久久欧美精品| 欧美在线视频免费播放| 欧美大秀在线观看| 97在线视频免费看| 高清亚洲成在人网站天堂| 日韩免费av片在线观看| 午夜精品久久久久久久99热| 狠狠色噜噜狠狠狠狠97| 国产精品视频午夜| 成人444kkkk在线观看| 亚洲a一级视频| 欧美国产欧美亚洲国产日韩mv天天看完整| 日韩在线观看你懂的| 亚洲美女精品成人在线视频| 欧美在线视频观看免费网站| 成人黄色在线观看| 亚洲第一福利网| 国产成人涩涩涩视频在线观看| 尤物tv国产一区| 国产91精品最新在线播放| 亚洲成人精品久久| 日韩电影视频免费| 91免费在线视频| 欧美一区二区视频97| 中日韩美女免费视频网址在线观看| 亚洲欧美日韩高清| 992tv成人免费影院| 国产精品尤物福利片在线观看| 亚洲一区二区久久久久久| 欧洲成人免费视频| 中文字幕亚洲一区二区三区五十路| 日韩在线免费观看视频| 日韩av资源在线播放| 国产精品私拍pans大尺度在线| 色偷偷av亚洲男人的天堂| 久久久久久国产三级电影| 亚洲最大在线视频| 2019国产精品自在线拍国产不卡| 国产精品www| 一本色道久久88亚洲综合88| 黑人精品xxx一区一二区| 黑人精品xxx一区| 亚洲剧情一区二区| 亚洲免费中文字幕| 亚洲高清色综合| 中文字幕欧美日韩| 97视频在线观看网址| 欧美专区国产专区| 亚洲国产精品久久| 国产精品成人av在线| 国产精品亚洲综合天堂夜夜| 97视频在线观看免费高清完整版在线观看| 国产日韩精品电影| 成人黄色免费看| 精品美女久久久久久免费| 久久精品中文字幕电影| 亚洲aⅴ男人的天堂在线观看| 久久人人爽亚洲精品天堂| 在线观看国产成人av片| 日韩av一区二区在线| 亚洲人午夜色婷婷| 日韩免费看的电影电视剧大全| 亚洲日韩欧美视频一区| 精品福利一区二区| 4388成人网| 国产精品69精品一区二区三区| 久久天天躁狠狠躁夜夜躁2014| 亚洲少妇中文在线| 欧美疯狂xxxx大交乱88av| 91久久久久久久| 日韩中文字幕免费看| 最近2019中文字幕大全第二页| 国产精品毛片a∨一区二区三区|国| 亚洲精品久久久久中文字幕欢迎你| 亚洲视频axxx| 国内精品中文字幕| 亚洲最新av在线网站| 九色精品美女在线| 午夜精品一区二区三区在线播放| 亚洲精品中文字幕av| 欧美日韩亚洲精品一区二区三区| 51精品国产黑色丝袜高跟鞋| 日本高清久久天堂| 亚洲欧美精品中文字幕在线| 国产裸体写真av一区二区| 精品国产一区二区三区四区在线观看| 亚洲欧美中文字幕在线一区| 4p变态网欧美系列| 欧美丰满少妇xxxxx| 日本午夜人人精品| 亚洲欧美另类中文字幕| 中文字幕综合一区| 亚洲一区二区少妇| 久久久久免费精品国产| 成人久久一区二区三区| 亚洲大胆人体视频| 亚洲人成电影网站色www| 在线播放日韩专区| 韩国欧美亚洲国产| 97在线视频观看| 国语自产偷拍精品视频偷| 亚洲va欧美va在线观看| 午夜精品久久久久久99热软件| 国产亚洲欧洲高清一区| 91高潮精品免费porn| 国产盗摄xxxx视频xxx69| 国产亚洲日本欧美韩国| 麻豆国产va免费精品高清在线| 亚洲美女在线观看| 国语自产精品视频在线看抢先版图片| 午夜精品久久久99热福利| 精品网站999www| 国产不卡在线观看| 久久久久在线观看| 亚洲精品国产欧美| 亚洲欧美日韩在线高清直播| 日本久久久久亚洲中字幕| 亚洲高清一区二| 亚洲人成五月天| 色综合久久悠悠| 久久精品视频在线| 45www国产精品网站| 国产极品精品在线观看| 欧美怡春院一区二区三区| 97成人精品视频在线观看| 国外日韩电影在线观看| 久久99精品视频一区97| 91国偷自产一区二区三区的观看方式| 伊人成人开心激情综合网| 国产精品视频中文字幕91| 精品视频一区在线视频| 高清日韩电视剧大全免费播放在线观看| 一区三区二区视频| 亚洲欧美一区二区精品久久久| 亚洲在线免费观看| 亚洲精品免费在线视频| 一区三区二区视频| 久久精彩免费视频| 成人写真视频福利网| 中文字幕欧美精品日韩中文字幕| 欧美一区二区色| 国产精品视频专区| 国产suv精品一区二区| 亚洲人成网站色ww在线| 欧美夜福利tv在线| 国产精品福利在线| 国产一区二区三区毛片| 国产免费一区二区三区在线能观看| 美女扒开尿口让男人操亚洲视频网站| 欧美做受高潮1| 91精品国产99久久久久久| 午夜精品久久久99热福利| 精品国产成人在线| 亚洲欧美在线一区二区| 久久久亚洲欧洲日产国码aⅴ| 国产乱肥老妇国产一区二|