leod / rendology

Glium-based 3D rendering pipeline

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cube example fails on macOS: `Use of undeclared identifier 'closest_depth'`

aDotInTheVoid opened this issue · comments

$ RUST_BACKTRACE=full cargo run --example cube
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s
     Running `target/debug/examples/cube`
2019-12-17 17:33:15,150 INFO  [rendology::pipeline::shadow] Creating shadow texture
2019-12-17 17:33:15,150 INFO  [rendology::pipeline::shadow] Shadow mapping initialized
2019-12-17 17:33:15,150 INFO  [rendology::pipeline::deferred] Creating deferred buffer textures
2019-12-17 17:33:15,151 INFO  [rendology::pipeline::deferred] Creating deferred light programs
2019-12-17 17:33:15,307 INFO  [rendology::pipeline::deferred] Creating screen quad
2019-12-17 17:33:15,307 INFO  [rendology::pipeline::deferred] Creating sphere
2019-12-17 17:33:15,307 INFO  [rendology::pipeline::deferred] Creating light buffers
2019-12-17 17:33:15,307 INFO  [rendology::pipeline::deferred] Deferred shading initialized
2019-12-17 17:33:15,308 INFO  [rendology::pipeline::glow] Creating blur program
2019-12-17 17:33:15,356 INFO  [rendology::pipeline::glow] Creating screen quad
2019-12-17 17:33:15,392 INFO  [rendology::fxaa] Creating FXAA program
2019-12-17 17:33:15,704 INFO  [rendology::fxaa] Creating screen quad
2019-12-17 17:33:15,710 INFO  [rendology::pipeline] Creating screen quad
2019-12-17 17:33:15,710 INFO  [rendology::pipeline] Pipeline initialized
2019-12-17 17:33:15,710 INFO  [rendology::pipeline::components] Creating shadow pass for `C=rendology::basic_obj::scene::Core`
2019-12-17 17:33:15,710 INFO  [rendology::shader] Demoting vertex output v_color to local
2019-12-17 17:33:15,710 INFO  [rendology::shader] Demoting vertex output v_world_normal to local
2019-12-17 17:33:15,710 INFO  [rendology::shader] Demoting vertex output v_world_pos to local
2019-12-17 17:33:15,722 INFO  [rendology::shader] Removing vertex output v_color
2019-12-17 17:33:15,724 INFO  [rendology::shader] Removing vertex output v_world_normal
2019-12-17 17:33:15,728 INFO  [rendology::pipeline::components] Creating scene pass for `C=rendology::basic_obj::scene::Core`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: CreationError(ShaderBuild(BuildError { compiled_vertex_source: "#version 330\n\nuniform vec2 context_camera_viewport_size;\nuniform mat4 context_camera_projection;\nuniform mat4 context_camera_view;\nuniform vec3 context_main_light_pos;\nuniform vec3 context_ambient_light;\n\nin mat4 instance_transform;\nin vec4 instance_color;\n\nuniform mat4 shadow_light_projection_view;\n\nin vec3 position;\nin vec3 normal;\n\nsmooth out vec4 v_color;\nsmooth out vec4 v_light_space_pos;\nsmooth out vec3 v_world_normal;\nsmooth out vec4 v_world_pos;\n\n\nvoid main() {\n\n    v_world_normal = normalize(transpose(inverse(mat3(instance_transform))) * normal);\n    v_world_pos = instance_transform * vec4(position, 1.0);\n    v_color = instance_color;\n    gl_Position = context_camera_projection * context_camera_view * v_world_pos;\n    v_light_space_pos = shadow_light_projection_view * (v_world_pos + 0.02 * vec4(v_world_normal, 0.0));\n}\n", compiled_fragment_source: "#version 330\n\nuniform vec2 context_camera_viewport_size;\nuniform mat4 context_camera_projection;\nuniform mat4 context_camera_view;\nuniform vec3 context_main_light_pos;\nuniform vec3 context_ambient_light;\n\nuniform sampler2D shadow_map;\n\nsmooth in vec4 v_color;\nsmooth in vec4 v_light_space_pos;\nsmooth in vec3 v_world_normal;\nsmooth in vec4 v_world_pos;\n\nout  vec4 f_color;\nout  vec3 f_glow_color;\nout  float f_shadow;\nout  vec4 f_world_normal;\nout  vec4 f_world_pos;\n\n\n        float shadow_calculation(vec4 light_space_pos) {\n            vec3 light_dir = normalize(vec3(context_main_light_pos - v_world_pos.xyz));\n\n            vec3 proj_coords = light_space_pos.xyz / light_space_pos.w;\n            proj_coords = proj_coords * 0.5 + 0.5;\n\n            if (dot(light_dir, v_world_normal) < 0.0)\n                return 0.5;\n\n            // Q: Is there a way to do this on texture-level?\n            // Answer: yes, for x/y, but it\'s not supported in glium.\n            // (GL_CLAMP_TO_BORDER + GL_TEXTURE_BORDER_COLOR)\n            if (proj_coords.z > 1.0\n                || proj_coords.x < 0.0\n                || proj_coords.x > 1.0\n                || proj_coords.y < 0.0\n                || proj_coords.y > 1.0)\n            {\n                return 1.0;\n            }\n\n            float shadow = 0.0;\n            for (int x = -1; x <= 1; ++x) {\n                for (int y = -1; y <= 1; ++y) {\n                    float closest_depth = textureOffset(\n                        shadow_map, \n                        proj_coords.xy,\n                        ivec2(x, y)\n                    ).r;\n                    \n                    shadow += proj_coords.z > closest_depth ? 0.5 : 1.0;\n                }\n            }\n            shadow /= 9;\n\n            return shadow;\n        }\n    \nvoid main() {\n\n    f_color = v_color;\n    f_glow_color = vec3(0.0, 0.0, 0.0);\n    f_shadow = shadow_calculation(v_light_space_pos);\n    f_world_pos = v_world_pos;\n    f_world_normal = vec4(v_world_normal, 0.0);\n}\n", error: CompilationError("ERROR: 0:47: Argument 3 to function \'textureOffset\' must be a constant expression\nERROR: 0:53: Use of undeclared identifier \'closest_depth\'\n") }))', src/libcore/result.rs:1165:5
stack backtrace:
   0:        0x106c26865 - std::sys_common::at_exit_imp::push::hbcb9accb9aed3616
   1:        0x106c44fa0 - core::fmt::ArgumentV1::show_usize::h5612effbabb12159
   2:        0x106c24e3b - std::io::Write::write_fmt::h7bd7b6fe8b47c5fb
   3:        0x106c2846a - std::panicking::default_hook::{{closure}}::heee79636c241547c
   4:        0x106c28175 - std::panicking::default_hook::hfcbd07059d15441e
   5:        0x106c28ad7 - <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get::h2b8b0a58863fcf2c
   6:        0x106c2864d - std::panicking::continue_panic_fmt::h0e74ab2b215a1401
   7:        0x106c285a9 - std::panicking::try::do_call::ha1a4587e2a4eb439
   8:        0x106c4cb5f - core::panicking::panic_fmt::h09741a3213dba543
                               at src/libcore/panicking.rs:85
   9:        0x106c4cc39 - core::result::unwrap_failed::hf47c31c429b02014
                               at src/libcore/result.rs:1165
  10:        0x106800333 - core::result::Result<T,E>::unwrap::he678555fc2e233b5
                               at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/result.rs:933
  11:        0x10680a6b0 - cube::main::h4195418d11ad7d04
                               at examples/cube.rs:112
  12:        0x106841102 - std::rt::lang_start::{{closure}}::ha5c289ebf3eca20f
                               at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libstd/rt.rs:64
  13:        0x106c28528 - std::panicking::try::do_call::ha1a4587e2a4eb439
  14:        0x106c2a41f - panic_unwind::dwarf::eh::read_encoded_pointer::h8a85bd7bb8b1ba5e
  15:        0x106c28e7e - <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get::h2b8b0a58863fcf2c
  16:        0x1068410e2 - std::rt::lang_start::h065d2859c761f0bb
                               at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libstd/rt.rs:64
  17:        0x10680b132 - <cube::Scene as core::default::Default>::default::h83e062376678005b

