私はOpenGL ES 1.0とQuartzを使用して書かれた私のペイントアプリケーションを持っています。 私は、より良いパフォーマンスと新機能のためにOpenGL ES 2.0を使って書き直そうとしています。 私は2つのシェーダを書いています.1つはユーザーの入力をテクスチャにレンダリングし、もう1つはいくつかのルールに従ってこのテクスチャを他のテクスチャとミックスします。 突然、私は第二世代のシェーダがiPad 1世代で長すぎることに気付きました - 私は10-15fpsしか持っていません。 iPad 2は60+ fpsで完璧に動作します。私は、元のアプリケーション(OpenGL ES 1.0)が両方のデバイスで正常に動作するので、少しショックを受けました。それは2つのポリゴンだけをレンダリングします(ただしほぼフルスクリーンです)。 精度の変更、いくつかの数学演算のコメント、ハードコーディングされたテクスチャ呼び出しなど、いくつかの最適化を試みました。少し助けましたが、私はまだ60fpsから遠いです。このシェーダの呼び出しに完全にコメントするときだけ、60fpsが得られます。iPad上でのシェーダの低性能第1世代
何か不足していますか?私はOpenGLであまり経験はありませんが、オリジナルのアプリケーションのように、このシェーダは両方の世代のデバイスでうまく動作しなければならないと思います。私の頂点とフラグメントシェーダは以下のとおりです。
===============バーテックスシェーダ===================
uniform mat4 modelViewProjectionMatrix;
attribute vec3 position;
attribute vec2 texCoords;
varying vec2 fTexCoords;
void main()
{
fTexCoords = texCoords;
vec4 postmp = vec4(position.xyz, 1.0);
gl_Position = modelViewProjectionMatrix * postmp;
}
===============フラグメントシェーダ===================
precision highp float;
varying lowp vec4 colorVarying;
varying highp vec2 fTexCoords;
uniform sampler2D texture; // black & white user should paint
uniform sampler2D drawingTexture; // texture with user drawings I rendered earlier
uniform sampler2D paperTexture; // texture of sheet of paper
uniform float currentArea; // which area we should not shadow
uniform float isShadowingOn; // bool - should we shadow some areas of picture
void main()
{
// I pass 1024*1024 texture here but I only need 560*800 so I do some calculations to find real texture coordinates
vec2 convertedTexCoords = vec2(fTexCoords.x * 560.0/1024.0, fTexCoords.y * 800.0/1024.0);
vec4 bgImageColor = texture2D(texture, convertedTexCoords);
float area = bgImageColor.a;
bgImageColor.a = 1.0;
vec4 paperColor = texture2D(paperTexture, convertedTexCoords);
vec4 drawingColor = texture2D(drawingTexture, convertedTexCoords);
// if special area
if (abs(area - 1.0) < 0.0001) {
// if shadowing ON
if (isShadowingOn == 1.0) {
// if color of original image is black
if ((bgImageColor.r < 0.1) && (bgImageColor.g < 0.1) && (bgImageColor.b < 0.1)) {
gl_FragColor = vec4(bgImageColor.rgb, 1.0) * vec4(0.5, 0.5, 0.5, 1.0);
}
// if color of original image is grey
else if (abs(bgImageColor.r - bgImageColor.g) < 0.15 && abs(bgImageColor.r - bgImageColor.b) < 0.15 && abs(bgImageColor.g - bgImageColor.b) < 0.15 && bgImageColor.r < 0.8 && bgImageColor.g < 0.8 && bgImageColor.b < 0.8){ gl_FragColor = vec4(paperColor.rgb * bgImageColor.rgb * 0.4 - drawingColor.rgb * 0.4, 1.0);}
else
{
gl_FragColor = vec4(bgImageColor.rgb, 1.0) * vec4(0.5, 0.5, 0.5, 1.0);
}
}
// if shadowing is OFF
else {
// if color of original image is black
if ((bgImageColor.r < 0.1) && (bgImageColor.g < 0.1) && (bgImageColor.b < 0.1)) {
gl_FragColor = vec4(bgImageColor.rgb, 1.0);
}
// if color of original image is gray
else if (abs(bgImageColor.r - bgImageColor.g) < 0.15 && abs(bgImageColor.r - bgImageColor.b) < 0.15 && abs(bgImageColor.g - bgImageColor.b) < 0.15
&& bgImageColor.r < 0.8 && bgImageColor.g < 0.8 && bgImageColor.b < 0.8){
gl_FragColor = vec4(paperColor.rgb * bgImageColor.rgb * 0.4 - drawingColor.rgb * 0.4, 1.0);
}
// rest
else {
gl_FragColor = vec4(bgImageColor.rgb, 1.0);
}
}
}
// if area of fragment is equal to current area
else if (abs(area-currentArea/255.0) < 0.0001) {
gl_FragColor = vec4(paperColor.rgb * bgImageColor.rgb - drawingColor.rgb, 1.0);
}
// if area of fragment is NOT equal to current area
else {
if (isShadowingOn == 1.0) {
gl_FragColor = vec4(paperColor.rgb * bgImageColor.rgb - drawingColor.rgb, 1.0) * vec4(0.5, 0.5, 0.5, 1.0);
} else {
gl_FragColor = vec4(paperColor.rgb * bgImageColor.rgb - drawingColor.rgb, 1.0);
}
}
}
このような詳細な回答ありがとうございます!今私は自分の間違いを理解し、正しい方向性を持っています。 P.P.ところで、Brad、それはあなたがOpenGLを堪能する際に私を刺激したのです。 iTunesのMATCのレッスンをありがとう!すごい仕事! – Seify