みなさんこんにちは。
Habréに関する私の8つの記事はすべてゲーム開発に関する記事であり、それらのほとんどはXNAなどのすばらしいフレームワークに関連しています。 XNAの最初の知り合いは、 音楽玩具の作成に関する記事でした。その後、記事の複雑さが増し、 パーティクルシステム 、 シェーダー 、 シェーダーについて書き始めました。
一般に、シェーダーで仕上げたかったのですが、少し補足する必要がある場合は、ゲームのグラフィックスを改善するためのいくつかのアルゴリズムについて説明します。 改善の例:
興味がある場合-habrakatの下。
はじめに
再びゲームの2Dコンポーネントに触れ、ピクセルシェーダーでのみ動作します。
この記事は他の記事とは少し異なりますが、理論と実践はすぐに進みます。つまり、 こことここでシェーダーに関する記事をすでに読んでいることを意味します。
ゲームで使用されたすべての効果と、そこになかったいくつかの効果を考えてみましょう。ビデオはかなり古く、ゲームはそれ以来すでに質的な変化を受けています。
歪み
目を引く最初の効果は歪みです。
この効果は、特別なシェーダーでは処理されません。一般に、前に書いた記事と同じです。
その爆発効果を見てみましょう。
ここでは次のテクスチャが使用されます。
左上隅には煙のテクスチャーがあり、煙は爆発の周りに「リング」を形成し、爆発中の明るい領域とロケットからの列車がすぐに消えます。 これがこの効果の主なテクスチャです。 目に見えるテクスチャと歪んだテクスチャとして使用されます。
次-煙の隣、それのおかげで-爆発の中心から来る稲妻があります。 目に見えるテクスチャおよび歪みテクスチャとしても使用されます。
さて、追加の美しさ-爆発からの粒子、ストリップ上の最大のテクスチャ。 しかし、プレーヤーが彼女をまっすぐに見ないことは注目に値します。 それは歪んでいて、すぐに消えます。
PSパーティクルシステムを作成する初心者向けのヒント:
- ゲーム中にパーティクルを作成しないでください。PoolObjectパターンを使用してください。
- パーティクルクラスにテクスチャプロパティを作成しないでください。 パーティクルのすべてのテクスチャがある列挙型と単一のテクスチャ(ストリップ)を使用します。 なぜなら パーティクルの描画プロセス中にグラフィックデバイスの状態を常に変更する場合(たとえば、テクスチャを変更する場合)-システムの高速化を期待しないでください。
- ルール:「粒子が多いほど美しい」-常に機能するとは限りません。
HUD歪み
ビデオで気付かれた2番目の効果は、インターフェイスの歪みです。
この効果は、たとえばCrysis 2やDeus Ex:Human revolutionなどのゲームに触発されました。 そこで、死とともに-インターフェースはさまざまな方法で歪曲し始めました。 私には面白そうだった。 また、単純なヒットでインターフェースの歪みを増やしました。
たとえば、プレイヤーの死:
このシェーダーは、以前のシェーダーである画像の歪みに非常に似ています。 ただし、彼とは根本的に異なります。 ディストーションはディストーションマップからではなく、数式から、シェーダーコードを見てみましょう(シェーダーは理解するためにできるだけ単純です)。
float force; // "" float timer; // , . float random1; // float random2; // float initialization; // "" float desaturation_float; // sampler TextureSampler : register(s0); float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { texCoord.y += cos(texCoord.x) * timer * 0.0002f * force; // if(initialization > 0) { texCoord.x += cos(texCoord.y) * initialization; // } if(texCoord.y > random1 && texCoord.y < random2) // { float moving = force; if(timer > 100) moving *= -1.0; texCoord.x += timer / 5000.0 * moving * random2; color *= 1 + random2 * force; } if(timer < 20 && force > 0.3) // { color.b = random2; color.g = random1; } if(timer > 50) // "" { color *= 1 + random1/3 * (1 + force); } float4 source = tex2D(TextureSampler, texCoord); float4 sourceR = tex2D(TextureSampler, texCoord + float2(0.01*force*random1, 0)); sourceR.g = 0; sourceR.b = 0; float4 sourceB = tex2D(TextureSampler, texCoord - float2(0.01*force*force*random2, 0)); sourceB.r = 0; sourceB.g = 0; float4 sourceG = tex2D(TextureSampler, texCoord - float2(0.01*force*((random1+random2) / 2), 0)); sourceG.r = 0; sourceG.b = 0; float4 output = (sourceR+sourceB+sourceG); output.a = source.a; float greyscale = dot(output.rgb, float3(0.3, 0.59, 0.11)); output.rgb = lerp(greyscale, output.rgb, 1.0 - desaturation_float); return color * output; } technique HUDDisplacer { pass DefaultPass { PixelShader = compile ps_2_0 main(); } }
コードは非常にシンプルで、シェーダーの結果自体は見事です。
静的テクスチャから動的テクスチャ
少ない生活から「生きている」テクスチャを作成します。 たとえば、気づいている人はほとんどいません-上のビデオの遠方の星のちらつき。 ただし、テクスチャ自体は静的です。
このシェーダーを検討してください。
float modifer; // sampler TextureSampler : register(s0); float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 output = tex2D(TextureSampler, texCoord); float greyscale = dot(output.rgb, float3(0.3, 0.59, 0.11)); if(greyscale > 0.2) { color *= 1 + (modifer*greyscale / 1.5); if(greyscale > 0.8) { color *= 1 + (modifer*2); } } return color * output; } technique BackgroundShader { pass DefaultPass { PixelShader = compile ps_2_0 main(); } }
ピクセルの輝度( グレースケール )が20%を超える場合-わずかなちらつきが作成され、80%を超える場合-強い。
これは写真には表示できません。すべてがビデオに表示されます。
さて、ビデオにはない、新しいバージョンに実装されている2つのエフェクトを検討してください。
ブルーム(グロー効果)
グロー効果は、 ブルーム (ブルーム)とも呼ばれる誰もが知っています。
アイデアは単純です。画像から明るい領域を抽出し(しきい値を入力します)、シーンとぼやけたシーンを上に描画します。 明るい部分が光り始めます。
写真の例:
シーンの明るさ:
元のシーン:
レディシーン:
シェーダーコードを考えてみましょう。これは、明るさを抽出するシェーダーと最終的な画像を形成するシェーダーの2つの部分で構成されています。
明るさを抽出するシェーダーのリスト:
sampler TextureSampler : register(s0); float4 main(float2 texCoord : TEXCOORD0) : COLOR0 { float4 c = tex2D(TextureSampler, texCoord); float BloomThreshold = 0.1; return saturate((c - BloomThreshold) / (1 - BloomThreshold)); } technique ThresholdEffect { pass DefaultPass { PixelShader = compile ps_2_0 main(); } }
最終結果を与えるシェーダーのリスト:
texture bloomMap; sampler TextureSampler : register(s0); sampler BloomSampler : samplerState { Texture = bloomMap; MinFilter = Linear; MagFilter = Linear; AddressU = Clamp; AddressV = Clamp; }; // - const float2 offsets[12] = { -0.326212, -0.405805, -0.840144, -0.073580, -0.695914, 0.457137, -0.203345, 0.620716, 0.962340, -0.194983, 0.473434, -0.480026, 0.519456, 0.767022, 0.185461, -0.893124, 0.507431, 0.064425, 0.896420, 0.412458, -0.321940, -0.932615, -0.791559, -0.597705, }; float4 AdjustSaturation(float4 color, float saturation) { float grey = dot(color, float3(0.3, 0.59, 0.11)); return lerp(grey, color, saturation); } float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float BlurPower = 0.01; // 0.01 float BaseIntensity = 1; float BloomIntensity = 0.4; // 0.4 float BaseSaturation = 1; float BloomSaturation = 1; float4 original = tex2D(TextureSampler, texCoord); // float4 sum = tex2D(BloomSampler, texCoord); for(int i = 0; i < 12; i++){ sum += tex2D(BloomSampler, texCoord + BlurPower * offsets[i]); } sum /= 13; original = AdjustSaturation(original, BaseSaturation) * BaseIntensity; sum = AdjustSaturation(sum, BloomSaturation) * BloomIntensity; return sum + original; } technique BloomEffect { pass DefaultPass { PixelShader = compile ps_2_0 main(); } }
モーションブラー
さて、最後の効果であるこのモーションブラーは、他の効果と組み合わせて「柔らかさ」を与え、マウスを鋭く動かして、
それも非常に簡単に実装されています:
float rad = direction_move.x; float xOffset = cos(rad); float yOffset = sin(rad); for(int idx=0; idx<15; idx++) { texCoord.x = texCoord.x - 0.001 * xOffset * direction_move.y; texCoord.y = texCoord.y - 0.001 * yOffset * direction_move.y; c += tex2D(TextureSampler, texCoord); } c /= 15;
direction_moveはモーションベクトルです。
おわりに
そのようなものの助けを借りて-あなたはあなたのゲームに大きな「ねじれ」を与えることができ、そのようなことは非常に簡単に行われます。
これについては、2Dゲームの「コース」は終わったと思います。しばらくしてから、3Dゲームの作成について書き始めます。
PSこのゲームの作成(ビデオにあるもの)-ほとんどの場合、この段階で残ります。 私はそのような大規模なプロジェクトだけで自殺するために十分なリソース(時間、熱意、インスピレーション)を持っていません。
PSSミス/エラーについての巨大なリクエスト、個人的なメッセージを書いてください、有用な意味論的な負荷なしでコメントを書かないでください。
PSSSは新しい連絡先を歓迎します;-)
成功を祈っています!