始める前にOpenGL ESを初めて使用する場合は、レッスン1と2を最初に学習することをお勧めします。このレッスンは以前のレッスンの知識に基づいているためです。
この記事で使用されるコードの基本は、ここから取得されます。
1.
http://andmonahov.blogspot.com/2012/10/opengl-es-20.html2.
http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/その結果、デバイスまたはエミュレータの画面にそのような画像が表示されます。
光と光源の種類について少し光は、特定の周波数の電磁波、または光子のストリーム(特定のエネルギーを持つ粒子)と見なすことができます。 どの光子が網膜の特定の場所に落ちたかによって、脳は視覚的な感覚を作り出します。
色の感覚は、光子のエネルギーまたは電磁放射の周波数に依存します。 真空中の波長が380〜400 nm(紫)のセクションを、光が占めるスペクトル範囲の短波長境界として採用し、760〜780 nm(赤)の部分を長波長境界としました。

色の感覚に加えて、単位時間あたりに網膜に当たる光子の数または電磁波の強度によって決定される光の明るさの概念は、私たちにとって非常に重要です。
周囲の世界のすべてのオブジェクトは、光を発するものとそれを反射するものに分けることができます。 しかし、私たちは世界の多様性を認識しています。光や色の明るさだけでなく、オブジェクト自体の反射能力、オブジェクトからの影なども重要です。 世界のコンピューターモデリングは、実際のオブジェクトの写真とコンピューターモデルを区別できるのは専門家だけである場合もあります。 照明オブジェクトには多くの分類およびモデリングシステムがありますが、そのうちのいくつかを検討してください。
背景照明オブジェクトがすべての側面で均等に照らされている場合、背景照明について話します。 自然界では、これは通常曇りの日に起こります。 屋内にいる場合、そのような照明は、異なるオブジェクトから光が複数回反射される場合、または特別な方法で分散された多くの光源がある場合に発生します。 左側の写真には、指向性照明と背景照明が混合されている写真があり、右側には背景のみがあります。 背景の照明を計算するとき、サーフェスの法線(ビームがサーフェスに当たる角度)もカメラの現在の位置も考慮されません。
背景照明をプログラムで記述する方法は?オブジェクトを赤にし、背景の光をくすんだ白にします。 RGBカラーモデルを使用して、赤、緑、青の3色の配列として色を保存するとします。 次に、色の重み係数に特定の照明定数を掛ける必要があります。
最終色= {1、0、0} * {0.1、0.1、0.1} = {0.1、0.0、0.0}
これで、オブジェクトの最終的な色は鈍い赤になります。これは、赤いオブジェクトを鈍い白色光で照らした場合に実際に見えるものに対応します。
拡散照明拡散照明(拡散照明)-光源からの光は、特定のポイントに到達した後に散乱します。 光が落ちる角度に応じて、照明は強くまたは弱くなります。 ここでは、表面の法線が考慮されますが、カメラの位置は考慮されません。

光線が水平面上で45度の角度(光線とサーフェスの法線との角度)で落ちると想像してください。 拡散(散乱)反射の結果、光エネルギーはすべての方向に均一に反射されるため、3台のカメラはすべて同じ明るさの表面を削除します。 光が0度の角度(サーフェスに垂直)で落ちる場合、サーフェスが最も明るく照らされることは明らかです。 また、光線が90度に近い角度で落ちた場合、光線は表面上を滑空し、表面を照らしません。
拡散反射のソフトウェアモデリング拡散反射をモデル化するために、ランバート係数が使用されます。
light vector = light position - object position
cosine = dot product(object normal, normalize(light vector))
lambert factor = max(cosine, 0)
これらの3行のコードを説明します。
まず、光源の位置からオブジェクトの位置を引くことにより、光ベクトルが計算されます。
light vector = light position - object position
次に、表面の法線と正規化された光ベクトルの間のスカラー積を見つけることにより、光ベクトルと法線の間の角度の余弦を計算できます。 ライトベクトルを正規化するとは、その長さが1に等しくなるように変更することを意味しますが、ベクトルの方向は変更されません。 表面の法線の弾性率は既に1に等しくなっています。 2つの正規化されたベクトルのスカラー積を決定したら、それらの間の角度の余弦を求めます。
cosine = dot product(object normal, normalize(light vector))
スカラー積の範囲は-1〜1であるため、0〜1の範囲に制限する必要があります。関数max(x、y)は、「x」が「y」より大きい場合、「x」を返します。
lambert factor = max(cosine, 0)
明確にするために、例を考えてみましょう。

