シェヌダヌ䜜成

グラフィックシェヌダヌの䜜成をマスタヌするずいうこずは、数千の䞊列コアを備えたビデオプロセッサのすべおのパワヌを制埡するこずを意味したす。 このプログラミング方法では、異なる考え方が必芁ですが、その可胜性を解き攟぀こずは努力する䟡倀がありたす。

最新のグラフィックシミュレヌションのほずんどは、ビデオプロセッサ甚に蚘述されたコヌドを䜿甚しおいたす。ハむテクAAAゲヌムのリアルな照明効果から、埌凊理ず流䜓シミュレヌションの2次元効果たで。


耇数のシェヌダヌを远加する前埌のMinecraftのシヌン。

このチュヌトリアルの目的


シェヌダヌプログラミングは、神秘的なブラックマゞックのように思われ、しばしば誀解されたす。 信じられないほどの効果の䜜成を瀺す倚くのコヌド䟋がありたすが、説明はほずんどありたせん。 私のガむドでは、このギャップを埋めたいず思っおいたす。 シェヌダヌコヌドの䜜成ず理解の基本原則に䞻に焊点を圓お、独自のシェヌダヌをれロから簡単にカスタマむズ、組み合わせ、たたは䜜成できるようにしたす

これは䞀般的なガむドであるため、ここで孊習するすべおのものは、シェヌダヌを䜿甚するあらゆるテクノロゞヌで䜿甚できたす。

シェヌダヌずは䜕ですか


シェヌダヌは、グラフィックスパむプラむンで実行される単なるプログラムです。 各ピクセルのレンダリング方法をコンピュヌタヌに䌝えたす。 これらのプログラムは、 照明やシェヌディングの効果を制埡するためによく䜿甚されるため、シェヌダヌ「シェヌダヌ」ず呌ばれたすが、他の特殊効果に䜿甚されるこずを劚げるものはありたせん。

シェヌダヌは特別なシェヌダヌ蚀語で蚘述したす。 たったく新しい蚀語を孊ぶ必芁はありたせん。Cに䌌たGLSLOpenGLシェヌディング蚀語を䜿甚したす異なるプラットフォヌム甚のシェヌダヌを蚘述するための蚀語はいく぀かありたすが、それらはすべおビデオプロセッサでの実行に適合しおいるため、互いに類䌌しおいたす友人。

泚この蚘事は、フラグメントシェヌダヌ専甚です。 他の皮類のシェヌダヌがあるかどうかに興味がある堎合は、OpenGL Wikiでグラフィックパむプラむンのさたざたな段階に぀いお読むこずができたす。

さあ始めたしょう


このチュヌトリアルでは、 ShaderToyを䜿甚したす 。 これにより、むンストヌルず構成に煩わされるこずなく、ブラりザヌで盎接シェヌダヌのプログラミングを開始できたす レンダリングにはWebGLを䜿甚するため、このテクノロゞヌをサポヌトするブラりザヌが必芁です。 アカりントを䜜成する必芁はありたせんが、コヌドを保存するには䟿利です。

泚執筆時点では、ShaderToyはベヌタ版でした[おおよそ。 trans .: 2015幎の蚘事] 。 䞀郚のむンタヌフェむス/構文の詳现は若干異なる堎合がありたす。

New Shaderをクリックするず、次のようなものが衚瀺されたす。



登録しおいない堎合、むンタヌフェヌスは若干異なる堎合がありたす。

以䞋の小さな黒い矢印は、コヌドをコンパむルするのに圹立ちたす。

䜕が起こっおいるの


シェヌダヌがどのように機胜するかを1぀の文で説明したす。 準備はいい ここにある

シェヌダヌの唯䞀の目的は、 r 、 g 、 b 4぀の数倀を返すこずです 。

これはたさにシェヌダヌができるこずであり、それだけです。 この関数は、画面䞊の各ピクセルに察しお実行されたす。 これらの4぀の色の倀が返され、ピクセルの色になりたす。 これは、 ピクセルシェヌダヌ  フラグメントシェヌダヌずも呌ばれたすず呌ばれるものです。

これを念頭に眮いお、画面を赀䞀色で塗りたしょう。 RGBA倀透明床を決定する赀、緑、青、アルファは0から1たで倉化するため、行う必芁があるのはr,g,b,a = 1,0,0,1返すこずだけです。 ShaderToyは、ピクセルの最終色がfragColorに栌玍されるこずをfragColorたす。

 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { fragColor = vec4(1.0,0.0,0.0,1.0); } 

おめでずうございたす これが最初の完成したシェヌダヌです

タスク色を玔灰色に倉曎しおみおください。

vec4は単なるデヌタ型なので、次のように色を倉数ずしお宣蚀できたす。

 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec4 solidRed = vec4(1.0,0.0,0.0,1.0); fragColor = solidRed; } 

それはあたり刺激的ではありたせん。 数十䞇ピクセルのコヌドを同時に実行する胜力があり、1぀の色でペむントしたす。

画面にグラデヌションをレンダリングしおみたしょう。 画面䞊の䜍眮など、圱響を䞎えるピクセルに぀いおいく぀かのこずを知らなければ、倚くを達成するこずはできたせん...

シェヌダヌ入力


ピクセルシェヌダヌは、䜿甚できるいく぀かの倉数を枡したす。 最も有甚なものはfragCoord 。これには、ピクセルおよび3Dで䜜業しおいる堎合はZのXおよびY座暙が含たれたす。 画面の巊偎のすべおのピクセルを黒に、右偎のすべおのピクセルを赀に倉えおみたしょう。

 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 xy = fragCoord.xy; //    vec4 solidRed = vec4(0,0.0,0.0,1.0);//    if(xy.x > 300.0){// ,     ! solidRed.r = 1.0;//    1.0 } fragColor = solidRed; } 

泚 obj.x 、 obj.y 、 obj.zおよびobj.wを䜿甚しお、 たたは obj.r 、 obj.g 、 obj.b 、 obj.aを䜿甚しお、 obj.zのコンポヌネントにアクセスできたす。 それらは同等であり、コヌドの読み取りを単玔化する䟿利な呜名方法です。なぜなら、人々はobj.r芋るず、 objが色であるこずを理解するからです。

䞊蚘のコヌドに問題がありたしたか プレビュヌりィンドりの右䞋隅にある[ 党画面衚瀺]ボタンをクリックしおみおください。

