ダミー用のlibgdxのシェーダー

この記事は、libgdxとシェーダーに精通している人に役立ちます。 シェーダーは多くの場合、初心者には無視されますが、非常に簡単に多くの美しい効果を作成できます。 OpenGLやシェーダーについては詳しく説明しませんが、トップを通過するだけですが、他の人のシェーダーを使用したり、独自のシェーダーを作成するにはこれで十分です。



理論のビット



それでは、シェーダーとは何ですか? OpenGLシェーダーは、GLSLのようなCで書かれた小さなプログラムです。 これらのプログラムはGPUで直接実行されます。 シェーダーは、頂点シェーダーとフラグメントシェーダーのペアで機能します。







頂点シェーダーは、頂点の操作を実行します。 各プログラムの実行は、ちょうど1つの頂点に作用します。 三角形の描画を見ると、それぞれ3つの頂点があり、頂点シェーダーが3回実行されます。 頂点シェーダーは、カメラの位置を考慮して頂点の終了位置を設定し、フラグメントシェーダーに必要ないくつかの変数を準備して出力します。 単純なシェーダーを開発する場合、頂点シェーダーを変更する必要はおそらくないでしょう。



フラグメントシェーダーは、最終画像の各可視部分を処理します。 OpenGLレンダリングと画面に表示される最終画像のピクセルはサイズが異なる場合があるため、このような各フラグメントをピクセルと呼びますが、これは完全に真実ではありません。



フラグメントシェーダーの内部では、ライティング、シャドウ、反射、テクスチャ、必要なエフェクトなど、サーフェスに関連するすべてのものを処理します。 フラグメントシェーダーの結果は、RGBA形式のピクセルカラーです(赤、緑、青、およびアルファチャネル)。 ほとんどの効果については、変更します。



三角形が300ピクセルの領域をカバーすると仮定します。 この三角形の頂点シェーダーは3回実行されます。 フラグメントシェーダーは300回実行されます。 したがって、シェーダーを作成するときはこのことに留意してください。 フラグメントシェーダーで行われるすべての処理は、指数関数的に高価になります。 これは、シェーダーを使用するときは常に考慮する必要があります。



libgdxの標準シェーダー



標準シェーダーを開始する前に、もう少し理論を説明します。 GLSLはCに似た言語であり、基本的なことに集中しませんが、コードの解析を開始する前に説明する必要があるものがあります。



シェーダーは、属性、ユニフォーム、可変などの概念を使用します。



属性は、頂点の属性です 。 頂点にはさまざまな属性を設定できます。 たとえば、空間内の位置の座標、法線ベクトルの座標、色。 さらに、任意の属性を頂点シェーダーに渡すことができます。 属性は頂点のプロパティであるため、各頂点に指定する必要があることを理解することが重要です。 属性は頂点シェーダーのみに渡されます。 属性は頂点シェーダーに対して読み取り専用であり、上書きできません。



ユニフォームは、計算に使用できる外部データですが、上書きすることはできません。 ユニフォームは、頂点シェーダーとフラグメントシェーダーの両方に渡すことができます。 ユニフォームは特定の頂点に決して関連付けられておらず、グローバル定数です。 たとえば、光源の座標と目の座標(カメラ)は、ユニフォームとしてシェーダーに転送できます。



変数(可変) -これは、頂点シェーダーからフラグメントシェーダーに切り替えたときに、頂点のデータを平均化することによって各ピクセルに対して計算されるデータです。 詳しく説明します。 頂点シェーダーでは、特定の頂点の座標を扱います。 この頂点の座標を変化としてフラグメントシェーダーに転送すると、フラグメントシェーダーの入力で、各ピクセルの空間の座標を取得します。これは、頂点の座標を平均することによって取得されます。 平均化プロセスは補間と呼ばれます。 法線ベクトルの座標と色ベクトルの座標は、同じ方法で補間されます。 変化する変数は、頂点シェーダーとフラグメントシェーダーで同じように宣言する必要があります。



頂点シェーダー
attribute vec4 a_position; //  attribute vec4 a_color; //  attribute vec2 a_texCoord0; //  uniform mat4 u_projTrans; //,         varying vec4 v_color; //       varying vec2 v_texCoords; //  void main(){ v_color=a_color; //     SpriteBatch  ,    ABGR int   float. // -  NAN  ,      ,     (0-254) //    ,    float  1,     . //  libgdx         . v_color.a = v_color.a * (255.0/254.0); v_texCoords = a_texCoord0; //    ,       //     -     // gl_Position     gl_Position = u_projTrans * a_position; }
      
      







フラグメントシェーダー
 //#ifdef      ,   .    (GL_ES)  //   () .(highp –  ; mediump –  ; lowp –  ) #ifdef GL_ES #define LOWP lowp precision mediump float; #else #define LOWP #endif varying LOWP vec4 v_color; varying vec2 v_texCoords; // sampler2D      glsl     uniform sampler2D u_texture; void main(){ gl_FragColor = v_color * texture2D(u_texture, v_texCoords);//    }
      
      







Libgdxでシェーダーを操作する



LibgdxはShaderProgramクラスを使用してシェーダーを操作し、入力する2つのファイルまたは2行のシェーダーコードを受け入れます。



 //   shaderProgram=new ShaderProgram(Gdx.files.internal("shaders/default.vert"),Gdx.files.internal("shaders/default.frag")); //   vertexShader  fragmentShader  String      shaderProgram=new ShaderProgram(vertexShader,fragmentShader);
      
      





シェーダーを使用する場合、次のように記述することをお勧めします。



 ShaderProgram.pedantic = false;
      
      





これがないと、シェーダーがコンパイルされない可能性があるため、シェーダーに使用されていないユニフォームがあるとlibgdxが誓います。 シェーダーが不要になったら、リソースを解放することを忘れないことが重要です。



 shaderProgram.dispose().
      
      





シェーダーを理解したので、ピクセルの色を反対に変更する簡単なシェーダーを作成しましょう。 このタスクでは、フラグメントシェーダーのみを変更する必要があります。 変換自体は2行で実行されます。



 //         gl_FragColor = v_color * texture2D(u_texture, v_texCoords); //   ,     gl_FragColor.rgb=1.0-gl_FragColor.rgb;
      
      





取得したい結果




フラグメントシェーダー
 #ifdef GL_ES #define LOWP lowp precision mediump float; #else #define LOWP #endif varying LOWP vec4 v_color; varying vec2 v_texCoords; uniform sampler2D u_texture; void main(){ //         gl_FragColor = v_color * texture2D(u_texture, v_texCoords); //   ,     gl_FragColor.rgb=1.0-gl_FragColor.rgb; }
      
      







最終コード
 import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.scenes.scene2d.Stage; public class ShaderDemo extends ApplicationAdapter { SpriteBatch batch; Texture img; ShaderProgram shader; @Override public void create() { batch = new SpriteBatch(); img = new Texture("badlogic.jpg"); // ,       ,     ShaderProgram.pedantic = false; shader = new ShaderProgram(Gdx.files.internal("shaders/default.vert"), (Gdx.files.internal("shaders/invertColors.frag"))); if (!shader.isCompiled()) { System.err.println(shader.getLog()); System.exit(0); } batch = new SpriteBatch(1000); batch.setShader(shader); } @Override public void render() { Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); batch.begin(); batch.draw(img, 0, 0,Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); batch.end(); } @Override public void dispose() { //      ,     batch.dispose(); shader.dispose(); img.dispose(); } }
      
      








All Articles