#ifdef DESC [program] type: graphics vertex: main fragment: main #endif #include "forward.h" #ifdef DESC [binding] name: verts rate: vertex [attribute] name: position type: vec2 [attribute] name: uv type: vec2 [interpolator] name: uv type: vec2 [texture] name: shadowmaps stage: fragment dimension: shadowArray [texture] name: previous stage: fragment dimension: 2 [texture] name: depthmap stage: fragment dimension: 2 [struct] name: Config [variable] name: inv_view type: mat4 [variable] name: inv_proj type: mat4 [variable] name: prev_vp type: mat4 [struct] name: Caster_Config [variable] name: index type: int [cbuffer] name: config type: Config stage: fragment [cbuffer] name: caster_config type: Caster_Config stage: fragment [sbuffer] name: casters type: Caster stage: fragment [target] name: shadow_amount type: float #endif #ifdef VERTEX_SHADER void main() { interpolator.uv = uv; gl_Position = vec4(position, 1.0, 1.0); } #endif #ifdef FRAGMENT_SHADER vec2 poissonDisk[16] = vec2[]( vec2(-0.94201624, -0.39906216), vec2(0.94558609, -0.76890725), vec2(-0.094184101, -0.92938870), vec2(0.34495938, 0.29387760), vec2(-0.91588581, 0.45771432), vec2(-0.81544232, -0.87912464), vec2(-0.38277543, 0.27676845), vec2(0.97484398, 0.75648379), vec2(0.44323325, -0.97511554), vec2(0.53742981, -0.47373420), vec2(-0.26496911, -0.41893023), vec2(0.79197514, 0.19090188), vec2(-0.24188840, 0.99706507), vec2(-0.81409955, 0.91437590), vec2(0.19984126, 0.78641367), vec2(0.14383161, -0.14100790) ); float random(vec3 seed, int i){ vec4 seed4 = vec4(seed,i); float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673)); return fract(sin(dot_product) * 43758.5453); } float get_shadow(int id, vec3 wpos) { const int taps = 4; const float w = 1.0 / float(taps); const float m = 1.0 / 1000.0; int i; float d = 0.0f; Caster caster = casters[id]; vec4 surf = caster.projection * vec4(wpos, 1.0); surf /= surf.w; surf.xy = surf.xy * 0.5 + 0.5; surf.z -= 0.005; for (i = 0; i < taps; i++) { int index = int(16.0 * random(floor(wpos.xyz * 1000.0), i + globals.frame)) % 16; vec2 coord = surf.xy + poissonDisk[index] * m; vec4 vec = vec4(coord, float(id), surf.z); d += texture(shadowmaps, vec).r * w; } return d; } vec3 get_world_pos(float depth, vec2 uv) { float z = depth; vec4 clip = vec4(uv * 2.0 - 1.0, z, 1.0); vec4 view = config.inv_proj * clip; view /= view.w; return (config.inv_view * view).xyz; } void main() { vec2 uv = interpolator.uv; float d = texture(depthmap, uv).r; vec3 wpos = get_world_pos(d, uv); float prev = texture(previous, uv).r; float current = get_shadow(caster_config.index, wpos); shadow_amount = (prev + current) * 0.5; } #endif