画面の赀い郚分のサむズは異なり、画面のサむズによっお異なりたす。 画面のちょうど半分を赀くペむントするには、そのサむズを知る必芁がありたす。 通垞、画面サむズはアプリケヌションを䜜成するプログラマヌによっお遞択されるため、ピクセルの䜍眮のようなむンラむン倉数ではありたせん 。 この堎合、画面サむズはShaderToy開発者によっお蚭定されたす。

䜕かが組み蟌み倉数でない堎合、この情報を䞭倮凊理装眮メむンプログラムからからビデオプロセッサシェヌダヌに送信できたす。 ShaderToyはこのタスクを匕き受けたす。 シェヌダヌに枡されるすべおの倉数は、「 シェヌダヌ入力」タブで指定されたす。 このようにしおCPUからビデオプロセッサに転送される倉数は、GLSL ナニフォヌムグロヌバルず呌ばれたす。



画面の䞭心を正しく決定するためにコヌドを倉曎したしょう。 iResolutionシェヌダヌiResolutionを䜿甚する必芁がありiResolution 。

 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 xy = fragCoord.xy; //    xy.x = xy.x / iResolution.x; //     xy.y = xy.y / iResolution.y; //  x      0,      1 vec4 solidRed = vec4(0,0.0,0.0,1.0); //    if(xy.x > 0.5){ solidRed.r = 1.0; //    1.0 } fragColor = solidRed; } 

プレビュヌりィンドりのサむズを倉曎しようずするず、色によっお画面が正確に半分に分割されたす。

スプリットからグラデヌションぞ


これをグラデヌションに倉えるのは非垞に簡単です。 色の倀は0から1たで倉化し、座暙も0から1たで倉化し0 。

 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 xy = fragCoord.xy; //    xy.x = xy.x / iResolution.x; //     xy.y = xy.y / iResolution.y; //  x      0,      1 vec4 solidRed = vec4(0,0.0,0.0,1.0); //    solidRed.r = xy.x; //     x fragColor = solidRed; } 

出来䞊がり

タスクこの写真を垂盎方向のグラデヌションに倉えるこずができたすか 察角線はどうですか いく぀かの色のグラデヌションはどうですか

コヌドを詊しおみるず、巊䞊隅の座暙が(0,0)ではなく (0,0) (0,1)であるこずに気付くでしょう。 これは芚えおおくこずが重芁です。

画像レンダリング


色を詊しおみるのは面癜いですが、印象的なこずをしたい堎合、シェヌダヌは画像を受け取り、入力ずしお倉曎する方法を孊ぶ必芁がありたす。 したがっお、ゲヌム画面党䜓に圱響するシェヌダヌ「氎䞭」゚フェクトや色補正などを取埗したり、特定のオブゞェクトに察しおのみ必芁な方法で動䜜したりするこずができたす䟋えば、珟実的な照明システムを䜜成するため。

通垞のプラットフォヌムでプログラミングした堎合、画面解像床を送信するのず同じように、画像プロセッサたたはテクスチャを均䞀ずしおビデオプロセッサに転送する必芁がありたす。 ShaderToyがこれを凊理しおくれたす。 画面の䞋郚に4぀の入力チャネルがありたす。


4぀の入力チャンネルShaderToy

iChannel0をクリックしお、テクスチャ画像を遞択したす。

その結果、シェヌダヌに枡されるむメヌゞがありたす。 ただし、1぀の問題がありたすDrawImage()関数の欠劂です。 ピクセルシェヌダヌでできるこずは、各ピクセルの色を倉曎するこずだけです。

色のみを返すこずができる堎合、どのようにしお画面にテクスチャを描画できたすか シェヌダヌの珟圚のピクセルをテクスチャの察応するピクセルに䜕らかの方法でバむンドする必芁がありたす。


画面䞊の䜍眮0,0によっおは、テクスチャを適切にスナップするためにY軞を反転する必芁がある堎合がありたす。 執筆時点では、ShaderToyは曎新されおおり、開始点は巊䞊隅にあるため、䜕も反映する必芁はありたせん。

texture(textureData,coordinates)関数を䜿甚しおバむンドできたす。この関数は入力でテクスチャデヌタず座暙のペア(x, y)を受け取り、これらの座暙のテクスチャカラヌをvec4ずしおvec4たす。

座暙を奜きなように画面にスナップできたす。 画面党䜓の4分の1にテクスチャ党䜓を描画するピクセルをスキップする、぀たり瞮尺を小さくするか、テクスチャの䞀郚のみを描画するこずができたす。

画像を芋たいだけなので、ピクセルは11スケヌルで䞀臎したす

 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 xy = fragCoord.xy / iResolution.xy;//     vec4 texColor = texture(iChannel0,xy);//  iChannel0    xy fragColor = texColor;//     } 

最初の画像ができたした



これで、テクスチャからデヌタを正しく受け取る方法を孊習したので、それらを䜿っお䜕でもできたす それらを匕き䌞ばしたり、拡倧瞮小したり、色を実隓したりできたす。

前にやったように、画像にグラデヌションを適甚しおみたしょう

 texColor.b = xy.x; 




おめでずうございたす、あなたはあなたの最初の埌凊理効果を曞いたばかりです

タスクむメヌゞを癜黒にするシェヌダヌを䜜成できたすか

静止画像を遞択したしたが、衚瀺されるものはすべおリアルタむムで実行されるこずに泚意しおください。 これを確認するには、静止画像をビデオに眮き換えたす。iChannel0をクリックしお、任意のビデオを遞択したす。

モヌションを远加


これたでのずころ、゚フェクトはすべお静的です。 ShaderToyが提䟛する入力を䜿甚しお、さらに興味深いこずができたす。 iGlobalTimeは増え続ける倉数です。 これをシヌドずしお䜿甚しお、呚期的な効果を䜜成できたす。 色を少し詊しおみたしょう。

 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 xy = fragCoord.xy / iResolution.xy; //      vec4 texColor = texture(iChannel0,xy); //   iChannel0    xy texColor.r *= abs(sin(iGlobalTime)); texColor.g *= abs(cos(iGlobalTime)); texColor.b *= abs(sin(iGlobalTime) * cos(iGlobalTime)); fragColor = texColor; //      } 

GLSLにはサむン関数ずコサむン関数が組み蟌たれおいるほか、他の倚くの䟿利な関数ベクトルの長さや2぀のベクトル間の距離の取埗などがありたす。 色の倀を負にするこずはできないため、 abs関数を䜿甚しお絶察倀を取埗する必芁がありたす。

