mik*_*ker 5 opengl glsl fragment-shader
我有一个片段着色器,它基本上读取颜色alpha并将其转换为像素上的抖动效果.
但是,对于所有mod和if语句来说,它是处理器密集型的.有没有人对优化下面的代码有任何建议?
varying vec2 the_uv;
varying vec4 color;
void main()
{
// The pixel color will correspond
// to the uv coords of the texture
// for the given vertice, retrieved
// by the Vertex shader through varying vec2 the_uv
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
vec4 tex = texture2D(_MainTex, the_uv);
tex = tex * color ;
float r = tex.a;
if ( r > 0.1 ) {
if ( ( mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y, 4.0) ) > 6.00 ) {
gl_FragColor = color;
}
}
if ( r > 0.5 ) {
if ( ( mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y, 4.0) ) > 6.00 ) {
gl_FragColor = color;
}
}
if ( r > 0.7 ) {
if ( ( mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0) ) > 6.00 ) {
gl_FragColor = color;
}
}
if ( r > 0.9 ) {
if ( ( mod(gl_FragCoord.x + 1.0, 4.001) + mod(gl_FragCoord.y + 1.0, 4.0) ) > 6.00 ) {
gl_FragColor = color;
}
}
if ( r > 0.3 ) {
if ( ( mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0) ) > 6.00 ) {
gl_FragColor = color;
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是基于反馈的解决方案:
varying vec2 the_uv;
varying vec4 color;
void main()
{
color = gl_Color;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
the_uv = gl_MultiTexCoord0.st;
}
#endif
#ifdef FRAGMENT
uniform sampler2D _MainTex;
uniform sampler2D _GridTex;
varying vec2 the_uv;
varying vec4 color;
void main()
{
if (texture2D(_MainTex, the_uv).a * color.a > texture2D(_GridTex, vec2(gl_FragCoord.x, gl_FragCoord.y)*.25).a) gl_FragColor = color;
else gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
}
Run Code Online (Sandbox Code Playgroud)
您要做的是选择是否应根据源alpha在4x4网格上点亮每个像素.最简单的方法就是做到这一点.
首先使用像素通过所需的相应alpha来初始化4x4纹理(我选择1.0作为从未在此处显示的alpha)
1.0 0.5 1.0 0.1
1.0 1.0 0.9 1.0
1.0 0.3 1.0 0.7
1.0 1.0 1.0 1.0
Run Code Online (Sandbox Code Playgroud)
使用repeat设置此纹理以完全避免mod,并使用最近的滤镜来避免线性过滤.
然后,使用该纹理的采样来决定是否点亮像素.
vec4 dither = texture2D(_my4x4, gl_FragCoord / 4.); // 4 is the size of the texture
if (r > dither) { gl_FragColor = color; }
Run Code Online (Sandbox Code Playgroud)
这假设r永远不是1.有一些简单的方法可以解决这个问题,例如将4x4纹理中的值除以1.0,除了1.0之外,然后在if测试之前将抖动乘以2,但是在获取之后.
一些进一步的潜在优化:
归档时间: |
|
查看次数: |
3252 次 |
最近记录: |