DirectX Graphics 프로그래밍 가이드 고도의 주제 이펙트 상위 레벨 언어에 의한 이펙트 그로의 적용 [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
이 예에서는, 2 개의 테크닉을 사용하고 있다. 1 번째의 테크닉은 GlowOnly 라고 해, 개체에 그로를 적용한다. GlowOnly 는, Unskinned 함수를 사용해 라이트를 계산해, 텍스처 좌표를 복사 한다. 한층 더 Unskinned 함수는, 헬퍼-함수 TransformUnskinned 를 사용해, 위치 좌표 및 법선 데이터를 변환 한다.
2 번째의 테크닉은 GlowAndNormal 라고 해, 2 살의 패스로부터 구성된다. 제 1 패스로 개체를 보통 대로 드로잉(Drawing) 해, 제 2 패스로 아우트라인을 드로잉(Drawing) 한다.
이 예는, 상위 레벨 언어의 샘플을 나타내, 다음에 나타내는 예에서는 컴파일은 실시하지 않는다.
// 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; } }