为什么gl_FragCoord.z总是为零?

时间:2017-04-15 22:04:57

标签: shader fragment-shader vulkan depth-testing

我正在使用Vulkan(GTX 980),我有这个片段着色器:

#version 450

#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable

layout (location = 0) in vec4 inColor;

layout (location = 0) out vec4 outFragColor;

void main() {
    outFragColor = inColor;
    gl_FragDepth = gl_FragCoord.z / gl_FragCoord.w;
}

但我注意到深度缓冲区工作不正常,所以我补充道:

if (gl_FragCoord.z == 0) {
    discard;
}

果然,没有任何吸引力。即使我在几何着色器中执行此操作

gl_Position.z = 0.5;
EmitVertex();

gl_FragCoord.z仍然归零。 x,y和w值似乎很好(它们不为零)。如果我根本没有设置gl_FragDepth,它似乎不默认任何东西(输出闪烁,所以我假设垃圾值)。

作为参考,这是我的几何着色器。它创建了狭窄的圆锥截面来表示矢量场的方向。

#version 450

#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable

#define FACE_COUNT 16

#define PI 3.14159265

layout (points) in;
layout (triangle_strip, max_vertices = FACE_COUNT * 2 * 3) out;

layout (location = 0) in vec4 inPos[1];

layout (location = 0) out vec4 outColor;

layout (push_constant) uniform constants_t {
    mat4x4 world;
    mat4x4 projection;
    vec4 boundsMin;
    vec4 boundsMax;
    uvec4 resolution;
    float arrowSize;
} constants;

vec4 m(vec4 pos, mat4x4 matrix) {
    pos.w = 1.0;
    return matrix * pos;
}

vec4 transform(vec3 pos) {
    vec4 temp = vec4(pos, 1);
    temp = m(temp, constants.world);
    temp = m(temp, constants.projection);
    return temp;
}

vec3 demux() {
    uint temp = gl_PrimitiveIDIn;
    float xIndex = mod(temp, constants.resolution.x);
    temp /= constants.resolution.x;
    float yIndex = mod(temp, constants.resolution.y);
    temp /= constants.resolution.y;
    float zIndex = temp;
    vec3 centeringOffset = vec3(.5);
    return (vec3(xIndex, yIndex, zIndex) + centeringOffset) / constants.resolution.xyz * (constants.boundsMax - constants.boundsMin).xyz + constants.boundsMin.xyz;
}

// light a triangle based on surface normal and return color
vec4 light(vec3 a, vec3 b, vec3 c, vec4 color) {
    vec3 normal = cross(normalize(b - a), normalize(c - a));
    float upness = (normal.y + 1) * 0.5;
    float lightenRange = 0.1;
    float lighten = max(0, upness - 1 + lightenRange) / lightenRange;

    float downness = 1.0 - upness;
    float darkenRange = 0.4;
    float darken = max(0, downness - 1 + darkenRange) / darkenRange;

    return (color + vec4(0.5) * lighten) * (1 - darken * 0.5);
}

void draw(vec3 a, vec3 b, vec3 c, vec4 color) {
    outColor = light(a, b, c, color);
    gl_Position = transform(a);
    EmitVertex();
    gl_Position = transform(b);
    EmitVertex();
    gl_Position = transform(c);
    EmitVertex();
    EndPrimitive();
}

void main(void)
{
    // world position of arrow base
    vec3 base = demux();
    // direction of arrow
    vec3 forward = inPos[0].xyz;


    float horizontalLen = length(forward.xz);
    // a direction "right" of forward
    vec3 right = horizontalLen > 0.00001 ? normalize(vec3(forward.z, 0, -forward.x)) : vec3(1, 0, 0);
    // a direction "up" of forward
    vec3 up = normalize(cross(forward.xyz, right.xyz));

    // world position of arrow tip
    vec3 tip = base + forward * constants.arrowSize * 10;

    // populate world positions of "rim" vertices
    vec3 pos[FACE_COUNT];
    for (int i = 0; i < FACE_COUNT; ++i) {
        float theta = i * PI * 2 / FACE_COUNT;
        pos[i] = base + (up * cos(theta) + right * sin(theta)) * constants.arrowSize;
    }

    for (int i = 0; i < FACE_COUNT; ++i) {
        int j = (i + 1) % FACE_COUNT;
        draw(pos[i], pos[j], tip, vec4(1, 0, 0, 1));
        draw(pos[j], pos[i], base, vec4(0, 1, 0, 1));
    }

}

0 个答案:

没有答案