我尝试在启用多重采样的情况下尝试深度剥离,并且在透明层中出现一些错误数据的问题。我使用以下内容检查样本(最初是片段)是否对此传递有效:
float depth = texelFetch(depthMinima, ivec2(gl_FragCoord.xy), gl_SampleID).r;
if (gl_FragCoord.z <= depth)
{
discard;
}
depthMinima
定义为
uniform sampler2DMS depthMinima;
我启用了GL_SAMPLE_SHADING
,如果我理解正确的话,应该导致在每个样本的基础上调用片段着色器。如果不是这样的话,有没有办法让这件事发生?
结果是第一层或第二层看起来正确,但在那之下(我做了8层)我开始得到垃圾值 - 大部分是纯蓝色,有时是前一层的值。
这适用于单采样缓冲区,但不适用于多采样缓冲区。 discard关键字是否仍会丢弃整个片段?
答案 0 :(得分:1)
我启用了GL_SAMPLE_SHADING,如果我理解正确的话,应该导致基于每个样本调用片段着色器。
仅启用GL_SAMPLE_SHADING
是不够的。您还需要设置:
glMinSampleShading(1.0f)
值1.0表示帧缓冲区中的每个样本都应该是独立着色的。值0.0有效地允许GL忽略采样率着色。 0.0到1.0之间的任何值都允许GL仅遮蔽每个覆盖片段中的总样本的子集。哪些样本带阴影,用于选择片段样本子集的算法取决于实现。
换句话说,1.0
告诉它遮蔽所有样本。 0.5
告诉它至少遮半样品。
// Check the current value
GLfloat value;
glGetFloatv(GL_MIN_SAMPLE_SHADING_VALUE, &value);
如果GL_MULTISAMPLE
或GL_SAMPLE_SHADING
被禁用,则样本着色无效。
每个片段都会有多个片段着色器调用,每个片段都是片段的子集。换一种说法。样本着色指定了每个片段要处理的最小样本数。
如果GL_MIN_SAMPLE_SHADING_VALUE
设置为1.0
,则会为每个样本(在基元内)发出片段着色器调用。
如果设置为0.5
,那么每隔一个样本就会有一个着色器调用。
max(ceil(MIN_SAMPLE_SHADING_VALUE * SAMPLES), 1)
每个人都在他们的样本位置(gl_SamplePosition
)进行评估。
gl_SampleID
是当前正在处理的样本的索引。
应该逐个丢弃工作,还是只能按片段工作?
使用或不使用样本着色discard
仍然只会终止对着色器的单次调用。
资源:
答案 1 :(得分:0)
在多样本缓冲区上使用depth_peeling时,我遇到了类似的问题。
当使用来自先前果皮的多样本深度纹理和当前片段深度时,由于depth_test错误而出现一些伪像。
vec4 previous_peel_depth_tex = texelFetch(previous_peel_depth, coord, 0);
第三个参数是您要用于比较的样本,它将提供与片段中心不同的值。就像作者所说的,您可以使用gl_SampleID
vec4 previous_peel_depth_tex = texelFetch(previous_peel_depth, ivec2(gl_FragCoord.xy), gl_SampleID);
这解决了我的问题,但是性能下降很大,如果有4个样本,则片段着色器将运行4次,如果有4个剥离,则意味着4x4调用。如果至少打开glEnable(GL_MULTISAMPLE);
,则无需设置opengl标志
在片段着色器中任何静态使用[gl_SampleID]都会导致整个 要对每个样本进行评估的着色器
我决定使用其他方法,并在进行深度比较时增加偏差
float previous_linearized = linearize_depth(previous_peel_depth_tex.r, near, far);
float current_linearized = linearize_depth(gl_FragCoord.z, near, far);
float bias_meter = 0.05;
bool belong_to_previous_peel = delta_depth < bias_meter;
这解决了我的问题,但某些伪影可能仍然出现,您需要以eye_space单位(米,厘米,...)调整偏差