最新版 |
編集中の文章 |
3行目: |
3行目: |
| 1[[ポリゴン]]あたり1[[法線]]と[[データ]]量が非常に少なく、非常に高速に処理できるという利点があり、[[リアルタイムレンダリング]]が求められる[[ポリゴン]]を使った初期の[[ゲーム]]でよく用いられた。現在では[[ハードウェアT&L]]や[[プログラマブルシェーダー]]の登場でほぼ見かけることはなくなった。 | | 1[[ポリゴン]]あたり1[[法線]]と[[データ]]量が非常に少なく、非常に高速に処理できるという利点があり、[[リアルタイムレンダリング]]が求められる[[ポリゴン]]を使った初期の[[ゲーム]]でよく用いられた。現在では[[ハードウェアT&L]]や[[プログラマブルシェーダー]]の登場でほぼ見かけることはなくなった。 |
| | | |
− | ==GLSL== | + | == GLSL == |
− | [[GLSL]]では[[バーテックスシェーダー]]の出力変数に「flat修飾子」を付けるとフラットシェーディングとなる。
| + | GLSLでは[[バーテックスシェーダー]]の出力変数に「flat修飾子」を付けるとフラットシェーディングとなる。<syntaxhighlight lang="glsl"> |
− | <syntaxhighlight lang="glsl"> | |
| // 入力 | | // 入力 |
| layout (location = 0) in vec3 VertexPosition; | | layout (location = 0) in vec3 VertexPosition; |
− | layout (location = 1) in vec3 VertexNormal; | + | layout (location = 1) ih vec3 VertexNormal; |
| | | |
| // 出力(これ) | | // 出力(これ) |
16行目: |
15行目: |
| void main() | | void main() |
| { | | { |
| + | // フォンシェーディングやグローシェーディングなんかを書いておく |
| // 出力変数に「flat out」と書かれていると、ここが頂点1個分しか呼ばれない | | // 出力変数に「flat out」と書かれていると、ここが頂点1個分しか呼ばれない |
| } | | } |
− | </syntaxhighlight>
| |
| | | |
− | [[バーテックスシェーダー]]の出力値を格納する変数にflat修飾子をつけると、その[[バーテックスシェーダー]]では[[ポリゴン]]を構成する3つの[[頂点]]のいずれか1つだけが計算され、その値が[[フラグメントシェーダー]]に渡ってくる。前述の概要で「[[法線]]を面単位で持つ」と書いたが、GLSLでは「ポリゴンを構成する[[頂点]]の[[法線]]のいずれか1つが使われる」という内容になっている。 | + | </syntaxhighlight>この場合、[[バーテックスシェーダー]]に[[フォンシェーディング]]や[[グローシェーディング]]などを[[アルゴリズム]]を書いておいても、[[ポリゴン]]を構成する3つの[[頂点]]のいずれか1つだけが計算され、その結果が[[フラグメントシェーダー]]に渡ってくる。前述の概要で「[[法線]]を面単位で持つ」と書いたが「ポリゴンを構成する[[頂点]]の[[法線]]のいずれか1つが使われる」という内容になっている。 |
− | | |
− | == HLSL ==
| |
− | [[HLSL]]にはフラットシェーディングを扱う方法がない。このため普通に3頂点を計算して擬似的にフラットシェーディングを実装することになる。見た目がフラットシェーディング風になるだけなので速度的な利点は一切ない。
| |
− | | |
− | <syntaxhighlight>
| |
− | float4x4 World;
| |
− | float4x4 View;
| |
− | float4x4 Projection;
| |
− | | |
− | float4 AmbientColor = float4(1, 1, 1, 1);
| |
− | float AmbientIntensity = 0.1f;
| |
− | | |
− | float3 DiffuseLightDirection = float3(1, 0, 0);
| |
− | float4 DiffuseColor = float4(1, 1, 1, 1);
| |
− | float DiffuseIntensity = 1.0f;
| |
− | | |
− | texture ModelTexture;
| |
− | sampler2D textureSampler = sampler_state {
| |
− | Texture = (ModelTexture);
| |
− | MinFilter = Linear;
| |
− | MagFilter = Linear;
| |
− | AddressU = Clamp;
| |
− | AddressV = Clamp;
| |
− | };
| |
− | | |
− | struct VertexShaderInput
| |
− | {
| |
− | float4 Position : POSITION0;
| |
− | float4 Normal : NORMAL0;
| |
− | float2 TextureCoordinate : TEXCOORD0;
| |
− | };
| |
− | | |
− | struct VertexShaderOutput
| |
− | {
| |
− | float4 Position : POSITION0;
| |
− | float4 PositionWorld : TEXCOORD0;
| |
− | float2 TextureCoordinate : TEXCOORD1;
| |
− | };
| |
− | | |
− | VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
| |
− | {
| |
− | VertexShaderOutput output;
| |
− | | |
− | float4 worldPosition = mul(input.Position, World);
| |
− | float4 viewPosition = mul(worldPosition, View);
| |
− | output.Position = mul(viewPosition, Projection);
| |
− | output.PositionWorld = worldPosition;
| |
− | | |
− | output.TextureCoordinate = input.TextureCoordinate;
| |
− | | |
− | return output;
| |
− | }
| |
− | | |
− | float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
| |
− | {
| |
− | float3 Normal = cross(ddy(input.PositionWorld.xyz), ddx(input.PositionWorld.xyz));
| |
− | Normal = normalize(Normal);
| |
− | | |
− | float lightIntensity = dot(Normal, DiffuseLightDirection);
| |
− | float4 lightColor = lightIntensity * DiffuseColor * DiffuseIntensity + AmbientColor * AmbientIntensity;
| |
− | lightColor.a = 1;
| |
− | | |
− | float4 textureColor = tex2D(textureSampler, input.TextureCoordinate);
| |
− | textureColor.a = 1;
| |
− | | |
− | return saturate(textureColor * lightColor);
| |
− | }
| |
− | | |
− | technique FlatTextured
| |
− | {
| |
− | pass Pass1
| |
− | {
| |
− | VertexShader = compile vs_3_0 VertexShaderFunction();
| |
− | PixelShader = compile ps_3_0 PixelShaderFunction();
| |
− | }
| |
− | }
| |
− | | |
− | </syntaxhighlight>
| |
| | | |
| ==関連項目== | | ==関連項目== |