多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > Deferred shading技術簡介

Deferred shading技術簡介

來源:程序員人生   發布時間:2016-02-28 10:07:27 閱讀次數:2408次

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

基本思想以下:

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

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


Deferred shading技術的利用使得我們避免了利用反射模型于終究不可見的片斷上。例如,斟酌這樣的像素,它位于兩個多邊形堆疊的區域。通常的片斷著色器會讀對每一個多邊形分別計算那個像素1次;但是,兩次履行的結果終究只有1個成為該像素的終究色彩(這里基于的1個假定是:混合已被禁用)。這樣,其中的1次計算就是無用的。有了Deferred shading技術,反射模型的計算會推延到所有幾何體被處理以后,那時候每一個像素位置幾何體的可見性也是已知的。這樣,對屏幕上的每一個像素,反射模型的計算只會產生1次。


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


2、結合例子來講明Deferred shading技術

下面的例子采取Deferred shading技術渲染了1個包括1個茶壺和1個圓環的場景。效果以下:

圖1 場景渲染效果圖

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

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

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


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

[cpp] view plaincopy
  1. GLuint depthBuf, posTex, normTex, colorTex;

  2. // Create and bind the FBO
  3. glGenFramebuffers(1, &deferredFBO);
  4. glBindFramebuffer(GL_FRAMEBUFFER, deferredFBO);

  5. // The depth buffer
  6. glGenRenderbuffers(1, &depthBuf);
  7. glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);
  8. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);

  9. // The position buffer
  10. glActiveTexture(GL_TEXTURE0); // Use texture unit 0
  11. glGenTextures(1, &posTex);
  12. glBindTexture(GL_TEXTURE_2D, posTex);
  13. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  14. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  15. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  16. // The normal buffer
  17. glActiveTexture(GL_TEXTURE1);
  18. glGenTextures(1, &normTex);
  19. glBindTexture(GL_TEXTURE_2D, normTex);
  20. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  21. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  22. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  23. // The color buffer
  24. glActiveTexture(GL_TEXTURE2);
  25. glGenTextures(1, &colorTex);
  26. glBindTexture(GL_TEXTURE_2D, colorTex);
  27. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  28. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  29. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  30. // Attach the images to the framebuffer
  31. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf);
  32. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, posTex, 0);
  33. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normTex, 0);
  34. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorTex, 0);

  35. GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
  36. GL_COLOR_ATTACHMENT2};
  37. glDrawBuffers(4, drawBuffers);

  38. glBindFramebuffer(GL_FRAMEBUFFER, 0);
[cpp] view plaincopy
  1. GLuint depthBuf, posTex, normTex, colorTex;

  2. // Create and bind the FBO
  3. glGenFramebuffers(1, &deferredFBO);
  4. glBindFramebuffer(GL_FRAMEBUFFER, deferredFBO);

  5. // The depth buffer
  6. glGenRenderbuffers(1, &depthBuf);
  7. glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);
  8. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);

  9. // The position buffer
  10. glActiveTexture(GL_TEXTURE0); // Use texture unit 0
  11. glGenTextures(1, &posTex);
  12. glBindTexture(GL_TEXTURE_2D, posTex);
  13. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  14. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  15. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  16. // The normal buffer
  17. glActiveTexture(GL_TEXTURE1);
  18. glGenTextures(1, &normTex);
  19. glBindTexture(GL_TEXTURE_2D, normTex);
  20. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  21. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  22. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  23. // The color buffer
  24. glActiveTexture(GL_TEXTURE2);
  25. glGenTextures(1, &colorTex);
  26. glBindTexture(GL_TEXTURE_2D, colorTex);
  27. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
  28. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  29. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  30. // Attach the images to the framebuffer
  31. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf);
  32. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, posTex, 0);
  33. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normTex, 0);
  34. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorTex, 0);

  35. GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
  36. GL_COLOR_ATTACHMENT2};
  37. glDrawBuffers(4, drawBuffers);

  38. glBindFramebuffer(GL_FRAMEBUFFER, 0);

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

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


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


片斷著色器以下:

[cpp] view plaincopy
  1. #version 400

  2. struct LightInfo {
  3. vec4 Position; // Light position in eye coords.
  4. vec3 Intensity; // A,D,S intensity
  5. };
  6. uniform LightInfo Light;

  7. struct MaterialInfo {
  8. vec3 Kd; // Diffuse reflectivity
  9. };
  10. uniform MaterialInfo Material;

  11. subroutine void RenderPassType();
  12. subroutine uniform RenderPassType RenderPass;

  13. uniform sampler2D PositionTex, NormalTex, ColorTex;

  14. in vec3 Position;
  15. in vec3 Normal;
  16. in vec2 TexCoord;

  17. layout (location = 0) out vec4 FragColor;
  18. layout (location = 1) out vec3 PositionData;
  19. layout (location = 2) out vec3 NormalData;
  20. layout (location = 3) out vec3 ColorData;

  21. vec3 diffuseModel( vec3 pos, vec3 norm, vec3 diff )
  22. {
  23. vec3 s = normalize(vec3(Light.Position) - pos);
  24. float sDotN = max( dot(s,norm), 0.0 );
  25. vec3 diffuse = Light.Intensity * diff * sDotN;

  26. return diffuse;
  27. }

  28. subroutine (RenderPassType)
  29. void pass1()
  30. {
  31. // Store position, normal, and diffuse color in textures
  32. PositionData = Position;
  33. NormalData = Normal;
  34. ColorData = Material.Kd;
  35. }

  36. subroutine(RenderPassType)
  37. void pass2()
  38. {
  39. // Retrieve position and normal information from textures
  40. vec3 pos = vec3( texture( PositionTex, TexCoord ) );
  41. vec3 norm = vec3( texture( NormalTex, TexCoord ) );
  42. vec3 diffColor = vec3( texture(ColorTex, TexCoord) );

  43. FragColor = vec4( diffuseModel(pos,norm,diffColor), 1.0 );
  44. }

  45. void main() {
  46. // This will call either pass1 or pass2
  47. RenderPass();
  48. }
[cpp] view plaincopy
  1. #version 400

  2. struct LightInfo {
  3. vec4 Position; // Light position in eye coords.
  4. vec3 Intensity; // A,D,S intensity
  5. };
  6. uniform LightInfo Light;

  7. struct MaterialInfo {
  8. vec3 Kd; // Diffuse reflectivity
  9. };
  10. uniform MaterialInfo Material;

  11. subroutine void RenderPassType();
  12. subroutine uniform RenderPassType RenderPass;

  13. uniform sampler2D PositionTex, NormalTex, ColorTex;

  14. in vec3 Position;
  15. in vec3 Normal;
  16. in vec2 TexCoord;

  17. layout (location = 0) out vec4 FragColor;
  18. layout (location = 1) out vec3 PositionData;
  19. layout (location = 2) out vec3 NormalData;
  20. layout (location = 3) out vec3 ColorData;

  21. vec3 diffuseModel( vec3 pos, vec3 norm, vec3 diff )
  22. {
  23. vec3 s = normalize(vec3(Light.Position) - pos);
  24. float sDotN = max( dot(s,norm), 0.0 );
  25. vec3 diffuse = Light.Intensity * diff * sDotN;

  26. return diffuse;
  27. }

  28. subroutine (RenderPassType)
  29. void pass1()
  30. {
  31. // Store position, normal, and diffuse color in textures
  32. PositionData = Position;
  33. NormalData = Normal;
  34. ColorData = Material.Kd;
  35. }

  36. subroutine(RenderPassType)
  37. void pass2()
  38. {
  39. // Retrieve position and normal information from textures
  40. vec3 pos = vec3( texture( PositionTex, TexCoord ) );
  41. vec3 norm = vec3( texture( NormalTex, TexCoord ) );
  42. vec3 diffColor = vec3( texture(ColorTex, TexCoord) );

  43. FragColor = vec4( diffuseModel(pos,norm,diffColor), 1.0 );
  44. }

  45. void main() {
  46. // This will call either pass1 or pass2
  47. RenderPass();
  48. }

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

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


在OpenGL利用程序里面,

實行第1步的步驟以下:

1、綁定FBO;

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

3、渲染場景。


實行第2步的步驟是:

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

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

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


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

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

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

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


參考資料:

《GPU Gems 2》的第9章

《GPU Gems 3》的第19章

版權聲明:本文為【借你1秒】原創文章,轉載請標明出處。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: www.羞羞| 国产v片成人影院在线观看 国产v片在线观看 | 校园春色欧美 | 欧美一级性视频 | 毛片黄| 欧美成人免费观看国产 | 欧美乱大交xxxx | 国产福利不卡一区二区三区 | 亚洲都市春色系列小说类型 | 日本中文字幕永久在线 | 新japanesevideo乱| 美国人成毛片在线播放 | 欧美理论片在线观看一区二区 | 精品一区二区三区高清免费不卡 | 欧美高清成人videosex | 一区二区三区精品国产 | 精品国产91久久久久 | 日本系列 1页 亚洲系列 | 亚洲成av人影片在线观看 | 99操视频| 亚州免费一级毛片 | 国产福利写真视频在线观看 | 18以下勿进色禁视频免费看 | 国产美女福利在线 | 黑人巨大三根一起进hd | 男人午夜视频在线观看 | aa老外一级毛片 | 免费视频不卡一区二区三区 | 亚洲精品图区 | 色一情一伦一区二区三 | 天堂网男人 | 动漫精品一级毛片动漫 | 黄色a大片 | 亚洲第一页国产 | 夜夜影院未满十八勿进 | 亚洲色图欧美 | 欧美第一福利 | 精品无码久久久久久久动漫 | 欧美乱人伦中文在线观看不卡 | 黑人巨大 | 久久久久国产精品美女毛片 |