タスクむメヌゞを癜黒からカラヌ、たたはその逆に倉曎するシェヌダヌを䜜成できたすか

シェヌダヌのデバッグに関する泚意


コヌドをデバッグする堎合、ステップごずにコヌドを実行したり、倀を印刷したりできたすが、シェヌダヌを䜜成する堎合は䞍可胜です。 プラットフォヌムのデバッグツヌルを怜玢できたすが、䞀般的なケヌスでは、チェックされた倀を衚瀺可胜な䜕らかのグラフィック情報にバむンドするのが最善です。

たずめるず


これらはシェヌダヌを操䜜するための非垞に基本的なものですが、それらをマスタヌすれば、さらに倚くを達成できたす。 ShaderToy゚フェクトをチェックしお、理解たたは再珟できるかどうかを確認しおください 

このチュヌトリアルでは、 頂点シェヌダヌに぀いおは蚀及したせんでした。 それらは同じ蚀語で曞かれおいたすが、ピクセルではなく各頂点に察しお実行され、色ずずもに䜍眮を返したす。 通垞、頂点シェヌダヌは3Dシヌンを画面に投圱したすこの機胜はほずんどのグラフィックパむプラむンに組み蟌たれおいたす。 ピクセルシェヌダヌは、画面に衚瀺されるほずんどの耇雑な効果を提䟛するので、それらを確認したす。

別のタスク ShaderToyを䜿甚しおビデオから緑を削陀し、最初のビデオの背景ずしお別のビデオを远加するシェヌダヌを䜜成できたすか

以前に䜿甚したShaderToyは、迅速なテストず実隓に最適ですが、その機胜はかなり制限されおいたす。 たずえば、シェヌダヌに枡されるデヌタを制埡するこずはできたせん。 シェヌダヌを起動するための独自の環境があれば、あらゆる皮類の興味深い゚フェクトを䜜成し、独自のプロゞェクトで䜿甚できたす ブラりザヌでシェヌダヌを実行するには、フレヌムワヌクずしおThree.jsを䜿甚したす。 WebGLはシェヌダヌをレンダリングできるJavascript APIです。Three.jsは䜜業を簡玠化するためにのみ必芁です。

JavaScriptたたはWebプラットフォヌムに興味がない堎合は、心配しないでください。Webレンダリングの機胜に぀いおは説明したせんただし、フレヌムワヌクに぀いお詳しく知りたい堎合は、 このチュヌトリアルを参照しおください 。 ブラりザヌでシェヌダヌをセットアップするのが最速の方法ですが、このプロセスをマスタヌすれば、どのプラットフォヌムでもシェヌダヌを簡単に構成しお䜿甚できたす。

カスタマむズ


このセクションでは、シェヌダヌのロヌカル構成に぀いお怜蚎したす。 このビルトむンCodePenりィゞェットのおかげで、䜕かをダりンロヌドするこずなく、私の埌に繰り返すこずができたす 


フォヌクを䜜成し、 CodePenでプロゞェクトを線集できたす 。

こんにちはThree.js


Three.jsは、シェヌダヌのレンダリングに必芁なWebGLのボむラヌプレヌトコヌドの倧郚分を匕き継ぐJavaScriptフレヌムワヌクです。 最も簡単な開始方法は、CDNに投皿されおいるバヌゞョンを䜿甚するこずです。

HTMLファむルをダりンロヌドできたす 。これは、単玔なThreejsシヌンです。

ファむルをディスクに保存し、ブラりザで開きたす。 黒い画面が衚瀺されるはずです。 ただあたり面癜くないので、すべおが機胜するこずを確認するためだけにキュヌブを远加しおみたしょう。

キュヌブを䜜成するには、ゞオメトリずマテリアルを決定し、それをシヌンに远加する必芁がありたす。 次のコヌドスニペットを[ Add your code hereフィヌルドにAdd your code here 。

 var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00} );//    var cube = new THREE.Mesh( geometry, material ); //     scene.add( cube ); cube.position.z = -3;//   ,     

シェヌダヌにもっず興味があるので、キュヌブを詳现に怜蚎したせん。 しかし、すべおが正しく行われるず、画面の䞭倮に緑色の立方䜓が衚瀺されたす。



ここにいる間に、スピンさせおみたしょう。 render関数はフレヌムごずに実行されたす。 cube.rotation.x たたは.yたたは.z を介しおキュヌブの回転にアクセスできたす。 倀を増やしお、レンダリング関数が次のようになるようにしおください。

 function render() { cube.rotation.y += 0.02; requestAnimationFrame( render ); renderer.render( scene, camera ); } 

課題キュヌブを別の軞で回転できたすか 同時に2぀の車軞はどうですか

これで準備が敎いたした。シェヌダヌを远加したしょう

シェヌダヌを远加する


この段階で、シェヌダヌを実装するプロセスに぀いお考え始めるこずができたす。 ほずんどの堎合、プラットフォヌムに関係なく同じような状況になりたす。すべおが構成され、オブゞェクトが画面に描画されたす。ビデオプロセッサにアクセスするにはどうすればよいでしょうか。

ステップ1GLSLコヌドをダりンロヌドする


JavaScriptを䜿甚しおシヌンを䜜成したす。 他の状況では、C ++、Lua、たたはその他の蚀語を䜿甚できたす。 これに関係なく、シェヌダヌは特別なシェヌダヌ蚀語で蚘述されたす 。 OpenGLシェヌダヌ蚀語はGLSL Open GL S had L anguageず呌ばれたす。 OpenGLベヌスのWebGLを䜿甚しおいるため、GLSLで蚘述したす。

GLSLコヌドはどこでどのように曞かれおいたすか 基本ルヌルGLSLコヌドはずしおロヌドされ 。 その埌、ビデオプロセッサで解析ず実行のために転送できたす。

JavaScriptでは、次のように倉数内にコヌドを枡すだけでこれを実行できたす。

 var shaderCode = "  ;" 

これは機胜したすが、JavaScriptで耇数行の文字列を䜜成する簡単な方法はないため、これはあたり䟿利ではありたせん。 ほずんどのプログラマヌは、テキストファむルにシェヌダヌコヌドを蚘述し、拡匵子.glslたたは.frag  fragment shaderの略を付けおから、ファむルをダりンロヌドするだけです。

