亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

OpenGL - 無法一次將所有數據傳遞到著色器中

OpenGL - 無法一次將所有數據傳遞到著色器中

HUWWW 2021-11-01 15:08:18
我正在嘗試使用 opengl 3.3 在四邊形(2 個三角形)上顯示紋理在四邊形上繪制紋理效果很好;但是,當我有一個紋理(精靈圖集)但使用 2 個四邊形(對象)來顯示圖集的不同部分時。在繪制循環中,它們最終會切換回第四個(一個消失然后再次出現,等等)在它們各自的翻譯位置。我繪制它的方式不是每個四邊形(或對象)的標準 DrawElements,而是我打包所有四邊形、uv、平移等將它們作為一個大塊(作為“in”變量)發送到著色器:頂點著色器: #version 330 core// Input vertex data, different for all executions of this shader.in vec3 vertexPosition_modelspace;in vec3 vertexColor;in vec2 vertexUV;in vec3 translation;in vec4 rotation;in vec3 scale;// Output data ; will be interpolated for each fragment.out vec2 UV;// Output data ; will be interpolated for each fragment.out vec3 fragmentColor;// Values that stay constant for the whole mesh.uniform mat4 MVP;...void main(){    mat4 Model = mat4(1.0);    mat4 t = translationMatrix(translation);    mat4 s = scaleMatrix(scale);    mat4 r = rotationMatrix(vec3(rotation), rotation[3]);    Model *= t * r * s;    gl_Position = MVP * Model * vec4 (vertexPosition_modelspace,1); //* MVP;    // The color of each vertex will be interpolated    // to produce the color of each fragment    fragmentColor = vertexColor;    // UV of the vertex. No special space for this one.    UV = vertexUV;}頂點著色器是否像我認為的那樣在處理大量數據時工作 - 它單獨繪制每個段作為統一傳遞,因為它看起來不像?我的思路是否正確?為了完整起見,這是我的片段著色器:#version 330 core// Interpolated values from the vertex shadersin vec3 fragmentColor;// Interpolated values from the vertex shadersin vec2 UV;// Ouput dataout vec4 color;// Values that stay constant for the whole mesh.uniform sampler2D myTextureSampler;void main(){    // Output color = color of the texture at the specified UV    color = texture2D( myTextureSampler, UV ).rgba;}
查看完整描述

2 回答

?
叮當貓咪

TA貢獻1776條經驗 獲得超12個贊

你只有單身 sampler2D

  • 這意味著您只有一個紋理可供您使用

  • 不管你綁定了多少。

  • 如果您確實需要將數據作為單個塊傳遞

  • 那么你應該為你得到的每個紋理添加采樣器

  • 不確定你有多少對象/紋理

  • 但是通過這種數據傳遞方式,您受到紋理單元的 gfx hw 限制

  • 您還需要在數據中添加另一個值,告訴哪個圖元使用哪個紋理單元

  • 然后在片段內部選擇正確的紋理采樣器......

你應該添加這樣的東西:

// vertex

in int usedtexture;

out int txr;


void main()

 {

 txr=usedtexture;

 }


// fragment

uniform sampler2D myTextureSampler0;

uniform sampler2D myTextureSampler1;

uniform sampler2D myTextureSampler2;

uniform sampler2D myTextureSampler3;

in vec2 UV;

in int txr;

out vec4 color;

void main

 {

      if (txr==0) color = texture2D( myTextureSampler0, UV ).rgba;

 else if (txr==1) color = texture2D( myTextureSampler1, UV ).rgba;

 else if (txr==2) color = texture2D( myTextureSampler2, UV ).rgba;

 else if (txr==3) color = texture2D( myTextureSampler3, UV ).rgba;

 else color=vec4(0.0,0.0,0.0,0.0);

 }

由于以下原因,這種傳遞方式并不好:

  • 使用的紋理數量僅限于硬件紋理單元限制

  • 如果您的渲染需要額外的紋理,如法線/光澤度/光照貼圖

  • 那么每個對象類型需要超過 1 個紋理,并且您的限制突然除以 2,3,4 ...

  • 您需要if/switch片段內的語句,這會大大減慢速度

  • 是的,您可以少吃早午餐,但是您需要一直訪問所有紋理,從而無緣無故地增加 gfx 的熱應力...

這種傳球適合

  • 單個圖像中的所有紋理(正如你提到的紋理圖集)

  • 對于具有少量對象類型(或材料)但對象數量較多的場景,這種方式可以更快并且合理......


查看完整回答
反對 回復 2021-11-01
  • 2 回答
  • 0 關注
  • 160 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號