System Information

OS: macOS Mojave 10.14.6 18G1012 x86_64
GPU: Intel HD Graphics 4000
cargo 1.39.0 (1c6ec66d5 2019-09-30)

compiled_vertex_source

#version 330

uniform vec2 context_camera_viewport_size;
uniform mat4 context_camera_projection;
uniform mat4 context_camera_view;
uniform vec3 context_main_light_pos;
uniform vec3 context_ambient_light;

in mat4 instance_transform;
in vec4 instance_color;

uniform mat4 shadow_light_projection_view;

in vec3 position;
in vec3 normal;

smooth out vec4 v_color;
smooth out vec4 v_light_space_pos;
smooth out vec3 v_world_normal;
smooth out vec4 v_world_pos;


void main() {

    v_world_normal = normalize(transpose(inverse(mat3(instance_transform))) * normal);
    v_world_pos = instance_transform * vec4(position, 1.0);
    v_color = instance_color;
    gl_Position = context_camera_projection * context_camera_view * v_world_pos;
    v_light_space_pos = shadow_light_projection_view * (v_world_pos + 0.02 * vec4(v_world_normal, 0.0));
}
", compiled_fragment_source: "#version 330

uniform vec2 context_camera_viewport_size;
uniform mat4 context_camera_projection;
uniform mat4 context_camera_view;
uniform vec3 context_main_light_pos;
uniform vec3 context_ambient_light;

