「図々しいですがキューブマップなどの環境マップ系なども教えていただけたらな〜と思っています。」
…というリクエストがあったので、今回はキューブマップを使った反射エフェクトです。
なんか、作った結果がかな〜りあやしいですが…一応、公開しておきます。






00104: ///--------------------------------------------------------------
00105: /// <summary>
00106: /// キューブマップの各面に描画を行う
00107: /// </summary>
00108: ///--------------------------------------------------------------
00109: public void DrawToTexture()
00110: {
00111: Vector3 target = Vector3.Zero;
00112:
00113: //各面に対して処理
00114: for (int index = 0; index < NumFaces; index++)
00115: {
00116: CubeMapFace cubeMapface = (CubeMapFace)index;
00117: switch (cubeMapface)
00118: {
00119: case CubeMapFace.PositiveX:
00120: {
00121: target = mPosition + Vector3.UnitX;
00122: mView = Matrix.CreateLookAt(mPosition, target, Vector3.Up);
00123: }
00124: break;
00125:
00126: case CubeMapFace.NegativeX:
00127: {
00128: target = mPosition - Vector3.UnitX;
00129: mView = Matrix.CreateLookAt(mPosition, target, Vector3.Up);
00130: }
00131: break;
00132:
00133: case CubeMapFace.PositiveY:
00134: {
00135: target = mPosition + Vector3.UnitY;
00136: mView = Matrix.CreateLookAt(mPosition, target, -Vector3.UnitZ);
00137: }
00138: break;
00139:
00140: case CubeMapFace.NegativeY:
00141: {
00142: target = mPosition - Vector3.UnitY;
00143: mView = Matrix.CreateLookAt(mPosition, target, Vector3.UnitZ);
00144: }
00145: break;
00146:
00147: case CubeMapFace.PositiveZ:
00148: {
00149: target = mPosition + Vector3.UnitZ;
00150: mView = Matrix.CreateLookAt(mPosition, target, Vector3.Up);
00151: }
00152: break;
00153:
00154: case CubeMapFace.NegativeZ:
00155: {
00156: target = mPosition - Vector3.UnitZ;
00157: mView = Matrix.CreateLookAt(mPosition, target, Vector3.Up);
00158: }
00159: break;
00160:
00161: default:
00162: {
00163: /* defaultは通らないが念のため /*
00164: mView = Matrix.CreateLookAt(mPosition, Vector3.Zero, Vector3.Up);
00165: }
00166: break;
00167: }
00168:
00169: //描画する面をレンダーターゲットに指定
00170: mDevice.SetRenderTarget(0, mRenderTarget, cubeMapface);
00171:
00172: //バッファをクリア
00173: mDevice.Clear(Color.White);
00174:
00175: //描画メソッドを呼び出し
00176: mDrawBackGroundMethod();
00177:
00178: //レンダーターゲットをもとに戻す
00179: mDevice.SetRenderTarget(0, null);
00180: }
00181:
00182: //テクスチャを取得し,格納
00183: mCubeMap = mRenderTarget.GetTexture();
00184: }
上記コードで、動的にキューブマップが作成できます。
00063: //----------------------------------------------------------------------
00064: // Name : VertexShaderFunction()
00065: // Desc : 頂点シェーダ.
00066: //----------------------------------------------------------------------
00067: VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
00068: {
00069: VertexShaderOutput output = (VertexShaderOutput)0;
00070:
00071: float4 worldPosition = mul(input.Position, World);
00072: float4 viewPosition = mul(worldPosition, View);
00073: output.Position = mul(viewPosition, Projection);
00074:
00075: // TODO: add your vertex shader code here.
00076: float3 worldNormal = mul(input.Normal, World);
00077: float3 viewNormal = mul(worldNormal, View);
00078:
00079: output.Reflection = reflect( normalize(viewPosition), normalize(viewNormal) );
00080: output.Normal = mul( input.Normal, World );
00081: output.Light = LightPosition.xyz - worldPosition.xyz;
00082:
00083: return output;
00084: }
00085:
00086: //----------------------------------------------------------------------
00087: // Name : PixelShaderFunction()
00088: // Desc : ピクセルシェーダ.
00089: //----------------------------------------------------------------------
00090: float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
00091: {
00092: // TODO: add your pixel shader code here.
00093: float4 texcolor = texCUBE(EnvSmp, input.Reflection);
00094:
00095: float3 L = normalize(input.Light);
00096: float3 N = normalize(input.Normal);
00097: float3 diffuse = ModelDiffuseColor * (max( dot(N, L), 0.0f) * 0.5f + 0.5f);
00098: float4 result = float4( lerp(diffuse, texcolor, Reflective), 1.0f );
00099:
00100: return result;
00101: }
頂点シェーダでやってるのは、反射ベクトルを求めてピクセルシェーダ側に送っている処理です。あとは、Halfランバート用に法線やらライトやらのベクトルを構造体に格納しているだけです。