LumixEngine/data/pipelines/terrain.shd
Mikulas Florek 1e55c6312e fixed esm
2019-10-18 22:00:28 +02:00

169 lines
No EOL
3.8 KiB
Text

include "pipelines/common.glsl"
texture_slot {
name = "Heightmap",
default_texture = "textures/common/white.tga"
}
texture_slot {
name = "Albedo",
default_texture = "textures/common/white.tga"
}
texture_slot {
name = "Splatmap",
default_texture = "textures/common/white.tga"
}
texture_slot {
name = "Satellite",
default_texture = "textures/common/white.tga"
}
vertex_shader [[
out int v_vid;
void main()
{
v_vid = gl_VertexID;
}
]]
common [[
layout(std140, binding = 4) uniform Drawcall {
ivec4 u_from_to;
ivec4 u_from_to_sup;
vec4 u_position;
vec4 u_rel_camera_pos;
vec4 u_terrain_scale;
vec2 u_hm_size;
int u_lod;
};
]]
geometry_shader [[
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
in int v_vid[];
out vec2 v_uv;
layout (binding=0) uniform sampler2D u_hm;
void getVertex(ivec2 ij, out vec3 pos, out vec2 uv)
{
pos = vec3(ij.x, 0.0, ij.y) * (1 << u_lod);
vec3 npos = vec3(ij.x & ~1, 0.0, ij.y & ~1) * (1 << u_lod);
vec2 size = vec2(u_from_to_sup.zw - u_from_to_sup.xy);
vec2 rel = (ij - u_from_to_sup.xy) / size;
rel = saturate(abs(rel - vec2(0.5)) * 10 - 4);
pos.xz = mix(pos.xz, npos.xz, rel.yx);
uv = (pos.xz + vec2(0.5 * u_terrain_scale.xz)) / u_hm_size ;
//pos.xz *= u_terrain_scale.xz;
}
void main()
{
// if (u_lod != 0) return;
ivec2 size = u_from_to.zw - u_from_to.xy;
ivec2 ij = ivec2(
u_from_to.x + v_vid[0] % size.x,
u_from_to.y + v_vid[0] / size.x
);
float s = pow(2, u_lod);
float hscale = u_terrain_scale.y;
vec3 v;
getVertex(ij, v, v_uv);
float h = texture(u_hm, v_uv).x * hscale;
gl_Position = u_pass_view_projection * vec4(u_position.xyz + v + vec3(0, h, 0), 1);
EmitVertex();
getVertex(ij + ivec2(1, 0), v, v_uv);
h = texture(u_hm, v_uv).x * hscale;
gl_Position = u_pass_view_projection * vec4(u_position.xyz + v + vec3(0, h, 0), 1);
EmitVertex();
getVertex(ij + ivec2(0, 1), v, v_uv);
h = texture(u_hm, v_uv).x * hscale;
gl_Position = u_pass_view_projection * vec4(u_position.xyz + v + vec3(0, h, 0), 1);
EmitVertex();
getVertex(ij + ivec2(1, 1), v, v_uv);
h = texture(u_hm, v_uv).x * hscale;
gl_Position = u_pass_view_projection * vec4(u_position.xyz + v + vec3(0, h, 0), 1);
EmitVertex();
}
]]
fragment_shader [[
#ifdef DEFERRED
layout(location = 0) out vec4 o_gbuffer0;
layout(location = 1) out vec4 o_gbuffer1;
layout(location = 2) out vec4 o_gbuffer2;
#else
layout(location = 0) out vec4 o_color;
#endif
in vec2 v_uv;
layout(binding=0) uniform sampler2D u_hm;
layout(binding=1) uniform sampler2DArray u_albedo;
layout(binding=2) uniform sampler2D u_splatmap;
layout(binding=3) uniform sampler2D u_satellite;
vec3 getNormal(vec2 uv)
{
float hscale = u_terrain_scale.y / u_terrain_scale.x;
ivec3 off = ivec3(-1, 0, 1);
float s01 = textureLodOffset(u_hm, uv, 0, off.xy).x;
float s21 = textureLodOffset(u_hm, uv, 0, off.zy).x;
float s10 = textureLodOffset(u_hm, uv, 0, off.yx).x;
float s12 = textureLodOffset(u_hm, uv, 0, off.yz).x;
vec3 va = normalize(vec3(1.0, (s21-s01) * hscale, 0.0));
vec3 vb = normalize(vec3(0.0, (s12-s10) * hscale, 1.0));
return normalize(cross(vb,va));
}
void getData()
{
data.normal = getNormal(v_uv);
data.albedo = texture(u_satellite, vec3(v_uv, 0).xy);
data.wpos = vec3(0);
data.roughness = 0.9;
data.metallic = 0;
data.emission = 0;
}
#ifdef DEPTH
void main()
{
o_color = vec4(shadowmapValue(gl_FragCoord.z));
}
#elif defined DEFERRED
void main()
{
getData();
o_gbuffer0 = vec4(data.albedo.rgb, data.roughness);
o_gbuffer1 = vec4(data.normal * 0.5 + 0.5, data.metallic);
o_gbuffer2 = vec4(data.emission, 0, 0, 1);
}
#else
void main()
{
getData();
o_color.rgb = vec3(1, 0, 1);
o_color.w = 1;
}
#endif
]]