uniform sampler2D shadow_map;

smooth in vec4 v_color;
smooth in vec4 v_light_space_pos;
smooth in vec3 v_world_normal;
smooth in vec4 v_world_pos;

out  vec4 f_color;
out  vec3 f_glow_color;
out  float f_shadow;
out  vec4 f_world_normal;
out  vec4 f_world_pos;


        float shadow_calculation(vec4 light_space_pos) {
            vec3 light_dir = normalize(vec3(context_main_light_pos - v_world_pos.xyz));

            vec3 proj_coords = light_space_pos.xyz / light_space_pos.w;
            proj_coords = proj_coords * 0.5 + 0.5;

            if (dot(light_dir, v_world_normal) < 0.0)
                return 0.5;

            // Q: Is there a way to do this on texture-level?
            // Answer: yes, for x/y, but it's not supported in glium.
            // (GL_CLAMP_TO_BORDER + GL_TEXTURE_BORDER_COLOR)
            if (proj_coords.z > 1.0
                || proj_coords.x < 0.0
                || proj_coords.x > 1.0
                || proj_coords.y < 0.0
                || proj_coords.y > 1.0)
            {
                return 1.0;
            }

            float shadow = 0.0;
            for (int x = -1; x <= 1; ++x) {
                for (int y = -1; y <= 1; ++y) {
                    float closest_depth = textureOffset(
                        shadow_map,
                        proj_coords.xy,
                        ivec2(x, y)
                    ).r;

                    shadow += proj_coords.z > closest_depth ? 0.5 : 1.0;
                }
            }
            shadow /= 9;

            return shadow;
        }

void main() {

    f_color = v_color;
    f_glow_color = vec3(0.0, 0.0, 0.0);
    f_shadow = shadow_calculation(v_light_space_pos);
    f_world_pos = v_world_pos;
    f_world_normal = vec4(v_world_normal, 0.0);
}

error

ERROR: 0:47: Argument 3 to function 'textureOffset' must be a constant expression
ERROR: 0:53: Use of undeclared identifier 'closest_depth'
commented

Thank you for the detailed bug report! This is very valuable, since I'm not able to test on Mac OS myself.

I think I understand what is going on here. textureOffset can only be evaluated at constant offsets. The code for smoothing shadow maps, however, evaluates it in a for loop here:

            for (int x = -1; x <= 1; ++x) {
                for (int y = -1; y <= 1; ++y) {
                    float closest_depth = textureOffset(
                        shadow_map,
                        proj_coords.xy,
                        ivec2(x, y)
                    ).r;

                    shadow += proj_coords.z > closest_depth ? 0.5 : 1.0;
                }
            }

When I wrote this code, I was crossing my fingers, hoping that the fact that for loops are unrolled means that ivec2(x, y) is essentially a constant expression. This does work on my NVIDIA GPU, but as usual you can't rely on anything to be portable in graphics programming.

Will try to fix soon by manually unrolling the loop, thanks again!

commented

I was able to reproduce the error on Ubuntu 18.04 with an Intel HD Graphics 5500 GPU. The error message is pretty similar:

0:50(2): error: parameter `in offset' must be a constant expression
0:47(24): error: type mismatch
0:53(28): warning: `closest_depth' used uninitialized