diff --git a/Makefile b/Makefile index dea88eda0f..7ba2ea63c2 100644 --- a/Makefile +++ b/Makefile @@ -6,48 +6,31 @@ ifeq "$(GLSLC)" "" break; endif -FLAGS = -c -g +define outpath +$(addsuffix .$(1), $(subst /shaders/,/compiled/,$(2))) +endef -SHADERS=$(wildcard amethyst_rendy/shaders/**/*) -COMP_SHADERS = $(patsubst amethyst_rendy/shaders/%,amethyst_rendy/compiled/%.spv,$(SHADERS)) -COMP_DISASMS = $(patsubst amethyst_rendy/shaders/%,amethyst_rendy/compiled/%.spvasm,$(SHADERS)) -SHADERS_UI=$(wildcard amethyst_ui/shaders/*) -COMP_SHADERS_UI = $(patsubst amethyst_ui/shaders/%,amethyst_ui/compiled/%.spv,$(SHADERS_UI)) -COMP_DISASMS_UI = $(patsubst amethyst_ui/shaders/%,amethyst_ui/compiled/%.spvasm,$(SHADERS_UI)) -SHADERS_TILES=$(wildcard amethyst_tiles/shaders/*) -COMP_SHADERS_TILES = $(patsubst amethyst_tiles/shaders/%,amethyst_tiles/compiled/%.spv,$(SHADERS_TILES)) -COMP_DISASMS_TILES = $(patsubst amethyst_tiles/shaders/%,amethyst_tiles/compiled/%.spvasm,$(SHADERS_TILES)) +SHADERS = $(filter-out /header/,$(wildcard */shaders/**/*.vert */shaders/**/*.frag)) +OUT = $(call outpath,spv,$(SHADERS)) $(call outpath,spvasm,$(SHADERS)) +all: $(OUT) -all: $(COMP_SHADERS) $(COMP_DISASMS) $(COMP_SHADERS_UI) $(COMP_DISASMS_UI) $(COMP_SHADERS_TILES) $(COMP_DISASMS_TILES) - -amethyst_rendy/compiled/%.spv: amethyst_rendy/shaders/% +%.spv: mkdir -p $(dir $@) - $(GLSLC) -MD -c -O -o $@ $< + $(GLSLC) -MD -c -g -O -o $@ $< -amethyst_rendy/compiled/%.spvasm: amethyst_rendy/shaders/% +%.spvasm: mkdir -p $(dir $@) $(GLSLC) -MD -S -g -O -o $@ $< -amethyst_tiles/compiled/%.spv: amethyst_tiles/shaders/% - mkdir -p $(dir $@) - $(GLSLC) -MD -c -O -o $@ $< - -amethyst_tiles/compiled/%.spvasm: amethyst_tiles/shaders/% - mkdir -p $(dir $@) - $(GLSLC) -MD -S -g -O -o $@ $< +define shader_rules +$(call outpath,spv,$1): $1 +$(call outpath,spvasm,$1) : $1 +endef -amethyst_ui/compiled/%.spv: amethyst_ui/shaders/% - mkdir -p $(dir $@) - $(GLSLC) -MD -c -O -o $@ $< - -amethyst_ui/compiled/%.spvasm: amethyst_ui/shaders/% - mkdir -p $(dir $@) - $(GLSLC) -MD -S -g -O -o $@ $< +$(foreach shader,$(SHADERS),$(eval $(call shader_rules,$(shader)))) clean: - rm amethyst_rendy/compiled/**/*.spv amethyst_rendy/compiled/**/*.spvasm amethyst_rendy/compiled/**/*.d - rm amethyst_ui/compiled/*.spv amethyst_ui/compiled/*.spvasm amethyst_ui/compiled/*.d - rm amethyst_tiles/compiled/*.spv amethyst_tiles/compiled/*.spvasm amethyst_tiles/compiled/*.d + $(RM) */compiled/**/*.spv */compiled/**/*.spvdis */compiled/**/*.d .PHONY: all clean \ No newline at end of file diff --git a/amethyst_rendy/shaders/fragment/flat.frag b/amethyst_rendy/shaders/fragment/flat.frag index 7516a79cd3..f764c4130d 100644 --- a/amethyst_rendy/shaders/fragment/flat.frag +++ b/amethyst_rendy/shaders/fragment/flat.frag @@ -1,9 +1,6 @@ #version 450 -struct UvOffset { - vec2 u_offset; - vec2 v_offset; -}; +#include "header/math.frag" layout(std140, set = 1, binding = 0) uniform Material { UvOffset uv_offset; @@ -20,16 +17,8 @@ layout(location = 0) in VertexData { layout(location = 0) out vec4 out_color; -float tex_coord(float coord, vec2 offset) { - return offset.x + coord * (offset.y - offset.x); -} - -vec2 tex_coords(vec2 coord, vec2 u, vec2 v) { - return vec2(tex_coord(coord.x, u), tex_coord(coord.y, v)); -} - void main() { - vec4 albedo = texture(albedo, tex_coords(vertex.tex_coord, uv_offset.u_offset, uv_offset.v_offset)); + vec4 albedo = texture(albedo, tex_coords(vertex.tex_coord, uv_offset)); if(albedo.w < alpha_cutoff) discard; out_color = albedo * vertex.color; } diff --git a/amethyst_rendy/shaders/fragment/header/environment.frag b/amethyst_rendy/shaders/fragment/header/environment.frag new file mode 100644 index 0000000000..5541af8140 --- /dev/null +++ b/amethyst_rendy/shaders/fragment/header/environment.frag @@ -0,0 +1,45 @@ +// Environment shader definition. +// Set 0. +// Keep in sync with amethyst_rendy/src/submodules/environment.rs + +struct PointLight { + vec3 position; + vec3 color; + float intensity; +}; + +struct DirectionalLight { + vec3 color; + float intensity; + vec3 direction; +}; + +struct SpotLight { + vec3 position; + vec3 color; + vec3 direction; + float angle; + float intensity; + float range; + float smoothness; +}; + +layout(std140, set = 0, binding = 1) uniform Environment { + vec3 ambient_color; + vec3 camera_position; + int point_light_count; + int directional_light_count; + int spot_light_count; +}; + +layout(std140, set = 0, binding = 2) uniform PointLights { + PointLight plight[128]; +}; + +layout(std140, set = 0, binding = 3) uniform DirectionalLights { + DirectionalLight dlight[16]; +}; + +layout(std140, set = 0, binding = 4) uniform SpotLights { + SpotLight slight[128]; +}; \ No newline at end of file diff --git a/amethyst_rendy/shaders/fragment/header/math.frag b/amethyst_rendy/shaders/fragment/header/math.frag new file mode 100644 index 0000000000..7b0a25bbed --- /dev/null +++ b/amethyst_rendy/shaders/fragment/header/math.frag @@ -0,0 +1,49 @@ +#ifndef MATH_FRAG +#define MATH_FRAG + +const float PI = 3.14159265359; + +struct UvOffset { + vec2 u_offset; + vec2 v_offset; +}; + +float tex_coord(float coord, vec2 offset) { + return offset.x + coord * (offset.y - offset.x); +} + +vec2 tex_coords(vec2 coord, UvOffset offset) { + return vec2(tex_coord(coord.x, offset.u_offset), tex_coord(coord.y, offset.v_offset)); +} + +vec3 schlick_fresnel(float HdotV, vec3 fresnel_base) { + return fresnel_base + (1.0 - fresnel_base) * pow(1.0 - HdotV, 5.0); +} + +float ggx_normal_distribution(vec3 N, vec3 H, float a) { + float a2 = a * a; + float NdotH = max(dot(N, H), 0.0); + float NdotH2 = NdotH*NdotH; + + float denom = (NdotH2 * (a2 - 1.0) + 1.0); + denom = PI * denom * denom; + + return (a2 + 0.0000001) / denom; +} + +float ggx_geometry(float NdotV, float NdotL, float r2) { + float a1 = r2 + 1.0; + float k = a1 * a1 / 8.0; + float denom = NdotV * (1.0 - k) + k; + float ggx1 = NdotV / denom; + denom = NdotL * (1.0 - k) + k; + float ggx2 = NdotL / denom; + return ggx1 * ggx2; +} + +float s_curve (float x) { + x = x * 2.0 - 1.0; + return -x * abs(x) * 0.5 + x + 0.5; +} + +#endif diff --git a/amethyst_rendy/shaders/fragment/pbr.frag b/amethyst_rendy/shaders/fragment/pbr.frag index 95c944d8a0..5252c11be5 100644 --- a/amethyst_rendy/shaders/fragment/pbr.frag +++ b/amethyst_rendy/shaders/fragment/pbr.frag @@ -1,53 +1,8 @@ #version 450 -// layout(early_fragment_tests) in; +#include "header/math.frag" -struct PointLight { - vec3 position; - vec3 color; - float intensity; -}; - -struct DirectionalLight { - vec3 color; - float intensity; - vec3 direction; -}; - -struct SpotLight { - vec3 position; - vec3 color; - vec3 direction; - float angle; - float intensity; - float range; - float smoothness; -}; - -layout(std140, set = 0, binding = 1) uniform Environment { - vec3 ambient_color; - vec3 camera_position; - int point_light_count; - int directional_light_count; - int spot_light_count; -}; - -layout(std140, set = 0, binding = 2) uniform PointLights { - PointLight plight[128]; -}; - -layout(std140, set = 0, binding = 3) uniform DirectionalLights { - DirectionalLight dlight[16]; -}; - -layout(std140, set = 0, binding = 4) uniform SpotLights { - SpotLight slight[128]; -}; - -struct UvOffset { - vec2 u_offset; - vec2 v_offset; -}; +#include "header/environment.frag" layout(std140, set = 1, binding = 0) uniform Material { UvOffset uv_offset; @@ -72,36 +27,6 @@ layout(location = 0) in VertexData { layout(location = 0) out vec4 out_color; -const float PI = 3.14159265359; - -float tex_coord(float coord, vec2 offset) { - return offset.x + coord * (offset.y - offset.x); -} - -vec2 tex_coords(vec2 coord, vec2 u, vec2 v) { - return vec2(tex_coord(coord.x, u), tex_coord(coord.y, v)); -} - -float normal_distribution(vec3 N, vec3 H, float a) { - float a2 = a * a; - float NdotH = max(dot(N, H), 0.0); - float NdotH2 = NdotH*NdotH; - - float denom = (NdotH2 * (a2 - 1.0) + 1.0); - denom = PI * denom * denom; - - return (a2 + 0.0000001) / denom; -} - -float geometry(float NdotV, float NdotL, float r2) { - float a1 = r2 + 1.0; - float k = a1 * a1 / 8.0; - float denom = NdotV * (1.0 - k) + k; - float ggx1 = NdotV / denom; - denom = NdotL * (1.0 - k) + k; - float ggx2 = NdotL / denom; - return ggx1 * ggx2; -} vec3 fresnel(float HdotV, vec3 fresnel_base) { return fresnel_base + (1.0 - fresnel_base) * pow(1.0 - HdotV, 5.0); @@ -118,12 +43,12 @@ vec3 compute_light(vec3 attenuation, vec3 fresnel_base) { vec3 halfway = normalize(view_direction + light_direction); - float normal_distribution = normal_distribution(normal, halfway, roughness2); + float normal_distribution = ggx_normal_distribution(normal, halfway, roughness2); float NdotV = max(dot(normal, view_direction), 0.0); float NdotL = max(dot(normal, light_direction), 0.0); float HdotV = max(dot(halfway, view_direction), 0.0); - float geometry = geometry(NdotV, NdotL, roughness2); + float geometry = ggx_geometry(NdotV, NdotL, roughness2); vec3 fresnel = fresnel(HdotV, fresnel_base); @@ -139,7 +64,7 @@ vec3 compute_light(vec3 attenuation, } void main() { - vec2 final_tex_coords = tex_coords(vertex.tex_coord, uv_offset.u_offset, uv_offset.v_offset); + vec2 final_tex_coords = tex_coords(vertex.tex_coord, uv_offset); vec4 albedo_alpha = texture(albedo, final_tex_coords); float alpha = albedo_alpha.a; if(alpha < alpha_cutoff) discard; diff --git a/amethyst_rendy/shaders/fragment/shaded.frag b/amethyst_rendy/shaders/fragment/shaded.frag index 657172c65a..5b6de1ddb6 100644 --- a/amethyst_rendy/shaders/fragment/shaded.frag +++ b/amethyst_rendy/shaders/fragment/shaded.frag @@ -1,36 +1,8 @@ #version 450 -struct PointLight { - vec3 position; - vec3 color; - float intensity; -}; - -struct DirectionalLight { - vec3 color; - float intensity; - vec3 direction; -}; - -layout(set = 0, binding = 1) uniform Environment { - vec3 ambient_color; - vec3 camera_position; - int point_light_count; - int directional_light_count; -}; - -layout(set = 0, binding = 2) uniform PointLights { - PointLight plight[128]; -}; - -layout(set = 0, binding = 3) uniform DirectionalLights { - DirectionalLight dlight[16]; -}; +#include "header/math.frag" -struct UvOffset { - vec2 u_offset; - vec2 v_offset; -}; +#include "header/environment.frag" layout(set = 1, binding = 0) uniform Material { UvOffset uv_offset; @@ -49,16 +21,9 @@ layout(location = 0) in VertexData { layout(location = 0) out vec4 out_color; -float tex_coord(float coord, vec2 offset) { - return offset.x + coord * (offset.y - offset.x); -} - -vec2 tex_coords(vec2 coord, vec2 u, vec2 v) { - return vec2(tex_coord(coord.x, u), tex_coord(coord.y, v)); -} void main() { - vec2 final_tex_coords = tex_coords(vertex.tex_coord, uv_offset.u_offset, uv_offset.v_offset); + vec2 final_tex_coords = tex_coords(vertex.tex_coord, uv_offset); vec4 albedo_alpha = texture(albedo, final_tex_coords); float alpha = albedo_alpha.a; if(alpha < alpha_cutoff) discard; diff --git a/amethyst_rendy/shaders/vertex/header/skinning.vert b/amethyst_rendy/shaders/vertex/header/skinning.vert new file mode 100644 index 0000000000..b72d9d24c4 --- /dev/null +++ b/amethyst_rendy/shaders/vertex/header/skinning.vert @@ -0,0 +1,10 @@ +#ifndef +SKINNING_LOC_VERTEX + #error "not defined" +#endif + +#ifndef SKINNING_LOC_INSTANCE + #define SKINNING_LOC_INSTANCE SKINNING_LOC_VERTEX + 1 +#endif + +layout(location = SKINNING_LOC_INSTANCE) in uint joints_offset; // instance rate