opengl - Undefined Behaviour with unused Shadow Samplers -
i have shader performs lighting passes in deferred renderer. takes uniforms various optional features, 1 of them being shadows.
i want use same shader performing lighting shadows without (see other question here). works great.
however, there problem when render light without shadows, , such don't bind texture shadow sampler, leaving other texture bound. on system, running nvidia 346.59 drivers, produces following gl error/warning:
program undefined behavior warning: sampler object 0 bound non-depth texture 0, yet used program uses shadow sampler . undefined behavior.
even though know sampler not used if case.
is there way around this? seems unnecessary have bind unused placeholder texture suppress warning.
edit: note work. issue warning being spit out driver.
edit: ok, here's shader. part relevant question main() function.
#version 330 #extension gl_arb_shading_language_420pack : enable #include "headers/blocks/camera" #include "headers/blocks/spotlight" #include "headers/uniform_disks" #include "headers/shadow/sample_spot" in vec2 texcrd; layout(std140, binding=0) uniform camerablock { camerablock cb; }; layout(std140, binding=1) uniform spotlightblock { spotlightblock lb; }; uniform int mode; uniform int shadquality; uniform int shadfilter; layout(binding=0) uniform sampler2d texdiff; layout(binding=1) uniform sampler2d texnorm; layout(binding=2) uniform sampler2d texsurf; layout(binding=3) uniform sampler2d texspec; layout(binding=4) uniform sampler2d texambi; layout(binding=5) uniform sampler2d texdepth; layout(binding=6) uniform sampler2dshadow texshad; out vec3 fragcolour; vec3 get_view_pos(in vec2 _tc) { float dep = texture(texdepth, _tc).r * 2.f - 1.f; vec4 p_pos = vec4(_tc * 2.f - 1.f, dep, 1.f); vec4 v_pos = cb.invproj * p_pos; return v_pos.xyz / v_pos.w; } float get_shadow_value(vec3 _wpos, vec3 _wsurf) { vec3 normpos = _wpos + _wsurf*0.04f; vec4 sc = lb.matrix * vec4(normpos, 1.f); vec3 shadcrd = sc.xyz / sc.w * 0.5f + 0.5f; float bias = get_bias(_wsurf, normalize(normpos - lb.position)); if (shadfilter < 2) return sample_shadow(shadcrd, bias, texshad); else { if (shadquality == 0) return sample_shadow_x4(shadcrd, bias, texshad); if (shadquality == 1) return sample_shadow_x8(shadcrd, bias, texshad); if (shadquality == 2) return sample_shadow_x16(shadcrd, bias, texshad); } } vec3 get_diffuse_value(vec3 _lightdir, vec3 _normal) { vec3 txdiff = texture(texdiff, texcrd).rgb; float dotprod = max(dot(-_lightdir, _normal), 0.f); return lb.colour * txdiff * dotprod; } vec3 get_specular_value(vec3 _lightdir, vec3 _normal, vec3 _position) { vec3 txspec = texture(texspec, texcrd).rgb; vec3 reflection = reflect(_lightdir, _normal); vec3 dirfromcam = normalize(-_position); float factor = pow(max(dot(dirfromcam, reflection), 0.f), 50.f); return lb.colour * txspec * factor; } void main() { vec3 v_pos = get_view_pos(texcrd); vec3 v_norm = normalize(texture(texnorm, texcrd).rgb * 2.f - 1.f); vec3 lightdir = normalize(v_pos - vec3(cb.view * vec4(lb.position, 1.f))); if (dot(-lightdir, v_norm) < -0.25f) discard; vec4 wp = cb.invview * vec4(v_pos, 1.f); vec3 w_pos = wp.xyz / wp.w; vec3 v_surf = normalize(texture(texsurf, texcrd).rgb * 2.f - 1.f); vec3 w_surf = normalize(vec3(cb.trnview * vec4(v_surf, 0.f))); vec3 spotdir = normalize(vec3(cb.view * vec4(lb.direction, 0.f))); float spotdist = distance(lb.position, w_pos); float angle = acos(dot(lightdir, spotdir)); if (angle > lb.angle || spotdist > lb.intensity) discard; bool doshad = bool(mode & 1); bool dodiff = bool(mode & 2); bool dospec = bool(mode & 4); float shad = 1.f; if (doshad) shad = get_shadow_value(w_pos, w_surf); if (shad == 0.f) discard; vec3 diff = vec3(0.f, 0.f, 0.f); if (dodiff) diff = get_diffuse_value(lightdir, v_norm); vec3 spec = vec3(0.f, 0.f, 0.f); if (dospec) spec = get_specular_value(lightdir, v_norm, v_pos); float fovrolf = pow((lb.angle - angle) / (1.f - lb.angle), sqrt(lb.softness)); float dstrolf = 1.f - spotdist / lb.intensity; float rolloff = fovrolf * dstrolf; fragcolour = (diff + spec) * shad * rolloff; }
i have read other question too.
what compile shader required/used samplers, , not expose unused samplers. doing give errors.
i know don't approach, ifdefs , create different versions of shader account shadow/noshadow lights. can cache them , switch them @ runtime in cpu. better branching in cpu in gpu; keep in mind once object, whereas in gpu once every pixel, wasteful.
something along lines of
#if defined(use_shadows) sampler2d [...] #endif
Comments
Post a Comment