2009-10-27 5 views
0

내 애플리케이션에서 불투명 마스크를 이미지에 적용 할 수 있도록 WPF WriteableBitmap 클래스를 사용하려고합니다.WPF WriteableBitmap 및 effects

기본적으로 나는 파란색 직사각형을 이미지로, 또 다른 100 % 투명한 녹색 직사각형 이미지를 파란색 위쪽에 표시합니다.

사용자가 녹색 (투명) 이미지 위에서 마우스를 움직이면 불투명 마스크 (간단한 타원을 사용)를 적용하여 녹색 광선이 발생하는 것처럼 보입니다.

은 임 의도적으로

어떤 생각 ... 정말 슈퍼 확대됨 할 필요 나는 결국 더 사전 덩어리로 타원을 교환하기 때문에이 XAML 및 표준 WPF 효과이다하고 있지?

감사합니다.

답변

2

죄송합니다. 귀하의 의도를 이해하지 못합니다. 어쩌면 내가 이미지를 볼 수 있을지 모르겠지만, 처음부터 정확하게 대답 할 수 있었지만, 여기에 내 첫 번째 어쩌면 틀린 대답이 있습니다.

슈퍼 퍼포먼스를 말하는 경우 픽셀 쉐이더를보고 싶을 것입니다. 그들은 G PU로 처리되며 사용자 지정 효과 형식으로 WPF에서 지원되며 구현하기 쉽습니다. 또한 WritableBitmap으로하기는 어렵지만 동영상 재생에 쉐이더를 적용 할 수 있습니다.

픽셀 쉐이더를 작성하려면 DirectX SDKShazzam tool의 FX 컴파일러 (fxc.exe) - Walt Ritscher의 WYSIWYG WPF 쉐이더 컴파일러가 필요합니다. 당신이 그 (것)들에게 모두를 얻을 때

, 가서 다음 HLSL 코드

float X : register(C0); // Mouse cursor X position 
float Y : register(C1); // Mouse cursor Y position 
float4 Color : register(C2); // Mask color 
float R : register(C3); // Sensitive circle radius. 

sampler2D implicitInputSampler : register(S0); 


float4 main(float2 uv : TEXCOORD) : COLOR 
{ 
    float4 finalColor = tex2D(implicitInputSampler, uv); 
    if ((uv.x - X) * (uv.x - X) + (uv.y - Y) * (uv.y - Y) < R*R) 
    { 
     finalColor = Color; // Blend/Change/Mask it as you wish here. 
    } 
    return finalColor; 
} 

이는 당신에게 다음 C# 효과를 제공하려고 :

namespace Shazzam.Shaders { 
    using System.Windows; 
    using System.Windows.Media; 
    using System.Windows.Media.Effects; 


    public class AutoGenShaderEffect : ShaderEffect { 

     public static DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(AutoGenShaderEffect), 0); 

     public static DependencyProperty XProperty = DependencyProperty.Register("X", typeof(double), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new double(), PixelShaderConstantCallback(0))); 

     public static DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(double), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new double(), PixelShaderConstantCallback(1))); 

     public static DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(System.Windows.Media.Color), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new System.Windows.Media.Color(), PixelShaderConstantCallback(2))); 

     public static DependencyProperty RProperty = DependencyProperty.Register("R", typeof(double), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new double(), PixelShaderConstantCallback(3))); 

     public AutoGenShaderEffect(PixelShader shader) { 
      // Note: for your project you must decide how to use the generated ShaderEffect class (Choose A or B below). 
      // A: Comment out the following line if you are not passing in the shader and remove the shader parameter from the constructor 

      PixelShader = shader; 

      // B: Uncomment the following two lines - which load the *.ps file 
      // Uri u = new Uri(@"pack://application:,,,/glow.ps"); 
      // PixelShader = new PixelShader() { UriSource = u }; 

      // Must initialize each DependencyProperty that's affliated with a shader register 
      // Ensures the shader initializes to the proper default value. 
      this.UpdateShaderValue(InputProperty); 
      this.UpdateShaderValue(XProperty); 
      this.UpdateShaderValue(YProperty); 
      this.UpdateShaderValue(ColorProperty); 
      this.UpdateShaderValue(RProperty); 
     } 

     public virtual System.Windows.Media.Brush Input { 
      get { 
       return ((System.Windows.Media.Brush)(GetValue(InputProperty))); 
      } 
      set { 
       SetValue(InputProperty, value); 
      } 
     } 

     public virtual double X { 
      get { 
       return ((double)(GetValue(XProperty))); 
      } 
      set { 
       SetValue(XProperty, value); 
      } 
     } 

     public virtual double Y { 
      get { 
       return ((double)(GetValue(YProperty))); 
      } 
      set { 
       SetValue(YProperty, value); 
      } 
     } 

     public virtual System.Windows.Media.Color Color { 
      get { 
       return ((System.Windows.Media.Color)(GetValue(ColorProperty))); 
      } 
      set { 
       SetValue(ColorProperty, value); 
      } 
     } 

     public virtual double R { 
      get { 
       return ((double)(GetValue(RProperty))); 
      } 
      set { 
       SetValue(RProperty, value); 
      } 
     } 
    } 
} 

는 이제 마우스 위치를 추적하고, 해당 설정할 수 있습니다 효과를 트리거하여 변경 사항을 트리거합니다. 한가지주의해야 할 점은 HLSL 코드에서 X와 Y의 범위는 0에서 1까지입니다. 따라서 실제 좌표를 셰이더로 전달하기 전에 실제 좌표를 백분율로 변환해야합니다.

상황이 픽셀 쉐이더와 WPF에 대한 자세한 내용을 읽을 수 있습니다 : MSDN에

희망이 :) 도움이

+0

이봐 감사 Anvaka, 좋은 대답을 먹으 렴! 아프다. 조금만 더 읽으면된다.하지만 마음이 편치 않다면, 문제의 다음 부분으로 넘어 간다. 마우스 뒤에서 빛을 내고 싶은 효과가 있긴하지만이 광선은 내 배경 이미지 앞에있는 이미지의 불투명 마스크 (마우스를 움직일 때 노출되는 고정 된 텍스처와 같음)처럼 보이게하고 싶습니다. 픽셀 쉐이더를 사용하여이 작업을 수행 할 수 있습니까? – Mark

+0

물론 가능합니다. HLSL 코드에서 원하는대로 색상의 알파 채널을 수정할 수 있습니다. finalColor.a = 0.75로 설정하는 것만 큼 쉽습니다. 알파에 75 %를 설정합니다. – Anvaka

+0

굉장해! 도움을 주셔서 감사합니다, 이것은 매우 흥미 롭습니다! – Mark