可胜ですが、このチュヌトリアルでは、シェヌダヌコヌドを新しい<script>内に蚘述し、そこからJavaScriptにロヌドしお、すべおのコヌドが1぀のファむルに収たるようにしたす。

次のようなHTMLで新しい<script>を䜜成したす。

 <script id="fragShader" type="shader-code">; </script> 

埌でアクセスできるfragShader 、圌にfragShader IDを割り圓おたす。 shader-codeタむプは、実際には存圚しない、架空のタむプのスクリプトです。 他の名前を遞択できたす。 これは、コヌドが実行されず、HTMLで衚瀺されないようにするためです。

次に、癜を返す非垞にシンプルなシェヌダヌを挿入したしょう。

 <script id="fragShader" type="shader-code"> void main() { gl_FragColor = vec4(1.0,1.0,1.0,1.0); } </script> 

この堎合のvec4コンポヌネントは、チュヌトリアルの冒頭で説明したように、RGBA倀に察応しおいたす。

次に、このコヌドをダりンロヌドする必芁がありたす。 これを、HTML芁玠を芋぀けお内郚テキストを受け取る単玔なJavaScript文字列にしたす。

 var shaderCode = document.getElementById("fragShader").innerHTML; 

キュヌブコヌドの䞋にある必芁がありたす。

忘れないでください文字列ずしおロヌドされたコヌドのみが有効なGLSLコヌドずしお解析されたす぀たり、 void main() {...} 。残りは単なるボむラヌプレヌトHTMLです。


フォヌクを䜜成し、 CodePenでプロゞェクトを線集できたす 。

ステップ2シェヌダヌを適甚する


シェヌダヌの䜿甚方法は異なる堎合がありたす。䜿甚するプラットフォヌムずビデオプロセッサずのむンタヌフェむスによっお異なりたす。 これに問題はありたせん。簡単な怜玢で、オブゞェクトを䜜成し、Three.jsを䜿甚しおシェヌダヌを適甚する方法を芋぀けるこずができたす 。

特別なマテリアルを䜜成し、シェヌダヌコヌドに枡す必芁がありたす。 シェヌダヌオブゞェクトずしお、プレヌンを䜜成したすただし、キュヌブも䜿甚できたす。 必芁なこずは次のずおりです。

 //  ,      var material = new THREE.ShaderMaterial({fragmentShader:shaderCode}) var geometry = new THREE.PlaneGeometry( 10, 10 ); var sprite = new THREE.Mesh( geometry,material ); scene.add( sprite ); sprite.position.z = -1;//   ,     

この時点で、癜い画面が衚瀺されるはずです。


フォヌクを䜜成し、 CodePenでプロゞェクトを線集できたす 。

シェヌダヌコヌドの色を他の色に眮き換えおペヌゞを曎新するず、新しい色が衚瀺されたす。

目的画面の䞀郚を赀、もう䞀方を青にできたすか うたくいかない堎合は、次のステップでヒントを瀺したす

ステップ3デヌタ転送


この時点で、既にシェヌダヌで䜕でもできたすが、䜕ができるかはただわかりたせん。 ピクセルgl_FragCoord䜍眮を決定する組み蟌み機胜のみがあり、芚えおいる堎合、この䜍眮は正芏化されたす。 少なくずも、画面のサむズを知る必芁がありたす。

デヌタをシェヌダヌに転送するには、 ナニフォヌム倉数ず呌ばれるものを送信する必芁がありたす。 これを行うには、 uniformsオブゞェクトを䜜成し、それに倉数を远加したす。 画面解像床を枡すための構文は次のずおりです。

 var uniforms = {}; uniforms.resolution = {type:'v2',value:new THREE.Vector2(window.innerWidth,window.innerHeight)}; 

各均䞀倉数には、 ずが必芁 。 この堎合、それはりィンドりの幅ず高さを座暙ずする2次元ベクトルです。 次の衚 Three.jsドキュメントから取埗は、送信可胜なすべおのタむプのデヌタずその識別子を瀺しおいたす。
均䞀な文字列タむプGLSLJavascriptタむプ
'i', '1i'
int
Number
'f', '1f'float
Number
'v2'
vec2
THREE.Vector2
'v3'
vec3
THREE.Vector3
'c'vec3
THREE.Color
'v4'vec4
THREE.Vector4
'm3'mat3
THREE.Matrix3
'm4'mat4
THREE.Matrix4
't'sampler2D
THREE.Texture
't'samplerCube
THREE.CubeTexture
それをシェヌダヌに送信するには、ベクトルを远加しおShaderMaterialのShaderMaterialむンスタンスを倉曎したす。

 var material = new THREE.ShaderMaterial({uniforms:uniforms,fragmentShader:shaderCode}) 

ただ完了しおいたせん シェヌダヌがこの倉数を取埗したので、それで䜕かをする必芁がありたす。 前ず同じようにグラデヌションを䜜成したしょう。座暙を正芏化し、それを䜿甚しお色の倀を䜜成したす。

シェヌダヌコヌドを次のように倉曎したす。

 uniform vec2 resolution;//      uniform- void main() { //     vec2 pos = gl_FragCoord.xy / resolution.xy; //   ! gl_FragColor = vec4(1.0,pos.x,pos.y,1.0); } 

その結果、矎しいグラデヌションが埗られたす


フォヌクを䜜成し、 CodePenでプロゞェクトを線集できたす 。

タスク画面を異なる色の4぀の等しい郚分に分割しおみたす。 このようなもの



ステップ4デヌタの曎新


デヌタをシェヌダヌに送信する方法を孊んだのは良いこずですが、デヌタを曎新する必芁がある堎合はどうでしょうか たずえば、 前の䟋を新しいタブで開き、りィンドりのサむズを倉曎した堎合、グラデヌションは以前の画面サむズを䜿甚するため曎新されたせん。

倉数を曎新するには、通垞、均䞀倉数が単に再送信されたす。 ただし、Three.jsでは、 render関数でuniformsオブゞェクトを曎新するのは非垞に簡単です。シェヌダヌはデヌタを再床送信する必芁はありたせん。

倉曎埌のレンダリング関数は次のようになりたす。

 function render() { cube.rotation.y += 0.02; uniforms.resolution.value.x = window.innerWidth; uniforms.resolution.value.y = window.innerHeight; requestAnimationFrame( render ); renderer.render( scene, camera ); } 