光源をT. S(0.10,10)に置き、法線が垂直に見える(0、1、0)水平面(これは単一ピクセルの場合があります)の照度を計算します。 次に、OSベクトル(ライトベクトル)と法線ベクトル(オブジェクト法線)
light vector = {0, 10, 10} - {0, 0, 0} = {0, 10, 10}
object normal = {0, 1, 0}
OSベクトルの長さを見つける
light vector length = square root(0*0 + 10*10 + 10*10) = square root(200) = 14.14
それを正規化する、すなわち その長さが1になるようにします。
normalized light vector = {0, 10/14.14, 10/14.14} = {0, 0.707, 0.707}
次に、スカラー積を計算します。
dot product({0, 1, 0}, {0, 0.707, 0.707}) = (0 * 0) + (1 * 0.707) + (0 * 0.707) = 0 + 0.707 + 0 = 0.707
誰が数学を忘れたのか、2つのベクトルのスカラー積はそれらのモジュールの積に等しく、それらの間の角度の余弦を乗じたことを思い出します。 モジュールのユニティが等しい場合、スカラー積はコサインに等しくなります。
小さな問題があります。これは、角度アルファが90〜180度の場合、原則としてコサインが負の値をとることができるということです。 したがって、Lambert係数の値の範囲を0〜1に制限します。
lambert factor = max(0.707, 0) = 0.707
反射またはグレア反射照明(鏡面照明)は、特定のポイントに到達した後に反射される光源からの光です。 反射光は、カメラに当たる場合にのみ表示されます。 したがって、ここでは通常位置とカメラ位置の両方が考慮されます。
ソフトウェアフレアの実装拡散照明の計算では、照明された点から正規化された光ベクトルに移動する単位長さベクトルが決定されました。 光源から表面上の点への入射光のベクトルを決定するには、符号をマイナスに変更するだけです。

GLSLで反射ベクトル(OS1方向)を計算するには、特別なリフレクト関数があります。
reflectvector = reflect(- normalized light vector, object normal);
カメラ座標は、u_cameraユニフォームとしてフラグメントシェーダーに転送されます。
uniform vec3 u_camera;
次に、照明点からカメラに向けてベクトルOKを計算し、正規化します。
lookvector = normalize(u_camera - object position);
次に、反射ベクトルOS1とカメラの方向OKの間のベータ角の余弦を計算する必要があります。 角度のコサインは、ドット(lookvector、reflectvector)の2つの単位ベクトルのスカラー積であることをすでに示しました。 ベータ角が小さいほど、ハイライトが明るくなります。
また、ランバート係数に関しては、max関数を使用してスカラー積の負の値を切り取ります。
max(dot(lookvector,reflectvector),0.0)
フレア自体のサイズは、光沢パラメーターを使用して調整できます。このためには、スカラー積の計算値を光沢の程度まで上げる必要があります。 べき乗のために、GLSLでpow関数が提供されています。 通常、数十のユニットが光沢値を取ります。 輝度が上がると、グレアのサイズは小さくなりますが、輝度は上がります。 逆に、輝度が低いほどフレアは大きくなりますが、輝度は低くなります。

