// vert // out vec3 view_dir; uniform vec4 view_corners[4]; void main(void) { gl_Position = qgl_ftransform(); view_dir = view_corners[gl_VertexID].xyz; } // frag // in vec3 view_dir; uniform vec2 dt; uniform float z_near; uniform sampler2D tex_0, tex_1, tex_2, tex_3, tex_4; uniform int lights_start, lights_count; uniform vec4 fog_color = vec4(0.5, 0.5, 0.5, 1); uniform float fog_decay = 10, fog_density = 0; const vec3 luma = vec3(0.299, 0.587, 0.114); const float _pe = 2.4e-7, _min_rough = 1.e-8; vec4 pos, lpos, shp; vec3 li, si, ldir, halfV, bn, bn2, lwdir; //vec3 vds, vds2; float shm_diff, shm_spec, dist, NdotL, NdotH, spot, ldist, diff, sdist, shadow; void calcLight(in int index, in vec3 n, in vec3 v) { lpos = qgl_light_position[index].position; ldir = lpos.xyz - (pos.xyz * lpos.w); ldist = length(ldir); ldir = normalize(ldir); //ldir = vec3(0,0,1); halfV = normalize(ldir + v); NdotL = max(dot(n, ldir), 1E-8); NdotH = max(dot(n, halfV), 1E-8); spot = step(1.001E-8, NdotL) * qgl_light_parameter[index].decay_intensity.w; #ifdef SPOT float scos = max(dot(-ldir, qgl_light_position[index].direction.xyz), 0.); spot *= scos * step(qgl_light_parameter[index].angles.w, scos); spot *= smoothstep(qgl_light_parameter[index].angles.w, qgl_light_parameter[index].angles.y, scos); /*//lwdir = mat3(mat_viewi) * qgl_Light[index].direction.xyz; //bn = normalize(cross(lwdir, vec3(1, 0, 0))); //bn2 = normalize(cross(lwdir, bn)); float ds = ldist/200.;//max(abs(sdist) / 5000, 0.02); //spot *= clamp(1. - sdist, 0, 1); vds = ds * bn.xyz; vds2 = ds * bn2.xyz; float shadow = getShadow(index, pos.xyz, vec3(0)) * 3.; shadow += getShadow(index, pos.xyz, vds ) * 2.; shadow += getShadow(index, pos.xyz, - vds ) * 2.; shadow += getShadow(index, pos.xyz, - vds2 ) * 2.; shadow += getShadow(index, pos.xyz, + vds2 ) * 2.; //shadow += getShadow(index, pos.xyz, vds - vds2 ) * 1.5; //shadow += getShadow(index, pos.xyz, vds + vds2 ) * 1.5; //shadow += getShadow(index, pos.xyz, - vds - vds2 ) * 1.5; //shadow += getShadow(index, pos.xyz, - vds + vds2 ) * 1.5; //shadow += getShadow(index, pos.xyz, vds + vds ); //shadow += getShadow(index, pos.xyz, - vds - vds ); //shadow += getShadow(index, pos.xyz, - vds2 - vds2); //shadow += getShadow(index, pos.xyz, + vds2 + vds2); //shadow += getShadow(index, pos.xyz, vds + vds - vds2 ); //shadow += getShadow(index, pos.xyz, - vds - vds - vds2 ); //shadow += getShadow(index, pos.xyz, vds + vds + vds2 ); //shadow += getShadow(index, pos.xyz, - vds - vds + vds2 ); //shadow += getShadow(index, pos.xyz, vds - vds2 - vds2); //shadow += getShadow(index, pos.xyz, vds + vds2 + vds2); //shadow += getShadow(index, pos.xyz, - vds - vds2 - vds2); //shadow += getShadow(index, pos.xyz, - vds + vds2 + vds2); //shadow += shadow += getShadow(index, pos.xyz, vds+vds2)*10; spot *= mix(1., shadow / 11., shadow_on);*/ #endif vec3 dist_decay = vec3(1, ldist, ldist*ldist); spot /= dot(qgl_light_parameter[index].decay_intensity.xyz, dist_decay); float NdotLs = NdotL*NdotL; float NdotHs = NdotH*NdotH; float ndlc = (1. - NdotLs) / NdotLs; float der = NdotLs * (shm_diff + ndlc); diff = 2. / (1. + sqrt(1. + (1. - shm_diff) * ndlc)); li += spot * diff * qgl_light_parameter[index].color.rgb; ndlc = (1. - NdotHs) / NdotHs; der = NdotHs * (shm_spec + ndlc); si += spot * (shm_spec / (der*der) / 3.1416) * qgl_light_parameter[index].color.rgb; } void main(void) { ivec2 tc = ivec2(gl_FragCoord.xy); vec4 v1 = texelFetch(tex_1, tc, 0); float z = v1.w; if (z == 1.) { qgl_FragColor = vec4(fog_color.rgb, 0); return; } pos.w = 1; pos.xyz = view_dir * z; vec3 v = normalize(-pos.xyz); vec4 v0 = texelFetch(tex_0, tc, 0), v2 = texelFetch(tex_2, tc, 0), v3 = texelFetch(tex_3, tc, 0), v4 = texelFetch(tex_4, tc, 0); vec3 diffuse = v0.rgb; vec3 normal = v1.xyz; vec3 specular = v2.rgb; vec3 emission = v3.rgb; float alpha = v0.a; float reflectivity = v2.w; float roughness = v3.w; //bn = normalize(vec3(v3.w, v4.zw)); //bn2 = normalize(cross(n, bn)); roughness = max(roughness, _min_rough); shm_diff = roughness; shm_spec = max(roughness*roughness*roughness, _min_rough); //sh_pow = 1. / max(roughness, 0.00001); li = vec3(0.);//qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity; si = vec3(0.); for (int i = 0; i < lights_count; ++i) calcLight(lights_start + i, normal, v); vec3 res_col = max(vec3(0), li * diffuse + si * specular + emission); float plen = length(pos.xyz); float fog = 1 - exp(-plen / fog_decay); fog = clamp(fog * fog_color.a * fog_density, 0, 1); res_col = mix(res_col, fog_color.rgb, fog); qgl_FragColor = vec4(res_col, alpha); //qgl_FragColor.rgb = vec3(normal); }