Error when writing a very simple HLSL pixel shader
我正在编写SlimDX应用程序来测试人类视觉系统的颜色对比度灵敏度阈值。向对象显示与背景对比度较低的大字母,并要求识别该字母。但是我需要能够显示更多颜色,然后每个通道的颜色深度只需8位即可。 (即rgb值0-255)。我打算这样做的方法是通过实现为HLSL像素着色器的简单"抖动"算法。基本上,如果要求slimDX将文本渲染到Color4(0.55f,0.55f,0.55f)颜色的表面上,该颜色对应于rgb值(140.25,140.25,140.25),我希望每个像素的每个颜色通道都具有被设置为141的机会为25%,被设置为140的机会为75%。这应该(在许多像素的范围内)导致字母以灰色??阴影的形式出现-在140到141之间。
但是,在尝试使用fxc进行编译时,我的原型着色器代码中出现错误。我在编译时收到非法字符代码,不知道为什么。另外,如果您是HLSL专家,请查看我的代码并提出任何让您印象深刻的注释。注意我从这个问题的答案中得到了HLSL随机函数。
我可以在像素着色器中生成随机数吗?
下面是我的着色器代码。如果我的第一个HLSL代码有很多错误,请原谅我:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | float4 DitherByChance(float2 coords : TEXCOORD0) : COLOR0 { float4 newColor; // The pixel color to return float4 oldColor = tex2D(s0, coords); // Note I know that as the code stands now rCutOff = gCutOff = bCutOff I will sort a fix for this out later float rCutOff = random(coords); // A random float that determines if the red channel will be rounded up or down float gCutOff = random(coords); // A random float that determines if the green channel will be rounded up or down float bCutOff = random(coords); // A random float that determines if the blue channel will be rounded up or down float rPercentChance = frac(oldColor.r * 255); //Chance to round red channel up float gPercentChance = frac(oldColor.g * 255); //Chance to round green channel up float bPercentChance = frac(oldColor.b * 255); //Chance to round blue channel up //In the code below (1/255) is the floating point represntaion of an incress of one on the 0-255 RGB scale if (rCutOff <= rPercentChance) newColor.r = oldColor.r + ((1 - rPercentChance) / 255); //Bump up one r value else newColor.r = oldColor.r - rPercentChance * (1 / 255); //Bump down to ensure r is not rounded up if (gCutOff <= gPercentChance) newColor.g = oldColor.g + ((1 - gPercentChance) / 255); //Bump up one g value else newColor.b = oldColor.b - bPercentChance * (1 / 255); //Bump down to ensure g is not rounded up if (bCutOff <= bPercentChance) newColor.b = oldColor.b + ((1 - bPercentChance) / 255); //Bump up one b value else newColor.b = oldColor.b - bPercentChance * (1 / 255); //Bump down to ensure b is not rounded up return newColor; } // Input: It uses texture coords as the random number seed. // Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive. // Author: Michael Pohoreski // Copyright: Copyleft 2012 :-) float random( vec2 p ) { // We need irrationals for pseudo randomness. // Most (all?) known transcendental numbers will (generally) work. const vec2 r = vec2( 23.1406926327792690, // e^pi (Gelfond's constant) 2.6651441426902251); // 2^sqrt(2) (Gelfond–Schneider constant) return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) ); } |
编辑:
在下面的答案的帮助下,我已经更接近解决方案了,但是仍然存在一些问题。我采纳了catflier的评论,即我借用的随机函数是用GLSL而不是HLSL编写的。我必须将vec2更改为float2,然后将random函数放在顶部。除此之外,我还必须编写一个mod函数,因为GLSL mod()!= HLSL fmod。并将GLSL fract()更改为HLSL frac()。我的文本文件使用UTF-8编码时也遇到了问题,我认为这会导致fxc出现问题。重新编码为ANSI后,我得到了一些更好的错误消息。但是我仍然有一些问题。
我尝试使用
此行
中的
我不确定这个s0参数到底是什么,我只是在另一个着色器示例中看到了。我看到了另一个示例,其中有人声明了Global sampler2D变量并使用了该变量而不是s0,所以我尝试了以下操作:
1 2 3 4 5 | sampler2D Tex0; ... .... ..... float4 oldColor = tex2D(Tex0, coords); |
但是现在当我运行
有什么想法吗?
首先,由于vec2是glsl语法,因此您需要在随机函数中将vec2替换为float2。
然后将随机函数放置在PixelShader(c样式)上方。
您的着色器现在应该可以编译,如果没有,请发布错误消息。
从最新的位开始编辑:
1 | sampler2D Tex0; |
这是一个采样器单元,您需要将其绑定到纹理,因为采样器会告诉您如何对其进行过滤(线性/点)并对其进行寻址(环绕/钳位...)
http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb509644(v = vs.85).aspx
由于您编译了像素着色器,因此您需要使用fxc / T ps_3_0,因为您将其编译为像素着色器,而不是顶点着色器。