たとえば、輝度が30である場合、結果のスカラー積を30の累乗に上げます。
pow( max(dot(lookvector,reflectvector),0.0), 30.0 )
結果の値に鏡面照明の係数k_specularを乗算し、指定されたピクセルの鏡面照明の輝度を取得します。
float specular = k_specular * pow( max(dot(lookvector,reflectvector),0.0), 30.0 );
トータルライティング実生活でオブジェクトの照明をシミュレートするには、さまざまなタイプのオブジェクトの照明を一定の割合で要約する必要があります。 たとえば、照明を考慮に入れてピクセルの色を取得するには、照明の周囲、拡散+鏡面反射の背景、拡散、ミラー部分を追加し、頂点v_colorの色を補間して得られたピクセルの色のベクトルを掛ける必要があります。
gl_FragColor = (ambient+diffuse+specular)*v_color;
頂点の補間色でピクセルを色付けしたくない場合は、白いベクトルを定義するだけで十分です。
vec4 one=vec4(1.0,1.0,1.0,1.0);
そして光の明るさにそれを掛けます:
gl_FragColor = (ambient+diffuse+specular)*one;
最初にアンビエント= 1、拡散= 0、鏡面反射= 0の場合の画像の変化を評価できます。ケースの中心の画像= 0、拡散= 1、鏡面反射= 0、そのような値の右側の画像は環境= 0、拡散= 0、鏡面反射= 1。

この線は、照明と色を混ぜています。
gl_FragColor = mix(lightColor,v_color,0.6)
混合係数が0の場合、画像の見え方(左側)を見てください。実際、光の明るさの分布が見られます。 係数を1にすると、純粋な色が表示されます。

ソースに移る前に、それらについて少しコメントしてください。
1.最後のレッスンで、マニフェストファイルにそのような行が表示されていることに気づきました
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
これで、Google PlayはOpenGL ESをサポートしていないデバイスでアプリケーションを表示しなくなります。
2. 2番目のレッスンでは、GLES20.glDrawArraysメソッド(GLES20.GL_TRIANGLES、0、3)のみを使用して三角形を描きました。
このレッスンでは、新しいメソッドGLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP、0、4)が登場しました。
その助けを借りて、四角形と複雑なレリーフを描くのがより便利です。 海、空、船を描くために使用しました。 このメソッドの適用に関する良いレッスンがここにあります。
http://www.learnopengles.com/tag/triangle-strips/
3.ボートは、0Z軸に沿ってわずかに突出して描かれています。 カメラの位置を変更すると、この変位、マトリックスの働き、表面照明の変化を確認できます。 左側では、カメラは0Uで5単位上昇し、右側では0Xで4単位シフトしました。

コード自体に他の説明があります。
最初にプロジェクトを開始してから、さまざまな係数を再生して実験することをお勧めします。
プロジェクトを作成する
Android StudioでOpenGLESLightingプロジェクトを作成する
メインアクティビティはOpengles3Activityと呼ばれます。
さらに3つのJavaファイルを作成します。
MyClassSurfaceView.java
MyClassRenderer.java
Shader.java

コードをコピーして、自動的に生成されたものの代わりにファイルに貼り付けます。
写真をお楽しみください。
記事にエラーが忍び込んでいる場合、私はそれらを修正し、あなたから学ぶことを嬉しく思います。
最高!
コードソース
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.adc2017gmail.opengleslighting" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" /> <uses-feature android:glEsVersion="0x00020000" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".Opengles3Activity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Opengles3Activity.java
public class Opengles3Activity extends Activity {
MyClassSurfaceView.java
package com.adc2017gmail.opengleslighting; import android.content.Context; import android.opengl.GLSurfaceView;
MyClassRenderer.java
package com.adc2017gmail.opengleslighting; import android.content.Context; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.Matrix; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; public class MyClassRenderer implements GLSurfaceView.Renderer{
Shader.java
package com.adc2017gmail.opengleslighting; import android.opengl.GLES20; import java.nio.FloatBuffer; public class Shader {
ソース:
http://andmonahov.blogspot.com/2012/10/opengl-es-20.html
http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/
http:// www .learnopengles.com / tag / triangle-strips /
http://eax.me/opengl-lighting/
http://www.john-chapman.net/content.php?id=3