最新版 |
編集中の文章 |
1行目: |
1行目: |
− | '''フラットシェーディング'''とは、[[3DCG]]の陰影処理技法のひとつで、[[法線]]を[[ポリゴン]]面単位で保持し、[[法線]]はポリゴン面に対して常に垂直なものとして扱うものをいう。1ポリゴンごとに1色で塗りつぶされる。 | + | '''フラットシェーディング'''とは、[[3DCG]]の陰影処理技法のひとつで、[[法線]]を[[ポリゴン]]面単位で保持し、[[法線]]はポリゴン面に対して常に垂直なものとして扱うものをいう。 |
| | | |
− | 1[[ポリゴン]]あたり1[[法線]]と[[データ]]量が非常に少なく、非常に高速に処理できるという利点があり、[[リアルタイムレンダリング]]が求められる[[ポリゴン]]を使った初期の[[ゲーム]]でよく用いられた。現在では[[ハードウェアT&L]]や[[プログラマブルシェーダー]]の登場でほぼ見かけることはなくなった。
| + | 1ポリゴンあたり1法線と[[データ]]量が非常に少なく、非常に高速に処理できるという利点があり、[[リアルタイムレンダリング]]が求められる[[ポリゴン]]を使った初期の[[ゲーム]]でよく用いられた。現在では[[ハードウェアT&L]]や[[プログラマブルシェーダー]]の登場でほぼ見かけることはなくなった。 |
| | | |
− | ==GLSL==
| + | == 関連項目 == |
− | [[GLSL]]では[[バーテックスシェーダー]]の出力変数に「flat修飾子」を付けるとフラットシェーディングとなる。
| + | * [[シェーダー]] |
− | <syntaxhighlight lang="glsl">
| + | * [[フラットシェーディング]] |
− | // 入力
| + | * [[グローシェーディング]] |
− | layout (location = 0) in vec3 VertexPosition;
| + | * [[フォンシェーディング]] |
− | layout (location = 1) in vec3 VertexNormal;
| + | * [[フォン反射モデル]] |
− | | + | * [[ブリン・フォン反射モデル]] |
− | // 出力(これ)
| |
− | flat out vec3 Intensity;
| |
− | | |
− | // バーテックスシェーダー
| |
− | void main()
| |
− | {
| |
− | // 出力変数に「flat out」と書かれていると、ここが頂点1個分しか呼ばれない
| |
− | }
| |
− | </syntaxhighlight>
| |
− | | |
− | [[バーテックスシェーダー]]の出力値を格納する変数にflat修飾子をつけると、その[[バーテックスシェーダー]]では[[ポリゴン]]を構成する3つの[[頂点]]のいずれか1つだけが計算され、その値が[[フラグメントシェーダー]]に渡ってくる。前述の概要で「[[法線]]を面単位で持つ」と書いたが、GLSLでは「ポリゴンを構成する[[頂点]]の[[法線]]のいずれか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>
| |
− | | |
− | ==関連項目== | |
− | | |
− | *[[シェーダー]] | |
− | *[[フラットシェーディング]] | |
− | *[[グローシェーディング]] | |
− | *[[フォンシェーディング]] | |
− | *[[フォン反射モデル]] | |
− | *[[ブリン・フォン反射モデル]] | |
| | | |
| [[category: 3DCG]] | | [[category: 3DCG]] |