LumixEngine/data/pipelines/impostor.shd
Mikulas Florek 8854c967bb cleanup
2021-12-12 21:15:55 +01:00

179 lines
No EOL
4.7 KiB
Text

texture_slot {
name = "Albedo",
default_texture = "textures/common/white.tga"
}
texture_slot {
name = "Normal",
define = "HAS_NORMAL"
}
texture_slot {
name = "Self shadow",
default_texture = "textures/common/white.tga"
}
include "pipelines/common.glsl"
define "ALPHA_CUTOUT"
uniform("Center", "vec3")
------------------
vertex_shader [[
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec2 a_uv;
layout(location = 2) in vec3 a_normal;
#ifdef _HAS_ATTR3
layout(location = 3) in vec3 a_tangent;
#else
const vec3 a_tangent = vec3(0, 1, 0);
#endif
layout(location = 4) in vec4 i_rot_quat;
layout(location = 5) in vec4 i_pos_scale;
layout(location = 6) in float i_lod;
layout (location = 0) out vec2 v_uv;
layout (location = 1) out vec3 v_normal;
layout (location = 2) out vec3 v_tangent;
layout (location = 3) out vec4 v_wpos;
#if !defined DEPTH && !defined DEFERRED
layout (location = 4) out vec4 v_shadow_coefs;
#endif
layout (location = 5) out float v_lod;
vec2 dirToGrid(vec3 vec)
{
vec.y = min(vec.y, -0.001);
vec = normalize(vec);
vec.xz /= dot( vec3(1.0), abs(vec) );
return vec2(vec.x + vec.z, vec.x - vec.z) * 0.5 + 0.5;
}
void main() {
mat3 tangent_space;
#ifndef DEPTH
vec3 N = normalize(i_pos_scale.xyz);
#else
vec3 N = normalize(Global.light_dir.xyz);
#endif
tangent_space[0] = normalize(cross(N, vec3(0, 1, 0)));
tangent_space[1] = normalize(cross(tangent_space[0], N));
tangent_space[2] = cross(tangent_space[0], tangent_space[1]);
vec3 vd = vec3(N.x, N.y, N.z);
vec4 to_model_space = vec4(-i_rot_quat.xyz, i_rot_quat.w);
vd = rotateByQuat(to_model_space, vd);
v_lod = i_lod;
#if !defined DEPTH && !defined DEFERRED
vec3 ld = rotateByQuat(to_model_space, -Global.light_dir.xyz);
v_shadow_coefs = max(vec4(ld.x, -ld.z, -ld.x, ld.z), vec4(0));
v_shadow_coefs /= dot(v_shadow_coefs, vec4(1));
#endif
vec2 grid = dirToGrid(normalize(vd));
v_uv = a_uv / 9 + ivec2(grid * 9) / 9.0;
vec3 p = u_center.xyz + tangent_space * (a_position - u_center.xyz);
p *= i_pos_scale.w;
v_tangent = tangent_space[0];
v_normal = tangent_space[2];
v_wpos = vec4(i_pos_scale.xyz + p, 1);
gl_Position = Pass.view_projection * v_wpos;
}
]]
---------------------
fragment_shader [[
layout (binding=0) uniform sampler2D u_albedomap;
#ifdef HAS_NORMAL
layout (binding=1) uniform sampler2D u_normalmap;
#endif
layout (binding=2) uniform sampler2D u_selfshadow;
layout (binding=6) uniform samplerCubeArray u_reflection_probes;
layout (location = 0) in vec2 v_uv;
layout (location = 1) in vec3 v_normal;
layout (location = 2) in vec3 v_tangent;
layout (location = 3) in vec4 v_wpos;
#ifdef DEFERRED
layout(location = 0) out vec4 o_gbuffer0;
layout(location = 1) out vec4 o_gbuffer1;
layout(location = 2) out vec4 o_gbuffer2;
#elif !defined DEPTH
layout(location = 0) out vec4 o_color;
layout (location = 4) in vec4 v_shadow_coefs;
#endif
layout (location = 5) in float v_lod;
Surface getSurface()
{
Surface data;
vec4 c = texture(u_albedomap, v_uv) * u_material_color;
data.albedo = c.rgb;
data.alpha = c.a;
#ifdef ALPHA_CUTOUT
if(data.alpha < 0.5) discard;
#endif
mat3 tbn = mat3(
normalize(v_tangent),
normalize(v_normal),
normalize(cross(v_normal, v_tangent))
);
data.wpos = v_wpos.xyz;
data.V = normalize(-data.wpos);
data.roughness = u_roughness;
data.metallic = u_metallic;
#ifdef HAS_NORMAL
data.N.xz = texture(u_normalmap, v_uv).xy * 2 - 1;
data.N.y = sqrt(saturate(1 - dot(data.N.xz, data.N.xz)));
data.N = tbn * data.N;
#else
data.N = Global.light_dir.xyz;
#endif
data.emission = u_emission;
data.translucency = u_translucency;
data.ao = 1;
return data;
}
#ifdef DEPTH
void main()
{
if (ditherLOD(v_lod)) discard;
#ifdef ALPHA_CUTOUT
vec4 c = texture(u_albedomap, v_uv);
if(c.a < 0.5) discard;
#endif
}
#elif defined DEFERRED
void main()
{
Surface data = getSurface();
packSurface(data, o_gbuffer0, o_gbuffer1, o_gbuffer2);
}
#else
void main()
{
if (ditherLOD(v_lod)) discard;
Surface surface = getSurface();
vec4 self_shadow = texture(u_selfshadow, v_uv);
float shadow = saturate(dot(self_shadow, v_shadow_coefs));
vec3 res = computeDirectLight(surface
, Global.light_dir.xyz
, Global.light_color.rgb * Global.light_intensity * shadow);
res += surface.emission * surface.albedo;
float linear_depth = dot(surface.wpos.xyz, Pass.view_dir.xyz);
Cluster cluster = getClusterLinearDepth(linear_depth);
//res += pointLightsLighting(cluster, surface, shadow_atlas);
res += envProbesLighting(cluster, surface);
res += reflProbesLighting(cluster, surface, u_reflection_probes);
o_color = vec4(res, surface.alpha);
}
#endif
]]