背景
ロシア語のLammersの本が出ました、占星術師は予測します...
DevGAMMカンファレンスで、私はケニーランマーズによる高価な本を購入しました。この本では、後にシモノフ、ガレンキク、およびプリデュークに署名しました。 印象的な2晩で、私はようやく途中でそれを終えて、最初にそこに書かれたものをすべて集め、それを消化し、絵を描き、記事を書くことにしました。

この記事は、レッスンからC#コードをほとんどコピーできない初心者を対象としているため、既に説明した理論については説明しません。 この場所では、実用的な問題を解決し、「すべてが輝いて輝いた」だけでなく、シェーダーが必要であることがわかります。
はじめに
シェーダーとは何ですか? これは、ビデオカードで実行されるこのようなクールなプログラムです。 かっこいい? ただし、1つのカーブシェーダーを使用すると、FPSをゼロまで無駄にしたり、時間を巻き戻したりすることができます。 シェーダーも全体的ではなく、ピクセル(ピクセルシェーダー)および頂点(頂点シェーダー)でも実行されます。 つまり、実際には、ラスターの各ピクセルに対して小さなプログラムが呼び出され、そこに何かを計算しますが、それでもまだそれをひねり、完了したかどうかを指示すると、非常に苦痛になります。 これを行うために、ダンブルドアは
名前を呼び出せない人
Unity3Dは、HLSLおよびCG(シェーダー言語)の一種のラッパーを作成しました-Shader Lab。 これにより、各APIに新しいシェーダーを書く必要がなくなり、おいしいものすべてが提供されます。 しかし、Shader Labは依然としてラッパーであり、内部ではこれらの言語の1つで記述していますが、歴史的にはほとんどすべての人がCGで記述しています。 Unity3Dはまた、ほとんどの情報をシェーダー自体にスローするため、必要なものを記述するだけで、エンジンがそれを把握します。
サーフェスシェーダーは、ピクセルシェーダーと頂点シェーダーから私たちを抽象化する機能であり、サーフェスを操作します。 つまり、色、反射力、法線を言うだけです。 このすべてが頂点関数とピクセル関数にコンパイルされます。 シェーダーを簡単かつ簡単に作成できる非常に強力なツールです。
最初のシェーダーを書く
その結果、次のようになります。

