I am running to a problem where I have a WPF shader effect (modified from Rene Schulte) to simulate Dot Matrix Display (DMD). Everything works great, but all dots are aliased.
我正在运行一个问题,我有一个WPF着色效果(从Rene Schulte修改)模拟点矩阵显示(DMD)。一切都很好,但所有的点都是假的。
See attached image.
请看附呈的形象。
I tried many features within WPF, to bring antialiasing, nothing to do.
我尝试了WPF中的许多特性,以带来抗锯齿,没有什么可做的。
in constructor (image within a textbox);
在构造函数中(文本框中的图像);
RenderOptions.SetBitmapScalingMode(MarqueeTB, BitmapScalingMode.HighQuality);
RenderOptions.SetEdgeMode(MarqueeTB, EdgeMode.Unspecified);
RenderOptions.SetClearTypeHint(MarqueeTB, ClearTypeHint.Enabled);
I don't think it is my graphic card or Windows config. I did some testing on two PCs, same results; Windows 8.1 and Windows 7.
我不认为这是我的图形卡或Windows配置。我在两台pc上做了一些测试,结果是一样的;Windows 8.1和Windows 7。
I have no clue how to proceed. Any help or advises would be welcome.
我不知道该怎么做。欢迎任何帮助或建议。
Thanks in advance, regards, Shader code:
感谢您的支持,祝福,着色代码:
// Project: Shaders
//
// Description: Mosaic Shader for Coding4Fun.
//
// Changed by: $Author$
// Changed on: $Date$
// Changed in: $Revision$
// Project: $URL$
// Id: $Id$
//
//
// Copyright (c) 2010 Rene Schulte
//
/// <description>Mosaic Shader for Coding4Fun.</description>
/// <summary>The number pixel blocks.</summary>
/// <type>Single</type>
/// <minValue>2</minValue>
/// <maxValue>500</maxValue>
/// <defaultValue>50</defaultValue>
float BlockCount : register(C0);
/// <summary>The rounding of a pixel block.</summary>
/// <type>Single</type>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0.45</defaultValue>
float Max : register(C2);
/// <summary>The aspect ratio of the image.</summary>
/// <type>Single</type>
/// <minValue>0</minValue>
/// <maxValue>10</maxValue>
/// <defaultValue>1</defaultValue>
float AspectRatio : register(C3);
// Sampler
sampler2D input : register(S0);
// Static computed vars for optimization
static float2 BlockCount2 = float2(BlockCount, BlockCount / AspectRatio);
static float2 BlockSize2 = 1.0f / BlockCount2;
// Shader
float4 main(float2 uv : TEXCOORD) : COLOR
{
// Calculate block center
float2 blockPos = floor(uv * BlockCount2);
float2 blockCenter = blockPos * BlockSize2 + BlockSize2 * 0.5;
// Scale coordinates back to original ratio for rounding
float2 uvScaled = float2(uv.x * AspectRatio, uv.y);
float2 blockCenterScaled = float2(blockCenter.x * AspectRatio, blockCenter.y);
// Round the block by testing the distance of the pixel coordinate to the center
float dist = length(uvScaled - blockCenterScaled) * BlockCount2;
if(dist < 0 || dist > Max)
{
return 1;
}
// Sample color at the calculated coordinate
return tex2D(input, blockCenter);
}
2 个解决方案
#1
0
Is it layout rounding? Try MarqueeTB.UseLayoutRounding = false;
布局舍入吗?MarqueeTB试试。UseLayoutRounding = false;
#2
0
Here is a solution & the corrected code accordingly. I am not sure if this is 'the best' way, but it worked. (see antialiasedCircle section, solution from: http://gamedev.stackexchange.com/questions/34582/how-do-i-use-screen-space-derivatives-to-antialias-a-parametric-shape-in-a-pixel )
这里有一个解决方案和相应的修正代码。我不确定这是否是“最好的”方法,但它确实奏效了。(参见antialiasedCircle一节,解决方案:http://gamedev.stackexchange.com/questions/34582/how-do-i-use-screen- screen-space派生到antialias-a- parameter - shapmly)
//
// Project: Dot Matrix Display (DMD) Shader
// Inspired from From Mosaic shader Copyright (c) 2010 Rene Schulte
/// <summary>The number pixel blocks.</summary>
/// <type>Single</type>
/// <minValue>2</minValue>
/// <maxValue>500</maxValue>
/// <defaultValue>34</defaultValue>
float BlockCount : register(C0);
/// <summary>The rounding of a pixel block.</summary>
/// <type>Single</type>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0.45</defaultValue>
float Max : register(C2);
/// <summary>The aspect ratio of the image.</summary>
/// <type>Single</type>
/// <minValue>0</minValue>
/// <maxValue>10</maxValue>
/// <defaultValue>1.55</defaultValue>
float AspectRatio : register(C3);
/// <summary>The monochrome color used to tint the input.</summary>
/// <defaultValue>Yellow</defaultValue>
float4 FilterColor : register(C1);
/// <summary>monochrome.</summary>
/// <defaultValue>1</defaultValue>
float IsMonochrome : register(C4);
// Sampler
sampler2D input : register(S0);
// Static computed vars for optimization
static float2 BlockCount2 = float2(BlockCount, BlockCount / AspectRatio);
static float2 BlockSize2 = 1.0f / BlockCount2;
float4 setMonochrome(float4 color) : COLOR
{
float4 monochrome= color;
if(((int)IsMonochrome) == 1)
{
float3 rgb = color.rgb;
float3 luminance = dot(rgb, float3(0.30, 0.59, 0.11));
monochrome= float4(luminance * FilterColor.rgb, color.a);
}
return monochrome;
}
float4 SetDMD(float2 uv : TEXCOORD, sampler2D samp) : COLOR
{
// Calculate block center
float2 blockPos = floor(uv * BlockCount2);
float2 blockCenter = blockPos * BlockSize2 + BlockSize2 * 0.5;
// Scale coordinates back to original ratio for rounding
float2 uvScaled = float2(uv.x * AspectRatio, uv.y);
float2 blockCenterScaled = float2(blockCenter.x * AspectRatio, blockCenter.y);
// Round the block by testing the distance of the pixel coordinate to the center
float dist = length(uvScaled - blockCenterScaled) * BlockCount2;
float4 insideColor= tex2D(samp, blockCenter);
float4 outsideColor = insideColor;
outsideColor.r = 0;
outsideColor.g = 0;
outsideColor.b = 0;
outsideColor.a = 1;
float distFromEdge = Max - dist; // positive when inside the circle
float thresholdWidth = .22; // a constant you'd tune to get the right level of softness
float antialiasedCircle = saturate((distFromEdge / thresholdWidth) + 0.5);
return lerp(outsideColor, insideColor, antialiasedCircle);
}
// Shader
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 DMD= SetDMD(uv, input);
DMD = setMonochrome(DMD);
return DMD;
}
Here is an image of the successful solution;
这是一个成功的解决方案;
#1
0
Is it layout rounding? Try MarqueeTB.UseLayoutRounding = false;
布局舍入吗?MarqueeTB试试。UseLayoutRounding = false;
#2
0
Here is a solution & the corrected code accordingly. I am not sure if this is 'the best' way, but it worked. (see antialiasedCircle section, solution from: http://gamedev.stackexchange.com/questions/34582/how-do-i-use-screen-space-derivatives-to-antialias-a-parametric-shape-in-a-pixel )
这里有一个解决方案和相应的修正代码。我不确定这是否是“最好的”方法,但它确实奏效了。(参见antialiasedCircle一节,解决方案:http://gamedev.stackexchange.com/questions/34582/how-do-i-use-screen- screen-space派生到antialias-a- parameter - shapmly)
//
// Project: Dot Matrix Display (DMD) Shader
// Inspired from From Mosaic shader Copyright (c) 2010 Rene Schulte
/// <summary>The number pixel blocks.</summary>
/// <type>Single</type>
/// <minValue>2</minValue>
/// <maxValue>500</maxValue>
/// <defaultValue>34</defaultValue>
float BlockCount : register(C0);
/// <summary>The rounding of a pixel block.</summary>
/// <type>Single</type>
/// <minValue>0</minValue>
/// <maxValue>1</maxValue>
/// <defaultValue>0.45</defaultValue>
float Max : register(C2);
/// <summary>The aspect ratio of the image.</summary>
/// <type>Single</type>
/// <minValue>0</minValue>
/// <maxValue>10</maxValue>
/// <defaultValue>1.55</defaultValue>
float AspectRatio : register(C3);
/// <summary>The monochrome color used to tint the input.</summary>
/// <defaultValue>Yellow</defaultValue>
float4 FilterColor : register(C1);
/// <summary>monochrome.</summary>
/// <defaultValue>1</defaultValue>
float IsMonochrome : register(C4);
// Sampler
sampler2D input : register(S0);
// Static computed vars for optimization
static float2 BlockCount2 = float2(BlockCount, BlockCount / AspectRatio);
static float2 BlockSize2 = 1.0f / BlockCount2;
float4 setMonochrome(float4 color) : COLOR
{
float4 monochrome= color;
if(((int)IsMonochrome) == 1)
{
float3 rgb = color.rgb;
float3 luminance = dot(rgb, float3(0.30, 0.59, 0.11));
monochrome= float4(luminance * FilterColor.rgb, color.a);
}
return monochrome;
}
float4 SetDMD(float2 uv : TEXCOORD, sampler2D samp) : COLOR
{
// Calculate block center
float2 blockPos = floor(uv * BlockCount2);
float2 blockCenter = blockPos * BlockSize2 + BlockSize2 * 0.5;
// Scale coordinates back to original ratio for rounding
float2 uvScaled = float2(uv.x * AspectRatio, uv.y);
float2 blockCenterScaled = float2(blockCenter.x * AspectRatio, blockCenter.y);
// Round the block by testing the distance of the pixel coordinate to the center
float dist = length(uvScaled - blockCenterScaled) * BlockCount2;
float4 insideColor= tex2D(samp, blockCenter);
float4 outsideColor = insideColor;
outsideColor.r = 0;
outsideColor.g = 0;
outsideColor.b = 0;
outsideColor.a = 1;
float distFromEdge = Max - dist; // positive when inside the circle
float thresholdWidth = .22; // a constant you'd tune to get the right level of softness
float antialiasedCircle = saturate((distFromEdge / thresholdWidth) + 0.5);
return lerp(outsideColor, insideColor, antialiasedCircle);
}
// Shader
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 DMD= SetDMD(uv, input);
DMD = setMonochrome(DMD);
return DMD;
}
Here is an image of the successful solution;
这是一个成功的解决方案;