texture_slot { name = "Albedo", default_texture = "textures/common/white.tga" } texture_slot { name = "Normal", default_texture = "textures/common/default_normal.tga" } texture_slot { name = "Roughness", default_texture = "textures/common/white.tga" } texture_slot { name = "Metallic", default_texture = "textures/common/white.tga" } include "pipelines/common.glsl" define "ALPHA_CUTOUT" define "VEGETATION" ------------------ 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 = 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; #ifdef GRASS layout (location = 4) out float v_darken; #endif vec2 dirToGrid(vec3 vec) { vec.y = max(0.001,vec.y); vec = normalize(vec); vec.xz /= dot( vec3(1.0), abs(vec) ); return vec2(vec.x + vec.z, vec.x - vec.z); } void main() { mat3 tangent_space; vec3 N = normalize(i_pos_scale.xyz); tangent_space[0] = normalize(cross(N, vec3(0, 1, 0))); tangent_space[1] = vec3(0, 1, 0); tangent_space[2] = cross(tangent_space[0], tangent_space[1]); vec3 vd = vec3(u_pass_view_dir.z, 0, u_pass_view_dir.x); vd = rotateByQuat(i_rot_quat, vd); vec2 grid = dirToGrid(normalize(vd)) * 0.5 + 0.5; v_uv = a_uv / 9 + ivec2(grid * 9) / 9.0; vec3 p = tangent_space * a_position * i_pos_scale.w; v_tangent = tangent_space[0]; v_normal = tangent_space[2]; #ifdef VEGETATION p = vegetationAnim(i_pos_scale.xyz, p); #endif v_wpos = vec4(i_pos_scale.xyz + p, 1); gl_Position = u_pass_view_projection * v_wpos; } ]] --------------------- fragment_shader [[ layout (binding=0) uniform sampler2D u_albedomap; layout (binding=1) uniform sampler2D u_normalmap; layout (binding=2) uniform sampler2D u_roughnessmap; layout (binding=3) uniform sampler2D u_metallicmap; layout (binding=4) uniform sampler2D u_shadowmap; 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; #else layout(location = 0) out vec4 o_color; #endif 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.roughness = texture(u_roughnessmap, v_uv).r * u_roughness; data.metallic = texture(u_metallicmap, v_uv).r * u_metallic; data.N = texture(u_normalmap, v_uv).xzy * 2 - 1; data.N = tbn * data.N; data.emission = u_emission; return data; } #ifdef DEPTH void main() { #ifdef ALPHA_CUTOUT vec4 c = texture(u_albedomap, v_uv); if(c.a < 0.5) discard; #endif } #else void main() { Surface data = getSurface(); packSurface(data, o_gbuffer0, o_gbuffer1, o_gbuffer2); } #endif ]]