新しいCodePenを開いおりィンドりのサむズを倉曎するず、ビュヌポヌトの元のサむズが同じたたであるにもかかわらず、色がどのように倉化するかがわかりたす。 これに気付く最も簡単な方法は、角の色を芋お、それらが倉わらないこずを確認するこずです。

泚通垞、ビデオプロセッサぞのデヌタ送信はコストのかかる䜜業です。フレヌムごずに耇数の倉数を送信するこずは非垞に正垞ですが、フレヌムごずに数癟の倉数を送信するず、フレヌムレヌトが倧幅に䜎䞋したす。これはありそうもないようですが、画面䞊に数癟のオブゞェクトがあり、それらすべおに異なるプロパティの照明が適甚されるず、すべおがすぐに制埡䞍胜になりたす。埌でシェヌダヌの最適化に぀いお孊びたす。

タスク色を埐々に倉えおみおください。

ステップ5テクスチャの䜿甚


すべおのプラットフォヌムでの読み蟌み方法ずテクスチャ圢匏に関係なく、これらは均䞀な倉数ずしおシェヌダヌに転送されたす。

JavaScriptでのファむルのダりンロヌドに関する小さなメモ倖郚URLから画像を簡単にアップロヌドできたすこれがたさに私たちが行うこずです。ただし、画像をロヌカルにアップロヌドする堎合、JavaScriptは通垞システム䞊のファむルにアクセスできないため、アクセスできないため、アクセス蚱可に問題がありたす。最も簡単な解決策は、ロヌカルPythonサヌバヌを起動するこずです。これは実際には思ったより簡単です。

Three.jsには、画像をテクスチャずしおロヌドするための小さな䟿利な機胜がありたす。

 THREE.ImageUtils.crossOrigin = '';//     var tex = THREE.ImageUtils.loadTexture( "https://tutsplus.imtqy.com/Beginners-Guide-to-Shaders/Part2/SIPI_Jelly_Beans.jpg" ); 

最初の行は䞀床だけ蚭定されたす。任意の画像URLを挿入できたす。

次に、オブゞェクトにテクスチャを远加する必芁がありたすuniforms。

 uniforms.texture = {type:'t',value:tex}; 

そしお最埌に、シェヌダヌコヌドで均䞀倉数を宣蚀し、関数を䜿甚しお以前ず同じ方法でそれを描画する必芁がありたすtexture2D。

 uniform vec2 resolution; uniform sampler2D texture; void main() { vec2 pos = gl_FragCoord.xy / resolution.xy; gl_FragColor = texture2D(texture,pos); } 

お菓子の匕き䌞ばされた画像が画面に衚瀺されたす



これは、コンピュヌタグラフィックスで暙準テスト画像である、から取られる信号ず画像凊理研究所SIPI南カリフォルニア倧孊はしたがっお、それはIPIの略を瀺しお。私たちはただのグラフィックシェヌダを勉匷しおいるので、それは、私たちに合うず思いたす

タスクテクスチャの色をフルカラヌからグレヌスケヌルに埐々に倉曎しおみおください。

远加の手順シェヌダヌを他のオブゞェクトに適甚する


䜜成した飛行機には特別なものはありたせん。シェヌダヌをキュヌブにも適甚できたす。実際、単玔に線を平面のゞオメトリに眮き換えるこずができたす。

 var geometry = new THREE.PlaneGeometry( 10, 10 ); 

に

 var geometry = new THREE.BoxGeometry( 1, 1, 1 ); 

出来䞊がり、お菓子は立方䜓に描かれおいたす


あなたは反察するかもしれたせん「埅っおください、これは立方䜓ぞのテクスチャの正しい投圱ではないようです」あなたは正しいですシェヌダヌを芋るず、実際に圌に「この画像のすべおのピクセルを画面に配眮する」ず䌝えおいるこずがわかりたす。キュヌブ䞊にあるからずいっお、単にその倖偎のすべおのピクセルが砎棄されるこずを意味したす。

キュヌブに物理的に描かれるようにテクスチャを適甚したい堎合、3D゚ンゞンの発明に䌌た䜜業になりたす3D゚ンゞンを既に䜿甚しおいるので、それを芁求するだけでかなりバカになりたす䞡偎に個別にテクスチャを描画したす。このチュヌトリアルでは、それ以倖の堎合は䞍可胜なものにシェヌダヌを䜿甚するため、そのような詳现には觊れたせん。 詳现を知りたい堎合は、Udacity に3Dグラフィックスの基瀎に関する優れたコヌスがありたす

次のステップ


この段階で、ShaderToyで行ったこずはすべお実行できたすが、珟圚では、任意のプラットフォヌムで任意のテクスチャずオブゞェクトを䜿甚できたす。

こうした自由床があれば、リアルな圱ず光源を備えた照明システムのようなこずができたす。これは以䞋で行いたす。さらに、シェヌダヌ最適化手法に぀いおも説明したす。

シェヌダヌの基本を習埗したので、実際にはビデオプロセッサのパワヌを䜿甚しおリアルなダむナミックラむティングを䜜成したす。

この時点から、特定のプラットフォヌムに瞛られるこずなく、グラフィックシェヌダヌの䞀般的な抂念を怜蚎したす。 䟿宜䞊、すべおのコヌド䟋は匕き続きJavaScript / WebGLを䜿甚したす。

開始するには、シェヌダヌを実行する適切な方法を芋぀けおください。JavaScript / WebGLが最も簡単な方法ですが、お気に入りのプラットフォヌムで実隓するこずをお勧めしたす

目暙


このチュヌトリアルの終わりたでに、照明システムでうたくナビゲヌトし始めるだけでなく、れロから独自に䜜成するこずもできたす。

最終結果は次のようになりたすクリックしおラむトをオンにしたす。


倚くのゲヌム゚ンゞンには既補の照明システムがありたすが、その䜜成方法ず独自の照明システムを䜜成する方法を理解するこずで、ゲヌムにナニヌクな倖芳を䞎える機䌚が増えたす。さらに、シェヌダヌ゚フェクトは「化粧」だけでなく、驚くべき新しいゲヌムメカニクスぞの扉を開きたす

この良い䟋がクロマです。プレヌダヌは、リアルタむムで䜜成された動的なシャドりに沿っお実行できたす。


はじめに開始シヌン


䞊蚘で詳现に説明されおいるため、初期セットアップでは倚くのこずを逃したす。テクスチャをレンダリングする単玔なフラグメントシェヌダから始めたしょう。


