我一直在敲Shadertoy - https://www.shadertoy.com/ - 最近,为了更多地了解OpenGL和GLSL.
据我所知,到目前为止,OpenGL用户首先必须准备要使用的所有几何体并配置OpenGL服务器(允许的光源数量,纹理存储等).一旦完成,用户就必须在OpenGL程序编译之前提供至少一个顶点着色器程序和一个片段着色器程序.
但是,当我查看Shadertoy上的代码示例时,我只看到一个着色器程序,并且大多数使用的几何图形似乎直接写入GLSL代码.
这是如何运作的?
我猜测顶点着色器已经预先准备好了,可编辑/样本着色器只是一个片段着色器.但是,这并没有解释一些更复杂的例子中的几何...
谁能解释Shadertoy是如何工作的?
我有传递顶点和片段着色器.
顶点着色器
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器
void main(void)
{
gl_FragColor = gl_Color;
}
Run Code Online (Sandbox Code Playgroud)
那些产生空渲染(黑色不是像glClearBuffer那样的背景颜色).
如果我修改顶点着色器以将gl_FrontColor设置为gl_Color,它会渲染未触及的OpenGl缓冲区...具有传递着色器的预期行为.
void main(void)
{
gl_FrontColor = gl_Color; //Added line
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Run Code Online (Sandbox Code Playgroud)
我很困惑,如何设置顶点着色器中的gl_FrontColor可以更改片段1中gl_Color的值?我错过了什么?
所以我用XNA 3.1做了一件事,我有很多通过像素着色器应用的单独效果.它们来自各种来源,例如特殊攻击,环境等.我遇到的问题是我注意到帧速率的显着降低.
目前,我正在将整个场景绘制到RenderTarget2D,然后我将所有效果应用到.我存储了一个包含效果及其ID的SortedDictionary(这些ID用于在运行时更改参数),我正在迭代它并逐个应用每个效果:
foreach(KeyValuePair<Ref<int>,Effect> p in renderEffects)
{
Effect r = p.Value;
g.SetRenderTarget(0, MainGame.MainRenderTarget);
//Change RenderTarget to allow code to grab existing texture in the same draw area.
levelDraw = MainGame.LevelRenderTarget.GetTexture();
//Change back to draw back to this texture, allowing render effects to be layered.
g.SetRenderTarget(0, MainGame.LevelRenderTarget);
MainGame.StartDraw(MainGame.GameBatch);
//Starts the sprite batch and sets some parameters
r.Begin();
r.CurrentTechnique.Passes[0].Begin();
MainGame.GameBatch.Draw(levelDraw, new Rectangle(0, 0, levelDraw.Width, levelDraw.Height), Color.White);
r.CurrentTechnique.Passes[0].End();
r.End();
MainGame.GameBatch.End();
}
Run Code Online (Sandbox Code Playgroud)
现在,当仅分层3个效果时,这会产生明显的帧丢失,当应用10时,它会从60FPS下降到16FPS,这当然是不可接受的.我想知道是否有更有效的方法来做到这一点.考虑到我只有一个纹理,我认为我可以将效果组合到一个文件中并执行多次传递而不会重新获取纹理.但是,我不确定这是否可行.
我不确定最好的方法是如何做到这一点,尽管我认为必须有一种比我正在做的更好的方式.
我知道Floyd-Steinberg抖动算法不能用像素着色器实现,因为该算法是严格顺序的.但也许存在一些高度并行的抖动算法,它的视觉输出类似于Floyd-Steinberg算法?
所以问题是 - 什么是抖动算法适合在像素着色器(最好是GLSL)上实现,输出质量(非常)类似于Floyd-Steinberg抖动?
BTW.允许多次传递算法,直到不超过2次传递,并且这些传递之间的CPU开销很小.
有任何想法吗 ?
编辑:
我需要从24位颜色到21位颜色抖动.
(也就是说 - 我需要将8位/通道转换为7位/通道.)
编辑2
也许我没有很好地解释问题.所以我会尝试扩展一些确切的问题.问题是这个 - 考虑一下我们有这张照片:
我们有上面的图片,但用抖动算法处理:
现在这是测试你的抖动对我有好处的程序:
1.在Photoshop中将这些图片作为一张图片加载2层.
2.选择"图层"混合模式为"差异".
3.对图层执行"合并可见"操作,以获得一个图层.
4.执行操作=>图像/调整/均衡
之后你必须得到这样的图像:
正如你所看到的那样 - 单调红色的中间像素根本没有抖动.左右图像区域的抖动也有点不同.尝试用这种行为重建抖动算法.
我们在HLSL中有一个像素着色器,它在一些地方用于稍微不同的东西,因此有几个条件块意味着在某些情况下省略了复杂的功能.同样,这意味着我们将纹理作为采样器参数传递,而这些参数可能并不总是被使用.
我不知道这两件事增加了多少性能,但特别是因为我们在集成图形芯片上支持SM2.0,效率低下是个问题.那么,传递纹理而不使用它意味着任何额外的开销吗?并且使用if
简单的行为来添加一些指令,还是会因为停顿等而对其进行大幅度的影响,就像进行CPU优化一样?
从我的主要问题开始:
我可以在FireMonkey应用程序中使用像素着色器模型3,4或5吗?
我希望能够在我的FireMonkey程序中动态创建像素着色器.为此,我现在使用DirectX SDK附带的fxc.exe编译像素着色器,并将编译后的代码加载到我的TShaderFilter后代中.这很好(如果你对我的表现感兴趣,请告诉我).
但是,如果我ps_2_0
作为目标配置文件进行编译,我只能让事情发挥作用.
我目前正在遇到着色器模型2.0的限制.例如,循环似乎是由编译器展开的,并且在2级着色器中可以有最大数量的指令.因此,可能性的数量非常有限.
示例:
下面的着色器代码创建了一个mandelbrot分形.如果我设置Iterations
得太高,它就不会编译.错误信息:
error X5608: Compiled shader code uses too many arithmetic instruction slots (78). Max. allowed by the target (ps_2_0) is 64.
#define Iterations 12
float2 Pan;
float Zoom;
float Aspect;
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
{
float2 c = (texCoord - 0.5) * Zoom * float2(1, Aspect) - Pan;
float2 v = 0;
for (int n = 0; n < Iterations; n++)
{
v = float2(v.x * …
Run Code Online (Sandbox Code Playgroud) 我已经看过许多像素着色器效果示例,像图像上的漩涡一样.但我想知道是否有人知道任何示例或教程更实用的着色器效果?
我并不是说漩涡效果没有它的用途,只是我发现的许多例子都有解释的基本效果,而不是如何巧妙地使用其他效果或过渡到产生美妙的效果.有一个视频在这里,它概述所有的WPF效果库,但我不知道我怎么会用他们有的在实际环境.
例如,当Flash 8出现模糊等效果时,我发现了一个精彩的视频,展示了如何使用模糊效果创建一个带有超速文本的炫酷效果,该视频启发了许多关于我可以用Flash中的效果做些什么的想法8.我正在寻找与Pixel Shader Effects类似的东西.
关于如何在像素着色器中处理alpha分量有什么不寻常之处吗?我有一个WPF应用程序,我的艺术家为我提供灰度图像作为背景,应用程序根据当前状态着色这些图像.所以我写了一个像素着色器(使用WPF像素着色器效果库基础结构)来用作Image元素的效果.着色器将颜色作为参数,将其转换为HSL,以便操作亮度.然后,对于每个灰色像素,它计算亮度在颜色参数和白色之间插入的颜色与源像素的亮度成比例.
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 src = tex2D(implicitInputSampler, uv);
// ...Do messy computation involving src brightness and color parameter...
float4 dst;
dst.r = ...
dst.g = ...
dst.b = ...
dst.a = src.a;
return dst;
}
Run Code Online (Sandbox Code Playgroud)
这对于alpha = 1的像素效果很好.但是在alpha = 0的情况下,结果像素变白,而不是让窗口的背景显示出来.所以我做了一个微小的改变:
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 src = tex2D(implicitInputSampler, uv);
if (src.a == 0)
return src;
...
Run Code Online (Sandbox Code Playgroud)
而现在透明的部分确实是透明的.为什么?为什么dst.a = src.a
第一个版本的声明没有实现呢?不幸的是,即使这只是一个部分修复,因为它看起来像0 <alpha <1的像素是白色的.
有谁知道我不了解alpha?
但是pow(0,2.0)给出0
似乎任何浮点指数给出1而整数指数给出0.
我正在使用DirectX 9和hlsl编译器"D3DCompiler_43.dll".确认在Nvidia和Ati卡上.
我很迷惑!这是某种已知的行为还是错误?
为了说明效果,请尝试以下简单的测试着色器:
// Test shader demonstrating strange pow behaviour
// when brightness becomes 0 resulting color will jump to white
float4x4 WorldViewProjXf : WorldViewProjection < string UIWidget="None";>;
float Brightness
<
string UIName = "Brightness";
float UIMin = 0;
float UIMax = 1;
> = 0;
struct VS_Input
{
float4 position : POSITION0;
};
struct VS_Output
{
float4 position : POSITION0;
};
VS_Output Vertex_Func( VS_Input in_data )
{
VS_Output outData;
outData.position = mul(in_data.position, WorldViewProjXf);
return outData;
} …
Run Code Online (Sandbox Code Playgroud) 在Microsoft的如何使用PixelShader 的示例中,他们使用单例.我在其他地方看到了相同的模式,他们在这里说
像素着色器存储在私有静态字段_pixelShader中.此字段是静态的,因为已编译的着色器代码的一个实例足以满足整个类的要求.
使用此模式时,我们已经看到了几个内存泄漏问题.涉及的PixelShader是事件处理,并不总是被正确清除.我们不得不冻结它们,看到了一些改进.我们不得不手动做一些分离
// Attach/detach effect as UI element is loaded/unloaded. This avoids
// a memory leak in the shader code as described here:
element.Loaded += (obj, args) =>
{
effect.PixelShader = ms_shader;
element.Effect = effect;
};
element.Unloaded += (obj, args) =>
{
effect.PixelShader = null;
element.Effect = null;
};
Run Code Online (Sandbox Code Playgroud)
即使现在处于压力之下,该领域仍然存在内存泄漏.有没有人知道PixelShader是否使用重型资源值得使用单例?
pixel-shader ×10
shader ×5
hlsl ×3
wpf ×3
c# ×2
glsl ×2
delphi ×1
delphi-xe2 ×1
dithering ×1
effect ×1
effects ×1
firemonkey ×1
javascript ×1
math ×1
opengl ×1
pixel ×1
rendering ×1
webgl ×1
xna ×1
xna-3.0 ×1