はい、これは地形ですが、ちょっと汚いです。 一番下の行は次のとおりです。
- メッシュを取ります
- 高さの地図を撮ります
- このマップ上のメッシュにテクスチャを付けます。
その結果、斜面汚染が発生します。 これは非常に簡単な例で、シェーダーが解決する主な機能とタスクを理解します。 コードについてコメントします。
Shader "Custom/HeightMapTexture" { // Properties { // Unity3D _HeightTex ("HeightMap Texture", 2D) = "white" {} // , . _GrassTex ("Grass Texture", 2D) = "white" {} // 2D _RockTex ("Rock Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } // LOD 200 CGPROGRAM // CG #pragma surface surf Lambert // . , : Surface . sampler2D _GrassTex; // Properties sampler2D _RockTex; sampler2D _HeightTex; struct Input { // , float2 uv_GrassTex; //uv , float2 uv_RockTex; float2 uv_HeightTex; }; void surf (Input IN, inout SurfaceOutput o) { // // UV float4 grass = tex2D(_GrassTex, IN.uv_GrassTex); // float4 rock = tex2D(_RockTex, IN.uv_RockTex); //\ float4 height = tex2D(_HeightTex, IN.uv_HeightTex); // o.Albedo = lerp(grass, rock, height); // // SurfaceOutput :) } ENDCG } FallBack "Diffuse" // - }
難しいようですが、ハリーはパトロンでディメントルを追い払うことができたので、ピクセルを補間することはできませんか? 次に、なぜこれを行うのかを説明します。コードが少し明確になります。
- これは高さマップです。 ピクセルの色を使用します。これは白黒であるため、高さとして解釈できます。 1が絶対的に高く、0が絶対的に低い(ゲームのコンバージョンよりも低い)としましょう。 これに基づいて、次のようなことができます。1の場合、石のテクスチャ全体を取り、0の場合は雑草を取ります。 灰色の場合、50 \ 50などです。マップからわかるように、高さはたくさんあるため、ハグリッドの腕のようにすべてが柔らかく落ちます。
- lerp()は、補間のためのそのような関数です。最初の2つの引数では、2つの値を指定します。 そこで、ピクセルのコンポーネントの1つ、たとえばrのみを渡すことができますが、この場合、すべてが一度に送信されます。 次に、これを行う必要がない理由を説明します。
- tex2D()-UVによってテクスチャからピクセルカラーを取得します。 とてもつまらない。 入力構造からUVを取得し、ユニットが面倒を見て、すべてをそこに配置しました。 テクスチャをアニメーション化するために、サイン時間だけUVをシフトできます。
はっきりした? そうでない場合は、早急にアップルパイを食べてから戻る必要があります。 70%で機能します。 ああ、スクリプトと同じ場所にシェーダーを作成します。 次に、それをマテリアルに掛けて、マテリアルをテレイン設定に配置します。

UV
UVについて少し説明し、次にUV、次にUV翔について説明します。
単純な場合、UV座標はオブジェクトの座標に単純に対応します。 UV座標は0から1の範囲にあります。この状況では、テクスチャはオブジェクト1から1に単純に重なり、所定の位置で伸びますが、恐れることはありません。 各頂点にUVを指定し、テクスチャがパーツに配置されているときにスキャンを取得できます。 私は確かに専門家ではありませんが、Unity3D自体が展開に関する情報をメッシュから取得してシェーダーに渡すので、まだ考える必要はありません。
ビューを与えないで美しくする方法。 または、法線マップを使用します
法線マップは、ベクトルがエンコードされるRGBのテクスチャです。 つまり、3次元空間では、通常のベクトルは3つの成分x、y、zで構成されます。 これは、テクスチャコンポーネントにちょうど収まります。 そのため、通常のテクスチャとして見るととても奇妙に見えますが、実際にはそこに座っている脳虫がいます。
ピクセルを描画するときにこのテクスチャを使用すると、ピクセルからベクトルを取得し、そこから光を屈折させて3次元効果を得ることができます。 複雑に聞こえますが、サーフェスシェーダーの魔法とUnity3Dライブラリを使用すると、このタスクの実装は非常に簡単です。
に

後

シェーダー:
Shader "Custom/BumpMapExample" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _BumpMap ("Bump map", 2D) = "bump" {} // } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; sampler2D _BumpMap; struct Input { float2 uv_MainTex; float2 uv_BumpMap; }; void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_MainTex, IN.uv_MainTex); o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); // o.Albedo = c.rgb; o.Alpha = ca; } ENDCG } FallBack "Diffuse" }
ここではすべてが過去と同じです。ピクセルを取得してUnpackNormal関数に渡すだけで、法線自体を取得し、SurfaceOutput構造体に入力するだけです。 さらに、照明機能の法線が代わりになり、そこで何をすべきかをすでに決定します。 ところで、法線マップは光源なしでは機能しません。
許されない3つの呪文
正しく行う方法について少し:
- テクスチャを1つに集めます。 高さマップがあり、ピクセルに最大4つの値をパックできると仮定します。高さには1つだけが必要です。 つまり、複数のテクスチャを1つに集めて、チャネルを介して散乱させることができます。 真のウィザードの良い習慣
- ロジックの一部は、スクリプトに転送できますし、転送する必要があります。 すべてのピクセルではなく、すべてのフレームのみをカウントするには十分です。 シェーダーは役立ちますが、シェーダーだけですべてを行うべきではありません。
- 条件ステートメントを使用しないでください。これは非常に忙しいシステムであり、回避策を探してみてください。
- テクスチャで事前にベイクできるものはすべて、ベイクします。 シェーダーを不要な作業から解放し、テクスチャからデータを再計算するよりもはるかに高速に取得します。
おわりに
これで最初のパートは終わりです。 次に、CubeMapを使用した鏡面反射、ディスプレイ、およびiPadのフレームに300個のアニメーションユニットを保持する方法について詳しく説明します。
私と他の初心者が学ぶことができるように、記事に関するすべてのコメントが可能な限り建設的に表現されることを本当に願っています。 私はこの問題に関して自分を専門家とは考えていませんが、ある程度の経験はありますが、これにはどれほどの微妙さがありますか。 Habrasocietyの助けを本当に期待しています。 シェーダーモデルやタグ設定の微妙さなどについての話を意図的に逃しました。このため、分析する完成したマテリアルはまだありません。