ここでは耇雑なこずは䜕も起こりたせん。JavaScriptコヌドはシヌンを蚭定し、レンダリングず画面サむズのためにシェヌダヌテクスチャを送信したす。

 var uniforms = { tex : {type:'t',value:texture},//  res : {type: 'v2',value:new THREE.Vector2(window.innerWidth,window.innerHeight)}//   } 

GLSLコヌドでは、これらの統䞀倉数を​​宣蚀しお䜿甚したす。

 uniform sampler2D tex; uniform vec2 res; void main() { vec2 pixel = gl_FragCoord.xy / res.xy; vec4 color = texture2D(tex,pixel); gl_FragColor = color; } 

ピクセルの座暙を䜿甚しおテクスチャをレンダリングする前に、それらを正芏化したす。

すべおを確実に理解するために、ここに小さなりォヌムアップタスクを瀺したす。

タスクアスペクト比を倉曎せずにテクスチャをレンダリングしたす自分で詊しおみおください。以䞋の゜リュヌションを芋おいきたす。

テクスチャが匕き䌞ばされおいる理由は明らかですが、ヒントは次のずおりです。座暙を正芏化する行を芋おください。

 vec2 pixel = gl_FragCoord.xy / res.xy; 

で陀算vec2しvec2たす。これは、個々のコンポヌネントを陀算するこずに䌌おいたす。蚀い換えるず、䞊蚘は以䞋ず同等です。

 vec2 pixel = vec2(0.0,0.0); pixel.x = gl_FragCoord.x / res.x; pixel.y = gl_FragCoord.y / res.y; 

xずyを異なる数に分割したす画面の幅ず高さで。圓然、画像は匕き䌞ばされたす。

xずy gl_FragCoordをxだけで陀算するずどうなりresたすかそれずもただ

簡単にするために、チュヌトリアルでは、正芏化されたコヌドは同じたたにしおおきたす。ここで䜕が起こっおいるのかを把握しおおくずいいでしょう。

ステップ1光源を远加する


面癜いものを䜜成する前に、光源が必芁です。「光源」は、シェヌダヌに枡される単なるポむントです。この点に぀いお、新しいナニフォヌムを䜜成したす。

 var uniforms = { //    light: {type:'v3', value:new THREE.Vector3()}, tex : {type:'t',value:texture},//  res : {type: 'v2',value:new THREE.Vector2(window.innerWidth,window.innerHeight)}//   } 

画面䞊の゜ヌスの䜍眮ずしお、およびradiusずしお-のx䞡方を䜿甚するため、3次元のベクトルを䜜成したした。JavaScriptで光源に倀を割り圓おたしょうyz



 uniforms.light.value.z = 0.2;//  

半埄は画面サむズの割合ずしお䜿甚するため0.2、画面の20になりたす。この遞択に関しお特別なこずは䜕もありたせん。サむズをピクセル単䜍で蚭定できたす。GLSLコヌドで䜕かを開始するたで、この数倀は䜕の意味もありたせん。

マりス䜍眮を取埗するには、むベントリスナヌを远加するだけです。 

 document.onmousemove = function(event){ //   ,      uniforms.light.value.x = event.clientX; uniforms.light.value.y = event.clientY; } 

次に、光源のこの座暙を利甚するシェヌダヌコヌドを蚘述したしょう。単玔なタスクから始めたしょう。光源の半埄内の各ピクセルが衚瀺され、残りが黒であるこずを確認しおください。

GLSLでは、次のようになりたす。

 uniform sampler2D tex; uniform vec2 res; uniform vec3 light;//     uniform! void main() { vec2 pixel = gl_FragCoord.xy / res.xy; vec4 color = texture2D(tex,pixel); //        float dist = distance(gl_FragCoord.xy,light.xy); if(light.z * res.x > dist){// ,      gl_FragColor = color; } else { gl_FragColor = vec4(0.0); } } 

ここでは、次のこずを行いたした。




痛い光源は奇劙な方法でマりスに远埓したす。

タスク修正できたすか以䞋でこの問題を解決する前に、自分でもう䞀床詊しおみおください。

光源移動補正


ここで、Y軞が反転しおいるこずを芚えおいるかもしれたせん。次のように入力するだけで急ぐこずができたす。

 light.y = res.y - light.y; 

これは数孊的には正しいですが、そうするずシェヌダヌはコンパむルされたせん問題は、均䞀倉数を倉曎できないこずです。理由を理解するには、このコヌドが個々のピクセルごずに䞊行しお実行されるこずを芚えおおく必芁がありたす。すべおのプロセッサコアが䞀床に1぀の倉数を倉曎しようずするこずを想像しおください。悪い状況

ナニフォヌムの代わりに新しい倉数を䜜成するこずにより、゚ラヌを修正できたす。たたはさらに良い- デヌタをシェヌダヌに転送する前に次の手順を実行できたす。


 uniforms.light.value.y = window.innerHeight - event.clientY; 

これで、シヌンの可芖半埄を正垞に決定できたした。しかし、圌はあたりにも鋭く芋えたす...

グラデヌションを远加


半埄の倖偎で黒に切り抜くのではなく、゚ッゞに滑らかなグラデヌションを䜜成しおみたしょう。これは、すでに蚈算しおいる距離を䜿甚しお実行できたす。

テクスチャカラヌの半埄内のすべおのピクセルを割り圓おる代わりに

 gl_FragColor = color; 

それに距離係数を掛けるこずができたす

 gl_FragColor = color * (1.0 - dist/(light.z * res.x)); 


これはdist、珟圚のピクセルず光源の間のピクセル単䜍の距離であるため機胜したす。(light.z * res.x)半埄の長さです。したがっお、光源の䞋のピクセルを正確に芋るず、それdistは等しくなりたす0。぀たり、乗算colorしお1フルカラヌを取埗したす。


この図ではdist、任意のピクセルに察しお蚈算されたす。distどのピクセルにいるかによっお倉化し、倀はlight.z * res.x䞀定です。

円の境界にあるピクセルを芋るdistず、半埄の長さず等しくなりたす。぀たり、結果ずしお、乗算colorし0お黒色を取埗したす。

ステップ2深さを远加する


これたでのずころ、特別なこずは䜕もせず、テクスチャにグラデヌションマスクを远加したした。すべおがただ平らに芋えたす。これを修正する方法を理解するために、照明システムが珟圚䜕をしおいるのかを芋お、䜕をすべきかず比范したしょう。



䞊蚘の堎合、点Aは光源がその真䞊にあるため最も匷く点灯し、BずCは実際には偎面に光線がないため暗くなりたす。

ただし、ここに照明システムが衚瀺するもの



がありたす。システムが考慮する唯䞀の芁玠はxy平面䞊の距離であるため、すべおのポむントは同じ方法で凊理されたす。。これらの各ポむントの高さが必芁だず思うかもしれたせんが、これは完党に真実ではありたせん。理由を確認するには、この図を怜蚎しおください



。Aは図の䞊郚にあり、BずCは偎面にありたす。Dは地球䞊の別のポむントです。AずDが最も明るく、Dが斜めに到達するため少し暗くなるこずがわかりたす。䞀方、BずCは光源からの光であるため、ほずんど光が届かないため、非垞に暗いはずです。

高さは、衚面が回転する方向ほど重芁ではありたせん。ず呌ばれたす衚面に察しお垂盎。

しかし、この情報をシェヌダヌに転送する方法はおそらく、個々のピクセルごずに膚倧な数の数の配列を送信するこずはできたせんか実際、それを行いたす配列ではなく、テクスチャず呌びたす。

これは、通垞のマップを䜜るものであるそれは単にの倀画像でありr、gか぀b各画玠には色、及び方向を衚したす。



䞊の図は、単玔な法線マップを瀺しおいたす。スポむトツヌルを䜿甚するず、デフォルトの方向「フラット」が色で衚されるこずがわかりたす。(0.5, 0.5, 1)画像の倧郚分を占める青。これはたっすぐ䞊を指す方向です。x、y、およびzの倀は、r、g、およびbの倀に割り圓おられたす。

右偎の傟斜偎は右に回転しおいるため、そのx倀は高くなりたす。x倀は赀の倀でもあるため、偎面が少し赀みを垯びおいるかピンクがかっおいたす。同じこずが他のすべおの関係者にも圓おはたりたす。

マップはレンダリング甚ではなく、これらのサヌフェスの通垞の倀を゚ンコヌドするだけなので、マップはおかしく芋えたす。

この単玔な法線マップをテスト甚にロヌドしたしょう

 var normalURL = "https://raw.githubusercontent.com/tutsplus/Beginners-Guide-to-Shaders/master/Part3/normal_maps/normal_test.jpg" var normal = THREE.ImageUtils.loadTexture(normalURL); 

そしお、それを䞀様倉数の1぀ずしお远加したす。

 var uniforms = { norm: {type:'t', value:normal}, //..    } 

正しくダりンロヌドしたこずを確認するには、コヌドをGLSLに倉曎しお、テクスチャの代わりにレンダリングしおみたすこの段階では、通垞のマップではなく背景テクスチャのみを䜿甚するこずに泚意しおください。


ステップ3照明モデルを適甚する


衚面の法線デヌタが埗られたので、照明モデルを実装する必芁がありたす。蚀い換えれば、最終的な明るさを蚈算するために利甚可胜なすべおの芁因を考慮する方法を衚面に䌝える必芁がありたす。

実装する最も簡単なモデルはPhongモデルです。仕組みは次のずおりです。



法線デヌタを持぀サヌフェスがあるずしたす。光源ずサヌフェス法線の間の角床を単玔に蚈算したす。角床が



小さいほど、ピクセルは明るくなりたす。

これは、角床差が0であるピクセルが光源の真䞋にあるずき、最も明るいこずを意味したす。最も暗いピクセルは、光源ず同じ方向を指したすこれはオブゞェクトの背面のように芋えたす。

このモデルを実装したしょう。

怜蚌には単玔な法線マップを䜿甚するため、テクスチャが単色で塗り぀ぶされお、すべおがうたくいくかどうかを明確に理解したしょう。

したがっお、代わりに

 vec4 color = texture2D(...); 

単色の癜色たたはその他の色を䜜成したしょう。

 vec4 color = vec4(1.0); //   

これは、vec4すべおのコンポヌネントが等しいGLSLを䜜成するための速蚘です1.0。

アルゎリズムは次のようになりたす。

  1. 珟圚のピクセルの法線ベクトルを取埗したす。
  2. ラむトの方向ベクトルを取埗したす。
  3. ベクトルを正芏化したす。
  4. それらの間の角床を蚈算したす。
  5. 最終的な色にこの係数を掛けたす。

1.珟圚のピクセルの法線ベクトルを取埗する


このピクセルに圓たる光の量を蚈算できるように、衚面がどの方向に「芋える」かを知る必芁がありたす。この方向は法線マップに保存されるため、法線ベクトルを取埗するには、法線テクスチャの珟圚のピクセルの色を取埗したす。

 vec3 NormalVector = texture2D(norm,pixel).xyz; 

アルファ倀は法線マップ䞊では䜕も意味しないため、最初の3぀のコンポヌネントのみが必芁です。

2.光の方向ベクトルを取埗する


次に、光がどの方向を指しおいるかを知る必芁がありたす。照明面は、マりスカヌ゜ルの䜍眮で画面に向けられた懐䞭電灯であるず想像できたす。したがっお、光源ずピクセル間の距離を䜿甚するだけで、光の方向ベクトルを蚈算できたす。

 vec3 LightVector = vec3(light.x - gl_FragCoord.x,light.y - gl_FragCoord.y,60.0); 

たた、Z座暙も必芁です3次元の衚面法線ベクトルに察する角床を蚈算できるようにするため。この倀を詊すこずができたす。小さいほど、明るい郚分ず暗い郚分のコントラストがはっきりしおいるこずがわかりたす。これは、ステヌゞ䞊の懐䞭電灯の高さであるず想像できたす。遠くにあるほど、光はより均等に広がりたす。

3.ベクトルの正芏化


次に、正芏化する必芁がありたす。

 NormalVector = normalize(NormalVector); LightVector = normalize(LightVector); 

䞡方のベクトルが長さ1.0を持぀ように、組み蟌みのnormalize関数を䜿甚したす。これは、スカラヌ積を䜿甚しお角床を蚈算するために必芁です。仕組みがよくわからない堎合は、線圢代数に぀いお少し勉匷する䟡倀がありたす。この目的のために、スカラヌ積が同じ長さのベクトル間の角床のコサむンを返すこずを知る必芁があるだけです。

4.ベクトル間の角床を蚈算する


組み蟌みのドット関数を䜿甚しおこれを実行したしょう。

 float diffuse = dot( NormalVector, LightVector ); 

この甚語はシヌンの衚面に到達する光の量を定矩するため、この甚語はPhongラむティングモデルで䜿甚されるため、倉数diffuseず名付けたした。

5.最終的な色にこの係数を掛けたす


以䞊です。次に、色に倀を掛けたす。distanceFactor方皋匏を読みやすくするために倉数を䜜成したした。

 float distanceFactor = (1.0 - dist/(light.z * res.x)); gl_FragColor = color * diffuse * distanceFactor; 

そしお、実甚的な照明モデルを埗た​​した効果がより顕著になるように、光源の半埄を倧きくしおみおください。


うヌん、䜕かが間違っおいるようです。゜ヌスが䜕らかの圢で傟いおいるようです。

蚈算をもう䞀床芋おみたしょう。ラむトベクトルがありたす。

 vec3 LightVector = vec3(light.x - gl_FragCoord.x,light.y - gl_FragCoord.y,60.0); 

私たちが知っお(0, 0, 60)いるように、光源が珟圚のピクセルより䞊にあるずきに私たちに䞎えるもの。正芏化埌、それは等しくなり(0, 0, 1)たす。

最倧の茝床を埗るには、光源に厳密に向けられた法線が必芁であるこずを忘れないでください。デフォルトの法線サヌフェスは䞊向きです(0.5, 0.5, 1)。

タスク゜リュヌションが䜕であるかを理解しおいたすか実装できたすか

問題は、負の倀を色の倀ずしおテクスチャに保存できないこずです。巊向きベクトルをずしおマヌクするこずはできたせん(-0.5, 0, 0)。したがっお、法線マップを䜜成するずきは、すべおに远加する必芁がありたす0.5。たたは、より䞀般的には、座暙系をシフトする必芁がありたす。マップを䜿甚する前に、各ピクセルから枛算する必芁があるこずを知るために、これを理解する必芁がありたす0.5。

以䞋0.5は、xおよびy座暙から法線ベクトルを枛算した埌のデモの様子です。


別の修正を行う必芁がありたす。スカラヌ積は角床のコサむンを返すこずに泚意しおください。これは、出力が-1から1の範囲に制限されるこずを意味したす。色の倀を負にするこずはできたせん。たた、WebGLは負の倀を自動的に拒吊するため、堎合によっおは動䜜がおかしくなりたす。この問題を解決するには、組み蟌みのmax関数を䜿甚しおこれを有効にしたす。

 float diffuse = dot( NormalVector, LightVector ); 

これに

 float diffuse = max(dot( NormalVector, LightVector ),0.0); 

そしお、実甚的な照明モデルを埗た​​した

背景に石のテクスチャを配眮し、GitHubのこのチュヌトリアルのリポゞトリにある実際の法線マップを取埗するこずができたす぀たり、ここ

1行だけをJavaScriptに倉曎する必芁がありたす。

 var normalURL = "https://raw.githubusercontent.com/tutsplus/Beginners-Guide-to-Shaders/master/Part3/normal_maps/normal_test.jpg" 

に

 var normalURL = "https://raw.githubusercontent.com/tutsplus/Beginners-Guide-to-Shaders/master/Part3/normal_maps/blocks_normal.JPG" 

GLSLの1行

 vec4 color = vec4(1.0);//   

単色の癜色は䞍芁になりたした。次のように実際のテクスチャをロヌドしたす。

 vec4 color = texture2D(tex,pixel); 

そしお、最終結果は次のずおりです。



最適化のヒント


ビデオプロセッサは非垞に効率的に䜜業を実行したすが、䜕が遅くなるかを知るこずは非垞に重芁です。 以䞋にいく぀かの提案を瀺したす。

分岐


シェヌダヌでは、可胜な堎合は通垞、分岐を回避するこずが望たしいです。ifCPUのコヌドでは倚くのデザむンが問題になるこずはめったにありたせんが、ビデオプロセッサのシェヌダヌではボトルネックになる可胜性がありたす。

理由を理解するには、GLSLコヌドが画面䞊の各ピクセルに察しお䞊列に実行されるこずを思い出しおください。グラフィックスカヌドは、すべおのピクセルが同じ操䜜を実行する必芁があるずいう事実に基づいお、倚くの最適化を実行できたす。ただし、codeに倚くのコヌドがある堎合if、ピクセルごずに異なるコヌドが実行されるため、䞀郚の最適化は倱敗したす。デザむンはありたすかif 実行を遅くするかどうかは、特定のハヌドりェアずグラフィックカヌドの実装に䟝存したすが、シェヌダヌを高速化する堎合はこれをよく芚えおおいおください。

遅延レンダリング


これは、照明を扱うずきに非垞に䟿利な抂念です。2぀の光源、3぀、たたは1ダヌスが必芁だず想像しおください。各衚面の法線ず光源の各点の間の角床を蚈算する必芁がありたす。その結果、シェヌダヌはタヌトル速床で実行されたす。遅延レンダリングは、シェヌダヌの䜜業を耇数のパスに分割するこずにより、このようなプロセスを最適化する方法です。これが䜕を意味するかを詳しく説明しおいる蚘事です。私たちにずっお重芁な郚分を匕甚したす。

— . .

たずえば、光源のポむントの配列を送信する代わりに、テクスチャ䞊に円の圢でそれらを描画できたす。円の各ピクセルの色は光の匷床を衚したす。このようにしお、シヌン内のすべおの光源の耇合効果を蚈算し、それを最終的なテクスチャたたは呌ばれるこずもあるバッファに枡すだけで、ラむティングを蚈算できたす。

䜜業を耇数のパスに分割する機胜は、シェヌダヌを䜜成するずきに非垞に䟿利な手法です。たずえば、液䜓/煙シェヌダヌだけでなく、がかし効果の蚈算でシェヌダヌを加速するために䜿甚されたす。

次のステップ


実甚的なラむティングシェヌダヌができたので、次のこずを詊しおみおください。


参照資料


このチュヌトリアルの石のテクスチャず法線マップは、OpenGameArthttp ://opengameart.org/content/50-free-textures-4-normalmapsから取埗されたす。

法線マップの䜜成に圹立぀倚くのプログラムがありたす。独自の法線マップの䜜成に぀いお詳しく知りたい堎合は、この蚘事が圹立ちたす。

Source: https://habr.com/ru/post/J333002/


All Articles