[英]Adding projection matrix to opengl es point sprites particle effect vertex shader
[英]OpenGL ES 2.0 point sprites with distinct rotations - calculate matrix in shader?
我試圖找到一種解決方案,使我可以使點精靈圍繞z軸旋轉,並具有不同的屬性(即統一不會這樣做)。
在我的應用程序中,每幀繪制了成百上千的點精靈,然后將它們存儲在VBO中(最終可能> 100萬)。 因此,我正在尋找內存使用和性能之間的最佳折衷。
頂點和片段着色器當前看起來像這樣:
// VERTEX SHADER
attribute vec4 a_position;
attribute vec4 a_color;
attribute float a_size;
uniform mat4 u_mvpMatrix;
varying vec4 v_color;
void main()
{
v_color = a_color;
gl_Position = u_mvpMatrix * a_position;
gl_PointSize = a_size;
}
// FRAGMENT SHADER
precision mediump float;
uniform sampler2D s_texture;
varying vec4 v_color;
void main()
{
vec4 textureColor = texture2D(s_texture, gl_PointCoord);
gl_FragColor = v_color * textureColor;
}
我目前可以想象以下可能性:
將mat4 rotMatrix
屬性添加到我的點精靈數據中。 將其傳遞到片段着色器並旋轉每個片段:
vec2 texCoord = (rotMatrix * vec4(gl_PointCoord, 0, 1)).xy gl_FragColor = v_color * texture2D(s_texture, texCoord);
GLKit
)。 將float angle
屬性添加到我的點精靈數據中,然后在頂點着色器中計算旋轉矩陣。 如上所述,將旋轉矩陣傳遞給片段着色器。
有什么好的方法的想法嗎?
最后我得到的解決方案是問題的第二個解決方案:在頂點着色器中計算旋轉矩陣。 這具有以下優點:
我猜想的缺點似乎並不適用。 即使在第一代iPad上運行,我也沒有注意到性能下降。 GLSL中的矩陣計算有些麻煩,但效果很好。 為了使其他任何人都可以嘗試這樣做,下面是頂點着色器的相關部分:
//...
attribute float a_angle;
varying mat4 v_rotationMatrix;
void main()
{
//...
float cos = cos(a_angle);
float sin = sin(a_angle);
mat4 transInMat = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0);
mat4 rotMat = mat4(cos, -sin, 0.0, 0.0,
sin, cos, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
mat4 resultMat = transInMat * rotMat;
resultMat[3][0] = resultMat[3][0] + resultMat[0][0] * -0.5 + resultMat[1][0] * -0.5;
resultMat[3][1] = resultMat[3][1] + resultMat[0][1] * -0.5 + resultMat[1][1] * -0.5;
resultMat[3][2] = resultMat[3][2] + resultMat[0][2] * -0.5 + resultMat[1][2] * -0.5;
v_rotationMatrix = resultMat;
//...
}
考慮到沒有明顯的性能影響,此解決方案是理想的,因為無需創建紋理貼圖/查找並消耗額外的內存,並且可以使其余代碼保持簡潔。
我不能說為每個頂點計算矩陣都沒有任何缺點(例如,減少了電池壽命),並且在不同情況下性能可能是一個問題,但這對我的需求很好。
您是否考慮過使用不同的預先計算和旋轉的紋理(紋理圖集)? 如果只有幾個角度足以達到您想要實現的效果,那么這將是一個非常快速的解決方案。
另一方面,片段着色器(間接紋理查找)中紋理坐標的計算會降低性能。 這對您的情況可能並不重要,但請記住。
這是您的預乘旋轉矩陣:
v_rotationMatrix = mat3(cos, sin, 0.0,
-sin, cos, 0.0,
(sin-cos+1.0)*0.5, (-sin-cos+1.0)*0.5, 1.0);
FWIW,這是我得到的與Stuart的代碼匹配的3x3預先計算的矩陣:
v_rotationMatrix = mat3(cos,-sin,0.0,sin,cos,0.0,(1.0-cos-sin)* 0.5,(1.0 + sin-cos)* 0.5,1.0);
請注意,glsl矩陣采用主列格式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.