precision mediump float; #define f32 float #define f64 double #define u32 uint #define i32 int #define b32 bool #ifdef VERTEX_SHADER # define varying_param out layout(location = 0) in vec4 a_color; layout(location = 1) in vec4 a_tangent; layout(location = 2) in vec3 a_pos; layout(location = 3) in vec3 a_normal; layout(location = 4) in vec2 a_uv0; layout(location = 5) in vec2 a_uv1; #else # define varying_param in layout(location = 0) out vec4 FragColor; #define AlbedoTexture u_texture0 #define NormalTexture u_texture1 #define MetallicTexture u_texture2 #define RoughnessTexture u_texture3 #define OcclusionTexture u_texture4 #define EmissionTexture u_texture5 #define HeightTexture u_texture6 #define CubemapTexture u_texture7 #define IrradianceTexture u_texture8 #define PrefilterTexture u_texture9 #define BRDFTexture u_texture10 uniform sampler2D u_texture0; uniform sampler2D u_texture1; uniform sampler2D u_texture2; uniform sampler2D u_texture3; uniform sampler2D u_texture4; uniform sampler2D u_texture5; uniform sampler2D u_texture6; uniform sampler2D u_texture7; uniform sampler2D u_texture8; uniform sampler2D u_texture9; uniform sampler2D u_texture10; #endif #define MMI_Albedo 0 #define MMI_Normal 1 #define MMI_Metallic 2 #define MMI_Roughness 3 #define MMI_Occlusion 4 #define MMI_Emission 5 #define MMI_Height 6 #define MMI_Cubemap 7 #define MMI_Irradiance 8 #define MMI_Prefilter 9 #define MMI_BRDF 10 #define MMI_MAX 11 #define AlbedoMaterial material_maps[MMI_Albedo] #define NormalMaterial material_maps[MMI_Normal] #define MetallicMaterial material_maps[MMI_Metallic] #define RoughnessMaterial material_maps[MMI_Roughness] #define OcclusionMaterial material_maps[MMI_Occlusion] #define EmissionMaterial material_maps[MMI_Emission] #define HeightMaterial material_maps[MMI_Height] #define CubemapMaterial material_maps[MMI_Cubemap] #define IrradianceMaterial material_maps[MMI_Irradiance] #define PrefilterMaterial material_maps[MMI_Prefilter] #define BRDFMaterial material_maps[MMI_BRDF] #define VertexMain main #define FragmentMain main struct MaterialMap { vec4 color; f32 value; }; layout(location = 0) varying_param vec2 v_uv0; layout(location = 1) varying_param vec2 v_uv1; layout(location = 2) varying_param vec3 v_normal; layout(location = 3) varying_param vec3 v_position; layout(location = 4) varying_param vec4 v_color; layout(std140, binding = 0) uniform Globals { mat4 projection; mat4 view; vec3 camera_position; vec3 ambient; }; layout(std140, binding = 1) uniform ModelState { bool albedo_texture; bool normal_texture; bool metallic_roughness_texture; bool occlusion_texture; bool emission_texture; bool height_texture; bool cubemap_texture; bool irradiance_texture; bool prefilter_texture; bool brdf_texture; bool no_material; }; layout(std140, binding = 2) uniform InstanceState { mat4 model_matrix; }; layout(std140, binding = 3) uniform Materials { MaterialMap material_maps[MMI_MAX]; }; f32 InverseLerp(f32 v, f32 min_value, f32 max_value) { return (v-min_value) / (max_value-min_value); } f32 Remap(f32 v, f32 in_min, f32 in_max, f32 out_min, f32 out_max) { f32 t = InverseLerp(v, in_min, in_max); return mix(out_min, out_max, t); } #ifdef VERTEX_SHADER void VertexMain() { gl_Position = projection * view * model_matrix * vec4(a_pos, 1.0); v_uv0 = a_uv0; v_normal = (model_matrix * vec4(a_normal, 0.0f)).xyz; v_position = (model_matrix * vec4(a_pos, 1.0f)).xyz; v_color = a_color; } #else void FragmentMain() { vec3 normal = normalize(v_normal); vec3 view_direction = normalize(camera_position - v_position); vec4 color; if(albedo_texture) { color = texture(AlbedoTexture, v_uv0); } else if(no_material) { color = v_color; } else { color = AlbedoMaterial.color; } if(color.a < 0.03f) { discard; } vec3 light_pos = vec3(0.0f, 100000.0f, 0.0f); vec3 light_dir = normalize(light_pos-v_position); vec3 light_color = vec3(1.0, 1.0, 0.9); // Hemi lighting vec3 sky_color = vec3(0.0, 0.3, 0.6); vec3 ground_color = vec3(0.6, 0.3, 0.1); f32 hemi_mix = Remap(normal.y, -1.0, 1.0, 0.0, 1.0); vec3 hemi = mix(ground_color, sky_color, hemi_mix); // Diffuse f32 dp = max(0.0, dot(light_dir, normal)); vec3 diffuse = dp * light_color; // Phong vec3 r = normalize(reflect(-light_dir, normal)); f32 phong_value = max(0.0, dot(view_direction, r)); phong_value = pow(phong_value, 32.0); vec3 specular = vec3(phong_value); vec3 lighting = ambient + hemi + diffuse + specular; lighting = pow(lighting, vec3(1.0/2.2)); FragColor = color * vec4(lighting, 1.0); } #endif