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'
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!
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