グローの適用

グローの適用

この例では、2 つのテクニックを使用している。1 番目のテクニックは GlowOnly といい、オブジェクトにグローを適用する。GlowOnly は、Unskinned 関数を使ってライトを計算し、テクスチャ座標をコピーする。さらに Unskinned 関数は、ヘルパー関数 TransformUnskinned を使って、位置座標および法線データをトランスフォームする。

2 番目のテクニックは GlowAndNormal といい、2 つのパスから構成される。第 1 パスでオブジェクトを通常どおり描画し、第 2 パスでアウトラインを描画する。

この例は、上位レベル言語のサンプルを表し、次に示す例ではコンパイルは行わない。

// effect.fx                                                                                    
texture tex0 < string name = "tiger.bmp"; >;

texture tex1 < string name = "banana.bmp"; >;

string XFile = "tiger.x";   // Model to load
string BIMG  = "lake.bmp";  // Background image
DWORD  BCLR = 0xff202080;   // Background color (if no image)

// Declare the required matrices with the appropriate semantics
//   so that the viewer can supply the necessary matrix information.
float4x4 mProjection :PROJECTION;
float4x3 mWorldView  :WORLDVIEW; 
float4x4 mViewProjection :VIEWPROJECTION;

// Declare data used by the shaders that the application can modify.
float3 vLightDirection = {0.0, 0.0, -1.0 };
float  vDisplace       =  0.015;
float4 vGlowColor      = { 0.5, 0.2, 0.2, 1.0 };
float4 vGlowAmbient    = { 0.2, 0.2, 0.0, 0.0 };


// Set up an output structure defining the output to the pixel shader. 
struct VS_OUTPUT_TEXCOORD0
{
float4 Position :POSITION;
float4 Diffuse  :COLOR;
float2 Texture0 :TEXCOORD0;
};

// Helper function to transform position/normal into view space
void TransformUnskinned
    (
float4 vPos, 
float3 vNormal, 
float3 vTransformedPosition, 
float3 vTransformedNormal
    )
{
// Transform the position into view space
vTransformedPosition = mul(vPos, mWorldView);
    
// Transform the normal into view space (just use the upper 3x3 of WorldView)
vTransformedNormal = mul(vNormal, (float3x3)mWorldView);
 }

// Draws unskinned object with one texture and one directional light.
VS_OUTPUT_TEXCOORD0 Unskinned
    (
float4 vPos :POSITION, 
float3 vNormal :NORMAL,
float2 vTexCoord0 :TEXCOORD0
    )
{
float3 vTransformedPosition = {0,0,0};
float3 vTransformedNormal   = {0,0,0};
VS_OUTPUT_TEXCOORD0 Output;
float fDot;
  
// Transform the position/normal into view space.
TransformUnskinned(vPos, vNormal, vTransformedPosition, vTransformedNormal);  
    
// Calculate amount of light from the one light direction.
fDot = dot(vTransformedNormal, vLightDirection);
    
// Transform view space position into screen space.
Output.Position = mul(float4(vTransformedPosition, 1.0), mProjection);
    
// Multiple amount of light times light color. 
// Note:Color could be negative with this equation, but will be 
//   clamped to zero before pixel shader.
Output.Diffuse = float4(1.0f, 1.0f, 1.0f, 1.0f) * fDot;
    
// Just copy the texture coordinate through.
Output.Texture0 = vTexCoord0;
    
return Output;    
}


// Declare the output of the GlowSkinned vertex shader to the pixel shader.
struct VS_OUTPUT
{
float4 Position :POSITION;
float4 Diffuse  :COLOR;
};


// Draws a transparent hull of the unskinned object.
VS_OUTPUT GlowUnskinned
    (
float4 vPos :POSITION, 
float3 vNormal :NORMAL
    )
{
float3 vTransformedPosition = {0,0,0};
float3 vTransformedNormal   = {0,0,0};
VS_OUTPUT Output;
float fPower;

// For standard "glow" this is the view direction.
float3 vGlowAxis = float3(0, 0, 1);
    
// Transform the position and normal into world space.
TransformUnskinned(vPos, vNormal, vTransformedPosition, vTransformedNormal);  
    
// Displace the position by the normal, so that the glow will not 
	//   overlap the non-glowed version.
vTransformedPosition += vTransformedNormal * vDisplace;
    
// The glow is determined by the angle between the normal and the glow axis.
//   This ends up being similar to a fresnel approximation.
fPower = dot(vTransformedNormal, vGlowAxis);
fPower = 1.0f - fPower * fPower;
fPower *= fPower;
    
// Transform position into screen space from view space.
Output.Position = mul(float4(vTransformedPosition, 1.0), mProjection);
    
// Output color is the compute power times the glow color.
Output.Diffuse = vGlowColor * fPower + vGlowAmbient;
    
return Output;    
}


// first technique - unskinned
// first pass draw the object normally
// second pass draw the outline
technique GlowOnly
{
pass P1
    {   
// Generate a 1_1 vertex shader to draw the outline of the object.
VertexShader = compile vs_1_1 GlowUnskinned();
        
Texture[0]   = NULL;

// Enable alpha blending
AlphaBlendEnable = True;
SrcBlend     = One;
DestBlend    = One;

// Set up TSS stages to just use the diffuse color.
ColorOp[0]   = SelectArg2;
ColorArg2[0] = Diffuse;
AlphaOp[0]   = SelectArg2;
AlphaArg2[0] = Diffuse;
ColorOp[1]   = Disable;
AlphaOp[1]   = Disable;
   }
}


// First technique - unskinned
// First pass draw the object normally
// Second pass draw the outline
technique GlowAndNormal
{
pass P0
    {   
// Generate a 1_1 vertex shader for unskinned 
//   single texture/one directional light.
VertexShader = compile vs_1_1 Unskinned();
        
// Set up texture stage info for single texture. 
ColorOp[0]   = Modulate;
ColorArg1[0] = Texture;
ColorArg2[0] = Current;
AlphaOp[0]   = Disable;

// Set texture filtering.
MinFilter[0] = Linear;
MagFilter[0] = Linear;
MipFilter[0] = Point;

// Set texture into stage 0.
Texture[0]   = (tex0);

// Disable Stage1.   
ColorOp[1]   = Disable;
AlphaOp[1]   = Disable;
        
    }
pass P1
    {   
// Generate a 1_1 vertex shader to draw the outline of the object.
VertexShader = compile vs_1_1 GlowUnskinned();
        
Texture[0]   = NULL;

// Enable alpha blending.
AlphaBlendEnable = True;
SrcBlend     = One;
DestBlend    = One;

// Set up TSS stages to just use the diffuse color.
ColorOp[0]   = SelectArg2;
ColorArg2[0] = Diffuse;
AlphaOp[0]   = SelectArg2;
AlphaArg2[0] = Diffuse;
ColorOp[1]   = Disable;
AlphaOp[1]   = Disable;
   }
}