From d44175ebda2d81de98166f06369b188e3baf427c Mon Sep 17 00:00:00 2001 From: Eddie S Date: Fri, 17 Nov 2023 15:21:16 +0300 Subject: [PATCH 01/15] ref --- include/limitless/ms/colors.hpp | 8 + include/limitless/ms/material.hpp | 15 ++ include/limitless/ms/property.hpp | 15 +- include/limitless/ms/shading.hpp | 5 +- shaders/API.md | 0 shaders/pipeline/material/shading.glsl | 6 + shaders/pipeline/shading/brdf.glsl | 79 ++++++-- shaders_ref/API.md | 19 ++ shaders_ref/lighting/light.glsl | 67 +++++++ shaders_ref/material/material.glsl | 206 ++++++++++++++++++++ shaders_ref/material/material_context.glsl | 192 ++++++++++++++++++ shaders_ref/shading/cloth_shading.glsl | 15 ++ shaders_ref/shading/lighting_context.glsl | 47 +++++ shaders_ref/shading/regular_shading.glsl | 15 ++ shaders_ref/shading/shade_for_light.glsl | 14 ++ shaders_ref/shading/shading_context.glsl | 50 +++++ shaders_ref/shading/subsurface_shading.glsl | 16 ++ src/limitless/ms/material_compiler.cpp | 51 +++-- 18 files changed, 781 insertions(+), 39 deletions(-) create mode 100644 include/limitless/ms/colors.hpp delete mode 100644 shaders/API.md create mode 100644 shaders_ref/API.md create mode 100644 shaders_ref/lighting/light.glsl create mode 100644 shaders_ref/material/material.glsl create mode 100644 shaders_ref/material/material_context.glsl create mode 100644 shaders_ref/shading/cloth_shading.glsl create mode 100644 shaders_ref/shading/lighting_context.glsl create mode 100644 shaders_ref/shading/regular_shading.glsl create mode 100644 shaders_ref/shading/shade_for_light.glsl create mode 100644 shaders_ref/shading/shading_context.glsl create mode 100644 shaders_ref/shading/subsurface_shading.glsl diff --git a/include/limitless/ms/colors.hpp b/include/limitless/ms/colors.hpp new file mode 100644 index 00000000..cbbd1caf --- /dev/null +++ b/include/limitless/ms/colors.hpp @@ -0,0 +1,8 @@ +#pragma once + +//namespace Limitless::ms { +// class Colors { +// public: +// static glm::vec4 +// }; +//} \ No newline at end of file diff --git a/include/limitless/ms/material.hpp b/include/limitless/ms/material.hpp index 2cae2444..0d9ef55a 100644 --- a/include/limitless/ms/material.hpp +++ b/include/limitless/ms/material.hpp @@ -65,6 +65,21 @@ namespace Limitless::ms { */ bool refraction {}; + /** + * Describes whether material is using specular anti-aliasing + */ + bool specular_antialiasing {true}; + + /** + * Describes specular anti-aliasing variance + */ + float specular_antialiasing_variance {0.15f}; + + /** + * Describes specular anti-aliasing threshold + */ + float specular_antialiasing_threshold {0.1f}; + /** * Unique material name */ diff --git a/include/limitless/ms/property.hpp b/include/limitless/ms/property.hpp index 71b73b00..274bbb6a 100644 --- a/include/limitless/ms/property.hpp +++ b/include/limitless/ms/property.hpp @@ -2,12 +2,13 @@ namespace Limitless::ms { enum class Property { - // vec4 + // vec4; rgb - color; a - intensity; linear space; [0 - 1] Color, + // vec4; rgb - color; a - intensity; linear space; [0 - n] EmissiveColor, - // texture Diffuse, + // texture Normal, EmissiveMask, BlendMask, @@ -35,5 +36,15 @@ namespace Limitless::ms { IoR, Absorption, + + Reflectance, + Transmission, + MicroThickness, + Thickness, + + SubsurfaceColor, + SubsurfacePower, + + SheenColor }; } \ No newline at end of file diff --git a/include/limitless/ms/shading.hpp b/include/limitless/ms/shading.hpp index 40988c82..b5278a82 100644 --- a/include/limitless/ms/shading.hpp +++ b/include/limitless/ms/shading.hpp @@ -21,7 +21,8 @@ namespace Limitless::ms { */ Unlit, -// Cloth, -// Subsurface + Cloth, + Subsurface, + Custom, }; } \ No newline at end of file diff --git a/shaders/API.md b/shaders/API.md deleted file mode 100644 index e69de29b..00000000 diff --git a/shaders/pipeline/material/shading.glsl b/shaders/pipeline/material/shading.glsl index d39fc68e..826689e7 100644 --- a/shaders/pipeline/material/shading.glsl +++ b/shaders/pipeline/material/shading.glsl @@ -4,3 +4,9 @@ #define LIT_SHADING 0u #define UNLIT_SHADING 1u + +#define SHADING_LIT_REGULAR +#define SHADING_LIT_CLOTH +#define SHADING_LIT_SUBSURFACE +#define SHADING_UNLIT +#define SHADING_CUSTOM diff --git a/shaders/pipeline/shading/brdf.glsl b/shaders/pipeline/shading/brdf.glsl index 0a134676..6e4b4f25 100644 --- a/shaders/pipeline/shading/brdf.glsl +++ b/shaders/pipeline/shading/brdf.glsl @@ -11,12 +11,8 @@ float F_Schlick(float F0, float f90, float VoH) { return F0 + (f90 - F0) * pow5(1.0 - VoH); } -float Fd_Lambert() { - return 1.0 / PI; -} - // "Microfacet Models for Refraction through Rough Surfaces", Walter et al. 2007 -float D_GGX(float roughness, float NoH, const vec3 h) { +float D_GGX(float roughness, float NoH) { float oneMinusNoHSquared = 1.0 - NoH * NoH; float a = NoH * roughness; float k = roughness / (oneMinusNoHSquared + a * a); @@ -25,22 +21,37 @@ float D_GGX(float roughness, float NoH, const vec3 h) { } // "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", Heitz 2014 -float V_SmithGGXCorrelated(float roughness, float NoV, float NoL, float a2) { - float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2); +float V_SmithGGXCorrelated(float NoV, float NoL, float a2, float lambdaV) { float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2); return 0.5 / (lambdaV + lambdaL); } +// Hammon 2017, "PBR Diffuse Lighting for GGX+Smith Microsurfaces" +float V_SmithGGXCorrelatedFast(float roughness, float NoV, float NoL) { + float v = 0.5 / mix(2.0 * NoL * NoV, NoL + NoV, roughness); + return v; +} + vec3 SpecularF(const vec3 F0, float LoH) { +#if defined (ENGINE_MATERIAL_QUALITY_LOW) + return F_Schlick(F0, LoH); +#else float F90 = saturate(dot(F0, vec3(50.0 * 0.33))); return F_Schlick(F0, F90, LoH); +#endif } -vec3 SpecularBRDF(float roughness, float NoH, float NoV, float NoL, float LoH, const vec3 H, const vec3 F0, float a2) { - float D = D_GGX(roughness, NoH, H); - float V = V_SmithGGXCorrelated(roughness, NoV, NoL, a2); - vec3 F = SpecularF(F0, LoH); - return (D * V) * F; +// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF" +float D_Charlie(float roughness, float NoH) { + float invAlpha = 1.0 / roughness; + float cos2h = NoH * NoH; + float sin2h = max(1.0 - cos2h, 0.0078125); // 2^(-14/2), so sin2h^2 > 0 in fp16 + return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI); +} + +// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886" +float V_Neubelt(float NoV, float NoL) { + return 1.0 / (4.0 * (NoL + NoV - NoL * NoV)); } // "Physically-Based Shading at Disney", Burley 2012 @@ -51,6 +62,46 @@ float Fd_Burley(float roughness, float NoV, float NoL, float LoH) { return lightScatter * viewScatter * (1.0 / PI); } -vec3 DiffuseBRDF(vec3 diffuse, float roughness, float NoV, float NoL, float LoH) { - return diffuse * Fd_Burley(roughness, NoV, NoL, LoH); +float Fd_Lambert() { + return 1.0 / PI; +} + +// Energy conserving wrap diffuse term, does *not* include the divide by pi +float Fd_Wrap(float NoL, float w) { + float w1 = 1.0 + w; + float x = w1 * w1; + return (NoL + w) / x; +} + +vec3 DiffuseBRDF(const ShadingContext sctx, const LightingContext lctx) { +#if defined (ENGINE_MATERIAL_DIFFUSE_BURLEY) + return sctx.diffuseColor * Fd_Burley(sctx.roughness, sctx.NoV, lctx.NoL, lctx.LoH); +#elif defined (ENGINE_MATERIAL_DIFFUSE_LAMBERT) + return sctx.diffuseColor * Fd_Lambert(); +#endif +} + +vec3 SpecularBRDF(const ShadingContext sctx, const LightingContext lctx) { + float D = D_GGX(sctx.roughness, lctx.NoH); +#if defined (ENGINE_MATERIAL_SPECULAR_GGX) + float V = V_SmithGGXCorrelated(sctx.NoV, lctx.NoL, sctx.a2, lctxlambdaV); +#elif defined (ENGINE_MATERIAL_SPECULAR_GGX_FAST) + float V = V_SmithGGXCorrelatedFast(sctx.roughness, sctx.NoV, lctx.NoL); +#endif + vec3 F = SpecularF(sctx.F0, lctx.LoH); + return (D * V) * F; +} + +vec3 DiffuseBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { + vec3 diffuse = DiffuseBRDF(sctx, lctx); +#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) + diffuse *= Fd_Wrap(lsctx.NoL, 0.5); +#endif + return diffuse; +} + +vec3 SpecularBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { + float D = D_Charlie(sctx.roughness, lctx.NoH); + float V = V_Neubelt(sctx.NoV, lctx.NoL); + return (D * V) * sctx.F0; } diff --git a/shaders_ref/API.md b/shaders_ref/API.md new file mode 100644 index 00000000..425c9be9 --- /dev/null +++ b/shaders_ref/API.md @@ -0,0 +1,19 @@ +Material shading models: + unlit + lit (pbr) + cloth + subsurface + custom + +lit pbr + color + diffuse albedo + metallic + roughness + reflectance + ambient occlusion + normal + emissive + ior + absorption + transmission diff --git a/shaders_ref/lighting/light.glsl b/shaders_ref/lighting/light.glsl new file mode 100644 index 00000000..ac145fa2 --- /dev/null +++ b/shaders_ref/lighting/light.glsl @@ -0,0 +1,67 @@ +#define LIGHT_TYPE_POINT 0 +#define LIGHT_TYPE_SPOT 1 + +struct Light { + // rgb - linear color, a - intensity + vec4 color; + // world position + vec3 position; + // maximum radius + float radius; + // spot light attenuation + vec2 scale_offset; + // light type + uint type; + // does light cast shadow + bool casts_shadow; +}; + +/* + if opengl's SSBO extension is supported, all lights stored in SSBO + + if there is no SSBO, then engine defines MAX_LIGHTS + which is guaranteed to be less or equal then UNIFORM MAX SIZE + + so actually there is limit on lights which is bound by uniform/ssbo max size divided by sizeof(light) +*/ + +#if defined (ENGINE_EXT_SSBO) + layout (std140) buffer LIGHTS_BUFFER { + Light _lights[]; + }; +#else + layout (std140) uniform LIGHTS_BUFFER { + Light _lights[MAX_LIGHTS]; + }; +#endif + +Light getLight(const uint index) { + return _lights[index]; +} + +vec3 computeLights(const ShadingContext sctx) { + vec3 color = vec3(0.0); + for (uint i = 0u; i < getLightsCount(); ++i) { + Light light = getLight(i); + + LightingContext lctx = computeLightingContext(sctx, light); + + if (lctx.len > light.radius || lctx.NoL <= 0.0 || light.attenuation <= 0.0) { + continue; + } + +#if defined (SHADOWS) + if (light.casts_shadow) { + + } +#endif + + if (lctx.visibility <= 0.0) { + continue; + } + + color += shadeForLight(sctx, lctx, light); + } + + return color; +} diff --git a/shaders_ref/material/material.glsl b/shaders_ref/material/material.glsl new file mode 100644 index 00000000..0725208d --- /dev/null +++ b/shaders_ref/material/material.glsl @@ -0,0 +1,206 @@ +layout (std140) uniform MATERIAL_BUFFER { +#if defined (ENGINE_MATERIAL_COLOR) + vec4 _material_color; +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVE_COLOR) + vec4 _material_emissive_color; +#endif + +#if defined (ENGINE_EXT_BINDLESS_TEXTURE) +#if defined (ENGINE_MATERIAL_DIFFUSE_TEXTURE) + sampler2D _material_diffuse_texture; +#endif + +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) + sampler2D _material_normal_texture; +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE) + sampler2D _material_emissive_mask_texture; +#endif + +#if defined (ENGINE_MATERIAL_BLENDMASK_TEXTURE) + sampler2D _material_blend_mask_texture; +#endif + +#if defined (ENGINE_MATERIAL_METALLIC_TEXTURE) + sampler2D _material_metallic_texture; +#endif + +#if defined (ENGINE_MATERIAL_ROUGHNESS_TEXTURE) + sampler2D _material_roughness_texture; +#endif + +#if defined (ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE) + sampler2D _material_ambient_occlusion_texture; +#endif + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) + sampler2D _material_orm_texture; +#endif +#endif + +#if defined (ENGINE_MATERIAL_TESSELLATION_FACTOR) + vec2 _material_tessellation_factor; +#endif + +#if defined (ENGINE_MATERIAL_METALLIC) + float _material_metallic; +#endif + +#if defined (ENGINE_MATERIAL_ROUGHNESS) + float _material_roughness; +#endif + +#if defined (ENGINE_MATERIAL_REFRACTION) +#if defined (ENGINE_MATERIAL_IOR) + float _material_ior; +#endif + +#if defined (ENGINE_MATERIAL_ABSORPTION) + float _material_absorption; +#endif +#endif + +#if defined (ENGINE_EXT_BINDLESS_TEXTURE) + ENGINE_MATERIAL_CUSTOM_SAMPLERS +#endif + + ENGINE_MATERIAL_CUSTOM_SCALARS +}; + +#if !defined (ENGINE_EXT_BINDLESS_TEXTURE) +#if defined (ENGINE_MATERIAL_DIFFUSE_TEXTURE) + uniform sampler2D _material_diffuse_texture; +#endif + +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) + uniform sampler2D _material_normal_texture; +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE) + uniform sampler2D _material_emissive_mask_texture; +#endif + +#if defined (ENGINE_MATERIAL_BLENDMASK_TEXTURE) + uniform sampler2D _material_blend_mask_texture; +#endif + +#if defined (ENGINE_MATERIAL_METALLIC_TEXTURE) + uniform sampler2D _material_metallic_texture; +#endif + +#if defined (ENGINE_MATERIAL_ROUGHNESS_TEXTURE) + uniform sampler2D _material_roughness_texture; +#endif + +#if defined (ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE) + uniform sampler2D _material_ambient_occlusion_texture; +#endif + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) + uniform sampler2D _material_orm_texture; +#endif + + ENGINE_MATERIAL_CUSTOM_SAMPLERS +#endif + +ENGINE_MATERIAL_GLOBAL_DEFINITIONS + +/** + * Public material access API + * + * Do NOT forget to edit API.md on public API change + */ +#if defined (ENGINE_MATERIAL_COLOR) + vec4 getMaterialColor() { + return _material_color; + } +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVE_COLOR) + vec3 getMaterialEmissiveColor() { + return _material_emissive_color.rgb; + } +#endif + +#if defined (ENGINE_MATERIAL_TESSELLATION_FACTOR) + vec2 getMaterialTesselationFactor() { + return _material_tessellation_factor; + } +#endif + +#if defined (ENGINE_MATERIAL_METALLIC) + float getMaterialMetallic() { + return _material_metallic; + } +#endif + +#if defined (ENGINE_MATERIAL_ROUGHNESS) + float getMaterialRoughness() { + return _material_roughness; + } +#endif + +#if defined (ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE) + float getMaterialAmbientOcclusion(vec2 uv) { + return texture(_material_ambient_occlusion_texture, uv).r; + } +#endif + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) + vec3 getMaterialORM(vec2 uv) { + return texture(_material_orm_texture, uv).rgb; + } +#endif + +#if defined (ENGINE_MATERIAL_REFRACTION) +#if defined (MATERIAL_IOR) + float getMaterialIOR() { + return _material_ior; + } +#endif + +#if defined (ENGINE_MATERIAL_ABSORPTION) + float getMaterialAbsorption() { + return _material_absorption; + } +#endif +#endif + +#if defined (ENGINE_MATERIAL_DIFFUSE_TEXTURE) + vec4 getMaterialDiffuse(vec2 uv) { + return texture(_material_diffuse_texture, uv); + } +#endif + +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) + vec3 getMaterialNormal(vec2 uv) { + return texture(_material_normal_texture, uv).xyz; + } +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE) + vec3 getMaterialEmissiveMask(vec2 uv) { + return texture(_material_emissive_mask_texture, uv).rgb; + } +#endif + +#if defined (ENGINE_MATERIAL_BLENDMASK_TEXTURE) + float getMaterialBlendMask(vec2 uv) { + return texture(_material_blend_mask_texture, uv).r; + } +#endif + +#if defined (ENGINE_MATERIAL_METALLIC_TEXTURE) + float getMaterialMetallic(vec2 uv) { + return texture(_material_metallic_texture, uv).r; + } +#endif + +#if defined (ENGINE_MATERIAL_ROUGHNESS_TEXTURE) + float getMaterialRoughness(vec2 uv) { + return texture(_material_roughness_texture, uv).r; + } +#endif \ No newline at end of file diff --git a/shaders_ref/material/material_context.glsl b/shaders_ref/material/material_context.glsl new file mode 100644 index 00000000..189e7ebb --- /dev/null +++ b/shaders_ref/material/material_context.glsl @@ -0,0 +1,192 @@ +struct MaterialContext { +#if defined (ENGINE_MATERIAL_COLOR) + vec4 color; +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVE_COLOR) + vec3 emissive_color; +#endif + +#if defined (ENGINE_MATERIAL_DIFFUSE_TEXTURE) + vec4 diffuse; +#endif + +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) + vec3 normal; +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE) + vec3 emissive_mask; +#endif + +#if defined (ENGINE_MATERIAL_BLENDMASK_TEXTURE) + float blend_mask; +#endif + + float metallic; + float roughness; + +#if defined (ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE) || defined (ENGINE_MATERIAL_ORM_TEXTURE) + float ao; +#endif + +#if defined (ENGINE_MATERIAL_TESSELLATION_FACTOR) + vec2 tessellation_factor; +#endif + +#if defined (ENGINE_MATERIAL_REFRACTION) + float IoR; + float absorption; +#endif +}; + +MaterialContext computeMaterialContext() { + MaterialContext mctx; + +#if defined (ENGINE_MATERIAL_COLOR) + mctx.color = getMaterialColor(); +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVE_COLOR) + mctx.emissive_color = getMaterialEmissiveColor(); +#endif + +#if defined (ENGINE_MATERIAL_DIFFUSE_TEXTURE) + mctx.diffuse = getMaterialDiffuse(getVertexUV()); +#endif + +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) + mctx.normal = getMaterialNormal(getVertexUV()); +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE) + mctx.emissive_mask = getMaterialEmissiveMask(getVertexUV()); +#endif + +#if defined (ENGINE_MATERIAL_BLENDMASK_TEXTURE) + mctx.blend_mask = getMaterialBlendMask(getVertexUV()); +#endif + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) + vec3 _orm = getMaterialORM(getVertexUV()); +#endif + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) + mctx.metallic = _orm.b; +#elif defined (ENGINE_MATERIAL_METALLIC_TEXTURE) + mctx.metallic = getMaterialMetallic(getVertexUV()); +#elif defined (ENGINE_MATERIAL_METALLIC) + mctx.metallic = getMaterialMetallic(); +#else + mctx.metallic = 0.1; +#endif + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) + mctx.roughness = _orm.g; +#elif defined (ENGINE_MATERIAL_ROUGHNESS_TEXTURE) + mctx.roughness = getMaterialRoughness(getVertexUV()); +#elif defined (ENGINE_MATERIAL_ROUGHNESS) + mctx.roughness = getMaterialRoughness(); +#else + mctx.roughness = 0.8; +#endif + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) + mctx.ao = _orm.r; +#elif defined (ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE) + mctx.ao = getMaterialAmbientOcclusion(getVertexUV()); +#endif + +#if defined (ENGINE_MATERIAL_TESSELLATION_FACTOR) + mctx.tessellation_factor = getMaterialTesselationFactor(); +#endif + +#if defined (ENGINE_MATERIAL_REFRACTION) +#if defined (MATERIAL_IOR) + mctx.IoR = getMaterialIOR(); +#else + mctx.IoR = 1.0; +#endif + +#if defined (ENGINE_MATERIAL_ABSORPTION) + mctx.absorption = getMaterialAbsorption(); +#else + mctx.absorption = 0.0; +#endif +#endif + + return mctx; +} + +vec4 computeMaterialColor(const MaterialContext mctx) { + vec4 color = vec4(1.0); + +#if defined (ENGINE_MATERIAL_COLOR) + color *= mctx.color; +#endif + +#if defined (ENGINE_MATERIAL_DIFFUSE_TEXTURE) + color *= mctx.diffuse; +#endif + +#if defined (ENGINE_MATERIAL_BLENDMASK_TEXTURE) + if (mctx.blend_mask == 0.0) { + discard; + } +#endif + +#if defined (EFFECT_MODEL) && defined (BeamEmitter) && defined (BeamSpeed_MODULE) + if (distance(getVertexPosition(), getParticleStart()) / distance(getParticleStart(), getParticleEnd()) >= getParticleLength()) { + discard; + } +#endif + +#if defined (EFFECT_MODEL) && defined (InitialColor_MODULE) + color *= getParticleColor(); +#endif + + return color; +} + +vec3 computeMaterialEmissiveColor(const MaterialContext mctx) { +#if !defined (ENGINE_MATERIAL_EMISSIVE_COLOR) && !defined (ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE) + return vec3(0.0); +#else + vec3 emissive = vec3(1.0); + +#if defined (ENGINE_MATERIAL_EMISSIVE_COLOR) + emissive *= mctx.emissive_color; +#endif + +#if defined (ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE) + emissive *= mctx.emissive_mask; +#endif + + return emissive; +#endif +} + +vec3 computeMaterialNormal(const MaterialContext mctx) { +#if defined (SpriteEmitter) || defined (BeamEmitter) + return getCameraPosition() - getVertexPosition(); +#else +#if defined (ENGINE_MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + vec3 normal = mctx.normal; + normal = normalize(normal * 2.0 - 1.0); + normal = normalize(getVertexTBN() * normal); +#else + vec3 normal = normalize(getVertexNormal()); +#endif + return normal; +#endif +} + +float computeMaterialAO(const MaterialContext mctx) { + float ao = 1.0; + +#if defined (ENGINE_MATERIAL_ORM_TEXTURE) || defined (ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE) + ao *= mctx.ao; +#endif + + return ao; +} \ No newline at end of file diff --git a/shaders_ref/shading/cloth_shading.glsl b/shaders_ref/shading/cloth_shading.glsl new file mode 100644 index 00000000..0c76fa01 --- /dev/null +++ b/shaders_ref/shading/cloth_shading.glsl @@ -0,0 +1,15 @@ +vec3 clothShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { + vec3 Fd = DiffuseBRDF_Cloth(sctx, lctx); + vec3 Fr = SpecularBRDF_Cloth(sctx, lctx); + +#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) + Fd *= saturate(sctx.subsurfaceColor + lctx.NoL); + vec3 color = Fd + Fr * NoL; + color *= light.color.rgb * (light.color.a * light.attenuation * lctx.visibility); +#else + vec3 color = Fd + Fr; + color *= light.color.rgb * (light.color.a * light.attenuation * lctx.NoL * lctx.visibility); +#endif + + return color; +} \ No newline at end of file diff --git a/shaders_ref/shading/lighting_context.glsl b/shaders_ref/shading/lighting_context.glsl new file mode 100644 index 00000000..d2d8994f --- /dev/null +++ b/shaders_ref/shading/lighting_context.glsl @@ -0,0 +1,47 @@ +struct LightingContext { + vec3 L; + float NoL; + + vec3 H; + float NoH; + + float len; + float visibility; + float LoH; + float attenuation; + +#if defined (ENGINE_MATERIAL_SPECULAR_GGX) + float lambdV; +#endif +}; + +float getAttenuation(const ShadingContext sctx, const Light light) { + vec3 L = light.position.xyz - sctx.worldPos; + + float distance = dot(L, L); + float factor = distance * falloff; + float smoothFactor = saturate(1.0 - factor * factor); + float attenuation = smoothFactor * factor; + + return attenuation / max(distance, 1e-4); +} + +LightingContext computeLightingContext(const ShadingContext sctx, const Light light) { + LightingContext lctx; + + lctx.attenuation = getAttenuation(sctx, light); + + lctx.visibility = 1.0; + lctx.L = normalize(light.position.xyz - sctx.worldPos); + lctx.H = normalize(context.V + L); + lctx.len = length(light.position.xyz - sctx.worldPos); + + lctx.NoL = saturate(dot(context.N, L)); + lctx.NoH = saturate(dot(context.N, H)); + lctx.LoH = saturate(dot(L, H)); + +#if defined (ENGINE_MATERIAL_SPECULAR_GGX) + lctx.lambdaV = lctx.NoL * sqrt((sctx.NoV - sctx.a2 * sctx.NoV) * sctx.NoV + sctx.a2); +#endif +} + diff --git a/shaders_ref/shading/regular_shading.glsl b/shaders_ref/shading/regular_shading.glsl new file mode 100644 index 00000000..48f29af3 --- /dev/null +++ b/shaders_ref/shading/regular_shading.glsl @@ -0,0 +1,15 @@ +/** + * Computes color for lit material with regular PBR shading model. +*/ +vec3 regularShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { + vec3 Fd = DiffuseBRDF(sctx, lctx); + vec3 Fr = SpecularBRDF(sctx, lctx); + + vec3 color = Fd + Fr * sctx.energyCompensation; + +#if defined (ENGINE_MATERIAL_REFRACTION) + Fd *= (1.0 - sctx.transmission); +#endif + + return (color * light.color.rgb) * (light.color.a * lctx.NoL * light.attenuation * lctx.visibility); +} diff --git a/shaders_ref/shading/shade_for_light.glsl b/shaders_ref/shading/shade_for_light.glsl new file mode 100644 index 00000000..dd2a584e --- /dev/null +++ b/shaders_ref/shading/shade_for_light.glsl @@ -0,0 +1,14 @@ +/** + * Shades current fragment with defined material model for specified light + */ +vec3 shadeForLight(const ShadingContext sctx, const LightingContext lctx, const Light light) { +#if defined (ENGINE_MATERIAL_SHADING_REGULAR_MODEL) + return regularShading(sctx, lctx, light); +#elif defined (ENGINE_MATERIAL_SHADING_CLOTH_MODEL) + return clothShading(sctx, lctx, light); +#elif defined (ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL) + return subsurfaceShading(sctx, lctx, light); +#elif defined (ENGINE_MATERIAL_SHADING_CUSTOM_MODEL) + return customShading(sctx, lctx, light); +#endif +} \ No newline at end of file diff --git a/shaders_ref/shading/shading_context.glsl b/shaders_ref/shading/shading_context.glsl new file mode 100644 index 00000000..da389327 --- /dev/null +++ b/shaders_ref/shading/shading_context.glsl @@ -0,0 +1,50 @@ +struct ShadingContext { + vec3 diffuseColor; + float metallic; + + vec3 worldPos; + float roughness; + + vec3 N; + float a2; + + vec3 V; + float NoV; + + vec3 F0; + float ambientOcclusion; +}; + +ShadingContext computeShadingContext( + const vec3 baseColor, float metallic, + const vec3 worldPos, float roughness, + const vec3 N, float ambientOcclusion +) { + ShadingContext context; + + context.metallic = saturate(metallic); + context.diffuseColor = computeDiffuseColor(baseColor, context.metallic); + + context.worldPos = worldPos; + + float perceptualRoughness = clamp(roughness, MIN_PERCEPTUAL_ROUGHNESS, 1.0); + context.roughness = perceptualRoughness * perceptualRoughness; + + context.N = N; + context.a2 = context.roughness * context.roughness; + + context.V = normalize(getCameraPosition() - context.worldPos); + context.NoV = computeNoV(context.N, context.V); + + context.F0 = computeF0(baseColor, context.metallic, 1.0); + context.ambientOcclusion = ambientOcclusion; + +#if defined (ENGINE_MATERIAL_ANISOTROPY) + vec3 direction = material.anisotropyDirection; + pixel.anisotropy = material.anisotropy; + pixel.anisotropicT = normalize(shading_tangentToWorld * direction); + pixel.anisotropicB = normalize(cross(getWorldGeometricNormalVector(), pixel.anisotropicT)); +#endif + + return context; +} diff --git a/shaders_ref/shading/subsurface_shading.glsl b/shaders_ref/shading/subsurface_shading.glsl new file mode 100644 index 00000000..12344fed --- /dev/null +++ b/shaders_ref/shading/subsurface_shading.glsl @@ -0,0 +1,16 @@ +vec3 subsurfaceShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { + vec3 Fd = DiffuseBRDF(sctx, lctx); + vec3 Fr = vec3(0.0); + if (lctx.NoL > 0.0) { + Fr = SpecularBRDF(sctx, lctx) * sctx.energyCompensation; + } + + vec3 color = (Fd + Fr) * (lctx.NoL * lctx.occlusion); + float scatterVoH = saturate(dot(sctx.V, -lctx.L)); + float forwardScatter = exp2(scatterVoH * pixel.subsurfacePower - pixel.subsurfacePower); + float backScatter = saturate(lctx.NoL * sctx.thickness + (1.0 - sctx.thickness)) * 0.5; + float subsurface = mix(backScatter, 1.0, forwardScatter) * (1.0 - sctx.thickness); + color += sctx.subsurfaceColor * (subsurface * Fd_Lambert()); + + return (color * lctx.color.rgb) * (lctx.color.a * light.attenuation); +} \ No newline at end of file diff --git a/src/limitless/ms/material_compiler.cpp b/src/limitless/ms/material_compiler.cpp index fb493200..a8eef6db 100644 --- a/src/limitless/ms/material_compiler.cpp +++ b/src/limitless/ms/material_compiler.cpp @@ -16,63 +16,72 @@ std::string MaterialCompiler::getMaterialDefines(const Material& material) noexc for (const auto& [property, ptr] : material.getProperties()) { switch (property) { case Property::Color: - property_defines.append("#define MATERIAL_COLOR\n"); + property_defines.append("#define ENGINE_MATERIAL_COLOR\n"); break; case Property::EmissiveColor: - property_defines.append("#define MATERIAL_EMISSIVE_COLOR\n"); + property_defines.append("#define ENGINE_MATERIAL_EMISSIVE_COLOR\n"); break; case Property::Diffuse: - property_defines.append("#define MATERIAL_DIFFUSE\n"); + property_defines.append("#define ENGINE_MATERIAL_DIFFUSE_TEXTURE\n"); break; case Property::Normal: - property_defines.append("#define MATERIAL_NORMAL\n"); + property_defines.append("#define ENGINE_MATERIAL_NORMAL_TEXTURE\n"); break; case Property::EmissiveMask: - property_defines.append("#define MATERIAL_EMISSIVEMASK\n"); + property_defines.append("#define ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE\n"); break; case Property::BlendMask: - property_defines.append("#define MATERIAL_BLENDMASK\n"); + property_defines.append("#define ENGINE_MATERIAL_BLENDMASK_TEXTURE\n"); break; case Property::Metallic: - property_defines.append("#define MATERIAL_METALLIC\n"); + property_defines.append("#define ENGINE_MATERIAL_METALLIC\n"); break; case Property::Roughness: - property_defines.append("#define MATERIAL_ROUGHNESS\n"); + property_defines.append("#define ENGINE_MATERIAL_ROUGHNESS\n"); break; case Property::MetallicTexture: - property_defines.append("#define MATERIAL_METALLIC_TEXTURE\n"); + property_defines.append("#define ENGINE_MATERIAL_METALLIC_TEXTURE\n"); break; case Property::RoughnessTexture: - property_defines.append("#define MATERIAL_ROUGHNESS_TEXTURE\n"); + property_defines.append("#define ENGINE_MATERIAL_ROUGHNESS_TEXTURE\n"); break; case Property::TessellationFactor: - property_defines.append("#define MATERIAL_TESSELLATION_FACTOR\n"); + property_defines.append("#define ENGINE_MATERIAL_TESSELLATION_FACTOR\n"); break; case Property::AmbientOcclusionTexture: - property_defines.append("#define MATERIAL_AMBIENT_OCCLUSION_TEXTURE\n"); + property_defines.append("#define ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE\n"); break; case Property::IoR: - property_defines.append("#define MATERIAL_IOR\n"); + property_defines.append("#define ENGINE_MATERIAL_IOR\n"); break; case Property::Absorption: - property_defines.append("#define MATERIAL_ABSORPTION\n"); + property_defines.append("#define ENGINE_MATERIAL_ABSORPTION\n"); break; case Property::ORM: - property_defines.append("#define MATERIAL_ORM_TEXTURE\n"); + property_defines.append("#define ENGINE_MATERIAL_ORM_TEXTURE\n"); break; } } if (material.getRefraction()) { - property_defines.append("#define MATERIAL_REFRACTION\n"); + property_defines.append("#define ENGINE_MATERIAL_REFRACTION\n"); } switch (material.getShading()) { case Shading::Lit: - property_defines.append("#define MATERIAL_LIT\n"); + property_defines.append("#define ENGINE_MATERIAL_SHADING_REGULAR_MODEL\n"); break; case Shading::Unlit: - property_defines.append("#define MATERIAL_UNLIT\n"); + property_defines.append("#define ENGINE_MATERIAL_SHADING_UNLIT_MODEL\n"); + break; + case Shading::Cloth: + property_defines.append("#define ENGINE_MATERIAL_SHADING_CLOTH_MODEL\n"); + break; + case Shading::Subsurface: + property_defines.append("#define ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL\n"); + break; + case Shading::Custom: + property_defines.append("#define ENGINE_MATERIAL_SHADING_CUSTOM_MODEL\n"); break; } @@ -127,10 +136,10 @@ void MaterialCompiler::replaceMaterialSettings(Shader& shader, const Material& m shader.replaceKey("_MATERIAL_VERTEX_SNIPPET", material.getVertexSnippet()); shader.replaceKey("_MATERIAL_FRAGMENT_SNIPPET", material.getFragmentSnippet()); - shader.replaceKey("_MATERIAL_GLOBAL_DEFINITIONS", material.getGlobalSnippet()); + shader.replaceKey("ENGINE_MATERIAL_GLOBAL_DEFINITIONS", material.getGlobalSnippet()); shader.replaceKey("_MATERIAL_TESSELLATION_SNIPPET", material.getTessellationSnippet()); - shader.replaceKey("_MATERIAL_SCALAR_UNIFORMS", getCustomMaterialScalarUniforms(material)); - shader.replaceKey("_MATERIAL_SAMPLER_UNIFORMS", getCustomMaterialSamplerUniforms(material)); + shader.replaceKey("ENGINE_MATERIAL_CUSTOM_SCALARS", getCustomMaterialScalarUniforms(material)); + shader.replaceKey("ENGINE_MATERIAL_CUSTOM_SAMPLERS", getCustomMaterialSamplerUniforms(material)); } void MaterialCompiler::compile(const Material& material, ShaderType pass_shader, InstanceType model_shader) { From 058b65e225fe9fa2a6c8c00416f117c16501155c Mon Sep 17 00:00:00 2001 From: hotstreams Date: Fri, 17 Nov 2023 15:23:08 +0300 Subject: [PATCH 02/15] test Signed-off-by: hotstreams --- include/limitless/ms/property.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/limitless/ms/property.hpp b/include/limitless/ms/property.hpp index 274bbb6a..9783b53d 100644 --- a/include/limitless/ms/property.hpp +++ b/include/limitless/ms/property.hpp @@ -46,5 +46,6 @@ namespace Limitless::ms { SubsurfacePower, SheenColor + }; } \ No newline at end of file From 80fc0112b05270a9ce71539b7072fa000d3b6f26 Mon Sep 17 00:00:00 2001 From: Eddie S Date: Fri, 17 Nov 2023 15:25:40 +0300 Subject: [PATCH 03/15] test2 --- include/limitless/ms/property.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/limitless/ms/property.hpp b/include/limitless/ms/property.hpp index 9783b53d..3f2651d8 100644 --- a/include/limitless/ms/property.hpp +++ b/include/limitless/ms/property.hpp @@ -37,6 +37,7 @@ namespace Limitless::ms { IoR, Absorption, + Reflectance, Transmission, MicroThickness, From b58751961f63e848caaa29e0e8e80098d120037d Mon Sep 17 00:00:00 2001 From: hotstreams Date: Sun, 19 Nov 2023 16:58:22 +0300 Subject: [PATCH 04/15] ref --- CMakeLists.txt | 4 +- .../limitless/core/shader/shader_defines.hpp | 33 +++ include/limitless/ms/material_compiler.hpp | 5 - .../limitless/ms/material_shader_definer.hpp | 85 ++++++++ include/limitless/pipeline/shader_type.hpp | 1 + .../render_settings_shader_definer.hpp | 15 ++ shaders_ref/functions/brdf.glsl | 107 ++++++++++ shaders_ref/functions/common.glsl | 34 +++ shaders_ref/instance/instance.glsl | 71 +++++++ shaders_ref/interface_block/effect_fs.glsl | 177 ++++++++++++++++ shaders_ref/interface_block/effect_vs.glsl | 60 ++++++ shaders_ref/interface_block/fragment.glsl | 5 + shaders_ref/interface_block/mesh_fs.glsl | 28 +++ shaders_ref/interface_block/mesh_vs.glsl | 10 + shaders_ref/interface_block/pass_through.glsl | 75 +++++++ .../interface_block/tess_control_input.glsl | 196 ++++++++++++++++++ .../interface_block/tess_control_output.glsl | 74 +++++++ .../interface_block/tess_control_pass.glsl | 69 ++++++ shaders_ref/interface_block/vertex.glsl | 5 + shaders_ref/material/material.glsl | 2 +- shaders_ref/material/material_context.glsl | 2 +- shaders_ref/pipeline/forward.frag | 21 ++ shaders_ref/pipeline/forward.vert | 33 +++ shaders_ref/scene.glsl | 67 ++++++ shaders_ref/shading/shading_context.glsl | 4 + shaders_ref/vertex_streams/beam_emitter.glsl | 88 ++++++++ shaders_ref/vertex_streams/mesh_emitter.glsl | 61 ++++++ shaders_ref/vertex_streams/model_mesh.glsl | 38 ++++ .../vertex_streams/sprite_emitter.glsl | 65 ++++++ shaders_ref/vertex_streams/vertex_stream.glsl | 15 ++ src/limitless/core/shader/shader_compiler.cpp | 63 +----- src/limitless/ms/material_compiler.cpp | 146 +------------ src/limitless/ms/material_shader_definer.cpp | 68 ++++++ .../render_settings_shader_definer.cpp | 71 +++++++ 34 files changed, 1596 insertions(+), 202 deletions(-) create mode 100644 include/limitless/core/shader/shader_defines.hpp create mode 100644 include/limitless/ms/material_shader_definer.hpp create mode 100644 include/limitless/renderer/render_settings_shader_definer.hpp create mode 100644 shaders_ref/functions/brdf.glsl create mode 100644 shaders_ref/functions/common.glsl create mode 100644 shaders_ref/instance/instance.glsl create mode 100644 shaders_ref/interface_block/effect_fs.glsl create mode 100644 shaders_ref/interface_block/effect_vs.glsl create mode 100644 shaders_ref/interface_block/fragment.glsl create mode 100644 shaders_ref/interface_block/mesh_fs.glsl create mode 100644 shaders_ref/interface_block/mesh_vs.glsl create mode 100644 shaders_ref/interface_block/pass_through.glsl create mode 100644 shaders_ref/interface_block/tess_control_input.glsl create mode 100644 shaders_ref/interface_block/tess_control_output.glsl create mode 100644 shaders_ref/interface_block/tess_control_pass.glsl create mode 100644 shaders_ref/interface_block/vertex.glsl create mode 100644 shaders_ref/pipeline/forward.frag create mode 100644 shaders_ref/pipeline/forward.vert create mode 100644 shaders_ref/scene.glsl create mode 100644 shaders_ref/vertex_streams/beam_emitter.glsl create mode 100644 shaders_ref/vertex_streams/mesh_emitter.glsl create mode 100644 shaders_ref/vertex_streams/model_mesh.glsl create mode 100644 shaders_ref/vertex_streams/sprite_emitter.glsl create mode 100644 shaders_ref/vertex_streams/vertex_stream.glsl create mode 100644 src/limitless/ms/material_shader_definer.cpp create mode 100644 src/limitless/renderer/render_settings_shader_definer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 06aea5ae..12fe053c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,7 @@ set(ENGINE_MS src/limitless/ms/material_builder.cpp src/limitless/ms/material_compiler.cpp src/limitless/ms/material_instance.cpp + src/limitless/ms/material_shader_definer.cpp ) set(ENGINE_TEXT @@ -195,7 +196,7 @@ set(ENGINE_FX ) set(ENGINE_PIPELINE - src/limitless/pipeline/pipeline.cpp + src/limitless/pipeline/pipeline.cpp src/limitless/pipeline/pipeline_pass.cpp src/limitless/pipeline/forward/color_pass.cpp src/limitless/pipeline/forward/particle_pass.cpp @@ -207,6 +208,7 @@ set(ENGINE_PIPELINE src/limitless/pipeline/forward/forward.cpp src/limitless/pipeline/forward/postprocessing.cpp src/limitless/renderer/renderer.cpp + src/limitless/renderer/render_settings_shader_definer.cpp src/limitless/pipeline/common/scene_data.cpp src/limitless/pipeline/deferred/effectupdate_pass.cpp src/limitless/pipeline/deferred/deferred_framebuffer_pass.cpp diff --git a/include/limitless/core/shader/shader_defines.hpp b/include/limitless/core/shader/shader_defines.hpp new file mode 100644 index 00000000..8af405dc --- /dev/null +++ b/include/limitless/core/shader/shader_defines.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +namespace Limitless { + enum class EngineShaderDefine { + GLSLVersion, + Extensions, + Settings, + MaterialType, + ModelType, + EmitterType, + + // GLSLVersion + Extensions + Settings + Common, + + // ALL OF ABOVE + MaterialDependent + }; + + static inline std::unordered_map ENGINE_SHADER_DEFINE_NAMES = + { + { EngineShaderDefine::GLSLVersion, "ENGINE::GLSLVERSION"}, + { EngineShaderDefine::Extensions, "ENGINE::EXTENSIONS"}, + { EngineShaderDefine::Settings, "ENGINE::SETTINGS"}, + { EngineShaderDefine::MaterialType, "ENGINE::MATERIALTYPE"}, + { EngineShaderDefine::ModelType, "ENGINE::MODELTYPE"}, + { EngineShaderDefine::EmitterType, "ENGINE::EMITTERTYPE"}, + { EngineShaderDefine::Common, "ENGINE::COMMON"}, + { EngineShaderDefine::MaterialDependent, "ENGINE::MATERIALDEPENDENT"}, + }; +} \ No newline at end of file diff --git a/include/limitless/ms/material_compiler.hpp b/include/limitless/ms/material_compiler.hpp index 274fe165..27412094 100644 --- a/include/limitless/ms/material_compiler.hpp +++ b/include/limitless/ms/material_compiler.hpp @@ -21,11 +21,6 @@ namespace Limitless::ms { protected: Assets& assets; - static std::string getCustomMaterialScalarUniforms(const Material& material) noexcept; - static std::string getCustomMaterialSamplerUniforms(const Material& material) noexcept; - static std::string getMaterialDefines(const Material& material) noexcept; - static std::string getModelDefines(const InstanceType& type); - static void replaceMaterialSettings(Shader& shader, const Material& material, InstanceType model_shader) noexcept; public: MaterialCompiler(Context& context, Assets& assets, const RenderSettings& settings) noexcept; diff --git a/include/limitless/ms/material_shader_definer.hpp b/include/limitless/ms/material_shader_definer.hpp new file mode 100644 index 00000000..41f7acba --- /dev/null +++ b/include/limitless/ms/material_shader_definer.hpp @@ -0,0 +1,85 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace Limitless { + class Shader; + + namespace ms { + class Material; + + class MaterialShaderDefiner { + private: + static inline std::unordered_map SHADER_PROPERTY_DEFINE = + { + { Property::Color, "ENGINE_MATERIAL_COLOR" }, + { Property::EmissiveColor, "ENGINE_MATERIAL_EMISSIVE_COLOR" }, + { Property::Diffuse, "ENGINE_MATERIAL_DIFFUSE_TEXTURE" }, + { Property::Normal, "ENGINE_MATERIAL_NORMAL_TEXTURE" }, + { Property::EmissiveMask, "ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE" }, + { Property::BlendMask, "ENGINE_MATERIAL_BLENDMASK_TEXTURE" }, + { Property::MetallicTexture, "ENGINE_MATERIAL_METALLIC_TEXTURE" }, + { Property::RoughnessTexture, "ENGINE_MATERIAL_ROUGHNESS_TEXTURE" }, + { Property::AmbientOcclusionTexture, "ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE" }, + { Property::ORM, "ENGINE_MATERIAL_ORM_TEXTURE" }, + { Property::TessellationFactor, "ENGINE_MATERIAL_TESSELLATION_FACTOR" }, + { Property::Metallic, "ENGINE_MATERIAL_METALLIC" }, + { Property::Roughness, "ENGINE_MATERIAL_ROUGHNESS" }, + { Property::IoR, "ENGINE_MATERIAL_IOR" }, + { Property::Absorption, "ENGINE_MATERIAL_ABSORPTION" }, + }; + + static inline std::unordered_map SHADER_SHADING_DEFINE = + { + { Shading::Lit, "ENGINE_MATERIAL_SHADING_REGULAR_MODEL" }, + { Shading::Unlit, "ENGINE_MATERIAL_SHADING_UNLIT_MODEL" }, + { Shading::Cloth, "ENGINE_MATERIAL_SHADING_CLOTH_MODEL" }, + { Shading::Subsurface, "ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL" }, + { Shading::Custom, "ENGINE_MATERIAL_SHADING_CUSTOM_MODEL" }, + }; + + static inline std::unordered_map SHADER_MODEL_DEFINE = + { + { InstanceType::Model, "ENGINE_MATERIAL_REGULAR_MODEL" }, + { InstanceType::Skeletal, "ENGINE_MATERIAL_SKELETAL_MODEL" }, + { InstanceType::Instanced, "ENGINE_MATERIAL_INSTANCED_MODEL" }, + { InstanceType::SkeletalInstanced, "ENGINE_MATERIAL_SKELETAL_INSTANCED_MODEL" }, + { InstanceType::Effect, "ENGINE_MATERIAL_EFFECT_MODEL" }, + }; + + enum class SnippetDefineType { + Vertex, + Tesselation, + Fragment, + Global, + CustomScalar, + CustomSamplers + }; + + static inline std::unordered_map SHADER_SNIPPET_DEFINE = + { + { SnippetDefineType::Vertex, "ENGINE_MATERIAL_VERTEX_SNIPPET" }, + { SnippetDefineType::Tesselation, "ENGINE_MATERIAL_TESSELATION_SNIPPET" }, + { SnippetDefineType::Fragment, "ENGINE_MATERIAL_FRAGMENT_SNIPPET" }, + { SnippetDefineType::Global, "ENGINE_MATERIAL_GLOBAL_DEFINITIONS" }, + { SnippetDefineType::CustomScalar, "ENGINE_MATERIAL_CUSTOM_SCALARS" }, + { SnippetDefineType::CustomSamplers, "ENGINE_MATERIAL_CUSTOM_SAMPLERS" }, + }; + + static std::string getPropertyDefines(const Material& material); + static std::string getShadingDefines(const Material& material); + static std::string getModelDefines(InstanceType model_shader); + static std::string getMaterialDefines(const Material& material); + static std::string getScalarUniformDefines(const Material& material); + static std::string getSamplerUniformDefines(const Material& material); + + MaterialShaderDefiner() noexcept = default; + public: + static void define(Shader &shader, const Material& material, InstanceType model_shader); + }; + } +} \ No newline at end of file diff --git a/include/limitless/pipeline/shader_type.hpp b/include/limitless/pipeline/shader_type.hpp index 425aebd5..05de63c0 100644 --- a/include/limitless/pipeline/shader_type.hpp +++ b/include/limitless/pipeline/shader_type.hpp @@ -83,6 +83,7 @@ namespace Limitless { Model, Skeletal, Instanced, + SkeletalInstanced, Effect }; diff --git a/include/limitless/renderer/render_settings_shader_definer.hpp b/include/limitless/renderer/render_settings_shader_definer.hpp new file mode 100644 index 00000000..4b8522f8 --- /dev/null +++ b/include/limitless/renderer/render_settings_shader_definer.hpp @@ -0,0 +1,15 @@ +#pragma once + +namespace Limitless { + class RenderSettings; + class Shader; + + class RenderSettingsShaderDefiner { + private: + const RenderSettings& settings; + public: + explicit RenderSettingsShaderDefiner(const RenderSettings& settings) noexcept; + + void define(Shader& shader); + }; +} \ No newline at end of file diff --git a/shaders_ref/functions/brdf.glsl b/shaders_ref/functions/brdf.glsl new file mode 100644 index 00000000..6e4b4f25 --- /dev/null +++ b/shaders_ref/functions/brdf.glsl @@ -0,0 +1,107 @@ +// "An Inexpensive BRDF Model for Physically-Based Rendering", Schlick 1994 +vec3 F_Schlick(const vec3 F0, float F90, float VoH) { + return F0 + (F90 - F0) * pow5(1.0 - VoH); +} + +vec3 F_Schlick(const vec3 F0, float VoH) { + return F0 + (vec3(1.0) - F0) * pow5(1.0 - VoH); +} + +float F_Schlick(float F0, float f90, float VoH) { + return F0 + (f90 - F0) * pow5(1.0 - VoH); +} + +// "Microfacet Models for Refraction through Rough Surfaces", Walter et al. 2007 +float D_GGX(float roughness, float NoH) { + float oneMinusNoHSquared = 1.0 - NoH * NoH; + float a = NoH * roughness; + float k = roughness / (oneMinusNoHSquared + a * a); + float d = k * k * (1.0 / PI); + return d; +} + +// "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", Heitz 2014 +float V_SmithGGXCorrelated(float NoV, float NoL, float a2, float lambdaV) { + float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2); + return 0.5 / (lambdaV + lambdaL); +} + +// Hammon 2017, "PBR Diffuse Lighting for GGX+Smith Microsurfaces" +float V_SmithGGXCorrelatedFast(float roughness, float NoV, float NoL) { + float v = 0.5 / mix(2.0 * NoL * NoV, NoL + NoV, roughness); + return v; +} + +vec3 SpecularF(const vec3 F0, float LoH) { +#if defined (ENGINE_MATERIAL_QUALITY_LOW) + return F_Schlick(F0, LoH); +#else + float F90 = saturate(dot(F0, vec3(50.0 * 0.33))); + return F_Schlick(F0, F90, LoH); +#endif +} + +// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF" +float D_Charlie(float roughness, float NoH) { + float invAlpha = 1.0 / roughness; + float cos2h = NoH * NoH; + float sin2h = max(1.0 - cos2h, 0.0078125); // 2^(-14/2), so sin2h^2 > 0 in fp16 + return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI); +} + +// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886" +float V_Neubelt(float NoV, float NoL) { + return 1.0 / (4.0 * (NoL + NoV - NoL * NoV)); +} + +// "Physically-Based Shading at Disney", Burley 2012 +float Fd_Burley(float roughness, float NoV, float NoL, float LoH) { + float F90 = 0.5 + 2.0 * roughness * LoH * LoH; + float lightScatter = F_Schlick(1.0, F90, NoL); + float viewScatter = F_Schlick(1.0, F90, NoV); + return lightScatter * viewScatter * (1.0 / PI); +} + +float Fd_Lambert() { + return 1.0 / PI; +} + +// Energy conserving wrap diffuse term, does *not* include the divide by pi +float Fd_Wrap(float NoL, float w) { + float w1 = 1.0 + w; + float x = w1 * w1; + return (NoL + w) / x; +} + +vec3 DiffuseBRDF(const ShadingContext sctx, const LightingContext lctx) { +#if defined (ENGINE_MATERIAL_DIFFUSE_BURLEY) + return sctx.diffuseColor * Fd_Burley(sctx.roughness, sctx.NoV, lctx.NoL, lctx.LoH); +#elif defined (ENGINE_MATERIAL_DIFFUSE_LAMBERT) + return sctx.diffuseColor * Fd_Lambert(); +#endif +} + +vec3 SpecularBRDF(const ShadingContext sctx, const LightingContext lctx) { + float D = D_GGX(sctx.roughness, lctx.NoH); +#if defined (ENGINE_MATERIAL_SPECULAR_GGX) + float V = V_SmithGGXCorrelated(sctx.NoV, lctx.NoL, sctx.a2, lctxlambdaV); +#elif defined (ENGINE_MATERIAL_SPECULAR_GGX_FAST) + float V = V_SmithGGXCorrelatedFast(sctx.roughness, sctx.NoV, lctx.NoL); +#endif + vec3 F = SpecularF(sctx.F0, lctx.LoH); + return (D * V) * F; +} + +vec3 DiffuseBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { + vec3 diffuse = DiffuseBRDF(sctx, lctx); +#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) + diffuse *= Fd_Wrap(lsctx.NoL, 0.5); +#endif + return diffuse; +} + +vec3 SpecularBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { + float D = D_Charlie(sctx.roughness, lctx.NoH); + float V = V_Neubelt(sctx.NoV, lctx.NoL); + return (D * V) * sctx.F0; +} diff --git a/shaders_ref/functions/common.glsl b/shaders_ref/functions/common.glsl new file mode 100644 index 00000000..2d6ba6da --- /dev/null +++ b/shaders_ref/functions/common.glsl @@ -0,0 +1,34 @@ +#define PI 3.14159265359 +#define MIN_ROUGHNESS 0.002025 +#define MIN_PERCEPTUAL_ROUGHNESS 0.045 + +#define MIN_NoV 1e-4 + +float pow5(float x) { + float x2 = x * x; + return x2 * x2 * x; +} + +float saturate(float val) { + return clamp(val, 0.0, 1.0); +} + +vec3 computeDiffuseColor(const vec3 baseColor, float metallic) { + return baseColor * (1.0 - metallic); +} + +vec3 computeF0(const vec3 baseColor, float metallic, float reflectance) { + return baseColor * metallic + (reflectance * (1.0 - metallic)); +} + +float computeNoV(const vec3 N, const vec3 V) { + float NoV = saturate(dot(N, V)); + return max(MIN_NoV, NoV); +} + +// "Material Advances in Call of Duty: WWII", Chan 2018 +float computeMicroShadowing(float NoL, float visibility) { + float aperture = inversesqrt(1.0 - visibility); + float microShadow = saturate(NoL * aperture); + return microShadow * microShadow; +} diff --git a/shaders_ref/instance/instance.glsl b/shaders_ref/instance/instance.glsl new file mode 100644 index 00000000..6a46f03f --- /dev/null +++ b/shaders_ref/instance/instance.glsl @@ -0,0 +1,71 @@ +// REGULAR MODEL OR SKELETAL MODEL +#if defined (ENGINE_MATERIAL_REGULAR_MODEL) || defined (ENGINE_MATERIAL_SKELETAL_MODEL) +uniform mat4 _model_transform; + +mat4 getModelMatrix() { + return _model_transform; +} +#endif +// + +// INSTANCED MODEL +#if defined (ENGINE_MATERIAL_INSTANCED_MODEL) +layout (std430) buffer model_buffer { + mat4 _models[]; +}; + +mat4 getModelMatrix() { + return _models[gl_InstanceID]; +} +#endif +// + +// SKELETAL MODEL +#if defined (ENGINE_MATERIAL_SKELETAL_MODEL) +layout (std430) buffer bone_buffer { + mat4 _bones[]; +}; + +mat4 getBoneMatrix() { + ivec4 bone_id = getVertexBoneID(); + vec4 bone_weight = getVertexBoneWeight(); + + mat4 bone_transform = _bones[bone_id[0]] * bone_weight[0]; + bone_transform += _bones[bone_id[1]] * bone_weight[1]; + bone_transform += _bones[bone_id[2]] * bone_weight[2]; + bone_transform += _bones[bone_id[3]] * bone_weight[3]; + + return bone_transform; +} +#endif +// + +// EFFECT MODEL +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) && !defined (MeshEmitter) + mat4 getModelMatrix() { + return mat4(1.0); +} +#endif + +mat4 getModelTransform() { + #if defined (ENGINE_MATERIAL_SKELETAL_MODEL) + return getModelMatrix() * getBoneMatrix(); + #else + return getModelMatrix(); + #endif +} + +// TBN matrix only for meshes +#if (defined (MeshEmitter) || defined (ENGINE_MATERIAL_REGULAR_MODEL) || defined (ENGINE_MATERIAL_SKELETAL_MODEL) || defined (ENGINE_MATERIAL_INSTANCED_MODEL)) && defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 getModelTBN(mat4 model_transform) { + //TODO: pass through uniform instance buffer ? bone transform ? + mat3 normal_matrix = transpose(inverse(mat3(model_transform))); + + vec3 T = normalize(normal_matrix * getVertexTangent()); + vec3 N = normalize(normal_matrix * getVertexNormal()); + T = normalize(T - dot(T, N) * N); + vec3 B = cross(N, T); + + return mat3(T, B, N); +} +#endif diff --git a/shaders_ref/interface_block/effect_fs.glsl b/shaders_ref/interface_block/effect_fs.glsl new file mode 100644 index 00000000..df4651ea --- /dev/null +++ b/shaders_ref/interface_block/effect_fs.glsl @@ -0,0 +1,177 @@ +in _vertex_data { + #if defined (InitialColor_MODULE) + vec4 color; + #endif + + #if defined (SubUV_MODULE) + vec4 subUV; + #endif + + #if defined (CustomMaterial_MODULE) + vec4 properties; + #endif + + #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) + vec3 acceleration; + float lifetime; + #endif + + #if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + #endif + + vec3 world_position; + + #if defined (SpriteEmitter) + float size; + #endif + + #if defined (InitialRotation_MODULE) || defined (Time_MODULE) + vec3 rotation; + float time; + #endif + + #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) + vec3 velocity; + #endif + + #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) + vec3 velocity; + float size; + #endif + + #if defined (MeshEmitter) + vec3 size; + #endif + + #if defined (BeamEmitter) || defined (MeshEmitter) + vec2 uv; + #endif + + #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) + vec3 start; + vec3 end; + float length; + #endif +} _in_data; + +#if defined (BeamEmitter) && defined (BeamSpeed_MODULE) + float getParticleLength() { + return _in_data.length; + } + + vec3 getParticleStart() { + return _in_data.start; + } + + vec3 getParticleEnd() { + return _in_data.end; + } +#endif + +#if defined (InitialColor_MODULE) + vec4 getParticleColor() { + return _in_data.color; + } +#endif + +#if defined (SubUV_MODULE) + vec4 getParticleSubUV() { + return _in_data.subUV; + } +#endif + +#if defined (CustomMaterial_MODULE) + vec4 getParticleProperties() { + return _in_data.properties; + } +#endif + +#if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) + vec3 getParticleAcceleration() { + return _in_data.acceleration; + } + + float getParticleLifetime() { + return _in_data.lifetime; + } +#endif + +vec3 getVertexPosition() { + return _in_data.world_position; +} + +#if defined (SpriteEmitter) + float getParticleSize() { + return _in_data.size; + } +#endif + +#if defined (InitialRotation_MODULE) || defined (Time_MODULE) + vec3 getParticleRotation() { + return _in_data.rotation; + } + + float getParticleTime() { + return _in_data.time; + } +#endif + +#if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) + vec3 getParticleVelocity() { + return _in_data.velocity; + } +#endif + +#if defined (BeamEmitter) && defined (InitialVelocity_MODULE) + vec3 getParticleVelocity() { + return _in_data.velocity; + } + + float getParticleSize() { + return _in_data.size; + } +#endif + +#if defined (BeamEmitter) || defined (MeshEmitter) + vec2 getVertexUV() { + return _in_data.uv; + } +#endif + +#if defined (SpriteEmitter) + vec2 getVertexUV() { + vec2 uv = gl_PointCoord; + + #if defined (InitialRotation_MODULE) + vec2 center = vec2(0.5, 0.5); + vec2 translated = uv - center; + mat2 rotation = mat2(cos(getParticleRotation().x), sin(getParticleRotation().x), -sin(getParticleRotation().x), cos(getParticleRotation().x)); + translated = rotation * translated; + translated = translated + center; + uv = clamp(translated, 0.0, 1.0); + #endif + + #if defined (SubUV_MODULE) + uv = uv * getParticleSubUV().xy + getParticleSubUV().zw; + #endif + + return uv; + } +#endif + +#if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 getVertexTBN() { + return _in_data.TBN; + } + #else + vec3 getVertexNormal() { + return _in_data.normal; + } + #endif +#endif diff --git a/shaders_ref/interface_block/effect_vs.glsl b/shaders_ref/interface_block/effect_vs.glsl new file mode 100644 index 00000000..84e1c873 --- /dev/null +++ b/shaders_ref/interface_block/effect_vs.glsl @@ -0,0 +1,60 @@ +out _vertex_data { + #if defined (InitialColor_MODULE) + vec4 color; + #endif + + #if defined (SubUV_MODULE) + vec4 subUV; + #endif + + #if defined (CustomMaterial_MODULE) + vec4 properties; + #endif + + #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) + vec3 acceleration; + float lifetime; + #endif + + #if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + #endif + + vec3 world_position; + + #if defined (SpriteEmitter) + float size; + #endif + + #if defined (InitialRotation_MODULE) || defined (Time_MODULE) + vec3 rotation; + float time; + #endif + + #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) + vec3 velocity; + #endif + + #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) + vec3 velocity; + float size; + #endif + + #if defined (MeshEmitter) + vec3 size; + #endif + + #if defined (BeamEmitter) || defined (MeshEmitter) + vec2 uv; + #endif + + #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) + vec3 start; + vec3 end; + float length; + #endif +} _out_data; diff --git a/shaders_ref/interface_block/fragment.glsl b/shaders_ref/interface_block/fragment.glsl new file mode 100644 index 00000000..2b95b1e0 --- /dev/null +++ b/shaders_ref/interface_block/fragment.glsl @@ -0,0 +1,5 @@ +#if defined (EFFECT_MODEL) + #include "./effect_fs.glsl" +#else + #include "./mesh_fs.glsl" +#endif diff --git a/shaders_ref/interface_block/mesh_fs.glsl b/shaders_ref/interface_block/mesh_fs.glsl new file mode 100644 index 00000000..04f2f425 --- /dev/null +++ b/shaders_ref/interface_block/mesh_fs.glsl @@ -0,0 +1,28 @@ +in _vertex_data { + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + + vec3 world_position; + vec2 uv; +} _in_data; + +vec3 getVertexPosition() { + return _in_data.world_position; +} + +vec2 getVertexUV() { + return _in_data.uv; +} + +#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 getVertexTBN() { + return _in_data.TBN; + } +#else + vec3 getVertexNormal() { + return _in_data.normal; + } +#endif diff --git a/shaders_ref/interface_block/mesh_vs.glsl b/shaders_ref/interface_block/mesh_vs.glsl new file mode 100644 index 00000000..4c088471 --- /dev/null +++ b/shaders_ref/interface_block/mesh_vs.glsl @@ -0,0 +1,10 @@ +out _vertex_data { + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + + vec3 world_position; + vec2 uv; +} _out_data; diff --git a/shaders_ref/interface_block/pass_through.glsl b/shaders_ref/interface_block/pass_through.glsl new file mode 100644 index 00000000..40b7edb2 --- /dev/null +++ b/shaders_ref/interface_block/pass_through.glsl @@ -0,0 +1,75 @@ +void InterfaceBlockPassThrough(vec3 world_position, vec2 uv, mat4 model_transform) { + #if defined (EFFECT_MODEL) + _out_data.world_position = world_position; + + #if !defined (SpriteEmitter) + _out_data.uv = uv; + #endif + + #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) + _out_data.start = getParticleStart(); + _out_data.end = getParticleEnd(); + _out_data.length = getParticleLength(); + #endif + + #if defined (SpriteEmitter) + #if defined (InitialSize_MODULE) + gl_PointSize = getProjection()[1][1] * getParticleSize() / gl_Position.w; + #else + gl_PointSize = getProjection()[1][1] * 16.0 / gl_Position.w; + #endif + #endif + + #if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + _out_data.TBN = getModelTBN(model_transform); + #else + _out_data.normal = transpose(inverse(mat3(model_transform))) * getVertexNormal(); + #endif + #endif + + #if defined (InitialColor_MODULE) + _out_data.color = getParticleColor(); + #endif + + #if defined (SubUV_MODULE) + _out_data.subUV = getParticleSubUV(); + #endif + + #if defined (CustomMaterial_MODULE) + _out_data.properties = getParticleProperties(); + #endif + + #if defined (InitialRotation_MODULE) || defined (Time_MODULE) + _out_data.rotation = getParticleRotation(); + _out_data.time = getParticleTime(); + #endif + + #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) + _out_data.velocity = getParticleVelocity(); + #endif + + #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_Module)) + _out_data.velocity = getParticleVelocity(); + _out_data.size = getParticleSize(); + #endif + + #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) + _out_data.acceleration = getParticleAcceleration(); + _out_data.lifetime = getParticleLifetime(); + #endif + + #if defined (SpriteEmitter) + _out_data.size = getParticleSize(); + #endif + #else + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + _out_data.TBN = getModelTBN(model_transform); + #else + _out_data.normal = transpose(inverse(mat3(model_transform))) * getVertexNormal(); + #endif + + _out_data.world_position = world_position; + _out_data.uv = uv; + #endif +} diff --git a/shaders_ref/interface_block/tess_control_input.glsl b/shaders_ref/interface_block/tess_control_input.glsl new file mode 100644 index 00000000..837c09f9 --- /dev/null +++ b/shaders_ref/interface_block/tess_control_input.glsl @@ -0,0 +1,196 @@ +#if defined (EFFECT_MODEL) +in _vertex_data { +#if defined (InitialColor_MODULE) + vec4 color; + #endif + + #if defined (SubUV_MODULE) + vec4 subUV; + #endif + + #if defined (CustomMaterial_MODULE) + vec4 properties; + #endif + + #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) + vec3 acceleration; + float lifetime; + #endif + + #if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + #endif + + vec3 world_position; + + #if defined (SpriteEmitter) + float size; + #endif + + #if defined (InitialRotation_MODULE) || defined (Time_MODULE) + vec3 rotation; + float time; + #endif + + #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) + vec3 velocity; + #endif + + #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) + vec3 velocity; + float size; + #endif + + #if defined (MeshEmitter) + vec3 size; + #endif + + #if defined (BeamEmitter) || defined (MeshEmitter) + vec2 uv; + #endif + + #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) + vec3 start; + vec3 end; + float length; + #endif +} _in_data[]; + +#if defined (BeamEmitter) && defined (BeamSpeed_MODULE) +float getParticleLength(uint id) { + return _in_data[id].length; +} + +vec3 getParticleStart(uint id) { + return _in_data[id].start; +} + +vec3 getParticleEnd(uint id) { + return _in_data[id].end; +} + #endif + + #if defined (InitialColor_MODULE) +vec4 getParticleColor(uint id) { + return _in_data[id].color; +} + #endif + + #if defined (SubUV_MODULE) +vec4 getParticleSubUV(uint id) { + return _in_data[id].subUV; +} + #endif + + #if defined (CustomMaterial_MODULE) +vec4 getParticleProperties(uint id) { + return _in_data[id].properties; +} + #endif + + #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) +vec3 getParticleAcceleration(uint id) { + return _in_data[id].acceleration; +} + +float getParticleLifetime(uint id) { + return _in_data[id].lifetime; +} + #endif + +vec3 getVertexPosition(uint id) { + return _in_data[id].world_position; +} + + #if defined (SpriteEmitter) +float getParticleSize(uint id) { + return _in_data[id].size; +} + #endif + + #if defined (InitialRotation_MODULE) || defined (Time_MODULE) +vec3 getParticleRotation(uint id) { + return _in_data[id].rotation; +} + +float getParticleTime(uint id) { + return _in_data[id].time; +} + #endif + + #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) +vec3 getParticleVelocity(uint id) { + return _in_data[id].velocity; +} + #endif + + #if defined (BeamEmitter) && defined (InitialVelocity_MODULE) +vec3 getParticleVelocity(uint id) { + return _in_data[id].velocity; +} + +float getParticleSize(uint id) { + return _in_data[id].size; +} + #endif + + #if defined (BeamEmitter) || defined (MeshEmitter) +vec2 getVertexUV(uint id) { + return _in_data[id].uv; +} + #endif + + #if defined (SpriteEmitter) +vec2 getVertexUV() { + vec2 uv = gl_PointCoord; + + return uv; +} + #endif + + #if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) +mat3 getVertexTBN(uint id) { + return _in_data[id].TBN; +} + #else +vec3 getVertexNormal(uint id) { + return _in_data[id].normal; +} + #endif + #endif + + #else +in _vertex_data { +#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + + vec3 world_position; + vec2 uv; +} _in_data[]; + +vec3 getVertexPosition(uint id) { + return _in_data[id].world_position; +} + +vec2 getVertexUV(uint id) { + return _in_data[id].uv; +} + + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) +mat3 getVertexTBN(uint id) { + return _in_data[id].TBN; +} + #else +vec3 getVertexNormal(uint id) { + return _in_data[id].normal; +} + #endif + #endif \ No newline at end of file diff --git a/shaders_ref/interface_block/tess_control_output.glsl b/shaders_ref/interface_block/tess_control_output.glsl new file mode 100644 index 00000000..17180000 --- /dev/null +++ b/shaders_ref/interface_block/tess_control_output.glsl @@ -0,0 +1,74 @@ +#if defined (EFFECT_MODEL) + out _vertex_data { + #if defined (InitialColor_MODULE) + vec4 color; + #endif + + #if defined (SubUV_MODULE) + vec4 subUV; + #endif + + #if defined (CustomMaterial_MODULE) + vec4 properties; + #endif + + #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) + vec3 acceleration; + float lifetime; + #endif + + #if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + #endif + + vec3 world_position; + + #if defined (SpriteEmitter) + float size; + #endif + + #if defined (InitialRotation_MODULE) || defined (Time_MODULE) + vec3 rotation; + float time; + #endif + + #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) + vec3 velocity; + #endif + + #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) + vec3 velocity; + float size; + #endif + + #if defined (MeshEmitter) + vec3 size; + #endif + + #if defined (BeamEmitter) || defined (MeshEmitter) + vec2 uv; + #endif + + #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) + vec3 start; + vec3 end; + float length; + #endif + } _out_data[]; + +#else + out _vertex_data { + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + mat3 TBN; + #else + vec3 normal; + #endif + + vec3 world_position; + vec2 uv; + } _out_data[]; +#endif \ No newline at end of file diff --git a/shaders_ref/interface_block/tess_control_pass.glsl b/shaders_ref/interface_block/tess_control_pass.glsl new file mode 100644 index 00000000..07a8d7d1 --- /dev/null +++ b/shaders_ref/interface_block/tess_control_pass.glsl @@ -0,0 +1,69 @@ +void InterfaceBlockPassThrough() { + uint index = uint(gl_InvocationID); + +#if defined (EFFECT_MODEL) + _out_data[gl_InvocationID].world_position = getVertexPosition(index); + + #if !defined (SpriteEmitter) + _out_data[gl_InvocationID].uv = getVertexUV(index); + #endif + + #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) + _out_data[gl_InvocationID].start = getParticleStart(index); + _out_data[gl_InvocationID].end = getParticleEnd(index); + _out_data[gl_InvocationID].length = getParticleLength(index); + #endif + + #if defined (MeshEmitter) + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + _out_data[gl_InvocationID].TBN = getVertexTBN(index); + #else + _out_data[gl_InvocationID].normal = getVertexNormal(index); + #endif + #endif + + #if defined (InitialColor_MODULE) + _out_data[gl_InvocationID].color = getParticleColor(index); + #endif + + #if defined (SubUV_MODULE) + _out_data[gl_InvocationID].subUV = getParticleSubUV(index); + #endif + + #if defined (CustomMaterial_MODULE) + _out_data[gl_InvocationID].properties = getParticleProperties(index); + #endif + + #if defined (InitialRotation_MODULE) || defined (Time_MODULE) + _out_data[gl_InvocationID].rotation = getParticleRotation(index); + _out_data[gl_InvocationID].time = getParticleTime(index); + #endif + + #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) + _out_data[gl_InvocationID].velocity = getParticleVelocity(index); + #endif + + #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_Module)) + _out_data[gl_InvocationID].velocity = getParticleVelocity(index); + _out_data[gl_InvocationID].size = getParticleSize(index); + #endif + + #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) + _out_data[gl_InvocationID].acceleration = getParticleAcceleration(index); + _out_data[gl_InvocationID].lifetime = getParticleLifetime(index); + #endif + + #if defined (SpriteEmitter) + _out_data[gl_InvocationID].size = getParticleSize(index); + #endif +#else + #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + _out_data[gl_InvocationID].TBN = getVertexTBN(index); + #else + _out_data[gl_InvocationID].normal = getVertexNormal(index); + #endif + + _out_data[gl_InvocationID].world_position = getVertexPosition(index); + _out_data[gl_InvocationID].uv = getVertexUV(index); +#endif +} diff --git a/shaders_ref/interface_block/vertex.glsl b/shaders_ref/interface_block/vertex.glsl new file mode 100644 index 00000000..fd16e727 --- /dev/null +++ b/shaders_ref/interface_block/vertex.glsl @@ -0,0 +1,5 @@ +#if defined (EFFECT_MODEL) + #include "./effect_vs.glsl" +#else + #include "./mesh_vs.glsl" +#endif diff --git a/shaders_ref/material/material.glsl b/shaders_ref/material/material.glsl index 0725208d..24d85dee 100644 --- a/shaders_ref/material/material.glsl +++ b/shaders_ref/material/material.glsl @@ -156,7 +156,7 @@ ENGINE_MATERIAL_GLOBAL_DEFINITIONS #endif #if defined (ENGINE_MATERIAL_REFRACTION) -#if defined (MATERIAL_IOR) +#if defined (ENGINE_MATERIAL_IOR) float getMaterialIOR() { return _material_ior; } diff --git a/shaders_ref/material/material_context.glsl b/shaders_ref/material/material_context.glsl index 189e7ebb..9424cd3e 100644 --- a/shaders_ref/material/material_context.glsl +++ b/shaders_ref/material/material_context.glsl @@ -102,7 +102,7 @@ MaterialContext computeMaterialContext() { #endif #if defined (ENGINE_MATERIAL_REFRACTION) -#if defined (MATERIAL_IOR) +#if defined (ENGINE_MATERIAL_IOR) mctx.IoR = getMaterialIOR(); #else mctx.IoR = 1.0; diff --git a/shaders_ref/pipeline/forward.frag b/shaders_ref/pipeline/forward.frag new file mode 100644 index 00000000..10a52301 --- /dev/null +++ b/shaders_ref/pipeline/forward.frag @@ -0,0 +1,21 @@ +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/fragment.glsl" +#include "../scene.glsl" +#include "../shading/fragment.glsl" + +out vec4 color; + +void main() { + MaterialContext mctx = computeMaterialContext(); + + + + FragmentData data = initializeFragmentData(); + + customFragment(data); + + + + color = computeFragment(data); +} \ No newline at end of file diff --git a/shaders_ref/pipeline/forward.vert b/shaders_ref/pipeline/forward.vert new file mode 100644 index 00000000..e3fab37a --- /dev/null +++ b/shaders_ref/pipeline/forward.vert @@ -0,0 +1,33 @@ +ENGINE::MATERIALDEPENDENT + +#include "../vertex_streams/vertex_stream.glsl" +#include "../interface_block/vertex.glsl" +#include "../shading/common.glsl" +#include "../scene.glsl" +#include "../instance/instance.glsl" +#include "../material/material.glsl" +#include "../interface_block/pass_through.glsl" + +void main() { + #if !defined (SpriteEmitter) + vec2 uv = getVertexUV(); + #else + vec2 uv = vec2(0.0); + #endif + + vec3 vertex_position = getVertexPosition(); + + // %uv + // %vertex_position + _MATERIAL_VERTEX_SNIPPET + + mat4 model_transform = getModelTransform(); + + vec4 world_position = model_transform * vec4(vertex_position, 1.0); + + #if !defined (MATERIAL_TESSELATION_FACTOR) + gl_Position = getViewProjection() * world_position; + #endif + + InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); +} diff --git a/shaders_ref/scene.glsl b/shaders_ref/scene.glsl new file mode 100644 index 00000000..618a48c6 --- /dev/null +++ b/shaders_ref/scene.glsl @@ -0,0 +1,67 @@ +/* + mat4 getProjection(); + mat4 getProjectionInverse(); + mat4 getView(); + mat4 getViewInverse(); + mat4 getViewProjection(); + mat4 getViewProjectionInverse(); + vec3 getCameraPosition(); +*/ + +layout (std140) uniform scene_data { + mat4 _projection; + mat4 _projection_inverse; + mat4 _view_to_screen; + mat4 _view; + mat4 _view_inverse; + mat4 _VP; + mat4 _VP_inverse; + vec4 _camera_position; + vec2 _resolution; + float _far_plane; + float _near_plane; +}; + +mat4 getProjection() { + return _projection; +} + +mat4 getProjectionInverse() { + return _projection_inverse; +} + +mat4 getViewToScreen() { + return _view_to_screen; +} + +mat4 getView() { + return _view; +} + +mat4 getViewInverse() { + return _view_inverse; +} + +mat4 getViewProjection() { + return _VP; +} + +mat4 getViewProjectionInverse() { + return _VP_inverse; +} + +vec3 getCameraPosition() { + return _camera_position.xyz; +} + +float getCameraFarPlane() { + return _far_plane; +} + +float getCameraNearPlane() { + return _near_plane; +} + +vec2 getResolution() { + return _resolution; +} diff --git a/shaders_ref/shading/shading_context.glsl b/shaders_ref/shading/shading_context.glsl index da389327..5186daa0 100644 --- a/shaders_ref/shading/shading_context.glsl +++ b/shaders_ref/shading/shading_context.glsl @@ -48,3 +48,7 @@ ShadingContext computeShadingContext( return context; } + +ShadingContext computeShadingContext() { + +} diff --git a/shaders_ref/vertex_streams/beam_emitter.glsl b/shaders_ref/vertex_streams/beam_emitter.glsl new file mode 100644 index 00000000..834db8a6 --- /dev/null +++ b/shaders_ref/vertex_streams/beam_emitter.glsl @@ -0,0 +1,88 @@ +layout (location = 0) in vec4 vertex_position; + +vec3 getVertexPosition() { + return vertex_position.xyz; +} + +#if defined(InitialColor_MODULE) + layout (location = 1) in vec4 vertex_color; + + vec4 getParticleColor() { + return vertex_color; + } +#endif + +#if defined(SubUV_MODULE) + layout(location = 2) in vec4 vertex_subUV; + + vec4 getParticleSubUV() { + return vertex_subUV; + } +#endif + +#if defined(CustomMaterial_MODULE) + layout(location = 3) in vec4 vertex_properties; + + vec4 getParticleProperties() { + return vertex_properties; + } +#endif + +#if defined(Lifetime_MODULE) || defined(Acceleration_MODULE) + layout(location = 4) in vec4 vertex_acceleration_lifetime; + + vec3 getParticleAcceleration() { + return vertex_acceleration_lifetime.xyz; + } + + float getParticleLifetime() { + return vertex_acceleration_lifetime.w; + } +#endif + +#if defined(InitialRotation_MODULE) || defined(Time_MODULE) + layout(location = 5) in vec4 vertex_rotation_time; + + vec3 getParticleRotation() { + return vertex_rotation_time.xyz; + } + + float getParticleTime() { + return vertex_rotation_time.w; + } +#endif + +#if defined(InitialVelocity_MODULE) || defined(InitialSize_MODULE) + layout(location = 6) in vec4 vertex_velocity_size; + + vec3 getParticleVelocity() { + return vertex_velocity_size.xyz; + } + + float getParticleSize() { + return vertex_velocity_size.w; + } +#endif + +layout (location = 7) in vec4 vertex_uv_length; + +vec2 getVertexUV() { + return vertex_uv_length.xy; +} + +float getParticleLength() { + return vertex_uv_length.z; +} + +#if defined(BeamSpeed_MODULE) + layout (location = 8) in vec3 vertex_start; + layout (location = 9) in vec3 vertex_end; + + vec3 getParticleStart() { + return vertex_start; + } + + vec3 getParticleEnd() { + return vertex_end; + } +#endif diff --git a/shaders_ref/vertex_streams/mesh_emitter.glsl b/shaders_ref/vertex_streams/mesh_emitter.glsl new file mode 100644 index 00000000..3e3e51de --- /dev/null +++ b/shaders_ref/vertex_streams/mesh_emitter.glsl @@ -0,0 +1,61 @@ +#include "./model_mesh.glsl" + +struct MeshParticle { + mat4 model; + vec4 color; + vec4 subUV; + vec4 properties; + vec4 acceleration_lifetime; + vec4 position; + vec4 rotation_time; + vec4 velocity; + vec4 size; +}; + +layout (std430) buffer mesh_emitter_particles { + MeshParticle _particles[]; +}; + +mat4 getModelMatrix() { + return _particles[gl_InstanceID].model; +} + +vec4 getParticleColor() { + return _particles[gl_InstanceID].color; +} + +vec4 getParticleSubUV() { + return _particles[gl_InstanceID].subUV; +} + +vec4 getParticleProperties() { + return _particles[gl_InstanceID].properties; +} + +vec3 getParticleAcceleration() { + return _particles[gl_InstanceID].acceleration_lifetime.xyz; +} + +float getParticleLifetime() { + return _particles[gl_InstanceID].acceleration_lifetime.w; +} + +vec3 getParticlePosition() { + return _particles[gl_InstanceID].position.xyz; +} + +vec3 getParticleSize() { + return _particles[gl_InstanceID].size.xyz; +} + +vec3 getParticleRotation() { + return _particles[gl_InstanceID].rotation_time.xyz; +} + +float getParticleTime() { + return _particles[gl_InstanceID].rotation_time.w; +} + +vec3 getParticleVelocity() { + return _particles[gl_InstanceID].velocity.xyz; +} diff --git a/shaders_ref/vertex_streams/model_mesh.glsl b/shaders_ref/vertex_streams/model_mesh.glsl new file mode 100644 index 00000000..1bc0aea0 --- /dev/null +++ b/shaders_ref/vertex_streams/model_mesh.glsl @@ -0,0 +1,38 @@ +layout (location = 0) in vec3 _vertex_position; +layout (location = 1) in vec3 _vertex_normal; +#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + layout (location = 2) in vec3 _vertex_tangent; +#endif +layout (location = 3) in vec2 _vertex_uv; +#if defined (SKELETAL_MODEL) + layout (location = 4) in ivec4 _vertex_bone_id; + layout (location = 5) in vec4 _vertex_bone_weight; +#endif + +vec3 getVertexPosition() { + return _vertex_position; +} + +vec3 getVertexNormal() { + return _vertex_normal; +} + +vec2 getVertexUV() { + return _vertex_uv; +} + +#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + vec3 getVertexTangent() { + return _vertex_tangent; + } +#endif + +#if defined (SKELETAL_MODEL) + ivec4 getVertexBoneID() { + return _vertex_bone_id; + } + + vec4 getVertexBoneWeight() { + return _vertex_bone_weight; + } +#endif diff --git a/shaders_ref/vertex_streams/sprite_emitter.glsl b/shaders_ref/vertex_streams/sprite_emitter.glsl new file mode 100644 index 00000000..b48641fb --- /dev/null +++ b/shaders_ref/vertex_streams/sprite_emitter.glsl @@ -0,0 +1,65 @@ +#if defined(InitialColor_MODULE) + layout(location = 0) in vec4 vertex_color; + + vec4 getParticleColor() { + return vertex_color; + } +#endif + +#if defined(SubUV_MODULE) + layout(location = 1) in vec4 vertex_subUV; + + vec4 getParticleSubUV() { + return vertex_subUV; + } +#endif + +#if defined(CustomMaterial_MODULE) + layout(location = 2) in vec4 vertex_properties; + + vec4 getParticleProperties() { + return vertex_properties; + } +#endif + +#if defined(Lifetime_MODULE) || defined(Acceleration_MODULE) + layout(location = 3) in vec4 vertex_acceleration_lifetime; + + vec3 getParticleAcceleration() { + return vertex_acceleration_lifetime.xyz; + } + + float getParticleLifetime() { + return vertex_acceleration_lifetime.w; + } +#endif + +layout (location = 4) in vec4 vertex_position_size; + +vec3 getVertexPosition() { + return vertex_position_size.xyz; +} + +float getParticleSize() { + return vertex_position_size.w; +} + +#if defined (InitialRotation_MODULE) || defined (Time_MODULE) + layout(location = 5) in vec4 vertex_rotation_time; + + vec3 getParticleRotation() { + return vertex_rotation_time.xyz; + } + + float getParticleTime() { + return vertex_rotation_time.w; + } +#endif + +#if defined(InitialVelocity_MODULE) + layout(location = 6) in vec4 vertex_velocity; + + vec3 getParticleVelocity() { + return vertex_velocity.xyz; + } +#endif diff --git a/shaders_ref/vertex_streams/vertex_stream.glsl b/shaders_ref/vertex_streams/vertex_stream.glsl new file mode 100644 index 00000000..c0b8913b --- /dev/null +++ b/shaders_ref/vertex_streams/vertex_stream.glsl @@ -0,0 +1,15 @@ +#if defined (EFFECT_MODEL) + #if defined (SpriteEmitter) + #include "./sprite_emitter.glsl" + #endif + + #if defined (BeamEmitter) + #include "./beam_emitter.glsl" + #endif + + #if defined (MeshEmitter) + #include "./mesh_emitter.glsl" + #endif +#else + #include "./model_mesh.glsl" +#endif diff --git a/src/limitless/core/shader/shader_compiler.cpp b/src/limitless/core/shader/shader_compiler.cpp index 211b0d31..33e176cb 100644 --- a/src/limitless/core/shader/shader_compiler.cpp +++ b/src/limitless/core/shader/shader_compiler.cpp @@ -4,6 +4,8 @@ #include #include "limitless/core/shader/shader_program.hpp" #include +#include +#include using namespace Limitless; @@ -69,65 +71,10 @@ std::shared_ptr ShaderCompiler::compile() { void ShaderCompiler::replaceRenderSettings(Shader& shader) const { if (render_settings) { - std::string settings; - - if (render_settings->normal_mapping) { - settings.append("#define NORMAL_MAPPING\n"); - } - - if (render_settings->cascade_shadow_maps) { - settings.append("#define DIRECTIONAL_CSM\n"); - - settings.append("#define DIRECTIONAL_SPLIT_COUNT " + std::to_string(render_settings->csm_split_count) + '\n'); - - if (render_settings->csm_pcf) { - settings.append("#define DIRECTIONAL_PFC\n"); - } - } - - if (render_settings->screen_space_ambient_occlusion) { - settings.append("#define SCREEN_SPACE_AMBIENT_OCCLUSION\n"); - } - - if (render_settings->screen_space_reflections) { - settings.append("#define SCREEN_SPACE_REFLECTIONS\n"); - - if (render_settings->screen_space_reflections_settings.intersection_distance_attenuation) { - settings.append("#define SCREEN_SPACE_REFLECTIONS_INTERSECTION_DISTANCE_ATTENUATION\n"); - } - - if (render_settings->screen_space_reflections_settings.iteration_count_attenuation) { - settings.append("#define SCREEN_SPACE_REFLECTIONS_ITERATION_COUNT_ATTENUATION\n"); - } - - if (render_settings->screen_space_reflections_settings.borders_attenuation) { - settings.append("#define SCREEN_SPACE_REFLECTIONS_BORDERS_ATTENUATION\n"); - } - - if (render_settings->screen_space_reflections_settings.fresnel_attenuation) { - settings.append("#define SCREEN_SPACE_REFLECTIONS_FRESNEL_ATTENUATION\n"); - } - - if (render_settings->screen_space_reflections_settings.camera_facing_attenuation) { - settings.append("#define SCREEN_SPACE_REFLECTIONS_CAMERA_FACING_ATTENUATION\n"); - } - - if (render_settings->screen_space_reflections_settings.clip_to_frustrum) { - settings.append("#define SCREEN_SPACE_REFLECTIONS_CLIP_TO_FRUSTRUM\n"); - } - - if (render_settings->screen_space_reflections_settings.refiniment) { - settings.append("#define SCREEN_SPACE_REFLECTIONS_REFINEMENT\n"); - } - } - - if (render_settings->csm_micro_shadowing) { - settings.append("#define MICRO_SHADOWING\n"); - } - - shader.replaceKey("Limitless::Settings", settings); + RenderSettingsShaderDefiner settings {*render_settings}; + settings.define(shader); } else { - shader.replaceKey("Limitless::Settings", ""); + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Settings], ""); } } diff --git a/src/limitless/ms/material_compiler.cpp b/src/limitless/ms/material_compiler.cpp index a8eef6db..46e79395 100644 --- a/src/limitless/ms/material_compiler.cpp +++ b/src/limitless/ms/material_compiler.cpp @@ -3,6 +3,7 @@ #include #include #include +#include using namespace Limitless::ms; @@ -11,135 +12,8 @@ MaterialCompiler::MaterialCompiler(Context& context, Assets& _assets, const Rend , assets {_assets} { } -std::string MaterialCompiler::getMaterialDefines(const Material& material) noexcept { - std::string property_defines; - for (const auto& [property, ptr] : material.getProperties()) { - switch (property) { - case Property::Color: - property_defines.append("#define ENGINE_MATERIAL_COLOR\n"); - break; - case Property::EmissiveColor: - property_defines.append("#define ENGINE_MATERIAL_EMISSIVE_COLOR\n"); - break; - case Property::Diffuse: - property_defines.append("#define ENGINE_MATERIAL_DIFFUSE_TEXTURE\n"); - break; - case Property::Normal: - property_defines.append("#define ENGINE_MATERIAL_NORMAL_TEXTURE\n"); - break; - case Property::EmissiveMask: - property_defines.append("#define ENGINE_MATERIAL_EMISSIVEMASK_TEXTURE\n"); - break; - case Property::BlendMask: - property_defines.append("#define ENGINE_MATERIAL_BLENDMASK_TEXTURE\n"); - break; - case Property::Metallic: - property_defines.append("#define ENGINE_MATERIAL_METALLIC\n"); - break; - case Property::Roughness: - property_defines.append("#define ENGINE_MATERIAL_ROUGHNESS\n"); - break; - case Property::MetallicTexture: - property_defines.append("#define ENGINE_MATERIAL_METALLIC_TEXTURE\n"); - break; - case Property::RoughnessTexture: - property_defines.append("#define ENGINE_MATERIAL_ROUGHNESS_TEXTURE\n"); - break; - case Property::TessellationFactor: - property_defines.append("#define ENGINE_MATERIAL_TESSELLATION_FACTOR\n"); - break; - case Property::AmbientOcclusionTexture: - property_defines.append("#define ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE\n"); - break; - case Property::IoR: - property_defines.append("#define ENGINE_MATERIAL_IOR\n"); - break; - case Property::Absorption: - property_defines.append("#define ENGINE_MATERIAL_ABSORPTION\n"); - break; - case Property::ORM: - property_defines.append("#define ENGINE_MATERIAL_ORM_TEXTURE\n"); - break; - } - } - - if (material.getRefraction()) { - property_defines.append("#define ENGINE_MATERIAL_REFRACTION\n"); - } - - switch (material.getShading()) { - case Shading::Lit: - property_defines.append("#define ENGINE_MATERIAL_SHADING_REGULAR_MODEL\n"); - break; - case Shading::Unlit: - property_defines.append("#define ENGINE_MATERIAL_SHADING_UNLIT_MODEL\n"); - break; - case Shading::Cloth: - property_defines.append("#define ENGINE_MATERIAL_SHADING_CLOTH_MODEL\n"); - break; - case Shading::Subsurface: - property_defines.append("#define ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL\n"); - break; - case Shading::Custom: - property_defines.append("#define ENGINE_MATERIAL_SHADING_CUSTOM_MODEL\n"); - break; - } - - return property_defines; -} - -std::string MaterialCompiler::getModelDefines(const InstanceType& type) { - std::string defines; - switch (type) { - case InstanceType::Model: - defines.append("#define SIMPLE_MODEL\n"); - break; - case InstanceType::Skeletal: - defines.append("#define SKELETAL_MODEL\n"); - break; - case InstanceType::Instanced: - defines.append("#define INSTANCED_MODEL\n"); - break; - case InstanceType::Effect: - defines.append("#define EFFECT_MODEL\n"); - break; - } - return defines; -} - -std::string MaterialCompiler::getCustomMaterialScalarUniforms(const Material& material) noexcept { - std::string uniforms; - for (const auto& [name, uniform] : material.getUniforms()) { - if (uniform->getType() == UniformType::Value || uniform->getType() == UniformType::Time) { - auto decl = getUniformDeclaration(*uniform); - decl.erase(decl.find("uniform"), 7); - uniforms.append(decl); - } - } - return uniforms; -} - -std::string MaterialCompiler::getCustomMaterialSamplerUniforms(const Material& material) noexcept { - std::string uniforms; - for (const auto& [name, uniform] : material.getUniforms()) { - if (uniform->getType() == UniformType::Sampler) { - uniforms.append(getUniformDeclaration(*uniform)); - } - } - return uniforms; -} - void MaterialCompiler::replaceMaterialSettings(Shader& shader, const Material& material, InstanceType model_shader) noexcept { - shader.replaceKey("Limitless::MaterialType", getMaterialDefines(material)); - shader.replaceKey("Limitless::ModelType", getModelDefines(model_shader)); - shader.replaceKey("Limitless::EmitterType", ""); - - shader.replaceKey("_MATERIAL_VERTEX_SNIPPET", material.getVertexSnippet()); - shader.replaceKey("_MATERIAL_FRAGMENT_SNIPPET", material.getFragmentSnippet()); - shader.replaceKey("ENGINE_MATERIAL_GLOBAL_DEFINITIONS", material.getGlobalSnippet()); - shader.replaceKey("_MATERIAL_TESSELLATION_SNIPPET", material.getTessellationSnippet()); - shader.replaceKey("ENGINE_MATERIAL_CUSTOM_SCALARS", getCustomMaterialScalarUniforms(material)); - shader.replaceKey("ENGINE_MATERIAL_CUSTOM_SAMPLERS", getCustomMaterialSamplerUniforms(material)); + MaterialShaderDefiner::define(shader, material, model_shader); } void MaterialCompiler::compile(const Material& material, ShaderType pass_shader, InstanceType model_shader) { @@ -148,18 +22,18 @@ void MaterialCompiler::compile(const Material& material, ShaderType pass_shader, replaceRenderSettings(shader); }; - if (material.contains(Property::TessellationFactor)) { - auto tesc = Shader { assets.getShaderDir() / "tesselation" / "tesselation.tesc", Shader::Type::TessControl, props }; - auto tese = Shader { assets.getShaderDir() / "tesselation" / "tesselation.tese", Shader::Type::TessEval, props }; - - *this << std::move(tesc) - << std::move(tese); - } +// if (material.contains(Property::TessellationFactor)) { +// auto tesc = Shader { assets.getShaderDir() / "tesselation" / "tesselation.tesc", Shader::Type::TessControl, props }; +// auto tese = Shader { assets.getShaderDir() / "tesselation" / "tesselation.tese", Shader::Type::TessEval, props }; +// +// *this << std::move(tesc) +// << std::move(tese); +// } try { auto shader = compile(assets.getShaderDir() / SHADER_PASS_PATH.at(pass_shader), props); assets.shaders.add(pass_shader, model_shader, material.getShaderIndex(), shader); } catch (const std::exception& e) { - throw material_compilation_error{material.getName() + e.what()}; + throw material_compilation_error {material.getName() + e.what()}; } } diff --git a/src/limitless/ms/material_shader_definer.cpp b/src/limitless/ms/material_shader_definer.cpp new file mode 100644 index 00000000..7d9cd068 --- /dev/null +++ b/src/limitless/ms/material_shader_definer.cpp @@ -0,0 +1,68 @@ +#include + +#include +#include +#include + +using namespace Limitless::ms; + +std::string MaterialShaderDefiner::getPropertyDefines(const Material& material) { + std::string defines; + + for (const auto& [property, _] : material.getProperties()) { + defines.append(SHADER_PROPERTY_DEFINE[property]); + } + + if (material.getRefraction()) { + defines.append("#define ENGINE_MATERIAL_REFRACTION\n"); + } +} + +std::string MaterialShaderDefiner::getShadingDefines(const Material& material) { + return SHADER_SHADING_DEFINE[material.getShading()]; +} + +std::string MaterialShaderDefiner::getModelDefines(InstanceType model_shader) { + return SHADER_MODEL_DEFINE[model_shader]; +} + +void MaterialShaderDefiner::define(Shader &shader, const Material &material, InstanceType model_shader) { + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::MaterialType], getMaterialDefines(material)); + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::ModelType], getModelDefines(model_shader)); + shader.replaceKey("Limitless::EmitterType", ""); + + shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Vertex], material.getVertexSnippet()); + shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Tesselation], material.getTessellationSnippet()); + shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Fragment], material.getFragmentSnippet()); + shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Global], material.getGlobalSnippet()); + shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::CustomScalar], getScalarUniformDefines(material)); + shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::CustomSamplers], getSamplerUniformDefines(material)); +} + +std::string MaterialShaderDefiner::getScalarUniformDefines(const Material &material) { + std::string uniforms; + for (const auto& [name, uniform] : material.getUniforms()) { + if (uniform->getType() == UniformType::Value || uniform->getType() == UniformType::Time) { + auto decl = getUniformDeclaration(*uniform); + decl.erase(decl.find("uniform"), 7); + uniforms.append(decl); + } + } + return uniforms; +} + +std::string MaterialShaderDefiner::getSamplerUniformDefines(const Material &material) { + std::string uniforms; + for (const auto& [name, uniform] : material.getUniforms()) { + if (uniform->getType() == UniformType::Sampler) { + uniforms.append(getUniformDeclaration(*uniform)); + } + } + return uniforms; +} + +std::string MaterialShaderDefiner::getMaterialDefines(const Material &material) { + std::string defines = getPropertyDefines(material); + defines.append(getShadingDefines(material)); + return defines; +} diff --git a/src/limitless/renderer/render_settings_shader_definer.cpp b/src/limitless/renderer/render_settings_shader_definer.cpp new file mode 100644 index 00000000..9bc0c8eb --- /dev/null +++ b/src/limitless/renderer/render_settings_shader_definer.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +using namespace Limitless; + +RenderSettingsShaderDefiner::RenderSettingsShaderDefiner(const RenderSettings& settings) noexcept + : settings {settings} { + +} + +void RenderSettingsShaderDefiner::define(Shader &shader) { + std::string s; + + if (settings.normal_mapping) { + s.append("#define ENGINE_SETTINGS_NORMAL_MAPPING\n"); + } + + if (settings.cascade_shadow_maps) { + s.append("#define ENGINE_SETTINGS_CSM\n"); + + s.append("#define ENGINE_SETTINGS_CSM_SPLIT_COUNT " + std::to_string(settings.csm_split_count) + '\n'); + + if (settings.csm_pcf) { + s.append("#define ENGINE_SETTINGS_PFC\n"); + } + } + + if (settings.screen_space_ambient_occlusion) { + s.append("#define ENGINE_SETTINGS_SSAO\n"); + } + +// if (settings.screen_space_reflections) { +// s.append("#define SCREEN_SPACE_REFLECTIONS\n"); +// +// if (settings.screen_space_reflections_settings.intersection_distance_attenuation) { +// s.append("#define SCREEN_SPACE_REFLECTIONS_INTERSECTION_DISTANCE_ATTENUATION\n"); +// } +// +// if (settings.screen_space_reflections_settings.iteration_count_attenuation) { +// s.append("#define SCREEN_SPACE_REFLECTIONS_ITERATION_COUNT_ATTENUATION\n"); +// } +// +// if (settings.screen_space_reflections_settings.borders_attenuation) { +// s.append("#define SCREEN_SPACE_REFLECTIONS_BORDERS_ATTENUATION\n"); +// } +// +// if (settings.screen_space_reflections_settings.fresnel_attenuation) { +// s.append("#define SCREEN_SPACE_REFLECTIONS_FRESNEL_ATTENUATION\n"); +// } +// +// if (settings.screen_space_reflections_settings.camera_facing_attenuation) { +// s.append("#define SCREEN_SPACE_REFLECTIONS_CAMERA_FACING_ATTENUATION\n"); +// } +// +// if (settings.screen_space_reflections_settings.clip_to_frustrum) { +// s.append("#define SCREEN_SPACE_REFLECTIONS_CLIP_TO_FRUSTRUM\n"); +// } +// +// if (settings.screen_space_reflections_settings.refiniment) { +// s.append("#define SCREEN_SPACE_REFLECTIONS_REFINEMENT\n"); +// } +// } + + if (settings.csm_micro_shadowing) { + s.append("#define ENGINE_SETTINGS_MICRO_SHADOWING\n"); + } + + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Settings], s); +} From 2a054c24d426c06af7f399a6804039bd03c81189 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Sun, 19 Nov 2023 22:58:37 +0300 Subject: [PATCH 05/15] hell lot of refactoring --- include/limitless/core/keyline_extensions.hpp | 3 - include/limitless/core/shader/shader.hpp | 16 ++--- .../limitless/core/shader/shader_compiler.hpp | 20 +++++- .../render_settings_shader_definer.hpp | 4 +- shaders_ref/functions/linearize_depth.glsl | 10 +++ .../functions/reconstruct_position.glsl | 24 +++++++ shaders_ref/instance/instance.glsl | 2 + shaders_ref/interface_block/mesh_vs.glsl | 2 +- shaders_ref/interface_block/vertex.glsl | 2 +- shaders_ref/lighting/light.glsl | 40 +++-------- shaders_ref/lighting/lighting.glsl | 32 +++++++++ .../lighting_context.glsl | 27 +++++-- shaders_ref/material/material.glsl | 2 +- shaders_ref/material/material_context.glsl | 15 +++- shaders_ref/pipeline/composite.frag | 21 ++++++ shaders_ref/pipeline/composite.vert | 12 ++++ shaders_ref/pipeline/deferred.frag | 72 +++++++++++++++++++ shaders_ref/pipeline/deferred.vert | 11 +++ shaders_ref/pipeline/depth.frag | 15 ++++ shaders_ref/pipeline/depth.vert | 33 +++++++++ shaders_ref/pipeline/forward.frag | 14 +--- shaders_ref/pipeline/forward.vert | 13 ++-- shaders_ref/shading/regular_shading.glsl | 1 + shaders_ref/shading/shading_context.glsl | 9 ++- .../shading_context_from_material.glsl | 17 +++++ shaders_ref/vertex_streams/model_mesh.glsl | 8 +-- shaders_ref/vertex_streams/vertex_stream.glsl | 2 +- src/limitless/assets.cpp | 2 +- src/limitless/core/shader/shader.cpp | 44 +++--------- src/limitless/core/shader/shader_compiler.cpp | 60 +++++++++++++--- src/limitless/fx/effect_compiler.cpp | 2 +- src/limitless/ms/material_compiler.cpp | 2 +- .../render_settings_shader_definer.cpp | 4 +- src/limitless/shader_storage.cpp | 22 +++--- 34 files changed, 415 insertions(+), 148 deletions(-) create mode 100644 shaders_ref/functions/linearize_depth.glsl create mode 100644 shaders_ref/functions/reconstruct_position.glsl create mode 100644 shaders_ref/lighting/lighting.glsl rename shaders_ref/{shading => lighting}/lighting_context.glsl (58%) create mode 100644 shaders_ref/pipeline/composite.frag create mode 100644 shaders_ref/pipeline/composite.vert create mode 100644 shaders_ref/pipeline/deferred.frag create mode 100644 shaders_ref/pipeline/deferred.vert create mode 100644 shaders_ref/pipeline/depth.frag create mode 100644 shaders_ref/pipeline/depth.vert create mode 100644 shaders_ref/shading/shading_context_from_material.glsl diff --git a/include/limitless/core/keyline_extensions.hpp b/include/limitless/core/keyline_extensions.hpp index 27fb55c4..c794ec83 100644 --- a/include/limitless/core/keyline_extensions.hpp +++ b/include/limitless/core/keyline_extensions.hpp @@ -1,9 +1,6 @@ #pragma once namespace Limitless { - constexpr auto version_key = "Limitless::GLSL_VERSION"; - constexpr auto extensions_key = "Limitless::Extensions"; - constexpr auto bindless_texture = "GL_ARB_bindless_texture"; constexpr auto bindless_texture_define = "#define BINDLESS_TEXTURE\n"; constexpr auto extension_bindless_texture = "#extension GL_ARB_bindless_texture : require\n"; diff --git a/include/limitless/core/shader/shader.hpp b/include/limitless/core/shader/shader.hpp index 6aa0d86e..e261328c 100644 --- a/include/limitless/core/shader/shader.hpp +++ b/include/limitless/core/shader/shader.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace Limitless { class shader_file_not_found : public std::runtime_error { @@ -63,18 +64,9 @@ namespace Limitless { GLuint id {}; /** - * Replaces key-line "Limitless::Extensions" in shader source code with extensions enabled by Engine - * - * Replaced extensions depend on functionality used by Engine and GPU capabilities - */ - void replaceExtensions() noexcept; - - /** - * Replaces key-line "Limitless::GLSL_VERSION" in shader source code with version used by Engine - * - * It is always 3.3 version for now (Advanced functionality supported by use of extensions) + * Set to implement pragma once for includes in shaders (Now works only for file names, not file paths) */ - void replaceVersion() noexcept; + std::set include_entries; /** * Self-implemented "#include" directive for GLSL @@ -84,7 +76,7 @@ namespace Limitless { * @param base_dir - directory file path at which current include file is located */ void replaceIncludes(const fs::path& base_dir); - static void resolveIncludes(const fs::path& base_dir, std::string& src); + void resolveIncludes(const fs::path& base_dir, std::string& src); /** * Checks compilation status of shader diff --git a/include/limitless/core/shader/shader_compiler.hpp b/include/limitless/core/shader/shader_compiler.hpp index 82710280..bb19a369 100644 --- a/include/limitless/core/shader/shader_compiler.hpp +++ b/include/limitless/core/shader/shader_compiler.hpp @@ -49,11 +49,27 @@ namespace Limitless { /** * Sets up ShaderAction to be applied to shader source code * - * Replaces key-line with used settings + * Replaces EngineShaderDefine keys with corresponding values * * @param shader - shader to be applied to */ - void replaceRenderSettings(Shader& shader) const; + void replaceEngineDefines(Shader& shader) const; + + /** + * Replaces key-line "Limitless::Extensions" in shader source code with extensions enabled by Engine + * + * Replaced extensions depend on functionality used by Engine and GPU capabilities + */ + static std::string getVersionDefine(); + + /** + * Replaces key-line "Limitless::GLSL_VERSION" in shader source code with version used by Engine + * + * It is always 3.3 version for now (Advanced functionality supported by use of extensions) + */ + static std::string getExtensionsDefine(); + std::string getSettingsDefine() const; + std::string getCommonDefine() const; public: /** * Shader constructor diff --git a/include/limitless/renderer/render_settings_shader_definer.hpp b/include/limitless/renderer/render_settings_shader_definer.hpp index 4b8522f8..c37d821c 100644 --- a/include/limitless/renderer/render_settings_shader_definer.hpp +++ b/include/limitless/renderer/render_settings_shader_definer.hpp @@ -1,5 +1,7 @@ #pragma once +#include + namespace Limitless { class RenderSettings; class Shader; @@ -10,6 +12,6 @@ namespace Limitless { public: explicit RenderSettingsShaderDefiner(const RenderSettings& settings) noexcept; - void define(Shader& shader); + std::string define(); }; } \ No newline at end of file diff --git a/shaders_ref/functions/linearize_depth.glsl b/shaders_ref/functions/linearize_depth.glsl new file mode 100644 index 00000000..02e60a2b --- /dev/null +++ b/shaders_ref/functions/linearize_depth.glsl @@ -0,0 +1,10 @@ +/* + * Depth value in depth texture stored in [0, 1] range + * + * Normalized Device Coordinates for OpenGL in range [-1, 1] + * + */ +float linearize_depth(float depth, float near, float far) { + float z_n = 2.0 * depth - 1.0; + return 2.0 * near * far / (far + near - z_n * (far - near)); +} diff --git a/shaders_ref/functions/reconstruct_position.glsl b/shaders_ref/functions/reconstruct_position.glsl new file mode 100644 index 00000000..fa8a00c0 --- /dev/null +++ b/shaders_ref/functions/reconstruct_position.glsl @@ -0,0 +1,24 @@ +#include "./linearize_depth.glsl" +#include "../scene.glsl" + +vec3 reconstructPosition(vec2 uv, float depth) { + vec4 p = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); + p = getViewProjectionInverse() * p; + return p.xyz / p.w; +} + +/** + * Reconstructs world position from depth + + * uv - normalized coordinates [0, 1] + * depth - normalized depth [0, 1] + * fov_scale2 - {2.0 * tan(getProjectionInverse()[0][0] / 2.0), + * 2.0 * tan(getProjectionInverse()[1][1] / 2.0)} + */ +vec3 reconstructViewSpacePosition(vec2 uv, float depth) { + vec2 fov_scale2 = 2.0 * vec2(tan(getProjectionInverse()[0][0] / 2.0), tan(getProjectionInverse()[1][1] / 2.0)); + + float z = linearize_depth(depth, getCameraNearPlane(), getCameraFarPlane()); + vec2 half_ndc = vec2(0.5) - uv; // multiplication * 2.0 done in fov_scale2 + return vec3(half_ndc * fov_scale2 * -z, -z); +} diff --git a/shaders_ref/instance/instance.glsl b/shaders_ref/instance/instance.glsl index 6a46f03f..4ec9a997 100644 --- a/shaders_ref/instance/instance.glsl +++ b/shaders_ref/instance/instance.glsl @@ -1,3 +1,5 @@ +#include "../vertex_streams/vertex_stream.glsl" + // REGULAR MODEL OR SKELETAL MODEL #if defined (ENGINE_MATERIAL_REGULAR_MODEL) || defined (ENGINE_MATERIAL_SKELETAL_MODEL) uniform mat4 _model_transform; diff --git a/shaders_ref/interface_block/mesh_vs.glsl b/shaders_ref/interface_block/mesh_vs.glsl index 4c088471..443781aa 100644 --- a/shaders_ref/interface_block/mesh_vs.glsl +++ b/shaders_ref/interface_block/mesh_vs.glsl @@ -1,5 +1,5 @@ out _vertex_data { - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; diff --git a/shaders_ref/interface_block/vertex.glsl b/shaders_ref/interface_block/vertex.glsl index fd16e727..3410f666 100644 --- a/shaders_ref/interface_block/vertex.glsl +++ b/shaders_ref/interface_block/vertex.glsl @@ -1,4 +1,4 @@ -#if defined (EFFECT_MODEL) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) #include "./effect_vs.glsl" #else #include "./mesh_vs.glsl" diff --git a/shaders_ref/lighting/light.glsl b/shaders_ref/lighting/light.glsl index ac145fa2..347dd1e7 100644 --- a/shaders_ref/lighting/light.glsl +++ b/shaders_ref/lighting/light.glsl @@ -1,5 +1,5 @@ -#define LIGHT_TYPE_POINT 0 -#define LIGHT_TYPE_SPOT 1 +#define LIGHT_TYPE_POINT 0u +#define LIGHT_TYPE_SPOT 1u struct Light { // rgb - linear color, a - intensity @@ -14,6 +14,10 @@ struct Light { uint type; // does light cast shadow bool casts_shadow; + // falloff + float falloff; + // spot direction + vec3 direction; }; /* @@ -30,38 +34,14 @@ struct Light { Light _lights[]; }; #else + //TODO: remove to settigns + #define ENGINE_SETTINGS_MAX_LIGHTS 100 + layout (std140) uniform LIGHTS_BUFFER { - Light _lights[MAX_LIGHTS]; + Light _lights[ENGINE_SETTINGS_MAX_LIGHTS]; }; #endif Light getLight(const uint index) { return _lights[index]; } - -vec3 computeLights(const ShadingContext sctx) { - vec3 color = vec3(0.0); - for (uint i = 0u; i < getLightsCount(); ++i) { - Light light = getLight(i); - - LightingContext lctx = computeLightingContext(sctx, light); - - if (lctx.len > light.radius || lctx.NoL <= 0.0 || light.attenuation <= 0.0) { - continue; - } - -#if defined (SHADOWS) - if (light.casts_shadow) { - - } -#endif - - if (lctx.visibility <= 0.0) { - continue; - } - - color += shadeForLight(sctx, lctx, light); - } - - return color; -} diff --git a/shaders_ref/lighting/lighting.glsl b/shaders_ref/lighting/lighting.glsl new file mode 100644 index 00000000..8d1aab5e --- /dev/null +++ b/shaders_ref/lighting/lighting.glsl @@ -0,0 +1,32 @@ +#include "./lighting_context.glsl" +#include "../scene.glsl" +#include "../shading/shade_for_light.glsl" + +vec3 computeLights(const ShadingContext sctx) { + vec3 color = vec3(0.0); + //TODO: lights count + //for (uint i = 0u; i < getLightsCount(); ++i) { + for (uint i = 0u; i < 0u; ++i) { + Light light = getLight(i); + + LightingContext lctx = computeLightingContext(sctx, light); + + if (lctx.len > light.radius || lctx.NoL <= 0.0 || lctx.attenuation <= 0.0) { + continue; + } + + #if defined (SHADOWS) + if (light.casts_shadow) { + + } + #endif + + if (lctx.visibility <= 0.0) { + continue; + } + + //color += shadeForLight(sctx, lctx, light); + } + + return color; +} \ No newline at end of file diff --git a/shaders_ref/shading/lighting_context.glsl b/shaders_ref/lighting/lighting_context.glsl similarity index 58% rename from shaders_ref/shading/lighting_context.glsl rename to shaders_ref/lighting/lighting_context.glsl index d2d8994f..827d4d1a 100644 --- a/shaders_ref/shading/lighting_context.glsl +++ b/shaders_ref/lighting/lighting_context.glsl @@ -1,3 +1,7 @@ +#include "../functions/common.glsl" +#include "../shading/shading_context.glsl" +#include "./light.glsl" + struct LightingContext { vec3 L; float NoL; @@ -19,11 +23,20 @@ float getAttenuation(const ShadingContext sctx, const Light light) { vec3 L = light.position.xyz - sctx.worldPos; float distance = dot(L, L); - float factor = distance * falloff; + float factor = distance * light.falloff; float smoothFactor = saturate(1.0 - factor * factor); float attenuation = smoothFactor * factor; - return attenuation / max(distance, 1e-4); + attenuation = attenuation / max(distance, 1e-4); + + if (light.type == LIGHT_TYPE_SPOT) { + float cd = dot(-light.direction, L); + float att = saturate(cd * light.scale_offset.x + light.scale_offset.y); + float att2 = att * att; + attenuation *= att2; + } + + return attenuation; } LightingContext computeLightingContext(const ShadingContext sctx, const Light light) { @@ -33,15 +46,17 @@ LightingContext computeLightingContext(const ShadingContext sctx, const Light li lctx.visibility = 1.0; lctx.L = normalize(light.position.xyz - sctx.worldPos); - lctx.H = normalize(context.V + L); + lctx.H = normalize(sctx.V + lctx.L); lctx.len = length(light.position.xyz - sctx.worldPos); - lctx.NoL = saturate(dot(context.N, L)); - lctx.NoH = saturate(dot(context.N, H)); - lctx.LoH = saturate(dot(L, H)); + lctx.NoL = saturate(dot(sctx.N, lctx.L)); + lctx.NoH = saturate(dot(sctx.N, lctx.H)); + lctx.LoH = saturate(dot(lctx.L, lctx.H)); #if defined (ENGINE_MATERIAL_SPECULAR_GGX) lctx.lambdaV = lctx.NoL * sqrt((sctx.NoV - sctx.a2 * sctx.NoV) * sctx.NoV + sctx.a2); #endif + + return lctx; } diff --git a/shaders_ref/material/material.glsl b/shaders_ref/material/material.glsl index 24d85dee..4845031c 100644 --- a/shaders_ref/material/material.glsl +++ b/shaders_ref/material/material.glsl @@ -203,4 +203,4 @@ ENGINE_MATERIAL_GLOBAL_DEFINITIONS float getMaterialRoughness(vec2 uv) { return texture(_material_roughness_texture, uv).r; } -#endif \ No newline at end of file +#endif diff --git a/shaders_ref/material/material_context.glsl b/shaders_ref/material/material_context.glsl index 9424cd3e..05c4be47 100644 --- a/shaders_ref/material/material_context.glsl +++ b/shaders_ref/material/material_context.glsl @@ -1,3 +1,6 @@ +#include "./material.glsl" +#include "../interface_block/vertex.glsl" + struct MaterialContext { #if defined (ENGINE_MATERIAL_COLOR) vec4 color; @@ -40,7 +43,7 @@ struct MaterialContext { #endif }; -MaterialContext computeMaterialContext() { +MaterialContext computeDefaultMaterialContext() { MaterialContext mctx; #if defined (ENGINE_MATERIAL_COLOR) @@ -118,6 +121,16 @@ MaterialContext computeMaterialContext() { return mctx; } +void customMaterialContext(inout MaterialContext mctx) { + ENGINE_MATERIAL_FRAGMENT_SNIPPET +} + +MaterialContext computeMaterialContext() { + MaterialContext mctx = computeDefaultMaterialContext(); + customMaterialContext(mctx); + return mctx; +} + vec4 computeMaterialColor(const MaterialContext mctx) { vec4 color = vec4(1.0); diff --git a/shaders_ref/pipeline/composite.frag b/shaders_ref/pipeline/composite.frag new file mode 100644 index 00000000..6f8fc119 --- /dev/null +++ b/shaders_ref/pipeline/composite.frag @@ -0,0 +1,21 @@ +Limitless::GLSL_VERSION +Limitless::Extensions +Limitless::Settings + +#include "../../functions/tone_mapping.glsl" + +in vec2 uv; + +out vec3 color; + +uniform sampler2D lightened; + +uniform sampler2D bloom; +uniform float bloom_strength; + +void main() { + vec3 bloom_color = texture(bloom, uv).rgb * bloom_strength; + color = texture(lightened, uv).rgb + bloom_color; + + color = toneMapping(color, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/pipeline/composite.vert b/shaders_ref/pipeline/composite.vert new file mode 100644 index 00000000..719e0736 --- /dev/null +++ b/shaders_ref/pipeline/composite.vert @@ -0,0 +1,12 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +layout (location = 0) in vec3 vertex_position; +layout (location = 1) in vec2 vertex_uv; + +out vec2 uv; + +void main() { + uv = vertex_uv; + gl_Position = vec4(vertex_position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/pipeline/deferred.frag b/shaders_ref/pipeline/deferred.frag new file mode 100644 index 00000000..c6527cb6 --- /dev/null +++ b/shaders_ref/pipeline/deferred.frag @@ -0,0 +1,72 @@ +ENGINE::COMMON + +#include "../functions/reconstruct_position.glsl" +#include "../shading/shading_context.glsl" +#include "../lighting/lighting.glsl" + +/** GBUFFER */ + +// UNSIGNED NORMALIZED [0; 1] +// RGBA8 - RGB - base color, A - ao + +// SIGNED NORMALIZED [-1; 1] +// RGB - normal + +// UNSIGNED NORMALIZED [0; 1] +// R - roughness, G - metallic, B - shading model (uint) + +// FLOATING POINT +// RGB - emissive + +/** */ + +uniform sampler2D base_texture; +uniform sampler2D normal_texture; +uniform sampler2D props_texture; +uniform sampler2D depth_texture; +uniform sampler2D emissive_texture; + +in vec2 uv; + +out vec3 color; + +//#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) +// uniform sampler2D ssao_texture; +//#endif + +//TODO: refactor - separate responsibilities + +//#ifdef SCREEN_SPACE_REFLECTIONS +// uniform sampler2D ssr_texture; +// uniform float _ssr_strength; +//#endif + +void main() { + vec3 P = reconstructPosition(uv, texture(depth_texture, uv).r); + vec3 normal = texture(normal_texture, uv).rgb; + vec4 base = texture(base_texture, uv).rgba; + vec3 props = texture(props_texture, uv).rgb; + uint shading_model = uint(props.b * 255.0); + +//#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) +// base.a *= texture(ssao_texture, uv).r; +//#endif + + ShadingContext sctx = computeShadingContext( + base.rgb, + props.g, + P, + props.r, + normal, + base.a + ); + color = computeLights(sctx); + +// color = getFragmentColor(base.rgb, base.a, normal, P, metallic, roughness, shading_model); +// color += texture(emissive_texture, uv).rgb; +// just add for now for test +//#ifdef SCREEN_SPACE_REFLECTIONS +// // TODO: move to indirect lighting +// color += texture(ssr_texture, uv).rgb *_ssr_strength; +//#endif +} diff --git a/shaders_ref/pipeline/deferred.vert b/shaders_ref/pipeline/deferred.vert new file mode 100644 index 00000000..b1d752df --- /dev/null +++ b/shaders_ref/pipeline/deferred.vert @@ -0,0 +1,11 @@ +ENGINE::GLSLVERSION + +layout (location = 0) in vec3 vertex_position; +layout (location = 1) in vec2 vertex_uv; + +out vec2 uv; + +void main() { + uv = vertex_uv; + gl_Position = vec4(vertex_position, 1.0); +} diff --git a/shaders_ref/pipeline/depth.frag b/shaders_ref/pipeline/depth.frag new file mode 100644 index 00000000..404cb620 --- /dev/null +++ b/shaders_ref/pipeline/depth.frag @@ -0,0 +1,15 @@ +Limitless::GLSL_VERSION +Limitless::Extensions +Limitless::Settings +Limitless::MaterialType +Limitless::ModelType +Limitless::EmitterType + +#include "../interface_block/fragment.glsl" + +#include "../scene.glsl" +#include "../shading/depth_discarder.glsl" + +void main() { + discardForDepth(); +} diff --git a/shaders_ref/pipeline/depth.vert b/shaders_ref/pipeline/depth.vert new file mode 100644 index 00000000..e3fab37a --- /dev/null +++ b/shaders_ref/pipeline/depth.vert @@ -0,0 +1,33 @@ +ENGINE::MATERIALDEPENDENT + +#include "../vertex_streams/vertex_stream.glsl" +#include "../interface_block/vertex.glsl" +#include "../shading/common.glsl" +#include "../scene.glsl" +#include "../instance/instance.glsl" +#include "../material/material.glsl" +#include "../interface_block/pass_through.glsl" + +void main() { + #if !defined (SpriteEmitter) + vec2 uv = getVertexUV(); + #else + vec2 uv = vec2(0.0); + #endif + + vec3 vertex_position = getVertexPosition(); + + // %uv + // %vertex_position + _MATERIAL_VERTEX_SNIPPET + + mat4 model_transform = getModelTransform(); + + vec4 world_position = model_transform * vec4(vertex_position, 1.0); + + #if !defined (MATERIAL_TESSELATION_FACTOR) + gl_Position = getViewProjection() * world_position; + #endif + + InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); +} diff --git a/shaders_ref/pipeline/forward.frag b/shaders_ref/pipeline/forward.frag index 10a52301..16b40894 100644 --- a/shaders_ref/pipeline/forward.frag +++ b/shaders_ref/pipeline/forward.frag @@ -2,20 +2,12 @@ ENGINE::MATERIALDEPENDENT #include "../interface_block/fragment.glsl" #include "../scene.glsl" -#include "../shading/fragment.glsl" +#include "../lighting/light.glsl" out vec4 color; void main() { MaterialContext mctx = computeMaterialContext(); - - - - FragmentData data = initializeFragmentData(); - - customFragment(data); - - - - color = computeFragment(data); + ShadingContext sctx = computeShadingContext(mctx); + color = computeLights(sctx); } \ No newline at end of file diff --git a/shaders_ref/pipeline/forward.vert b/shaders_ref/pipeline/forward.vert index e3fab37a..dbdfa17f 100644 --- a/shaders_ref/pipeline/forward.vert +++ b/shaders_ref/pipeline/forward.vert @@ -1,11 +1,10 @@ ENGINE::MATERIALDEPENDENT -#include "../vertex_streams/vertex_stream.glsl" -#include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" -#include "../scene.glsl" + #include "../instance/instance.glsl" -#include "../material/material.glsl" + +#include "../material/material_context.glsl" + #include "../interface_block/pass_through.glsl" void main() { @@ -17,9 +16,7 @@ void main() { vec3 vertex_position = getVertexPosition(); - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET + ENGINE_MATERIAL_VERTEX_SNIPPET mat4 model_transform = getModelTransform(); diff --git a/shaders_ref/shading/regular_shading.glsl b/shaders_ref/shading/regular_shading.glsl index 48f29af3..88526c09 100644 --- a/shaders_ref/shading/regular_shading.glsl +++ b/shaders_ref/shading/regular_shading.glsl @@ -11,5 +11,6 @@ vec3 regularShading(const ShadingContext sctx, const LightingContext lctx, const Fd *= (1.0 - sctx.transmission); #endif + //TODO: add emissive ??? return (color * light.color.rgb) * (light.color.a * lctx.NoL * light.attenuation * lctx.visibility); } diff --git a/shaders_ref/shading/shading_context.glsl b/shaders_ref/shading/shading_context.glsl index 5186daa0..04085a7c 100644 --- a/shaders_ref/shading/shading_context.glsl +++ b/shaders_ref/shading/shading_context.glsl @@ -1,3 +1,6 @@ +#include "../functions/common.glsl" +#include "../scene.glsl" + struct ShadingContext { vec3 diffuseColor; float metallic; @@ -47,8 +50,4 @@ ShadingContext computeShadingContext( #endif return context; -} - -ShadingContext computeShadingContext() { - -} +} \ No newline at end of file diff --git a/shaders_ref/shading/shading_context_from_material.glsl b/shaders_ref/shading/shading_context_from_material.glsl new file mode 100644 index 00000000..2d29c2ec --- /dev/null +++ b/shaders_ref/shading/shading_context_from_material.glsl @@ -0,0 +1,17 @@ +#include "./shading_context.glsl" +#include "../material/material_context.glsl" + +ShadingContext computeShadingContext(const MaterialContext mctx) { + vec4 color = computeMaterialColor(mctx); + vec3 normal = computeMaterialNormal(mctx); + float ao = computeMaterialAO(mctx); + + return computeShadingContext( + color, + mctx.metallic, + getVertexPosition(), //TODO: make an argument? + mctx.roughness, + normal, + ao + ); +} \ No newline at end of file diff --git a/shaders_ref/vertex_streams/model_mesh.glsl b/shaders_ref/vertex_streams/model_mesh.glsl index 1bc0aea0..57714cd3 100644 --- a/shaders_ref/vertex_streams/model_mesh.glsl +++ b/shaders_ref/vertex_streams/model_mesh.glsl @@ -1,10 +1,10 @@ layout (location = 0) in vec3 _vertex_position; layout (location = 1) in vec3 _vertex_normal; -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) layout (location = 2) in vec3 _vertex_tangent; #endif layout (location = 3) in vec2 _vertex_uv; -#if defined (SKELETAL_MODEL) +#if defined (ENGINE_MATERIAL_SKELETAL_MODEL) layout (location = 4) in ivec4 _vertex_bone_id; layout (location = 5) in vec4 _vertex_bone_weight; #endif @@ -21,13 +21,13 @@ vec2 getVertexUV() { return _vertex_uv; } -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) vec3 getVertexTangent() { return _vertex_tangent; } #endif -#if defined (SKELETAL_MODEL) +#if defined (ENGINE_MATERIAL_SKELETAL_MODEL) ivec4 getVertexBoneID() { return _vertex_bone_id; } diff --git a/shaders_ref/vertex_streams/vertex_stream.glsl b/shaders_ref/vertex_streams/vertex_stream.glsl index c0b8913b..3924bb03 100644 --- a/shaders_ref/vertex_streams/vertex_stream.glsl +++ b/shaders_ref/vertex_streams/vertex_stream.glsl @@ -1,4 +1,4 @@ -#if defined (EFFECT_MODEL) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) #if defined (SpriteEmitter) #include "./sprite_emitter.glsl" #endif diff --git a/src/limitless/assets.cpp b/src/limitless/assets.cpp index 9632c8a0..191319d3 100644 --- a/src/limitless/assets.cpp +++ b/src/limitless/assets.cpp @@ -19,7 +19,7 @@ using namespace Limitless; Assets::Assets(const fs::path& _base_dir) noexcept : base_dir {_base_dir} - , shader_dir {_base_dir / "../shaders"} { + , shader_dir {_base_dir / "../shaders_ref"} { } Assets::Assets(fs::path _base_dir, fs::path _shader_dir) noexcept diff --git a/src/limitless/core/shader/shader.cpp b/src/limitless/core/shader/shader.cpp index 0d51b491..bf44c0ae 100644 --- a/src/limitless/core/shader/shader.cpp +++ b/src/limitless/core/shader/shader.cpp @@ -12,8 +12,6 @@ Shader::Shader(fs::path _path, Type _type, const ShaderAction& action) , type {_type} { source = getSource(path); - replaceVersion(); - replaceExtensions(); replaceIncludes(path.parent_path()); if (action) { @@ -73,12 +71,6 @@ void Shader::checkStatus() const { throw shader_compilation_error("failed to compile " + path.string() + ": " + log); } -void Shader::replaceVersion() noexcept { - static const auto version = "#version " + std::to_string(ContextInitializer::major_version) + std::to_string(ContextInitializer::minor_version) + "0 core"; - - replaceKey(version_key, version); -} - void Shader::replaceKey(const std::string& key, const std::string& value) noexcept { size_t found = 0; for (;;) { @@ -92,30 +84,6 @@ void Shader::replaceKey(const std::string& key, const std::string& value) noexce } } -void Shader::replaceExtensions() noexcept { - std::string extensions; - - if (ContextInitializer::isExtensionSupported(shader_storage_buffer_object)) { - extensions.append(extension_shader_storage_buffer_object); - } - - if (ContextInitializer::isExtensionSupported(shading_language_420pack)) { - extensions.append(extension_shading_language_420pack); - } - - if (ContextInitializer::isExtensionSupported(explicit_uniform_location)) { - extensions.append(extension_explicit_uniform_location); - } - - if (ContextInitializer::isExtensionSupported(bindless_texture)) { - extensions.append(extension_bindless_texture); - extensions.append(bindless_texture_define); - extensions.append(bindless_samplers); - } - - replaceKey(extensions_key, extensions); -} - std::string Shader::getSource(const fs::path& filepath) { try { std::ifstream file(filepath); @@ -153,11 +121,15 @@ void Shader::resolveIncludes(const fs::path& base_dir, std::string& src) { fs::path file_name = src.substr(beg, name_length); - auto include_src = getSource(base_dir / file_name); + if (!include_entries.count(file_name.stem().string())) { + include_entries.emplace(file_name.stem().string()); - resolveIncludes(base_dir / file_name.parent_path(), include_src); - - src.replace(found, include.length() + 3 + name_length, include_src); + auto include_src = getSource(base_dir / file_name); + resolveIncludes(base_dir / file_name.parent_path(), include_src); + src.replace(found, include.length() + 3 + name_length, include_src); + } else { + src.replace(found, include.length() + 3 + name_length, ""); + } } } diff --git a/src/limitless/core/shader/shader_compiler.cpp b/src/limitless/core/shader/shader_compiler.cpp index 33e176cb..39fff041 100644 --- a/src/limitless/core/shader/shader_compiler.cpp +++ b/src/limitless/core/shader/shader_compiler.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace Limitless; @@ -69,13 +70,11 @@ std::shared_ptr ShaderCompiler::compile() { return std::shared_ptr(new ShaderProgram(program_id)); } -void ShaderCompiler::replaceRenderSettings(Shader& shader) const { - if (render_settings) { - RenderSettingsShaderDefiner settings {*render_settings}; - settings.define(shader); - } else { - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Settings], ""); - } +void ShaderCompiler::replaceEngineDefines(Shader& shader) const { + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::GLSLVersion], getVersionDefine()); + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Extensions], getExtensionsDefine()); + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Settings], getSettingsDefine()); + shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Common], getCommonDefine()); } std::shared_ptr ShaderCompiler::compile(const fs::path& path, const ShaderAction& action) { @@ -84,8 +83,7 @@ std::shared_ptr ShaderCompiler::compile(const fs::path& path, con try { Shader shader { path.string() + extension.data(), type, action }; - replaceRenderSettings(shader); - + replaceEngineDefines(shader); std::string e = type == Shader::Type::Vertex ? ".vert" : ".frag"; // TODO: temp ref/remove @@ -108,3 +106,47 @@ std::shared_ptr ShaderCompiler::compile(const fs::path& path, con return compile(); } + +std::string ShaderCompiler::getVersionDefine() { + return "#version " + std::to_string(ContextInitializer::major_version) + std::to_string(ContextInitializer::minor_version) + "0 core\n"; +} + +std::string ShaderCompiler::getExtensionsDefine() { + std::string extensions; + + if (ContextInitializer::isExtensionSupported(shader_storage_buffer_object)) { + extensions.append(extension_shader_storage_buffer_object); + } + + if (ContextInitializer::isExtensionSupported(shading_language_420pack)) { + extensions.append(extension_shading_language_420pack); + } + + if (ContextInitializer::isExtensionSupported(explicit_uniform_location)) { + extensions.append(extension_explicit_uniform_location); + } + + if (ContextInitializer::isExtensionSupported(bindless_texture)) { + extensions.append(extension_bindless_texture); + extensions.append(bindless_texture_define); + extensions.append(bindless_samplers); + } + + return extensions; +} + +std::string ShaderCompiler::getSettingsDefine() const { + std::string define; + if (render_settings) { + RenderSettingsShaderDefiner settings {*render_settings}; + define = settings.define(); + } + return define; +} + +std::string ShaderCompiler::getCommonDefine() const { + std::string defines = getVersionDefine(); + defines.append(getExtensionsDefine()); + defines.append(getSettingsDefine()); + return defines; +} diff --git a/src/limitless/fx/effect_compiler.cpp b/src/limitless/fx/effect_compiler.cpp index 9c1550c9..68e3fd87 100644 --- a/src/limitless/fx/effect_compiler.cpp +++ b/src/limitless/fx/effect_compiler.cpp @@ -112,7 +112,7 @@ void EffectCompiler::compile(ShaderType shader_type, const T& emitter) { shader.replaceKey("Limitless::EmitterType", getEmitterDefines(emitter)); replaceMaterialSettings(shader, emitter.getMaterial(), InstanceType::Effect); - replaceRenderSettings(shader); + replaceEngineDefines(shader); }; assets.shaders.add({emitter.getUniqueShaderType(), shader_type}, compile(assets.getShaderDir() / SHADER_PASS_PATH.at(shader_type), props)); diff --git a/src/limitless/ms/material_compiler.cpp b/src/limitless/ms/material_compiler.cpp index 46e79395..6ad303bc 100644 --- a/src/limitless/ms/material_compiler.cpp +++ b/src/limitless/ms/material_compiler.cpp @@ -19,7 +19,7 @@ void MaterialCompiler::replaceMaterialSettings(Shader& shader, const Material& m void MaterialCompiler::compile(const Material& material, ShaderType pass_shader, InstanceType model_shader) { const auto props = [&] (Shader& shader) { replaceMaterialSettings(shader, material, model_shader); - replaceRenderSettings(shader); + replaceEngineDefines(shader); }; // if (material.contains(Property::TessellationFactor)) { diff --git a/src/limitless/renderer/render_settings_shader_definer.cpp b/src/limitless/renderer/render_settings_shader_definer.cpp index 9bc0c8eb..33c6a4f5 100644 --- a/src/limitless/renderer/render_settings_shader_definer.cpp +++ b/src/limitless/renderer/render_settings_shader_definer.cpp @@ -10,7 +10,7 @@ RenderSettingsShaderDefiner::RenderSettingsShaderDefiner(const RenderSettings& s } -void RenderSettingsShaderDefiner::define(Shader &shader) { +std::string RenderSettingsShaderDefiner::define() { std::string s; if (settings.normal_mapping) { @@ -67,5 +67,5 @@ void RenderSettingsShaderDefiner::define(Shader &shader) { s.append("#define ENGINE_SETTINGS_MICRO_SHADOWING\n"); } - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Settings], s); + return s; } diff --git a/src/limitless/shader_storage.cpp b/src/limitless/shader_storage.cpp index 0fe89e1b..51a2f3a1 100644 --- a/src/limitless/shader_storage.cpp +++ b/src/limitless/shader_storage.cpp @@ -106,20 +106,20 @@ void ShaderStorage::initialize(Context& ctx, const RenderSettings& settings, con ShaderCompiler compiler {ctx, settings}; //TODO: check if (settings.pipeline == RenderPipeline::Forward) { - add("blur", compiler.compile(shader_dir / "postprocessing/blur")); - add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); - add("postprocess", compiler.compile(shader_dir / "postprocessing/postprocess")); +// add("blur", compiler.compile(shader_dir / "postprocessing/blur")); +// add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); +// add("postprocess", compiler.compile(shader_dir / "postprocessing/postprocess")); } if (settings.pipeline == RenderPipeline::Deferred) { - add("deferred", compiler.compile(shader_dir / "pipeline/deferred/deferred")); - add("composite", compiler.compile(shader_dir / "pipeline/deferred/composite")); - add("ssao", compiler.compile(shader_dir / "postprocessing/ssao/ssao")); - add("ssao_blur", compiler.compile(shader_dir / "postprocessing/ssao/ssao_blur")); - - add("blur_downsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_downsample")); - add("blur_upsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_upsample")); - add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); + add("deferred", compiler.compile(shader_dir / "pipeline/deferred")); + add("composite", compiler.compile(shader_dir / "pipeline/composite")); +// add("ssao", compiler.compile(shader_dir / "postprocessing/ssao/ssao")); +// add("ssao_blur", compiler.compile(shader_dir / "postprocessing/ssao/ssao_blur")); + +// add("blur_downsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_downsample")); +// add("blur_upsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_upsample")); +// add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); } if (settings.fast_approximate_antialiasing) { From 6800b2ea854a54b72153502f5aff23600b05b3d3 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Wed, 22 Nov 2023 21:22:07 +0300 Subject: [PATCH 06/15] ref --- CMakeLists.txt | 13 +- demo/assets.cpp | 97 +++++----- demo/demo.cpp | 43 +++++ demo/lighting_demoscene.cpp | 8 +- demo/materials_demoscene.cpp | 20 +- include/limitless/core/keyline_extensions.hpp | 2 +- .../limitless/core/shader/shader_compiler.hpp | 25 +-- .../core/shader/shader_define_replacer.hpp | 39 ++++ .../limitless/core/shader/shader_defines.hpp | 33 ---- include/limitless/fx/effect_compiler.hpp | 2 - .../fx/effect_shader_define_replacer.hpp | 18 ++ include/limitless/lighting/lighting.hpp | 6 +- include/limitless/lighting/lights.hpp | 53 ++---- ...pp => material_shader_define_replacer.hpp} | 18 +- include/limitless/ms/shading.hpp | 14 +- .../pipeline/common/render_debug_pass.hpp | 22 +-- include/limitless/pipeline/shader_type.hpp | 12 +- .../limitless/renderer/render_settings.hpp | 15 +- .../render_settings_shader_definer.hpp | 6 +- include/limitless/util/stack_trace.hpp | 18 ++ shaders_ref/API.md | 17 ++ shaders_ref/functions/brdf.glsl | 17 +- shaders_ref/functions/circle.glsl | 4 + shaders_ref/functions/common.glsl | 13 ++ shaders_ref/functions/fresnel.glsl | 3 + shaders_ref/functions/hue_shift.glsl | 5 + shaders_ref/functions/refraction_sphere.glsl | 13 ++ shaders_ref/functions/tone_mapping.glsl | 3 + shaders_ref/instance/instance.glsl | 29 +-- shaders_ref/interface_block/effect_fs.glsl | 6 +- shaders_ref/interface_block/effect_vs.glsl | 2 +- shaders_ref/interface_block/fragment.glsl | 2 +- shaders_ref/interface_block/mesh_fs.glsl | 4 +- shaders_ref/interface_block/pass_through.glsl | 6 +- .../interface_block/tess_control_input.glsl | 10 +- .../interface_block/tess_control_output.glsl | 6 +- .../interface_block/tess_control_pass.glsl | 6 +- shaders_ref/lighting/ambient.glsl | 6 + shaders_ref/lighting/directional_shadows.frag | 10 + shaders_ref/lighting/directional_shadows.vert | 32 ++++ shaders_ref/lighting/light.glsl | 39 ++-- shaders_ref/lighting/lighting.glsl | 82 +++++++-- shaders_ref/lighting/lighting_context.glsl | 19 +- shaders_ref/lighting/refraction.glsl | 37 ++++ shaders_ref/lighting/scene_lighting.glsl | 25 +++ shaders_ref/lighting/shadows.glsl | 67 +++++++ shaders_ref/material/material.glsl | 6 + shaders_ref/material/material_context.glsl | 13 +- shaders_ref/pipeline/color_picker.frag | 19 ++ shaders_ref/pipeline/color_picker.vert | 30 +++ shaders_ref/pipeline/composite.frag | 6 +- shaders_ref/pipeline/composite.vert | 3 +- shaders_ref/pipeline/deferred.frag | 45 +---- shaders_ref/pipeline/deferred.vert | 2 +- shaders_ref/pipeline/depth.frag | 14 +- shaders_ref/pipeline/depth.vert | 7 +- shaders_ref/pipeline/forward.frag | 9 +- shaders_ref/pipeline/forward.vert | 8 +- shaders_ref/pipeline/gbuffer.frag | 26 +++ shaders_ref/pipeline/gbuffer.glsl | 47 +++++ shaders_ref/pipeline/gbuffer.vert | 30 +++ shaders_ref/pipeline/gbuffer_context.glsl | 31 ++++ shaders_ref/pipeline/quad.frag | 11 ++ shaders_ref/pipeline/quad.vert | 11 ++ shaders_ref/pipeline/skybox.frag | 27 +++ shaders_ref/pipeline/skybox.vert | 25 +++ .../postprocessing/bloom/blur_downsample.frag | 61 +++++++ .../postprocessing/bloom/blur_downsample.vert | 11 ++ .../postprocessing/bloom/blur_upsample.frag | 25 +++ .../postprocessing/bloom/blur_upsample.vert | 11 ++ .../postprocessing/bloom/brightness.frag | 13 ++ .../postprocessing/bloom/brightness.vert | 11 ++ shaders_ref/postprocessing/dof.frag | 33 ++++ shaders_ref/postprocessing/dof.vert | 13 ++ shaders_ref/postprocessing/fxaa.frag | 14 ++ shaders_ref/postprocessing/fxaa.vert | 12 ++ shaders_ref/postprocessing/postprocess.frag | 81 +++++++++ shaders_ref/postprocessing/postprocess.vert | 13 ++ shaders_ref/postprocessing/ssao/ssao.frag | 139 ++++++++++++++ shaders_ref/postprocessing/ssao/ssao.vert | 12 ++ .../postprocessing/ssao/ssao_blur.frag | 69 +++++++ .../postprocessing/ssao/ssao_blur.vert | 12 ++ shaders_ref/postprocessing/ssr/ssr.frag | 172 ++++++++++++++++++ shaders_ref/postprocessing/ssr/ssr.vert | 13 ++ shaders_ref/shading/cloth.glsl | 16 ++ shaders_ref/shading/cloth_shading.glsl | 15 -- shaders_ref/shading/custom.glsl | 3 + .../{regular_shading.glsl => regular.glsl} | 13 +- shaders_ref/shading/shade_for_light.glsl | 14 -- shaders_ref/shading/shading_context.glsl | 34 +++- .../shading/shading_context_from_gctx.glsl | 16 ++ ...al.glsl => shading_context_from_mctx.glsl} | 10 +- shaders_ref/shading/shading_gctx.glsl | 20 ++ shaders_ref/shading/shading_mctx.glsl | 29 +++ shaders_ref/shading/subsurface.glsl | 17 ++ shaders_ref/shading/subsurface_shading.glsl | 16 -- shaders_ref/text/text.frag | 12 ++ shaders_ref/text/text.vert | 16 ++ shaders_ref/text/text_selection.frag | 10 + shaders_ref/text/text_selection.vert | 12 ++ shaders_ref/vertex_streams/mesh_emitter.glsl | 39 +++- src/limitless/core/shader/shader_compiler.cpp | 64 +------ .../core/shader/shader_define_replacer.cpp | 54 ++++++ src/limitless/core/shader/shader_program.cpp | 2 +- src/limitless/fx/effect_compiler.cpp | 97 +--------- .../fx/effect_shader_define_replacer.cpp | 110 +++++++++++ src/limitless/lighting/cascade_shadows.cpp | 5 - src/limitless/lighting/light_container.cpp | 1 + src/limitless/lighting/lighting.cpp | 21 +-- src/limitless/ms/material_builder.cpp | 30 +-- src/limitless/ms/material_compiler.cpp | 13 +- .../ms/material_shader_define_replacer.cpp | 75 ++++++++ src/limitless/ms/material_shader_definer.cpp | 68 ------- .../pipeline/common/render_debug_pass.cpp | 28 +-- src/limitless/pipeline/deferred/deferred.cpp | 6 +- .../deferred/deferred_lighting_pass.cpp | 10 +- .../pipeline/deferred/translucent_pass.cpp | 2 +- .../render_settings_shader_definer.cpp | 17 +- src/limitless/shader_storage.cpp | 19 +- src/limitless/skybox/skybox.cpp | 2 +- src/limitless/util/renderer_helper.cpp | 41 +++-- src/limitless/util/stack_trace.cpp | 147 +++++++++++++++ 122 files changed, 2380 insertions(+), 736 deletions(-) create mode 100644 include/limitless/core/shader/shader_define_replacer.hpp delete mode 100644 include/limitless/core/shader/shader_defines.hpp create mode 100644 include/limitless/fx/effect_shader_define_replacer.hpp rename include/limitless/ms/{material_shader_definer.hpp => material_shader_define_replacer.hpp} (87%) create mode 100644 include/limitless/util/stack_trace.hpp create mode 100644 shaders_ref/functions/circle.glsl create mode 100644 shaders_ref/functions/fresnel.glsl create mode 100644 shaders_ref/functions/hue_shift.glsl create mode 100644 shaders_ref/functions/refraction_sphere.glsl create mode 100644 shaders_ref/functions/tone_mapping.glsl create mode 100644 shaders_ref/lighting/ambient.glsl create mode 100644 shaders_ref/lighting/directional_shadows.frag create mode 100644 shaders_ref/lighting/directional_shadows.vert create mode 100644 shaders_ref/lighting/refraction.glsl create mode 100644 shaders_ref/lighting/scene_lighting.glsl create mode 100644 shaders_ref/lighting/shadows.glsl create mode 100644 shaders_ref/pipeline/color_picker.frag create mode 100644 shaders_ref/pipeline/color_picker.vert create mode 100644 shaders_ref/pipeline/gbuffer.frag create mode 100644 shaders_ref/pipeline/gbuffer.glsl create mode 100644 shaders_ref/pipeline/gbuffer.vert create mode 100644 shaders_ref/pipeline/gbuffer_context.glsl create mode 100644 shaders_ref/pipeline/quad.frag create mode 100644 shaders_ref/pipeline/quad.vert create mode 100644 shaders_ref/pipeline/skybox.frag create mode 100644 shaders_ref/pipeline/skybox.vert create mode 100644 shaders_ref/postprocessing/bloom/blur_downsample.frag create mode 100644 shaders_ref/postprocessing/bloom/blur_downsample.vert create mode 100644 shaders_ref/postprocessing/bloom/blur_upsample.frag create mode 100644 shaders_ref/postprocessing/bloom/blur_upsample.vert create mode 100644 shaders_ref/postprocessing/bloom/brightness.frag create mode 100644 shaders_ref/postprocessing/bloom/brightness.vert create mode 100644 shaders_ref/postprocessing/dof.frag create mode 100644 shaders_ref/postprocessing/dof.vert create mode 100644 shaders_ref/postprocessing/fxaa.frag create mode 100644 shaders_ref/postprocessing/fxaa.vert create mode 100644 shaders_ref/postprocessing/postprocess.frag create mode 100644 shaders_ref/postprocessing/postprocess.vert create mode 100644 shaders_ref/postprocessing/ssao/ssao.frag create mode 100644 shaders_ref/postprocessing/ssao/ssao.vert create mode 100644 shaders_ref/postprocessing/ssao/ssao_blur.frag create mode 100644 shaders_ref/postprocessing/ssao/ssao_blur.vert create mode 100644 shaders_ref/postprocessing/ssr/ssr.frag create mode 100644 shaders_ref/postprocessing/ssr/ssr.vert create mode 100644 shaders_ref/shading/cloth.glsl delete mode 100644 shaders_ref/shading/cloth_shading.glsl create mode 100644 shaders_ref/shading/custom.glsl rename shaders_ref/shading/{regular_shading.glsl => regular.glsl} (60%) delete mode 100644 shaders_ref/shading/shade_for_light.glsl create mode 100644 shaders_ref/shading/shading_context_from_gctx.glsl rename shaders_ref/shading/{shading_context_from_material.glsl => shading_context_from_mctx.glsl} (66%) create mode 100644 shaders_ref/shading/shading_gctx.glsl create mode 100644 shaders_ref/shading/shading_mctx.glsl create mode 100644 shaders_ref/shading/subsurface.glsl delete mode 100644 shaders_ref/shading/subsurface_shading.glsl create mode 100644 shaders_ref/text/text.frag create mode 100644 shaders_ref/text/text.vert create mode 100644 shaders_ref/text/text_selection.frag create mode 100644 shaders_ref/text/text_selection.vert create mode 100644 src/limitless/core/shader/shader_define_replacer.cpp create mode 100644 src/limitless/fx/effect_shader_define_replacer.cpp create mode 100644 src/limitless/ms/material_shader_define_replacer.cpp delete mode 100644 src/limitless/ms/material_shader_definer.cpp create mode 100644 src/limitless/util/stack_trace.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 12fe053c..2fd22984 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,9 @@ OPTION(WEBGL_BUILD "Web build" OFF) OPTION(CODECOV "Compile with test coverage" OFF) OPTION(GLSLANG_SHADER_OUTPUT OFF) + +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +set(CMAKE_ENABLE_EXPORTS ON) ######################################### # SETTINGS COMPILE FLAGS AND DEFINITIONS @@ -25,7 +28,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") endif() if (CMAKE_BUILD_TYPE STREQUAL "Release") - set(LIMITLESS_COMPILE_OPTIONS -Wpedantic -Wextra -Wall -Wunused -Wno-attributes -O3) + set(LIMITLESS_COMPILE_OPTIONS -Wpedantic -Wextra -Wall -Wunused -Wno-attributes) add_compile_definitions(NDEBUG) endif() @@ -97,6 +100,7 @@ set(ENGINE_CORE src/limitless/core/shader/shader_program.cpp src/limitless/core/shader/shader_program_texture_setter.cpp src/limitless/core/shader/shader_compiler.cpp + src/limitless/core/shader/shader_define_replacer.cpp src/limitless/core/vertex_array.cpp src/limitless/core/framebuffer.cpp @@ -164,6 +168,7 @@ set(ENGINE_UTIL src/limitless/util/sorter.cpp src/limitless/util/renderer_helper.cpp src/limitless/util/color_picker.cpp + src/limitless/util/stack_trace.cpp ) set(ENGINE_MS @@ -173,7 +178,7 @@ set(ENGINE_MS src/limitless/ms/material_builder.cpp src/limitless/ms/material_compiler.cpp src/limitless/ms/material_instance.cpp - src/limitless/ms/material_shader_definer.cpp + src/limitless/ms/material_shader_define_replacer.cpp ) set(ENGINE_TEXT @@ -193,6 +198,7 @@ set(ENGINE_FX src/limitless/fx/effect_builder.cpp src/limitless/fx/effect_compiler.cpp src/limitless/fx/particle.cpp + src/limitless/fx/effect_shader_define_replacer.cpp ) set(ENGINE_PIPELINE @@ -318,9 +324,9 @@ target_link_libraries(limitless_engine_static PUBLIC glfw ${GLFW_LIBRARIES}) target_link_libraries(limitless_engine_static PUBLIC assimp ${ASSIMP_LIBRARIES}) target_link_libraries(limitless_engine_static PUBLIC freetype) target_link_libraries(limitless_engine_static PUBLIC glew ${GLEW_LIBRARIES}) +target_link_libraries(limitless_engine_static PUBLIC dbghelp) target_compile_options(limitless_engine_static PUBLIC "${LIMITLESS_COMPILE_OPTIONS}") - #if (CODECOV) # message("shrek1") # target_link_options(limitless_engine_static PUBLIC -lgcov --coverage) @@ -358,6 +364,7 @@ target_link_libraries(limitless_demo glfw ${GLFW_LIBRARIES}) target_link_libraries(limitless_demo assimp ${ASSIMP_LIBRARIES}) target_link_libraries(limitless_demo freetype) target_link_libraries(limitless_demo glew ${GLEW_LIBRARIES}) +target_link_libraries(limitless_demo dbghelp) ############################################## diff --git a/demo/assets.cpp b/demo/assets.cpp index ee4e22a3..8b56d9b7 100644 --- a/demo/assets.cpp +++ b/demo/assets.cpp @@ -163,8 +163,8 @@ void DemoAssets::loadMaterialsScene() { .add(Property::IoR, 1.5) .addUniform(std::make_unique("time")) .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga"))) - .setFragmentSnippet("data.IoR = texture(noise, vec2(getVertexUV().x, getVertexUV().y + time * 0.1)).r;" - "data.IoR = clamp(data.IoR, 0.0, 1.0);" + .setFragmentSnippet("mctx.IoR = texture(noise, vec2(getVertexUV().x, getVertexUV().y + time * 0.1)).r;" + "mctx.IoR = clamp(mctx.IoR, 0.0, 1.0);" ) .setShading(Shading::Unlit) .build(); @@ -209,19 +209,21 @@ void DemoAssets::loadMaterialsScene() { TextureLoaderFlags::Space::sRGB })) .add(Property::EmissiveColor, glm::vec4(2.5f, 0.9f, 0.1f, 1.0f)) + .add(Property::Color, glm::vec4(2.5f, 0.9f, 0.1f, 1.0f)) .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga"))) .addUniform(std::make_unique("time")) .setFragmentSnippet( "vec2 panned = vec2(getVertexUV().x + time * 0.1, getVertexUV().y + time * 0.05);" "vec2 uv = getVertexUV() + texture(noise, panned).r;" - "data.baseColor.rgb = getMaterialDiffuse(uv).rgb;" - "data.emissive *= texture(noise, panned).g;" + "mctx.color.rgb = getMaterialDiffuse(uv).rgb;" + "mctx.emissive_color *= texture(noise, panned).g;" ) .setShading(Shading::Unlit) .build(); builder .setName("ice") .add(Property::EmissiveColor, glm::vec4(1.0f)) + .add(Property::Color, glm::vec4(1.0f)) .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/ice.jpg", { TextureLoaderFlags::Space::sRGB })) @@ -229,24 +231,25 @@ void DemoAssets::loadMaterialsScene() { .addUniform(std::make_unique("time")) .setFragmentSnippet( "vec2 uv = getVertexUV() + time * 0.05;" - "data.baseColor.rgb += texture(snow, uv).rgb * abs(cos(time * 0.5));" - "data.emissive *= texture(snow, uv).r;" + "mctx.color.rgb += texture(snow, uv).rgb * abs(cos(time * 0.5));" + "mctx.emissive_color *= texture(snow, uv).r;" ) .setShading(Shading::Unlit) .build(); builder .setName("poison") .add(Property::EmissiveColor, glm::vec4(0.1f, 4.0f, 0.1f, 1.0f)) + .add(Property::Color, glm::vec4(0.1f, 4.0f, 0.1f, 1.0f)) .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/poison.jpg", { TextureLoaderFlags::Space::sRGB })) .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga"))) .addUniform(std::make_unique("time")) .setFragmentSnippet( - "vec2 panned = vec2(getVertexUV().x + time * 0.05, getVertexUV().y);" + "vec2 panned = vec2(getVertexUV().x + time * 0.05, getVertexUV().y);" "vec2 uv = vec2(getVertexUV().x, getVertexUV().y + texture(noise, panned).g);" - "data.baseColor.rgb = getMaterialDiffuse(uv).rgb;" - "data.emissive *= getMaterialDiffuse(uv).g;" + "mctx.color.rgb = getMaterialDiffuse(uv).rgb;" + "mctx.emissive_color *= getMaterialDiffuse(uv).g;" ) .setShading(Shading::Unlit) .build(); @@ -266,9 +269,9 @@ void DemoAssets::loadMaterialsScene() { "float s = texture(fire_mask, uv_1).r;\n" "float t = texture(fire_mask, uv_2).r;\n" "\n" - "data.emissive = getMaterialDiffuse(uv + vec2(s, t)).rgb;\n" + "mctx.emissive_color = getMaterialDiffuse(uv + vec2(s, t)).rgb;\n" "\n" - "if (data.emissive.r <= 0.2) discard;") + "if (mctx.emissive_color.r <= 0.2) discard;") .addUniform(std::make_unique("time")) .addUniform(std::make_unique("fire_mask", TextureLoader::load(*this, assets_dir / "textures/fireball_mask.png"))) .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/rock_lava.png")) @@ -300,10 +303,10 @@ void DemoAssets::loadMaterialsScene() { TextureLoaderFlags::Space::sRGB })) .setGlobalSnippet( - "#include \"../../functions/fresnel.glsl\"" + "#include \"../functions/fresnel.glsl\"" ) .setFragmentSnippet( - "data.emissive *= fresnel(getFragmentNormal(data), getCameraPosition() - getVertexPosition(), 5.0);" + "mctx.emissive_color *= fresnel(getVertexNormal(), getCameraPosition() - getVertexPosition(), 5.0);" ) .build(); @@ -313,11 +316,12 @@ void DemoAssets::loadMaterialsScene() { .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/albedo.jpg", { TextureLoaderFlags::Space::sRGB })) + .add(Property::Color, glm::vec4(1.0)) .setGlobalSnippet( - "#include \"../../functions/hue_shift.glsl\"" + "#include \"../functions/hue_shift.glsl\"" ) .setFragmentSnippet( - "data.baseColor.rgb = hue_shift(data.baseColor.rgb, time);" + "mctx.color.rgb = hue_shift(mctx.color.rgb, time);" ) .build(); } @@ -345,7 +349,7 @@ void DemoAssets::loadEffectsScene() { "\n" "float m_a = getMaterialDiffuse(uv1).r;\n" "\n" - "data.color.a = mix(0.0, m_a, pow(r, erode));" + "mctx.color.a = mix(0.0, m_a, pow(r, erode));" ) .addModelShader(InstanceType::Effect) .build(); @@ -402,13 +406,13 @@ void DemoAssets::loadEffectsScene() { .addUniform(std::make_unique>("vertex_offset_dir", glm::vec3(0.2))) .setFragmentSnippet("vec2 uv = getVertexUV();" "float fres = fresnel(getVertexNormal(), getCameraPosition() - getVertexPosition(), 3.5);" - "data.color.rgb *= 1.0 - texture(maintexture, uv).r;" - "data.color.rgb *= fres * vec3(33.0 / 255.0 * 15.0f, 99.0 / 255.0 * 15.0f, 1000.0 / 255.0 * 25.0f);" + "mctx.color.rgb *= 1.0 - texture(maintexture, uv).r;" + "mctx.color.rgb *= fres * vec3(33.0 / 255.0 * 15.0f, 99.0 / 255.0 * 15.0f, 1000.0 / 255.0 * 25.0f);" ) .setVertexSnippet( "vertex_position.xyz += sin(getParticleTime() * vertex_offset_freq) * getVertexNormal() * vertex_offset_dir *texture(noise, getParticleTime() + uv).r;") - .setGlobalSnippet("#include \"../../functions/fresnel.glsl\"") + .setGlobalSnippet("#include \"../functions/fresnel.glsl\"") .build(); } @@ -442,21 +446,22 @@ void DemoAssets::loadEffectsScene() { "\n" "float r = offset1 * offset2;\n" "\n" - "data.baseColor.rgb = getMaterialDiffuse(uv).rgb;\n" - "data.baseColor.rgb *= clamp((1.0 - getParticleProperties().z) * r, 0, 1);" + "mctx.color.rgb = getMaterialDiffuse(uv).rgb;\n" + "mctx.color.rgb *= clamp((1.0 - getParticleProperties().z) * r, 0, 1);" ) .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir /"textures/true_noise.tga"))) .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/true_fire.tga")) + .add(Property::Color, glm::vec4(1.0f)) .setShading(Shading::Unlit) .setBlending(Blending::Additive) - .setGlobalSnippet("#include \"../../functions/tone_mapping.glsl\"") + .setGlobalSnippet("#include \"../functions/tone_mapping.glsl\"") .addModelShader(::InstanceType::Effect) .build(); builder .setName("fireball_sparks") - .setFragmentSnippet("data.emissive *= circle(getVertexUV(), 0.7);" - "data.color.rgb *= circle(getVertexUV(), 0.7);") - .setGlobalSnippet("#include \"../../functions/circle.glsl\"") + .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7);" + "mctx.color.rgb *= circle(getVertexUV(), 0.7);") + .setGlobalSnippet("#include \"../functions/circle.glsl\"") .add(Property::EmissiveColor, glm::vec4{5.0f, 1.5f, 1.0f, 1.0f}) .add(Property::Color, glm::vec4(1.0)) @@ -500,9 +505,9 @@ void DemoAssets::loadEffectsScene() { .setBlending(Blending::Additive) .add(::Property::EmissiveColor, glm::vec4(2.0, 1.0, 0.3, 1.0)) .add(::Property::Color, glm::vec4(1.0, 1.0, 0.3, 1.0)) - .setFragmentSnippet("data.emissive *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" - "data.color.rgb *= circle(getVertexUV(), 0.7);") - .setGlobalSnippet("#include \"../../functions/circle.glsl\"") + .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" + "mctx.color.rgb *= circle(getVertexUV(), 0.7);") + .setGlobalSnippet("#include \"../functions/circle.glsl\"") .addModelShader(InstanceType::Effect) .build(); } @@ -532,9 +537,9 @@ void DemoAssets::loadEffectsScene() { .setBlending(Blending::Additive) .add(::Property::EmissiveColor, glm::vec4(5.0, 0.0, 5.0, 1.0)) .add(::Property::Color, glm::vec4(1.0, 0.0, 1.0, 1.0)) - .setFragmentSnippet("data.emissive *= circle(getVertexUV(), 0.5);" - "data.color.rgb = vec3(0.0);") - .setGlobalSnippet("#include \"../../functions/circle.glsl\"") + .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.5);" + "mctx.color.rgb = vec3(0.0);") + .setGlobalSnippet("#include \"../functions/circle.glsl\"") .addModelShader(InstanceType::Effect) .build(); } @@ -562,11 +567,11 @@ void DemoAssets::loadEffectsScene() { builder.setName("drop") .add(Property::EmissiveColor, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) .add(Property::Color, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) - .setFragmentSnippet("data.emissive *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" - "data.color.rgb *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;") + .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" + "mctx.color.rgb *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;") .setShading(Shading::Unlit) .setBlending(Blending::Additive) - .setGlobalSnippet("#include \"../../functions/circle.glsl\"") + .setGlobalSnippet("#include \"../functions/circle.glsl\"") .addModelShader(InstanceType::Effect) .build(); } @@ -591,7 +596,7 @@ void DemoAssets::loadEffectsScene() { MaterialBuilder builder {*this}; builder.setName("beam_lightning") .add(Property::EmissiveColor, glm::vec4(2.8f, 2.8f, 4.8f, 1.0f)) - .setFragmentSnippet("data.emissive *= getParticleColor().rgb;") + .setFragmentSnippet("mctx.emissive_color *= getParticleColor().rgb;") .setShading(Shading::Unlit) .setBlending(Blending::Opaque) .addModelShader(InstanceType::Effect) @@ -624,11 +629,11 @@ void DemoAssets::loadEffectsScene() { builder.setName("skeleton4ik") .add(Property::EmissiveColor, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) .add(Property::Color, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) - .setFragmentSnippet("data.emissive *= circle(getVertexUV(), 0.7);" - "data.color.rgb *= circle(getVertexUV(), 0.7);") + .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7);" + "mctx.color.rgb *= circle(getVertexUV(), 0.7);") .setShading(Shading::Unlit) .setBlending(Blending::Additive) - .setGlobalSnippet("#include \"../../functions/circle.glsl\"") + .setGlobalSnippet("#include \"../functions/circle.glsl\"") .addModelShader(InstanceType::Effect) .build(); } @@ -734,7 +739,7 @@ void DemoAssets::loadModelsScene() { .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/yellow_env.tga"))) - .setFragmentSnippet("data.emissive = texture(emissive_map, getVertexUV()).rgb;") + .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") .setShading(Shading::Lit) .addModelShader(InstanceType::Skeletal) .build(); @@ -745,7 +750,7 @@ void DemoAssets::loadModelsScene() { .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/bodygray_m.tga")) .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/gray_env.tga"))) - .setFragmentSnippet("data.emissive = texture(emissive_map, getVertexUV()).rgb;") + .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") .setShading(Shading::Lit) .addModelShader(InstanceType::Skeletal) .build(); @@ -757,7 +762,7 @@ void DemoAssets::loadModelsScene() { .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/eye_env.tga"))) - .setFragmentSnippet("data.emissive = texture(emissive_map, getVertexUV()).rgb;") + .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") .setShading(Shading::Lit) .addModelShader(InstanceType::Skeletal) .build(); @@ -769,7 +774,7 @@ void DemoAssets::loadModelsScene() { .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/blue_env.tga"))) - .setFragmentSnippet("data.emissive = texture(emissive_map, getVertexUV()).rgb;") + .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") .setShading(Shading::Lit) .addModelShader(InstanceType::Skeletal) .build(); @@ -888,9 +893,9 @@ void DemoAssets::loadModelsScene() { .add(Property::AmbientOcclusionTexture, TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body_OcclusionRoughnessMetallic.png")) .addUniform(std::make_unique("ao_r_m", TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body_OcclusionRoughnessMetallic.png"))) .setFragmentSnippet("vec3 skin = texture(ao_r_m, getVertexUV()).rgb;" - "data.ao = skin.r;" - "data.roughness = skin.g;" - "data.metallic = skin.b;") + "mctx.ao = skin.r;" + "mctx.roughness = skin.g;" + "mctx.metallic = skin.b;") .setShading(Shading::Lit) .addModelShader(InstanceType::Skeletal) .build(); @@ -952,7 +957,7 @@ void DemoAssets::loadModelsScene() { .add(::Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Rougness FireElemental.png")) .add(::Property::Metallic, 0.1f) .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Emission FireElemental.png"))) - .setFragmentSnippet("data.emissive = texture(emissive_map, getVertexUV()).rgb;") + .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") .setShading(Shading::Lit) .build(); diff --git a/demo/demo.cpp b/demo/demo.cpp index 26afba17..3817eda7 100644 --- a/demo/demo.cpp +++ b/demo/demo.cpp @@ -9,9 +9,51 @@ #include #include #include +#include using namespace Limitless; +std::ostream& operator<<(std::ostream& stream, const StackFrame& stackframe) { + return stream << stackframe.module << ": " << stackframe.func << std::endl; +} + +std::ostream& operator<<(std::ostream& stream, const StackTrace& stacktrace) { + for (const auto& frame : stacktrace) { + stream << frame; + } + return stream; +} + +static void terminationHandler() { + std::cerr << "The application has to be terminated due to a fatal error"; + bool printed_stack_trace = false; + + auto exception = std::current_exception(); + if (exception) { + try { + std::rethrow_exception(exception); + } + catch (const std::runtime_error& ex) { + std::cerr << ": " << ex.what() << std::endl; +// std::cerr << ex.stack_trace; + printed_stack_trace = true; + } + catch (const std::exception& ex) { + std::cerr << ": " << ex.what() << std::endl; + } + catch (...) { + std::cerr << "." << std::endl; + } + } else { + std::cerr << "." << std::endl; + } + + if (!printed_stack_trace) { + std::cerr << getStackTrace(1) << std::endl; + } + std::abort(); +} + class Game : public MouseMoveObserver, public KeyObserver, public FramebufferObserver { private: glm::uvec2 window_size {1080, 720}; @@ -153,6 +195,7 @@ class Game : public MouseMoveObserver, public KeyObserver, public FramebufferObs }; int main() { + std::set_terminate(terminationHandler); Game game; game.gameLoop(); return 0; diff --git a/demo/lighting_demoscene.cpp b/demo/lighting_demoscene.cpp index 3e057b37..db65bbad 100644 --- a/demo/lighting_demoscene.cpp +++ b/demo/lighting_demoscene.cpp @@ -53,7 +53,7 @@ bool LightingScene::isInsideFloor(const glm::vec3& position) { void LightingScene::addLights() { for (int i = 0; i < LIGHT_COUNT; ++i) { - lighting.point_lights.emplace_back( + lighting.lights.emplace_back( glm::vec4{FLOOR_INSTANCE_COUNT / 4.0f, 1.0f, FLOOR_INSTANCE_COUNT / 4.0f, 1.0f}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}, 2.0f @@ -88,16 +88,16 @@ void LightingScene::update(Limitless::Context& context, const Limitless::Camera& std::uniform_real_distribution<> dis_color(0.0, 1.0); for (std::size_t i = 0; i < data.size(); ++i) { - auto& light = lighting.point_lights.at(i); + auto& light = lighting.lights.at(i); auto& light_data = data[i]; - light.position += glm::vec4(light_data.direction, 0.0f) * delta_time * 10.0f; + light.position += glm::vec4(light_data.direction, 1.0) * delta_time * 10.0f; light.position = glm::clamp(light.position, glm::vec4(0.0f), glm::vec4(FLOOR_INSTANCE_COUNT / 2.0f)); if (light_data.duration <= 0.0f) { light_data.direction = glm::vec3(dis_direction(e), 0.0f, dis_direction(e)); light_data.duration = dis_duration(e); - light.color = glm::vec4(dis_color(e), dis_color(e), dis_color(e), 2.0f); + light.color = glm::vec4(dis_color(e), dis_color(e), dis_color(e), 1.0f); } else { light_data.duration -= delta_time; } diff --git a/demo/materials_demoscene.cpp b/demo/materials_demoscene.cpp index 6f8af2a4..1bb1b6bf 100644 --- a/demo/materials_demoscene.cpp +++ b/demo/materials_demoscene.cpp @@ -10,7 +10,25 @@ MaterialsScene::MaterialsScene(Limitless::Context& ctx, Limitless::Assets& asset : Limitless::Scene(ctx) { addModels(assets); setSkybox(assets.skyboxes.at("skybox")); - lighting.directional_light = {glm::vec4(2.0, -2.0, 1.5, 1.0f), glm::vec4{1.0f}}; + lighting.directional_light = {glm::vec4(1.0, -1.0, 0.5, 1.0f), glm::vec4{1.0f}}; + + lighting.lights.emplace_back( + glm::vec4{0.0f, 0.5f, 0.0f, 1.0f}, + glm::vec4{1.0f, 0.0f, 0.0f, 2.0f}, + 2.0f + ); + + lighting.lights.emplace_back( + glm::vec4{5.0f, 0.5f, 0.0f, 1.0f}, + glm::vec4{0.0f, 1.0f, 0.0f, 2.0f}, + 2.0f + ); + + lighting.lights.emplace_back( + glm::vec4{0.0f, 0.5f, 5.0f, 1.0f}, + glm::vec4{0.0f, 0.0f, 1.0f, 2.0f}, + 2.0f + ); } void MaterialsScene::addModels(const Limitless::Assets& assets) { diff --git a/include/limitless/core/keyline_extensions.hpp b/include/limitless/core/keyline_extensions.hpp index c794ec83..234e690f 100644 --- a/include/limitless/core/keyline_extensions.hpp +++ b/include/limitless/core/keyline_extensions.hpp @@ -2,7 +2,7 @@ namespace Limitless { constexpr auto bindless_texture = "GL_ARB_bindless_texture"; - constexpr auto bindless_texture_define = "#define BINDLESS_TEXTURE\n"; + constexpr auto bindless_texture_define = "#define ENGINE_EXT_BINDLESS_TEXTURE\n"; constexpr auto extension_bindless_texture = "#extension GL_ARB_bindless_texture : require\n"; constexpr auto bindless_samplers = "layout(bindless_sampler) uniform;\n"; diff --git a/include/limitless/core/shader/shader_compiler.hpp b/include/limitless/core/shader/shader_compiler.hpp index bb19a369..983d9a00 100644 --- a/include/limitless/core/shader/shader_compiler.hpp +++ b/include/limitless/core/shader/shader_compiler.hpp @@ -46,30 +46,7 @@ namespace Limitless { */ std::optional render_settings; - /** - * Sets up ShaderAction to be applied to shader source code - * - * Replaces EngineShaderDefine keys with corresponding values - * - * @param shader - shader to be applied to - */ - void replaceEngineDefines(Shader& shader) const; - - /** - * Replaces key-line "Limitless::Extensions" in shader source code with extensions enabled by Engine - * - * Replaced extensions depend on functionality used by Engine and GPU capabilities - */ - static std::string getVersionDefine(); - - /** - * Replaces key-line "Limitless::GLSL_VERSION" in shader source code with version used by Engine - * - * It is always 3.3 version for now (Advanced functionality supported by use of extensions) - */ - static std::string getExtensionsDefine(); - std::string getSettingsDefine() const; - std::string getCommonDefine() const; + void replaceCommonDefines(Shader& shader); public: /** * Shader constructor diff --git a/include/limitless/core/shader/shader_define_replacer.hpp b/include/limitless/core/shader/shader_define_replacer.hpp new file mode 100644 index 00000000..bd17bddc --- /dev/null +++ b/include/limitless/core/shader/shader_define_replacer.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include + +namespace Limitless { + class RenderSettings; + class Shader; + + class ShaderDefineReplacer { + protected: + enum class Define { + GLSLVersion, + Extensions, + Settings, + // contains three def above + Common, + // material type + MaterialDependent + }; + + static inline std::unordered_map DEFINE_NAMES = + { + { Define::GLSLVersion, "ENGINE::GLSLVERSION"}, + { Define::Extensions, "ENGINE::EXTENSIONS"}, + { Define::Settings, "ENGINE::SETTINGS"}, + { Define::Common, "ENGINE::COMMON"}, + { Define::MaterialDependent, "ENGINE::MATERIALDEPENDENT"}, + }; + + static std::string getVersionDefine(); + static std::string getExtensionDefine(); + static std::string getSettingsDefine(std::optional settings); + static std::string getCommonDefine(std::optional settings); + public: + static void replaceCommon(Shader& shader, std::optional settings); + }; +} \ No newline at end of file diff --git a/include/limitless/core/shader/shader_defines.hpp b/include/limitless/core/shader/shader_defines.hpp deleted file mode 100644 index 8af405dc..00000000 --- a/include/limitless/core/shader/shader_defines.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include - -namespace Limitless { - enum class EngineShaderDefine { - GLSLVersion, - Extensions, - Settings, - MaterialType, - ModelType, - EmitterType, - - // GLSLVersion + Extensions + Settings - Common, - - // ALL OF ABOVE - MaterialDependent - }; - - static inline std::unordered_map ENGINE_SHADER_DEFINE_NAMES = - { - { EngineShaderDefine::GLSLVersion, "ENGINE::GLSLVERSION"}, - { EngineShaderDefine::Extensions, "ENGINE::EXTENSIONS"}, - { EngineShaderDefine::Settings, "ENGINE::SETTINGS"}, - { EngineShaderDefine::MaterialType, "ENGINE::MATERIALTYPE"}, - { EngineShaderDefine::ModelType, "ENGINE::MODELTYPE"}, - { EngineShaderDefine::EmitterType, "ENGINE::EMITTERTYPE"}, - { EngineShaderDefine::Common, "ENGINE::COMMON"}, - { EngineShaderDefine::MaterialDependent, "ENGINE::MATERIALDEPENDENT"}, - }; -} \ No newline at end of file diff --git a/include/limitless/fx/effect_compiler.hpp b/include/limitless/fx/effect_compiler.hpp index 109482da..7b26f580 100644 --- a/include/limitless/fx/effect_compiler.hpp +++ b/include/limitless/fx/effect_compiler.hpp @@ -13,8 +13,6 @@ namespace Limitless::fx { class EffectCompiler : public ms::MaterialCompiler { private: - static std::string getEmitterDefines(const AbstractEmitter& emitter) noexcept; - template void compile(ShaderType shader_type, const T& emitter); public: diff --git a/include/limitless/fx/effect_shader_define_replacer.hpp b/include/limitless/fx/effect_shader_define_replacer.hpp new file mode 100644 index 00000000..fb736ecd --- /dev/null +++ b/include/limitless/fx/effect_shader_define_replacer.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace Limitless::ms { + class Material; +} + +namespace Limitless::fx { + class AbstractEmitter; + + class EffectShaderDefineReplacer : public ms::MaterialShaderDefineReplacer { + private: + static std::string getEmitterDefines(const AbstractEmitter& emitter) noexcept; + public: + static void replaceMaterialDependentDefine(Shader& shader, const ms::Material& material, InstanceType model_shader, const AbstractEmitter& emitter); + }; +} \ No newline at end of file diff --git a/include/limitless/lighting/lighting.hpp b/include/limitless/lighting/lighting.hpp index 22dbfc3c..3db05811 100644 --- a/include/limitless/lighting/lighting.hpp +++ b/include/limitless/lighting/lighting.hpp @@ -20,11 +20,7 @@ namespace Limitless { // global lighting DirectionalLight directional_light; - // point lighting - LightContainer point_lights; - - // spot lighting - LightContainer spot_lights; + LightContainer lights; explicit Lighting(Context& ctx); ~Lighting() = default; diff --git a/include/limitless/lighting/lights.hpp b/include/limitless/lighting/lights.hpp index c3cba519..89883213 100644 --- a/include/limitless/lighting/lights.hpp +++ b/include/limitless/lighting/lights.hpp @@ -12,44 +12,31 @@ namespace Limitless { DirectionalLight(const glm::vec4& _direction, const glm::vec4& _color) noexcept : direction {_direction} - , color {_color} {} + , color {_color} { + } }; - struct PointLight final { - static constexpr auto SHADER_STORAGE_NAME = "POINT_LIGHTS_BUFFER"; + struct Light final { + static constexpr auto SHADER_STORAGE_NAME = "LIGHTS_BUFFER"; - glm::vec4 position {}; glm::vec4 color {}; - float constant {1.0f}; - float linear {0.7f}; - float quadratic {1.8f}; - float radius {1.0f}; - - PointLight() = default; - ~PointLight() = default; - - PointLight(const glm::vec3& _position, const glm::vec4& _color, float _radius) noexcept - : position {_position, 1.0f} - , color {_color} - , radius {_radius} {} - }; - - struct SpotLight final { - static constexpr auto SHADER_STORAGE_NAME = "SPOT_LIGHTS_BUFFER"; - glm::vec4 position {}; glm::vec4 direction {}; - glm::vec4 color {}; - float cutoff {}; // cos (radians(degrees)) - float radius {5.0f}; - - SpotLight() = default; - ~SpotLight() = default; - - SpotLight(const glm::vec3& _position, const glm::vec3& _direction, const glm::vec4& _color, float _cutoff) noexcept - : position {_position, 1.0f} - , direction {_direction, 1.0f} - , color {_color} - , cutoff {_cutoff} {} + glm::vec2 scale_offset {}; + float falloff {}; + uint32_t type {1u}; + + Light() = default; + ~Light() = default; + + auto getRadius() const { + return sqrt(1.0 / falloff); + } + + Light(const glm::vec3& position, const glm::vec4& _color, const float radius) noexcept + : position {position, 1.0} + , color {_color} + , falloff {1.0f / (radius * radius)} { + } }; } diff --git a/include/limitless/ms/material_shader_definer.hpp b/include/limitless/ms/material_shader_define_replacer.hpp similarity index 87% rename from include/limitless/ms/material_shader_definer.hpp rename to include/limitless/ms/material_shader_define_replacer.hpp index 41f7acba..6fa28330 100644 --- a/include/limitless/ms/material_shader_definer.hpp +++ b/include/limitless/ms/material_shader_define_replacer.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace Limitless { class Shader; @@ -12,9 +13,9 @@ namespace Limitless { namespace ms { class Material; - class MaterialShaderDefiner { - private: - static inline std::unordered_map SHADER_PROPERTY_DEFINE = + class MaterialShaderDefineReplacer : public ShaderDefineReplacer { + protected: + static inline std::unordered_map PROPERTY_DEFINE = { { Property::Color, "ENGINE_MATERIAL_COLOR" }, { Property::EmissiveColor, "ENGINE_MATERIAL_EMISSIVE_COLOR" }, @@ -33,7 +34,7 @@ namespace Limitless { { Property::Absorption, "ENGINE_MATERIAL_ABSORPTION" }, }; - static inline std::unordered_map SHADER_SHADING_DEFINE = + static inline std::unordered_map SHADING_DEFINE = { { Shading::Lit, "ENGINE_MATERIAL_SHADING_REGULAR_MODEL" }, { Shading::Unlit, "ENGINE_MATERIAL_SHADING_UNLIT_MODEL" }, @@ -42,7 +43,7 @@ namespace Limitless { { Shading::Custom, "ENGINE_MATERIAL_SHADING_CUSTOM_MODEL" }, }; - static inline std::unordered_map SHADER_MODEL_DEFINE = + static inline std::unordered_map MODEL_DEFINE = { { InstanceType::Model, "ENGINE_MATERIAL_REGULAR_MODEL" }, { InstanceType::Skeletal, "ENGINE_MATERIAL_SKELETAL_MODEL" }, @@ -60,7 +61,7 @@ namespace Limitless { CustomSamplers }; - static inline std::unordered_map SHADER_SNIPPET_DEFINE = + static inline std::unordered_map SNIPPET_DEFINE = { { SnippetDefineType::Vertex, "ENGINE_MATERIAL_VERTEX_SNIPPET" }, { SnippetDefineType::Tesselation, "ENGINE_MATERIAL_TESSELATION_SNIPPET" }, @@ -74,12 +75,13 @@ namespace Limitless { static std::string getShadingDefines(const Material& material); static std::string getModelDefines(InstanceType model_shader); static std::string getMaterialDefines(const Material& material); + static std::string getMaterialDependentDefine(const Material& material, InstanceType model_shader); static std::string getScalarUniformDefines(const Material& material); static std::string getSamplerUniformDefines(const Material& material); - MaterialShaderDefiner() noexcept = default; + MaterialShaderDefineReplacer() noexcept = default; public: - static void define(Shader &shader, const Material& material, InstanceType model_shader); + static void replaceMaterialDependentDefine(Shader& shader, const Material& material, InstanceType model_shader); }; } } \ No newline at end of file diff --git a/include/limitless/ms/shading.hpp b/include/limitless/ms/shading.hpp index b5278a82..462da4bb 100644 --- a/include/limitless/ms/shading.hpp +++ b/include/limitless/ms/shading.hpp @@ -8,21 +8,23 @@ namespace Limitless::ms { */ enum class Shading { /** - * Standard model + * Unlit model turns off lighting computations * - * used to describe metallic and non-metallic surfaces + * Maybe used to render pre-lit models such as cubemaps, UI or emissive meshes */ - Lit, + Unlit, /** - * Unlit model turns off lighting computations + * Standard model * - * Maybe used to render pre-lit models such as cubemaps, UI or emissive meshes + * used to describe metallic and non-metallic surfaces */ - Unlit, + Lit, Cloth, + Subsurface, + Custom, }; } \ No newline at end of file diff --git a/include/limitless/pipeline/common/render_debug_pass.hpp b/include/limitless/pipeline/common/render_debug_pass.hpp index f20d24c3..8218c8e0 100644 --- a/include/limitless/pipeline/common/render_debug_pass.hpp +++ b/include/limitless/pipeline/common/render_debug_pass.hpp @@ -5,15 +5,15 @@ #include namespace Limitless { -// class RenderDebugPass final : public PipelinePass { -// private: -// RendererHelper helper; -// Lighting* lighting {}; -// public: -// explicit RenderDebugPass(Pipeline& pipeline, const RenderSettings& settings); -// ~RenderDebugPass() override = default; -// -// void update(Scene& scene, Instances& instances, Context& ctx, const Camera& camera) override; -// void draw(Instances& instances, Context& ctx, const Assets& assets, const Camera& camera, UniformSetter& setter) override; -// }; + class RenderDebugPass final : public PipelinePass { + private: + RendererHelper helper; + Lighting* lighting {}; + public: + explicit RenderDebugPass(Pipeline& pipeline, const RenderSettings& settings); + ~RenderDebugPass() override = default; + + void update(Scene& scene, Instances& instances, Context& ctx, const Camera& camera) override; + void draw(Instances& instances, Context& ctx, const Assets& assets, const Camera& camera, UniformSetter& setter) override; + }; } \ No newline at end of file diff --git a/include/limitless/pipeline/shader_type.hpp b/include/limitless/pipeline/shader_type.hpp index 05de63c0..be39d4b6 100644 --- a/include/limitless/pipeline/shader_type.hpp +++ b/include/limitless/pipeline/shader_type.hpp @@ -63,15 +63,15 @@ namespace Limitless { }; inline const std::map SHADER_PASS_PATH = { - {ShaderType::Forward, "pipeline" PATH_SEPARATOR "forward" PATH_SEPARATOR "forward" }, + {ShaderType::Forward, "pipeline" PATH_SEPARATOR "forward" }, - {ShaderType::Depth, "pipeline" PATH_SEPARATOR "deferred" PATH_SEPARATOR "depth" }, - {ShaderType::GBuffer, "pipeline" PATH_SEPARATOR "deferred" PATH_SEPARATOR "gbuffer" }, - {ShaderType::Skybox, "pipeline" PATH_SEPARATOR "deferred" PATH_SEPARATOR "skybox"}, + {ShaderType::Depth, "pipeline" PATH_SEPARATOR "depth" }, + {ShaderType::GBuffer, "pipeline" PATH_SEPARATOR "gbuffer" }, + {ShaderType::Skybox, "pipeline" PATH_SEPARATOR "skybox" }, - {ShaderType::DirectionalShadow, "pipeline" PATH_SEPARATOR "lighting" PATH_SEPARATOR "directional_shadows" }, + {ShaderType::DirectionalShadow, "lighting" PATH_SEPARATOR "directional_shadows" }, - {ShaderType::ColorPicker, "pipeline" PATH_SEPARATOR "util" PATH_SEPARATOR "color_picker" }, + {ShaderType::ColorPicker, "pipeline" PATH_SEPARATOR "color_picker" }, }; /** diff --git a/include/limitless/renderer/render_settings.hpp b/include/limitless/renderer/render_settings.hpp index adbc1ef4..266f1b01 100644 --- a/include/limitless/renderer/render_settings.hpp +++ b/include/limitless/renderer/render_settings.hpp @@ -26,7 +26,7 @@ namespace Limitless { /** * Screen Space Ambient Occlusion */ - bool screen_space_ambient_occlusion {true}; + bool screen_space_ambient_occlusion {false}; SSAO::Settings settings; /** @@ -64,7 +64,7 @@ namespace Limitless { /** * Micro-shadowing for CSM */ - bool csm_micro_shadowing = false; + bool csm_micro_shadowing = true; /** * @@ -74,6 +74,13 @@ namespace Limitless { float bloom_strength {1.0f}; uint32_t bloom_blur_iteration_count {8}; + /** + * + */ + bool specular_aa {true}; + float specular_aa_threshold {0.1f}; + float specular_aa_variance {0.2f}; + /** * Debug settings */ @@ -81,12 +88,12 @@ namespace Limitless { /** * Render lights impact area */ - bool light_radius = true; + bool light_radius = false; /** * Render System Axes */ - bool coordinate_system_axes = false; + bool coordinate_system_axes = true; /** * Render bounding boxes diff --git a/include/limitless/renderer/render_settings_shader_definer.hpp b/include/limitless/renderer/render_settings_shader_definer.hpp index c37d821c..90de7b9d 100644 --- a/include/limitless/renderer/render_settings_shader_definer.hpp +++ b/include/limitless/renderer/render_settings_shader_definer.hpp @@ -7,11 +7,7 @@ namespace Limitless { class Shader; class RenderSettingsShaderDefiner { - private: - const RenderSettings& settings; public: - explicit RenderSettingsShaderDefiner(const RenderSettings& settings) noexcept; - - std::string define(); + static std::string getDefine(const RenderSettings& settings); }; } \ No newline at end of file diff --git a/include/limitless/util/stack_trace.hpp b/include/limitless/util/stack_trace.hpp new file mode 100644 index 00000000..eb86bbdd --- /dev/null +++ b/include/limitless/util/stack_trace.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include + +namespace Limitless { + struct StackFrame { + std::string module; + std::string func; + std::string offset; + }; + + using StackTrace = std::vector; + + // Return stack trace for current stack frame. + StackTrace getStackTrace(size_t frames_to_skip = 0, size_t max_frames = 128); +} \ No newline at end of file diff --git a/shaders_ref/API.md b/shaders_ref/API.md index 425c9be9..b8ef458d 100644 --- a/shaders_ref/API.md +++ b/shaders_ref/API.md @@ -17,3 +17,20 @@ lit pbr ior absorption transmission + + +How final surface color is calculated: + +1) You should compute MaterialContext + MaterialContext already contains default material parameters and user invoked code to customize this parameters +2) You should compute ShadingContext from MaterialContext or pass parameters yourself +3) Lighting is calculated from ShadingContext +4) + + +transmission/ absorption / energyconserv ? + +refraction works only on translucent objects = forward render after deferred + + +make shaders include-consistent \ No newline at end of file diff --git a/shaders_ref/functions/brdf.glsl b/shaders_ref/functions/brdf.glsl index 6e4b4f25..e1ee1038 100644 --- a/shaders_ref/functions/brdf.glsl +++ b/shaders_ref/functions/brdf.glsl @@ -1,3 +1,14 @@ + +#if defined (ENGINE_MATERIAL_QUALITY_HIGH) + #define ENGINE_MATERIAL_DIFFUSE_BURLEY + #define ENGINE_MATERIAL_SPECULAR_GGX + #define ENGINE_MATERIAL_SPECULAR_SCHLICK +#else + #define ENGINE_MATERIAL_DIFFUSE_LAMBERT + #define ENGINE_MATERIAL_SPECULAR_GGX_FAST + #define ENGINE_MATERIAL_SPECULAR_SCHLICK_FAST +#endif + // "An Inexpensive BRDF Model for Physically-Based Rendering", Schlick 1994 vec3 F_Schlick(const vec3 F0, float F90, float VoH) { return F0 + (F90 - F0) * pow5(1.0 - VoH); @@ -33,11 +44,11 @@ float V_SmithGGXCorrelatedFast(float roughness, float NoV, float NoL) { } vec3 SpecularF(const vec3 F0, float LoH) { -#if defined (ENGINE_MATERIAL_QUALITY_LOW) - return F_Schlick(F0, LoH); -#else +#if defined (ENGINE_MATERIAL_SPECULAR_SCHLICK) float F90 = saturate(dot(F0, vec3(50.0 * 0.33))); return F_Schlick(F0, F90, LoH); +#elif defined (ENGINE_MATERIAL_SPECULAR_SCHLICK_FAST) + return F_Schlick(F0, LoH); #endif } diff --git a/shaders_ref/functions/circle.glsl b/shaders_ref/functions/circle.glsl new file mode 100644 index 00000000..089e61cd --- /dev/null +++ b/shaders_ref/functions/circle.glsl @@ -0,0 +1,4 @@ +float circle(in vec2 uv, in float r){ + vec2 dist = uv - vec2(0.5); + return 1.0 - smoothstep(r - (r * 0.3), r + (r * 0.3), dot(dist, dist) * 4.0); +} \ No newline at end of file diff --git a/shaders_ref/functions/common.glsl b/shaders_ref/functions/common.glsl index 2d6ba6da..852ed7f1 100644 --- a/shaders_ref/functions/common.glsl +++ b/shaders_ref/functions/common.glsl @@ -32,3 +32,16 @@ float computeMicroShadowing(float NoL, float visibility) { float microShadow = saturate(NoL * aperture); return microShadow * microShadow; } + +float specularAA(const vec3 normal, float perceptualRoughness, float aaThreshold, float aaVariance) { + vec3 du = dFdx(normal); + vec3 dv = dFdy(normal); + + float variance = aaVariance * (dot(du, du) + dot(dv, dv)); + + float roughness = perceptualRoughness * perceptualRoughness; + float kernelRoughness = min(2.0 * variance, aaThreshold); + float squareRoughness = saturate(roughness * roughness + kernelRoughness); + + return sqrt(sqrt(squareRoughness)); +} diff --git a/shaders_ref/functions/fresnel.glsl b/shaders_ref/functions/fresnel.glsl new file mode 100644 index 00000000..c2592bcc --- /dev/null +++ b/shaders_ref/functions/fresnel.glsl @@ -0,0 +1,3 @@ +float fresnel(vec3 normal, vec3 view, float power) { + return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0)), power); +} \ No newline at end of file diff --git a/shaders_ref/functions/hue_shift.glsl b/shaders_ref/functions/hue_shift.glsl new file mode 100644 index 00000000..f452297c --- /dev/null +++ b/shaders_ref/functions/hue_shift.glsl @@ -0,0 +1,5 @@ +vec3 hue_shift(vec3 color, float hue) { + const vec3 k = vec3(0.57735, 0.57735, 0.57735); + float cosAngle = cos(hue); + return vec3(color * cosAngle + cross(k, color) * sin(hue) + k * dot(k, color) * (1.0 - cosAngle)); +} \ No newline at end of file diff --git a/shaders_ref/functions/refraction_sphere.glsl b/shaders_ref/functions/refraction_sphere.glsl new file mode 100644 index 00000000..4f9d1ec5 --- /dev/null +++ b/shaders_ref/functions/refraction_sphere.glsl @@ -0,0 +1,13 @@ +float f0ToIor(float f0) { + float r = sqrt(f0); + return (1.0 + r) / (1.0 - r); +} + +vec3 refractionSolidSphere(const vec3 N, vec3 r, float etaIR, float etaRI, vec3 position) { + float thickness = 0.5; + r = refract(r, N, etaIR); + float NoR = dot(N, r); + float d = thickness * -NoR; + position = vec3(position + r * d); + return position; +} diff --git a/shaders_ref/functions/tone_mapping.glsl b/shaders_ref/functions/tone_mapping.glsl new file mode 100644 index 00000000..0f9b08c9 --- /dev/null +++ b/shaders_ref/functions/tone_mapping.glsl @@ -0,0 +1,3 @@ +vec3 toneMapping(vec3 color, float exposure) { + return vec3(1.0) - exp(-color * exposure); +} diff --git a/shaders_ref/instance/instance.glsl b/shaders_ref/instance/instance.glsl index 4ec9a997..09e20f4d 100644 --- a/shaders_ref/instance/instance.glsl +++ b/shaders_ref/instance/instance.glsl @@ -45,8 +45,8 @@ mat4 getBoneMatrix() { // EFFECT MODEL #if defined (ENGINE_MATERIAL_EFFECT_MODEL) && !defined (MeshEmitter) mat4 getModelMatrix() { - return mat4(1.0); -} + return mat4(1.0); + } #endif mat4 getModelTransform() { @@ -58,16 +58,21 @@ mat4 getModelTransform() { } // TBN matrix only for meshes -#if (defined (MeshEmitter) || defined (ENGINE_MATERIAL_REGULAR_MODEL) || defined (ENGINE_MATERIAL_SKELETAL_MODEL) || defined (ENGINE_MATERIAL_INSTANCED_MODEL)) && defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 getModelTBN(mat4 model_transform) { - //TODO: pass through uniform instance buffer ? bone transform ? - mat3 normal_matrix = transpose(inverse(mat3(model_transform))); +#if (defined (MeshEmitter) || defined (ENGINE_MATERIAL_REGULAR_MODEL) || defined (ENGINE_MATERIAL_SKELETAL_MODEL) || defined (ENGINE_MATERIAL_INSTANCED_MODEL)) && defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) + mat3 getModelTBN(mat4 model_transform) { + //TODO: pass through uniform instance buffer ? bone transform ? + mat3 normal_matrix = transpose(inverse(mat3(model_transform))); - vec3 T = normalize(normal_matrix * getVertexTangent()); - vec3 N = normalize(normal_matrix * getVertexNormal()); - T = normalize(T - dot(T, N) * N); - vec3 B = cross(N, T); + vec3 T = normalize(normal_matrix * getVertexTangent()); + vec3 N = normalize(normal_matrix * getVertexNormal()); + T = normalize(T - dot(T, N) * N); + vec3 B = cross(N, T); - return mat3(T, B, N); -} + return mat3(T, B, N); + } + //TODO: remove? + // added because material_context.glsl needed "getVertexTBN" to be compiled in vertex shader + mat3 getVertexTBN() { + return getModelTBN(getModelTransform()); + } #endif diff --git a/shaders_ref/interface_block/effect_fs.glsl b/shaders_ref/interface_block/effect_fs.glsl index df4651ea..29ebbfb9 100644 --- a/shaders_ref/interface_block/effect_fs.glsl +++ b/shaders_ref/interface_block/effect_fs.glsl @@ -17,7 +17,7 @@ in _vertex_data { #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; @@ -123,7 +123,7 @@ vec3 getVertexPosition() { #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) vec3 getParticleVelocity() { - return _in_data.velocity; + return _in_data.velocity; } #endif @@ -165,7 +165,7 @@ vec3 getVertexPosition() { #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 getVertexTBN() { return _in_data.TBN; } diff --git a/shaders_ref/interface_block/effect_vs.glsl b/shaders_ref/interface_block/effect_vs.glsl index 84e1c873..c7ffa6de 100644 --- a/shaders_ref/interface_block/effect_vs.glsl +++ b/shaders_ref/interface_block/effect_vs.glsl @@ -17,7 +17,7 @@ out _vertex_data { #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; diff --git a/shaders_ref/interface_block/fragment.glsl b/shaders_ref/interface_block/fragment.glsl index 2b95b1e0..a72e0591 100644 --- a/shaders_ref/interface_block/fragment.glsl +++ b/shaders_ref/interface_block/fragment.glsl @@ -1,4 +1,4 @@ -#if defined (EFFECT_MODEL) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) #include "./effect_fs.glsl" #else #include "./mesh_fs.glsl" diff --git a/shaders_ref/interface_block/mesh_fs.glsl b/shaders_ref/interface_block/mesh_fs.glsl index 04f2f425..7303d685 100644 --- a/shaders_ref/interface_block/mesh_fs.glsl +++ b/shaders_ref/interface_block/mesh_fs.glsl @@ -1,5 +1,5 @@ in _vertex_data { - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; @@ -17,7 +17,7 @@ vec2 getVertexUV() { return _in_data.uv; } -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 getVertexTBN() { return _in_data.TBN; } diff --git a/shaders_ref/interface_block/pass_through.glsl b/shaders_ref/interface_block/pass_through.glsl index 40b7edb2..4414f302 100644 --- a/shaders_ref/interface_block/pass_through.glsl +++ b/shaders_ref/interface_block/pass_through.glsl @@ -1,5 +1,5 @@ void InterfaceBlockPassThrough(vec3 world_position, vec2 uv, mat4 model_transform) { - #if defined (EFFECT_MODEL) + #if defined (ENGINE_MATERIAL_EFFECT_MODEL) _out_data.world_position = world_position; #if !defined (SpriteEmitter) @@ -21,7 +21,7 @@ void InterfaceBlockPassThrough(vec3 world_position, vec2 uv, mat4 model_transfor #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) _out_data.TBN = getModelTBN(model_transform); #else _out_data.normal = transpose(inverse(mat3(model_transform))) * getVertexNormal(); @@ -63,7 +63,7 @@ void InterfaceBlockPassThrough(vec3 world_position, vec2 uv, mat4 model_transfor _out_data.size = getParticleSize(); #endif #else - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) _out_data.TBN = getModelTBN(model_transform); #else _out_data.normal = transpose(inverse(mat3(model_transform))) * getVertexNormal(); diff --git a/shaders_ref/interface_block/tess_control_input.glsl b/shaders_ref/interface_block/tess_control_input.glsl index 837c09f9..b1bcb8e0 100644 --- a/shaders_ref/interface_block/tess_control_input.glsl +++ b/shaders_ref/interface_block/tess_control_input.glsl @@ -1,4 +1,4 @@ -#if defined (EFFECT_MODEL) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) in _vertex_data { #if defined (InitialColor_MODULE) vec4 color; @@ -18,7 +18,7 @@ in _vertex_data { #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; @@ -153,7 +153,7 @@ vec2 getVertexUV() { #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 getVertexTBN(uint id) { return _in_data[id].TBN; } @@ -166,7 +166,7 @@ vec3 getVertexNormal(uint id) { #else in _vertex_data { -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; @@ -184,7 +184,7 @@ vec2 getVertexUV(uint id) { return _in_data[id].uv; } - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 getVertexTBN(uint id) { return _in_data[id].TBN; } diff --git a/shaders_ref/interface_block/tess_control_output.glsl b/shaders_ref/interface_block/tess_control_output.glsl index 17180000..b1c5ff81 100644 --- a/shaders_ref/interface_block/tess_control_output.glsl +++ b/shaders_ref/interface_block/tess_control_output.glsl @@ -1,4 +1,4 @@ -#if defined (EFFECT_MODEL) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) out _vertex_data { #if defined (InitialColor_MODULE) vec4 color; @@ -18,7 +18,7 @@ #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; @@ -62,7 +62,7 @@ #else out _vertex_data { - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) mat3 TBN; #else vec3 normal; diff --git a/shaders_ref/interface_block/tess_control_pass.glsl b/shaders_ref/interface_block/tess_control_pass.glsl index 07a8d7d1..c13e6af7 100644 --- a/shaders_ref/interface_block/tess_control_pass.glsl +++ b/shaders_ref/interface_block/tess_control_pass.glsl @@ -1,7 +1,7 @@ void InterfaceBlockPassThrough() { uint index = uint(gl_InvocationID); -#if defined (EFFECT_MODEL) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) _out_data[gl_InvocationID].world_position = getVertexPosition(index); #if !defined (SpriteEmitter) @@ -15,7 +15,7 @@ void InterfaceBlockPassThrough() { #endif #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) _out_data[gl_InvocationID].TBN = getVertexTBN(index); #else _out_data[gl_InvocationID].normal = getVertexNormal(index); @@ -57,7 +57,7 @@ void InterfaceBlockPassThrough() { _out_data[gl_InvocationID].size = getParticleSize(index); #endif #else - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) + #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) _out_data[gl_InvocationID].TBN = getVertexTBN(index); #else _out_data[gl_InvocationID].normal = getVertexNormal(index); diff --git a/shaders_ref/lighting/ambient.glsl b/shaders_ref/lighting/ambient.glsl new file mode 100644 index 00000000..d020e767 --- /dev/null +++ b/shaders_ref/lighting/ambient.glsl @@ -0,0 +1,6 @@ +#include "./scene_lighting.glsl" + +vec3 computeAmbientLighting(vec3 albedo, float ao) { + vec4 ambient = getAmbientColor(); + return (ambient.rgb * albedo) * (ambient.a * ao); +} \ No newline at end of file diff --git a/shaders_ref/lighting/directional_shadows.frag b/shaders_ref/lighting/directional_shadows.frag new file mode 100644 index 00000000..8ac25b14 --- /dev/null +++ b/shaders_ref/lighting/directional_shadows.frag @@ -0,0 +1,10 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/fragment.glsl" +#include "../shading/shading_mctx.glsl" + +void main() { + const MaterialContext mctx = computeMaterialContext(); + shadeFragment(mctx); +} diff --git a/shaders_ref/lighting/directional_shadows.vert b/shaders_ref/lighting/directional_shadows.vert new file mode 100644 index 00000000..d1a983e6 --- /dev/null +++ b/shaders_ref/lighting/directional_shadows.vert @@ -0,0 +1,32 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/vertex.glsl" +#include "../scene.glsl" +#include "../instance/instance.glsl" +#include "../material/material.glsl" +#include "../interface_block/pass_through.glsl" + +uniform mat4 light_space; + +void main() { + #if !defined (SpriteEmitter) + vec2 uv = getVertexUV(); + #else + vec2 uv = vec2(0.0); + #endif + + vec3 vertex_position = getVertexPosition(); + + ENGINE_MATERIAL_VERTEX_SNIPPET + + mat4 model_transform = getModelTransform(); + + vec4 world_position = model_transform * vec4(vertex_position, 1.0); + + #if !defined (MATERIAL_TESSELATION_FACTOR) + gl_Position = light_space * world_position; + #endif + + InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); +} diff --git a/shaders_ref/lighting/light.glsl b/shaders_ref/lighting/light.glsl index 347dd1e7..0a723d26 100644 --- a/shaders_ref/lighting/light.glsl +++ b/shaders_ref/lighting/light.glsl @@ -1,23 +1,14 @@ -#define LIGHT_TYPE_POINT 0u -#define LIGHT_TYPE_SPOT 1u +#define LIGHT_TYPE_DIRECTIONAL 0u +#define LIGHT_TYPE_POINT 1u +#define LIGHT_TYPE_SPOT 2u struct Light { - // rgb - linear color, a - intensity vec4 color; - // world position - vec3 position; - // maximum radius - float radius; - // spot light attenuation + vec4 position; + vec4 direction; vec2 scale_offset; - // light type - uint type; - // does light cast shadow - bool casts_shadow; - // falloff float falloff; - // spot direction - vec3 direction; + uint type; }; /* @@ -29,18 +20,18 @@ struct Light { so actually there is limit on lights which is bound by uniform/ssbo max size divided by sizeof(light) */ -#if defined (ENGINE_EXT_SSBO) +//#if defined (ENGINE_EXT_SSBO) layout (std140) buffer LIGHTS_BUFFER { Light _lights[]; }; -#else - //TODO: remove to settigns - #define ENGINE_SETTINGS_MAX_LIGHTS 100 - - layout (std140) uniform LIGHTS_BUFFER { - Light _lights[ENGINE_SETTINGS_MAX_LIGHTS]; - }; -#endif +//#else +// //TODO: remove to settigns +// #define ENGINE_SETTINGS_MAX_LIGHTS 100 +// +// layout (std140) uniform LIGHTS_BUFFER { +// Light _lights[ENGINE_SETTINGS_MAX_LIGHTS]; +// }; +//#endif Light getLight(const uint index) { return _lights[index]; diff --git a/shaders_ref/lighting/lighting.glsl b/shaders_ref/lighting/lighting.glsl index 8d1aab5e..2192c2eb 100644 --- a/shaders_ref/lighting/lighting.glsl +++ b/shaders_ref/lighting/lighting.glsl @@ -1,31 +1,81 @@ #include "./lighting_context.glsl" #include "../scene.glsl" -#include "../shading/shade_for_light.glsl" -vec3 computeLights(const ShadingContext sctx) { +#include "../shading/regular.glsl" +#include "../shading/cloth.glsl" +#include "../shading/subsurface.glsl" +#include "../shading/custom.glsl" + +#include "./scene_lighting.glsl" +#include "./shadows.glsl" + +vec3 computeLight(const ShadingContext sctx, const LightingContext lctx, const Light light) { + /* [forward pipeline] */ +#if defined (ENGINE_MATERIAL_SHADING_REGULAR_MODEL) + return regularShading(sctx, lctx, light); +#elif defined (ENGINE_MATERIAL_SHADING_CLOTH_MODEL) + return clothShading(sctx, lctx, light); +#elif defined (ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL) + return subsurfaceShading(sctx, lctx, light); +#elif defined (ENGINE_MATERIAL_SHADING_CUSTOM_LIT_MODEL) + return customShading(sctx, lctx, light); +#else + /* [deferred pipeline] */ + switch (sctx.shading_model) { + case 1u: // Lit + return regularShading(sctx, lctx, light); + case 2u: // Cloth + return clothShading(sctx, lctx, light); + case 3u: // Subsurface + return subsurfaceShading(sctx, lctx, light); + default: + // deferred pipeline does not support custom shading + // and unlit paths calculated before + return vec3(10.0); + } +#endif +} + +vec3 computeDirectionalLight(const ShadingContext sctx) { + const Light light = getDirectionalLight(); + LightingContext lctx = computeLightingContext(sctx, light); + lctx.attenuation = 1.0; + vec3 color = vec3(0.0); - //TODO: lights count - //for (uint i = 0u; i < getLightsCount(); ++i) { - for (uint i = 0u; i < 0u; ++i) { - Light light = getLight(i); - LightingContext lctx = computeLightingContext(sctx, light); + if (lctx.NoL <= 0.0) { + return color; + } - if (lctx.len > light.radius || lctx.NoL <= 0.0 || lctx.attenuation <= 0.0) { - continue; - } + #if defined (ENGINE_SETTINGS_CSM) + float shadow = getDirectionalShadow(sctx.N, sctx.worldPos); + lctx.visibility *= (1.0 - shadow); + #endif - #if defined (SHADOWS) - if (light.casts_shadow) { + #if defined (ENGINE_SETTINGS_MICRO_SHADOWING) + lctx.visibility *= computeMicroShadowing(lctx.NoL, sctx.ambientOcclusion); + #endif - } - #endif + if (lctx.visibility <= 0.0) { + return color; + } + + return computeLight(sctx, lctx, light); +} + +vec3 computeLights(const ShadingContext sctx) { + vec3 color = computeDirectionalLight(sctx); + + for (uint i = 0u; i < getLightCount(); ++i) { + Light light = getLight(i); + + LightingContext lctx = computeLightingContext(sctx, light); - if (lctx.visibility <= 0.0) { + if (lctx.NoL <= 0.0 || lctx.attenuation <= 0.0) { continue; } - //color += shadeForLight(sctx, lctx, light); + color += computeLight(sctx, lctx, light); } return color; diff --git a/shaders_ref/lighting/lighting_context.glsl b/shaders_ref/lighting/lighting_context.glsl index 827d4d1a..3f5357f8 100644 --- a/shaders_ref/lighting/lighting_context.glsl +++ b/shaders_ref/lighting/lighting_context.glsl @@ -21,16 +21,15 @@ struct LightingContext { float getAttenuation(const ShadingContext sctx, const Light light) { vec3 L = light.position.xyz - sctx.worldPos; - - float distance = dot(L, L); - float factor = distance * light.falloff; + float distanceSquare = dot(L, L); + float factor = distanceSquare * light.falloff; float smoothFactor = saturate(1.0 - factor * factor); - float attenuation = smoothFactor * factor; + float attenuation = smoothFactor * smoothFactor; - attenuation = attenuation / max(distance, 1e-4); + attenuation = attenuation / max(distanceSquare, 1e-4); if (light.type == LIGHT_TYPE_SPOT) { - float cd = dot(-light.direction, L); + float cd = dot(-light.direction.xyz, L); float att = saturate(cd * light.scale_offset.x + light.scale_offset.y); float att2 = att * att; attenuation *= att2; @@ -45,7 +44,13 @@ LightingContext computeLightingContext(const ShadingContext sctx, const Light li lctx.attenuation = getAttenuation(sctx, light); lctx.visibility = 1.0; - lctx.L = normalize(light.position.xyz - sctx.worldPos); + + if (light.type == LIGHT_TYPE_DIRECTIONAL) { + lctx.L = normalize(-light.direction.xyz); + } else { + lctx.L = normalize(light.position.xyz - sctx.worldPos); + } + lctx.H = normalize(sctx.V + lctx.L); lctx.len = length(light.position.xyz - sctx.worldPos); diff --git a/shaders_ref/lighting/refraction.glsl b/shaders_ref/lighting/refraction.glsl new file mode 100644 index 00000000..cfb00cf3 --- /dev/null +++ b/shaders_ref/lighting/refraction.glsl @@ -0,0 +1,37 @@ +#if defined (ENGINE_MATERIAL_REFRACTION) + #include "../functions/refraction_sphere.glsl" + + uniform sampler2D _refraction_texture; + + vec3 getRefractionTextureValue(vec2 uv) { + return texture(_refraction_texture, uv).rgb; + } + + //TODO: refactor? pass Material/Shading COntext instead + vec3 computeRefraction(const ShadingContext sctx, float IoR, float absorption) { + #if !defined (ENGINE_MATERIAL_IOR) + IoR = f0ToIor(sctx.F0.g); + #endif + + const float airIor = 1.0; + + float etaIR = airIor / IoR; + float etaRI = IoR / airIor; + + vec3 p = refractionSolidSphere(sctx.N, -normalize(getCameraPosition() - getVertexPosition()), etaIR, etaRI, getVertexPosition()); + vec4 p_cs = getViewProjection() * vec4(p, 1.0); + p_cs.xy = p_cs.xy * (0.5 / p_cs.w) + 0.5; + + vec3 Ft = getRefractionTextureValue(p_cs.xy).rgb; + + #if !defined (ENGINE_MATERIAL_IOR) + Ft *= sctx.diffuseColor; + #endif + + #if defined (ENGINE_MATERIAL_ABSORPTION) + Ft *= 1.0 - absorption; + #endif + + return Ft; + } +#endif diff --git a/shaders_ref/lighting/scene_lighting.glsl b/shaders_ref/lighting/scene_lighting.glsl new file mode 100644 index 00000000..cf12d8c3 --- /dev/null +++ b/shaders_ref/lighting/scene_lighting.glsl @@ -0,0 +1,25 @@ +#include "./light.glsl" + +layout (std140) buffer scene_lighting { + vec4 _direction; + vec4 _color; + vec4 _ambient_color; + uint _light_count; +}; + +Light getDirectionalLight() { + Light light; + + light.direction.xyz = _direction.xyz; + light.color = _color; + + return light; +} + +vec4 getAmbientColor() { + return _ambient_color; +} + +uint getLightCount() { + return _light_count; +} diff --git a/shaders_ref/lighting/shadows.glsl b/shaders_ref/lighting/shadows.glsl new file mode 100644 index 00000000..c93f0b10 --- /dev/null +++ b/shaders_ref/lighting/shadows.glsl @@ -0,0 +1,67 @@ +#if defined (ENGINE_SETTINGS_CSM) + #include "./scene_lighting.glsl" + + layout (std140) buffer directional_shadows { + mat4 _dir_light_space[]; + }; + + uniform sampler2DArray _dir_shadows; + uniform vec4 _far_bounds; + + int getShadowFrustumIndex(vec3 position) { + vec4 p = getViewProjection() * vec4(position, 1.0); + p.xyz /= p.w; + + float z = p.z * 0.5 + 0.5; + + int index = ENGINE_SETTINGS_CSM_SPLIT_COUNT; + for (int i = 0; i < ENGINE_SETTINGS_CSM_SPLIT_COUNT; ++i) { + if (z < _far_bounds[i]) { + index = i; + break; + } + } + + return index; + } + + float getDirectionalShadow(vec3 normal, vec3 world_pos) { + Light light = getDirectionalLight(); + + int index = getShadowFrustumIndex(world_pos); + + mat4 light_space = _dir_light_space[index]; + + // transforming from global space to ndc light space + vec4 light_pos_space = light_space * vec4(world_pos, 1.0); +// vec3 ndc = light_pos_space.xyz / light_pos_space.w; ?????????/ + vec3 ndc = light_pos_space.xyz; + ndc = ndc * 0.5 + 0.5; + + if (ndc.z > 1.0) { + return 0.0; + } + + float closestDepth = texture(_dir_shadows, vec3(ndc.xy, index)).r; + float currentDepth = ndc.z; + + float shadow = 0.0; + const float MIN_BIAS = 0.0005; + float bias = max(0.05 * (1.0 - dot(normal, vec3(-light.direction.xyz))), MIN_BIAS); + + #if defined (ENGINE_SETTINGS_PCF) + vec2 texelSize = 1.0 / textureSize(_dir_shadows, 0).xy; + for (int x = -1; x <= 1; ++x) { + for (int y = -1; y <= 1; ++y) { + float pcfDepth = texture(_dir_shadows, vec3(ndc.xy + vec2(x, y) * texelSize, index)).r; + shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; + } + } + shadow /= 9.0; + #else + shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0; + #endif + + return shadow; + } +#endif diff --git a/shaders_ref/material/material.glsl b/shaders_ref/material/material.glsl index 4845031c..0b146c0a 100644 --- a/shaders_ref/material/material.glsl +++ b/shaders_ref/material/material.glsl @@ -68,6 +68,8 @@ layout (std140) uniform MATERIAL_BUFFER { #endif ENGINE_MATERIAL_CUSTOM_SCALARS + + uint _material_shading_model; }; #if !defined (ENGINE_EXT_BINDLESS_TEXTURE) @@ -204,3 +206,7 @@ ENGINE_MATERIAL_GLOBAL_DEFINITIONS return texture(_material_roughness_texture, uv).r; } #endif + +uint getMaterialShadingModel() { + return _material_shading_model; +} diff --git a/shaders_ref/material/material_context.glsl b/shaders_ref/material/material_context.glsl index 05c4be47..65ebf1b5 100644 --- a/shaders_ref/material/material_context.glsl +++ b/shaders_ref/material/material_context.glsl @@ -1,5 +1,4 @@ #include "./material.glsl" -#include "../interface_block/vertex.glsl" struct MaterialContext { #if defined (ENGINE_MATERIAL_COLOR) @@ -41,6 +40,8 @@ struct MaterialContext { float IoR; float absorption; #endif + + uint shading_model; }; MaterialContext computeDefaultMaterialContext() { @@ -118,6 +119,8 @@ MaterialContext computeDefaultMaterialContext() { #endif #endif + mctx.shading_model = getMaterialShadingModel(); + return mctx; } @@ -143,18 +146,18 @@ vec4 computeMaterialColor(const MaterialContext mctx) { #endif #if defined (ENGINE_MATERIAL_BLENDMASK_TEXTURE) - if (mctx.blend_mask == 0.0) { + if (mctx.blend_mask <= 0.0) { discard; } #endif -#if defined (EFFECT_MODEL) && defined (BeamEmitter) && defined (BeamSpeed_MODULE) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) && defined (BeamEmitter) && defined (BeamSpeed_MODULE) if (distance(getVertexPosition(), getParticleStart()) / distance(getParticleStart(), getParticleEnd()) >= getParticleLength()) { discard; } #endif -#if defined (EFFECT_MODEL) && defined (InitialColor_MODULE) +#if defined (ENGINE_MATERIAL_EFFECT_MODEL) && defined (InitialColor_MODULE) color *= getParticleColor(); #endif @@ -183,7 +186,7 @@ vec3 computeMaterialNormal(const MaterialContext mctx) { #if defined (SpriteEmitter) || defined (BeamEmitter) return getCameraPosition() - getVertexPosition(); #else -#if defined (ENGINE_MATERIAL_NORMAL) && defined (NORMAL_MAPPING) +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) vec3 normal = mctx.normal; normal = normalize(normal * 2.0 - 1.0); normal = normalize(getVertexTBN() * normal); diff --git a/shaders_ref/pipeline/color_picker.frag b/shaders_ref/pipeline/color_picker.frag new file mode 100644 index 00000000..5002d75f --- /dev/null +++ b/shaders_ref/pipeline/color_picker.frag @@ -0,0 +1,19 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/fragment.glsl" +#include "../shading/shading_mctx.glsl" + +out vec3 color; + +uniform vec3 color_id; + +void main() { + const MaterialContext mctx = computeMaterialContext(); + shadeFragment(mctx); + + color = color_id; +} + + + diff --git a/shaders_ref/pipeline/color_picker.vert b/shaders_ref/pipeline/color_picker.vert new file mode 100644 index 00000000..0532caf2 --- /dev/null +++ b/shaders_ref/pipeline/color_picker.vert @@ -0,0 +1,30 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/vertex.glsl" +#include "../scene.glsl" +#include "../instance/instance.glsl" +#include "../material/material.glsl" +#include "../interface_block/pass_through.glsl" + +void main() { + #if !defined (SpriteEmitter) + vec2 uv = getVertexUV(); + #else + vec2 uv = vec2(0.0); + #endif + + vec3 vertex_position = getVertexPosition(); + + ENGINE_MATERIAL_VERTEX_SNIPPET + + mat4 model_transform = getModelTransform(); + + vec4 world_position = model_transform * vec4(vertex_position, 1.0); + + #if !defined (MATERIAL_TESSELATION_FACTOR) + gl_Position = getViewProjection() * world_position; + #endif + + InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); +} diff --git a/shaders_ref/pipeline/composite.frag b/shaders_ref/pipeline/composite.frag index 6f8fc119..9e05fbb8 100644 --- a/shaders_ref/pipeline/composite.frag +++ b/shaders_ref/pipeline/composite.frag @@ -1,8 +1,6 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings +ENGINE::COMMON -#include "../../functions/tone_mapping.glsl" +#include "../functions/tone_mapping.glsl" in vec2 uv; diff --git a/shaders_ref/pipeline/composite.vert b/shaders_ref/pipeline/composite.vert index 719e0736..2dade937 100644 --- a/shaders_ref/pipeline/composite.vert +++ b/shaders_ref/pipeline/composite.vert @@ -1,5 +1,4 @@ -Limitless::GLSL_VERSION -Limitless::Extensions +ENGINE::COMMON layout (location = 0) in vec3 vertex_position; layout (location = 1) in vec2 vertex_uv; diff --git a/shaders_ref/pipeline/deferred.frag b/shaders_ref/pipeline/deferred.frag index c6527cb6..beb87ff8 100644 --- a/shaders_ref/pipeline/deferred.frag +++ b/shaders_ref/pipeline/deferred.frag @@ -1,30 +1,6 @@ ENGINE::COMMON -#include "../functions/reconstruct_position.glsl" -#include "../shading/shading_context.glsl" -#include "../lighting/lighting.glsl" - -/** GBUFFER */ - -// UNSIGNED NORMALIZED [0; 1] -// RGBA8 - RGB - base color, A - ao - -// SIGNED NORMALIZED [-1; 1] -// RGB - normal - -// UNSIGNED NORMALIZED [0; 1] -// R - roughness, G - metallic, B - shading model (uint) - -// FLOATING POINT -// RGB - emissive - -/** */ - -uniform sampler2D base_texture; -uniform sampler2D normal_texture; -uniform sampler2D props_texture; -uniform sampler2D depth_texture; -uniform sampler2D emissive_texture; +#include "../shading/shading_gctx.glsl" in vec2 uv; @@ -42,28 +18,13 @@ out vec3 color; //#endif void main() { - vec3 P = reconstructPosition(uv, texture(depth_texture, uv).r); - vec3 normal = texture(normal_texture, uv).rgb; - vec4 base = texture(base_texture, uv).rgba; - vec3 props = texture(props_texture, uv).rgb; - uint shading_model = uint(props.b * 255.0); - //#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) // base.a *= texture(ssao_texture, uv).r; //#endif - ShadingContext sctx = computeShadingContext( - base.rgb, - props.g, - P, - props.r, - normal, - base.a - ); - color = computeLights(sctx); + const GBufferContext gctx = computeGBufferContext(uv); + color = shadeFragment(gctx); -// color = getFragmentColor(base.rgb, base.a, normal, P, metallic, roughness, shading_model); -// color += texture(emissive_texture, uv).rgb; // just add for now for test //#ifdef SCREEN_SPACE_REFLECTIONS // // TODO: move to indirect lighting diff --git a/shaders_ref/pipeline/deferred.vert b/shaders_ref/pipeline/deferred.vert index b1d752df..cd1ca92a 100644 --- a/shaders_ref/pipeline/deferred.vert +++ b/shaders_ref/pipeline/deferred.vert @@ -1,4 +1,4 @@ -ENGINE::GLSLVERSION +ENGINE::COMMON layout (location = 0) in vec3 vertex_position; layout (location = 1) in vec2 vertex_uv; diff --git a/shaders_ref/pipeline/depth.frag b/shaders_ref/pipeline/depth.frag index 404cb620..027ed16e 100644 --- a/shaders_ref/pipeline/depth.frag +++ b/shaders_ref/pipeline/depth.frag @@ -1,15 +1,11 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT #include "../interface_block/fragment.glsl" -#include "../scene.glsl" -#include "../shading/depth_discarder.glsl" +#include "../shading/shading_mctx.glsl" void main() { - discardForDepth(); + const MaterialContext mctx = computeMaterialContext(); + shadeFragment(mctx); } diff --git a/shaders_ref/pipeline/depth.vert b/shaders_ref/pipeline/depth.vert index e3fab37a..0532caf2 100644 --- a/shaders_ref/pipeline/depth.vert +++ b/shaders_ref/pipeline/depth.vert @@ -1,8 +1,7 @@ +ENGINE::COMMON ENGINE::MATERIALDEPENDENT -#include "../vertex_streams/vertex_stream.glsl" #include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" #include "../scene.glsl" #include "../instance/instance.glsl" #include "../material/material.glsl" @@ -17,9 +16,7 @@ void main() { vec3 vertex_position = getVertexPosition(); - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET + ENGINE_MATERIAL_VERTEX_SNIPPET mat4 model_transform = getModelTransform(); diff --git a/shaders_ref/pipeline/forward.frag b/shaders_ref/pipeline/forward.frag index 16b40894..f2605787 100644 --- a/shaders_ref/pipeline/forward.frag +++ b/shaders_ref/pipeline/forward.frag @@ -1,13 +1,12 @@ +ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/fragment.glsl" -#include "../scene.glsl" -#include "../lighting/light.glsl" +#include "../shading/shading_mctx.glsl" out vec4 color; void main() { - MaterialContext mctx = computeMaterialContext(); - ShadingContext sctx = computeShadingContext(mctx); - color = computeLights(sctx); + const MaterialContext mctx = computeMaterialContext(); + color = shadeFragment(mctx); } \ No newline at end of file diff --git a/shaders_ref/pipeline/forward.vert b/shaders_ref/pipeline/forward.vert index dbdfa17f..0532caf2 100644 --- a/shaders_ref/pipeline/forward.vert +++ b/shaders_ref/pipeline/forward.vert @@ -1,10 +1,10 @@ +ENGINE::COMMON ENGINE::MATERIALDEPENDENT - +#include "../interface_block/vertex.glsl" +#include "../scene.glsl" #include "../instance/instance.glsl" - -#include "../material/material_context.glsl" - +#include "../material/material.glsl" #include "../interface_block/pass_through.glsl" void main() { diff --git a/shaders_ref/pipeline/gbuffer.frag b/shaders_ref/pipeline/gbuffer.frag new file mode 100644 index 00000000..d14c802d --- /dev/null +++ b/shaders_ref/pipeline/gbuffer.frag @@ -0,0 +1,26 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/fragment.glsl" +#include "../scene.glsl" +#include "../material/material_context.glsl" + +layout (location = 0) out vec4 albedo; +layout (location = 1) out vec3 normal; +layout (location = 2) out vec3 properties; +layout (location = 3) out vec3 emissive; + +void main() { + const MaterialContext mctx = computeMaterialContext(); + + albedo.rgb = computeMaterialColor(mctx).rgb; + albedo.a = computeMaterialAO(mctx); + + normal = computeMaterialNormal(mctx); + + properties.r = mctx.roughness; + properties.g = mctx.metallic; + properties.b = float(mctx.shading_model) / 255.0; + + emissive = computeMaterialEmissiveColor(mctx); +} diff --git a/shaders_ref/pipeline/gbuffer.glsl b/shaders_ref/pipeline/gbuffer.glsl new file mode 100644 index 00000000..f64739a1 --- /dev/null +++ b/shaders_ref/pipeline/gbuffer.glsl @@ -0,0 +1,47 @@ +#include "../functions/reconstruct_position.glsl" + +/** GBUFFER */ + +// UNSIGNED NORMALIZED [0; 1] +// RGBA8 - RGB - base color, A - ao + +// SIGNED NORMALIZED [-1; 1] +// RGB - normal + +// UNSIGNED NORMALIZED [0; 1] +// R - roughness, G - metallic, B - shading model (uint) + +// FLOATING POINT +// RGB - emissive + +/** */ + +uniform sampler2D _base_texture; +uniform sampler2D _normal_texture; +uniform sampler2D _props_texture; +uniform sampler2D _depth_texture; +uniform sampler2D _emissive_texture; + +vec4 getGBufferColor(vec2 uv) { + return texture(_base_texture, uv); +} + +vec3 getGBufferNormal(vec2 uv) { + return texture(_normal_texture, uv).xyz; +} + +vec3 getGBufferProps(vec2 uv) { + return texture(_props_texture, uv).rgb; +} + +vec3 getGBufferEmissiveColor(vec2 uv) { + return texture(_emissive_texture, uv).rgb; +} + +float getGBufferDepth(vec2 uv) { + return texture(_depth_texture, uv).r; +} + +vec3 getGBufferPosition(vec2 uv) { + return reconstructPosition(uv, getGBufferDepth(uv)); +} diff --git a/shaders_ref/pipeline/gbuffer.vert b/shaders_ref/pipeline/gbuffer.vert new file mode 100644 index 00000000..0532caf2 --- /dev/null +++ b/shaders_ref/pipeline/gbuffer.vert @@ -0,0 +1,30 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/vertex.glsl" +#include "../scene.glsl" +#include "../instance/instance.glsl" +#include "../material/material.glsl" +#include "../interface_block/pass_through.glsl" + +void main() { + #if !defined (SpriteEmitter) + vec2 uv = getVertexUV(); + #else + vec2 uv = vec2(0.0); + #endif + + vec3 vertex_position = getVertexPosition(); + + ENGINE_MATERIAL_VERTEX_SNIPPET + + mat4 model_transform = getModelTransform(); + + vec4 world_position = model_transform * vec4(vertex_position, 1.0); + + #if !defined (MATERIAL_TESSELATION_FACTOR) + gl_Position = getViewProjection() * world_position; + #endif + + InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); +} diff --git a/shaders_ref/pipeline/gbuffer_context.glsl b/shaders_ref/pipeline/gbuffer_context.glsl new file mode 100644 index 00000000..3faa434a --- /dev/null +++ b/shaders_ref/pipeline/gbuffer_context.glsl @@ -0,0 +1,31 @@ +#include "./gbuffer.glsl" + +struct GBufferContext { + vec3 color; + vec3 position; + vec3 normal; + vec3 emissive_color; + float roughness; + float metallic; + float ao; + uint shading_model; +}; + +GBufferContext computeGBufferContext(vec2 uv) { + GBufferContext gctx; + + vec4 color = getGBufferColor(uv); + gctx.color = color.rgb; + gctx.position = getGBufferPosition(uv); + gctx.normal = getGBufferNormal(uv); + gctx.emissive_color = getGBufferEmissiveColor(uv); + gctx.ao = color.a; + + vec3 props = getGBufferProps(uv); + + gctx.roughness = props.r; + gctx.metallic = props.g; + gctx.shading_model = uint(props.b * 255.0); + + return gctx; +} \ No newline at end of file diff --git a/shaders_ref/pipeline/quad.frag b/shaders_ref/pipeline/quad.frag new file mode 100644 index 00000000..b53f51ba --- /dev/null +++ b/shaders_ref/pipeline/quad.frag @@ -0,0 +1,11 @@ +ENGINE::COMMON + +in vec2 uv; + +out vec3 color; + +uniform sampler2D screen_texture; + +void main() { + color = texture(screen_texture, uv).rgb; +} \ No newline at end of file diff --git a/shaders_ref/pipeline/quad.vert b/shaders_ref/pipeline/quad.vert new file mode 100644 index 00000000..2dade937 --- /dev/null +++ b/shaders_ref/pipeline/quad.vert @@ -0,0 +1,11 @@ +ENGINE::COMMON + +layout (location = 0) in vec3 vertex_position; +layout (location = 1) in vec2 vertex_uv; + +out vec2 uv; + +void main() { + uv = vertex_uv; + gl_Position = vec4(vertex_position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/pipeline/skybox.frag b/shaders_ref/pipeline/skybox.frag new file mode 100644 index 00000000..dde3bb0a --- /dev/null +++ b/shaders_ref/pipeline/skybox.frag @@ -0,0 +1,27 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +in vec3 skybox_uv; + +#include "../interface_block/fragment.glsl" +#include "../shading/shading_mctx.glsl" + +layout (location = 0) out vec4 albedo; +layout (location = 1) out vec3 normal; +layout (location = 2) out vec3 properties; +layout (location = 3) out vec3 emissive; + +void main() { + const MaterialContext mctx = computeMaterialContext(); + + albedo.rgb = computeMaterialColor(mctx).rgb; + albedo.a = computeMaterialAO(mctx); + + normal = computeMaterialNormal(mctx); + + properties.r = mctx.roughness; + properties.g = mctx.metallic; + properties.b = float(mctx.shading_model) / 255.0; + + emissive = computeMaterialEmissiveColor(mctx); +} diff --git a/shaders_ref/pipeline/skybox.vert b/shaders_ref/pipeline/skybox.vert new file mode 100644 index 00000000..de015540 --- /dev/null +++ b/shaders_ref/pipeline/skybox.vert @@ -0,0 +1,25 @@ +ENGINE::COMMON +ENGINE::MATERIALDEPENDENT + +#include "../interface_block/vertex.glsl" +#include "../scene.glsl" +#include "../instance/instance.glsl" +#include "../material/material.glsl" +#include "../interface_block/pass_through.glsl" + +out vec3 skybox_uv; + +void main() { + vec2 uv = vec2(0.0); + + vec3 vertex_position = getVertexPosition(); + + ENGINE_MATERIAL_VERTEX_SNIPPET + + skybox_uv = getVertexPosition(); + + vec4 pos = getProjection() * mat4(mat3(getView())) * vec4(vertex_position, 1.0); + gl_Position = pos.xyww; + + InterfaceBlockPassThrough(pos.xyw, uv, getModelTransform()); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/bloom/blur_downsample.frag b/shaders_ref/postprocessing/bloom/blur_downsample.frag new file mode 100644 index 00000000..d2361850 --- /dev/null +++ b/shaders_ref/postprocessing/bloom/blur_downsample.frag @@ -0,0 +1,61 @@ +ENGINE::COMMON + +in vec2 uv; + +out vec3 color; + +uniform sampler2D source; +uniform float level; + +float max3(const vec3 v) { + return max(v.x, max(v.y, v.z)); +} + +vec3 box4x4(vec3 s0, vec3 s1, vec3 s2, vec3 s3) { + return (s0 + s1 + s2 + s3) * 0.25; +} + +vec3 box4x4Reinhard(vec3 s0, vec3 s1, vec3 s2, vec3 s3) { + float w0 = 1.0 / (1.0 + max3(s0)); + float w1 = 1.0 / (1.0 + max3(s1)); + float w2 = 1.0 / (1.0 + max3(s2)); + float w3 = 1.0 / (1.0 + max3(s3)); + return (s0 * w0 + s1 * w1 + s2 * w2 + s3 * w3) * (1.0 / (w0 + w1 + w2 + w3)); +} + +void main() { + vec3 c = textureLod(source, uv, level).rgb; + + vec3 lt = textureLodOffset(source, uv, level, ivec2(-1, -1)).rgb; + vec3 rt = textureLodOffset(source, uv, level, ivec2( 1, -1)).rgb; + vec3 rb = textureLodOffset(source, uv, level, ivec2( 1, 1)).rgb; + vec3 lb = textureLodOffset(source, uv, level, ivec2(-1, 1)).rgb; + + vec3 lt2 = textureLodOffset(source, uv, level, ivec2(-2, -2)).rgb; + vec3 rt2 = textureLodOffset(source, uv, level, ivec2( 2, -2)).rgb; + vec3 rb2 = textureLodOffset(source, uv, level, ivec2( 2, 2)).rgb; + vec3 lb2 = textureLodOffset(source, uv, level, ivec2(-2, 2)).rgb; + + vec3 l = textureLodOffset(source, uv, level, ivec2(-2, 0)).rgb; + vec3 t = textureLodOffset(source, uv, level, ivec2( 0, -2)).rgb; + vec3 r = textureLodOffset(source, uv, level, ivec2( 2, 0)).rgb; + vec3 b = textureLodOffset(source, uv, level, ivec2( 0, 2)).rgb; + + vec3 c0, c1; + + if (level <= 0.5) { + c0 = box4x4Reinhard(lt, rt, rb, lb); + c1 = box4x4Reinhard(c, l, t, lt2); + c1 += box4x4Reinhard(c, r, t, rt2); + c1 += box4x4Reinhard(c, r, b, rb2); + c1 += box4x4Reinhard(c, l, b, lb2); + } else { + c0 = box4x4(lt, rt, rb, lb); + c1 = box4x4(c, l, t, lt2); + c1 += box4x4(c, r, t, rt2); + c1 += box4x4(c, r, b, rb2); + c1 += box4x4(c, l, b, lb2); + } + + color = c0 * 0.5 + c1 * 0.125; +} diff --git a/shaders_ref/postprocessing/bloom/blur_downsample.vert b/shaders_ref/postprocessing/bloom/blur_downsample.vert new file mode 100644 index 00000000..abb2c082 --- /dev/null +++ b/shaders_ref/postprocessing/bloom/blur_downsample.vert @@ -0,0 +1,11 @@ +ENGINE::COMMON + +layout (location = 0) in vec3 v_position; +layout (location = 1) in vec2 v_uv; + +out vec2 uv; + +void main() { + uv = v_uv; + gl_Position = vec4(v_position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/bloom/blur_upsample.frag b/shaders_ref/postprocessing/bloom/blur_upsample.frag new file mode 100644 index 00000000..a9f0bc65 --- /dev/null +++ b/shaders_ref/postprocessing/bloom/blur_upsample.frag @@ -0,0 +1,25 @@ +ENGINE::COMMON + +in vec2 uv; + +out vec3 color; + +uniform sampler2D source; +uniform float level; +uniform vec4 resolution; + +void main() { + const float radius = 1.0; + vec4 d = vec4(resolution.zw, -resolution.zw) * radius; + vec3 c0, c1; + c0 = textureLod(source, uv + d.zw, level).rgb; + c0 += textureLod(source, uv + d.xw, level).rgb; + c0 += textureLod(source, uv + d.xy, level).rgb; + c0 += textureLod(source, uv + d.zy, level).rgb; + c0 += 4.0 * textureLod(source, uv, level).rgb; + c1 = textureLod(source, uv + vec2(d.z, 0.0), level).rgb; + c1 += textureLod(source, uv + vec2(0.0, d.w), level).rgb; + c1 += textureLod(source, uv + vec2(d.x, 0.0), level).rgb; + c1 += textureLod(source, uv + vec2( 0.0, d.y), level).rgb; + color = (c0 + 2.0 * c1) * (1.0 / 16.0); +} diff --git a/shaders_ref/postprocessing/bloom/blur_upsample.vert b/shaders_ref/postprocessing/bloom/blur_upsample.vert new file mode 100644 index 00000000..abb2c082 --- /dev/null +++ b/shaders_ref/postprocessing/bloom/blur_upsample.vert @@ -0,0 +1,11 @@ +ENGINE::COMMON + +layout (location = 0) in vec3 v_position; +layout (location = 1) in vec2 v_uv; + +out vec2 uv; + +void main() { + uv = v_uv; + gl_Position = vec4(v_position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/bloom/brightness.frag b/shaders_ref/postprocessing/bloom/brightness.frag new file mode 100644 index 00000000..c9a9b264 --- /dev/null +++ b/shaders_ref/postprocessing/bloom/brightness.frag @@ -0,0 +1,13 @@ +ENGINE::COMMON + +out vec3 color; + +in vec2 fs_uv; + +uniform sampler2D image; +uniform float threshold; + +void main() { + vec3 source = texture(image, fs_uv).rgb; + color = max(vec3(0.0), source - vec3(threshold)); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/bloom/brightness.vert b/shaders_ref/postprocessing/bloom/brightness.vert new file mode 100644 index 00000000..5e2733ad --- /dev/null +++ b/shaders_ref/postprocessing/bloom/brightness.vert @@ -0,0 +1,11 @@ +ENGINE::COMMON + +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 uv; + +out vec2 fs_uv; + +void main() { + fs_uv = uv; + gl_Position = vec4(position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/dof.frag b/shaders_ref/postprocessing/dof.frag new file mode 100644 index 00000000..c0dcc370 --- /dev/null +++ b/shaders_ref/postprocessing/dof.frag @@ -0,0 +1,33 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +#include "../pipeline/scene.glsl" +#include "../functions/reconstruct_position.glsl" + +in vec2 fs_uv; + +out vec3 color; + +uniform sampler2D depth_texture; +uniform sampler2D focus_texture; +uniform sampler2D unfocus_texture; + +uniform vec2 uv_focus; +uniform vec2 distance; + +void main() { + vec2 uv = fs_uv; + + float far = getCameraFarPlane(); + + vec3 position = reconstructPosition(uv, texture(depth_texture, uv).r); + + vec3 focus_position = reconstructPosition(uv_focus, texture(depth_texture, uv_focus).r); + + vec3 uf = texture(unfocus_texture, uv).rgb; + vec3 f = texture(focus_texture, uv).rgb; + + float blur = smoothstep(distance.x, distance.y, length(position - focus_position)); + + color = mix(f, uf, blur); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/dof.vert b/shaders_ref/postprocessing/dof.vert new file mode 100644 index 00000000..abb57776 --- /dev/null +++ b/shaders_ref/postprocessing/dof.vert @@ -0,0 +1,13 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 uv; + +out vec2 fs_uv; + +void main() +{ + fs_uv = uv; + gl_Position = vec4(position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/fxaa.frag b/shaders_ref/postprocessing/fxaa.frag new file mode 100644 index 00000000..eb82b167 --- /dev/null +++ b/shaders_ref/postprocessing/fxaa.frag @@ -0,0 +1,14 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +in vec2 uv; + +out vec3 color; + +uniform sampler2D scene; + +#include "../functions/fxaa.glsl" + +void main() { + color = fxaaProcess(scene, uv); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/fxaa.vert b/shaders_ref/postprocessing/fxaa.vert new file mode 100644 index 00000000..ba2e8301 --- /dev/null +++ b/shaders_ref/postprocessing/fxaa.vert @@ -0,0 +1,12 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +layout(location = 0) in vec3 vertex_position; +layout(location = 1) in vec2 vertex_uv; + +out vec2 uv; + +void main() { + uv = vertex_uv; + gl_Position = vec4(vertex_position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/postprocess.frag b/shaders_ref/postprocessing/postprocess.frag new file mode 100644 index 00000000..85eaa9ff --- /dev/null +++ b/shaders_ref/postprocessing/postprocess.frag @@ -0,0 +1,81 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +in vec2 fs_uv; + +out vec4 color; + +uniform sampler2D image; +uniform sampler2D image_depth; + +uniform bool bloom; +uniform sampler2D bloom_image; + +uniform bool gamma_correction; +uniform float gamma; + +uniform bool tone_mapping; +uniform float exposure; + +uniform bool vignette; +uniform float vignette_radius; +uniform float vignette_softness; + +uniform bool tone_shading; +uniform float number_of_colors; +uniform float line_texel_offset; +uniform float line_multiplier; +uniform float line_bias; + +uniform bool fxaa; + +#include "../glsl/fxaa.glsl" + +void main() +{ + vec3 scene_color = texture(image, fs_uv).rgb; + float scene_depth = texture(image_depth, fs_uv).r; + vec2 resolution = textureSize(image, 0); + + if (fxaa) { + scene_color = fxaaProcess(image, fs_uv); + } + + if (bloom) { + scene_color += texture(bloom_image, fs_uv).rgb; + } + + if (tone_mapping) { + scene_color = vec3(1.0) - exp(-scene_color * exposure); + } + + if (gamma_correction) { + scene_color = pow(scene_color, vec3(1.0 / gamma)); + } + + if (tone_shading) { + scene_color = scene_color * vec3(0.666) + floor(scene_color * number_of_colors) / number_of_colors; + vec2 inv_resolution = 1.0 / resolution; + + float right = texture(image_depth, inv_resolution * vec2(1.0 * line_texel_offset, 0.0) + fs_uv).r; + float left = texture(image_depth, inv_resolution * vec2(-1.0 * line_texel_offset, 0.0) + fs_uv).r; + + float top = texture(image_depth, inv_resolution * vec2(0.0, -1.0 * line_texel_offset) + fs_uv).r; + float down = texture(image_depth, inv_resolution * vec2(0.0, 1.0 * line_texel_offset) + fs_uv).r; + + float lines = 4.0 * scene_depth - right - left - top - down; + lines *= line_multiplier; + lines = pow(lines, line_bias); + lines = clamp(lines, 0.0, 1.0); + + scene_color = mix(scene_color, vec3(0.0), lines); + } + + if (vignette) { + float len = length(gl_FragCoord.xy / resolution - vec2(0.5)); + float vig = smoothstep(vignette_radius, vignette_softness, len); + scene_color = mix(scene_color, scene_color * vig, 0.5); + } + + color = vec4(scene_color, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/postprocess.vert b/shaders_ref/postprocessing/postprocess.vert new file mode 100644 index 00000000..abb57776 --- /dev/null +++ b/shaders_ref/postprocessing/postprocess.vert @@ -0,0 +1,13 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 uv; + +out vec2 fs_uv; + +void main() +{ + fs_uv = uv; + gl_Position = vec4(position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/ssao/ssao.frag b/shaders_ref/postprocessing/ssao/ssao.frag new file mode 100644 index 00000000..35dfb698 --- /dev/null +++ b/shaders_ref/postprocessing/ssao/ssao.frag @@ -0,0 +1,139 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +in vec2 uv; + +#include "../../pipeline/scene.glsl" +#include "../../functions/reconstruct_position.glsl" +#include "../../functions/reconstruct_normal.glsl" +#include "../../functions/random.glsl" +#include "../../pipeline/shading/common.glsl" + +layout (std140) uniform SSAO_BUFFER { + vec2 sample_count; + vec2 angle_inc_cos_sin; + float projection_scale_radius; + float intensity; + float spiral_turns; + float inv_radius_squared; + float min_horizon_angle_sine_squared; + float bias; + float peak2; + float power; + uint max_level; +}; + +uniform sampler2D depth_texture; + +out vec3 color; + +vec3 tapLocation(float i, const float noise) { + float offset = ((2.0 * PI) * 2.4) * noise; + float angle = ((i * sample_count.y) * spiral_turns) * (2.0 * PI) + offset; + float radius = (i + noise + 0.5) * sample_count.y; + return vec3(cos(angle), sin(angle), radius * radius); +} + +highp vec2 startPosition(const float noise) { + float angle = ((2.0 * PI) * 2.4) * noise; + return vec2(cos(angle), sin(angle)); +} + +highp mat2 tapAngleStep() { + vec2 t = angle_inc_cos_sin; + return mat2(t.x, t.y, -t.y, t.x); +} + +vec3 tapLocationFast(float i, vec2 p, const float noise) { + float radius = (i + noise + 0.5) * sample_count.y; + return vec3(p, radius * radius); +} + +void computeAmbientOcclusionSAO(inout float occlusion, inout vec3 bentNormal, + float i, float ssDiskRadius, + const highp vec2 uv, const highp vec3 origin, const vec3 normal, + const vec2 tapPosition, const float noise) { + + vec3 tap = tapLocationFast(i, tapPosition, noise); + float ssRadius = max(1.0, tap.z * ssDiskRadius); + + vec2 uvSamplePos = uv + vec2(ssRadius * tap.xy) * 1.0 / getResolution(); + + float level = clamp(floor(log2(ssRadius)) - 3.0, 0.0, float(max_level)); + //TODO: make mipmap depth + float occlusionDepth = texture(depth_texture, uvSamplePos).r; + + vec3 p = reconstructViewSpacePosition(uvSamplePos, occlusionDepth); + + // now we have the sample, compute AO + highp vec3 v = p - origin; // sample vector + float vv = dot(v, v); // squared distance + float vn = dot(v, normal); // distance * cos(v, normal) + + // discard samples that are outside of the radius, preventing distant geometry to + // cast shadows -- there are many functions that work and choosing one is an artistic + // decision. + float s = max(0.0, 1.0 - vv * inv_radius_squared); + float w = s * s; + + // discard samples that are too close to the horizon to reduce shadows cast by geometry + // not sufficently tessellated. The goal is to discard samples that form an angle 'beta' + // smaller than 'epsilon' with the horizon. We already have dot(v,n) which is equal to the + // sin(beta) * |v|. So the test simplifies to vn^2 < vv * sin(epsilon)^2. + w *= step(vv * min_horizon_angle_sine_squared, vn * vn); + + float sampleOcclusion = max(0.0, vn + (origin.z * bias)) / (vv + peak2); + occlusion += w * sampleOcclusion; +} + +/* + * https://research.nvidia.com/sites/default/files/pubs/2012-06_Scalable-Ambient-Obscurance/McGuire12SAO.pdf + */ +void scalableAmbientObscurance(out float obscurance, out vec3 bentNormal, vec2 uv, vec3 origin, vec3 normal) { + float noise = getRandom(gl_FragCoord.xy); + highp vec2 tapPosition = startPosition(noise); + highp mat2 angleStep = tapAngleStep(); + + // Choose the screen-space sample radius + // proportional to the projected area of the sphere + float ssDiskRadius = -(projection_scale_radius / origin.z); + + obscurance = 0.0; + bentNormal = normal; + for (float i = 0.0; i < sample_count.x; i += 1.0) { + computeAmbientOcclusionSAO(obscurance, bentNormal, i, ssDiskRadius, uv, origin, normal, tapPosition, noise); + tapPosition = angleStep * tapPosition; + } + obscurance = sqrt(obscurance * intensity); +} + +vec2 pack(highp float normalizedDepth) { + // we need 16-bits of precision + highp float z = clamp(normalizedDepth, 0.0, 1.0); + highp float t = floor(256.0 * z); + mediump float hi = t * (1.0 / 256.0); // we only need 8-bits of precision + mediump float lo = (256.0 * z) - t; // we only need 8-bits of precision + return vec2(hi, lo); +} + +highp float unpack(highp vec2 depth) { + // depth here only has 8-bits of precision, but the unpacked depth is highp + // this is equivalent to (x8 * 256 + y8) / 65535, which gives a value between 0 and 1 + return (depth.x * (256.0 / 257.0) + depth.y * (1.0 / 257.0)); +} + +void main() { + float depth = texture(depth_texture, uv).r; + float z = linearize_depth(depth, getCameraNearPlane(), getCameraFarPlane()); + + vec3 position = reconstructViewSpacePosition(uv, depth); + vec3 normal = reconstructViewSpaceNormal(depth_texture, uv, depth, position, vec2(1.0) / getResolution()); + + float occlusion = 0.0; + vec3 bentNormal; // will be discarded + scalableAmbientObscurance(occlusion, bentNormal, uv, position, normal); + + float aoVisibility = pow(saturate(1.0 - occlusion), power); + + color = vec3(aoVisibility, pack(position.z * 1.0 / getCameraFarPlane())); +} diff --git a/shaders_ref/postprocessing/ssao/ssao.vert b/shaders_ref/postprocessing/ssao/ssao.vert new file mode 100644 index 00000000..ba2e8301 --- /dev/null +++ b/shaders_ref/postprocessing/ssao/ssao.vert @@ -0,0 +1,12 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +layout(location = 0) in vec3 vertex_position; +layout(location = 1) in vec2 vertex_uv; + +out vec2 uv; + +void main() { + uv = vertex_uv; + gl_Position = vec4(vertex_position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/ssao/ssao_blur.frag b/shaders_ref/postprocessing/ssao/ssao_blur.frag new file mode 100644 index 00000000..b983ada1 --- /dev/null +++ b/shaders_ref/postprocessing/ssao/ssao_blur.frag @@ -0,0 +1,69 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +#include "../../pipeline/scene.glsl" +#include "../../functions/random.glsl" + +in vec2 uv; + +uniform sampler2D ssao; + +uniform float kernel[16]; +uniform vec2 axis; +uniform uint sample_count; +uniform float far_plane_over_edge_distance; + +out float color; + +float unpack(vec2 depth) { + // depth here only has 8-bits of precision, but the unpacked depth is highp + // this is equivalent to (x8 * 256 + y8) / 65535, which gives a value between 0 and 1 + return (depth.x * (256.0 / 257.0) + depth.y * (1.0 / 257.0)); +} + +float bilateralWeight(in highp float depth, in highp float sampleDepth) { + float diff = (sampleDepth - depth) * far_plane_over_edge_distance; + return max(0.0, 1.0 - diff * diff); +} + +void tap(inout float sum, inout float totalWeight, float weight, float depth, vec2 position) { + // ambient occlusion sample + vec3 data = texture(ssao, position).rgb; + + // bilateral sample + float bilateral = weight * bilateralWeight(depth, unpack(data.gb)); + sum += data.r * bilateral; + totalWeight += bilateral; +} + +void main() { + vec3 data = texture(ssao, uv).rgb; + + // This is the skybox, skip + if (data.g * data.b == 1.0) { + color= data.r; + return; + } + + float depth = unpack(data.gb); + float totalWeight = kernel[0]; + float sum = data.r * totalWeight; + + vec2 texel_size = axis / getResolution(); + + vec2 offset = texel_size; + for (int i = 1; i < int(sample_count); i++) { + float weight = kernel[i]; + tap(sum, totalWeight, weight, depth, uv + offset); + tap(sum, totalWeight, weight, depth, uv - offset); + offset += texel_size; + } + + float ao = sum * (1.0 / totalWeight); + + // simple dithering helps a lot (assumes 8 bits target) + // this is most useful with high quality/large blurs + ao += ((getRandom(uv) - 0.5) / 255.0); + + color = ao; +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/ssao/ssao_blur.vert b/shaders_ref/postprocessing/ssao/ssao_blur.vert new file mode 100644 index 00000000..ba2e8301 --- /dev/null +++ b/shaders_ref/postprocessing/ssao/ssao_blur.vert @@ -0,0 +1,12 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +layout(location = 0) in vec3 vertex_position; +layout(location = 1) in vec2 vertex_uv; + +out vec2 uv; + +void main() { + uv = vertex_uv; + gl_Position = vec4(vertex_position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/ssr/ssr.frag b/shaders_ref/postprocessing/ssr/ssr.frag new file mode 100644 index 00000000..55223616 --- /dev/null +++ b/shaders_ref/postprocessing/ssr/ssr.frag @@ -0,0 +1,172 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +#include "../../pipeline/scene.glsl" + +#include "../../functions/reconstruct_position.glsl" +#include "../../functions/random.glsl" +#include "../../functions/math.glsl" +#include "../../functions/trace_ray.glsl" +#include "../../pipeline/shading/common.glsl" +#include "../../pipeline/shading/brdf.glsl" + +// input normalized uv +in vec2 uv; + +// output vec3 reflected_color color +out vec3 color; + +// GBUFFER textures +uniform sampler2D normal_texture; +uniform sampler2D depth_texture; +uniform sampler2D props_texture; + +uniform sampler2D base_color_texture; + +// SSR settings +uniform float vs_thickness = 0.5; +uniform float stride = 2.0; +uniform float vs_max_distance = 1000.0; +uniform float bias = 0.1; +uniform float max_steps = 1000.0; + +uniform float reflection_threshold = 0.0; +uniform float roughness_factor = 0.1; + +uniform float camera_attenuation_lower_edge = 0.2; +uniform float camera_attenuation_upper_edge = 0.55; + +uniform float reflection_strength = 5.0; +uniform float reflection_falloff_exp = 1.0; + +float compute_attenuation(ivec2 hitPixel, vec2 hitUV, vec3 vsRayOrigin, vec3 vsHitPoint, float maxRayDistance, float numIterations) { + float attenuation = 1.0; + +#ifdef SCREEN_SPACE_REFLECTIONS_BORDERS_ATTENUATION + // Attenuation against the border of the screen + vec2 dCoords = smoothstep(0.2, 0.6, abs(vec2(0.5) - hitUV.xy)); + + attenuation *= clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0); +#endif + +#ifdef SCREEN_SPACE_REFLECTIONS_INTERSECTION_DISTANCE_ATTENUATION + // Attenuation based on the distance between the origin of the reflection ray and the intersection point + attenuation *= 1.0 - clamp(distance(vsRayOrigin, vsHitPoint) / maxRayDistance, 0.0, 1.0); +#endif + +#ifdef SCREEN_SPACE_REFLECTIONS_ITERATION_COUNT_ATTENUATION + // Attenuation based on the number of iterations performed to find the intersection + attenuation *= 1.0 - (numIterations / max_steps); +#endif + + return attenuation; +} + +void main() { + vec2 props = texture(props_texture, uv).rg; + float roughness = props.r; + float metallic = props.g; + + if (metallic < reflection_threshold) { + return; + } + + // normalized depth + float depth = texture(depth_texture, uv).r; + + // skip if skybox + if (abs(depth - 1.0) < 0.000001) { + return; + } + + // world space position + vec3 ws_position = reconstructPosition(uv, depth); + + // world space view direction + vec3 ws_view_dir = normalize(ws_position - getCameraPosition()); + + // world space normal (already normalized) + vec3 ws_normal = texture(normal_texture, uv).xyz; + + // world space reflected_color vector from current position + vec3 ws_reflected = reflect(ws_view_dir, ws_normal); + + // world space ray direction + vec3 ws_ray_direction = normalize(ws_reflected); + + // world space ray origin + vec3 ws_origin = ws_position + bias * ws_ray_direction; + + // view space ray origin + vec3 vs_origin = mul_mat4_vec3(getView(), ws_origin).xyz; + + // view space ray direction (independent of camera position) + vec3 vs_ray_direction = mul_mat3_vec3(getView(), ws_ray_direction); + + float attenuation = 1.0; +#ifdef SCREEN_SPACE_REFLECTIONS_CAMERA_FACING_ATTENUATION +// This will check the direction of the reflection vector with the view direction, +// and if they are pointing in the same direction, it will drown out those reflections +// since we are limited to pixels visible on screen. Attenuate reflections for angles between +// 60 degrees and 75 degrees, and drop all contribution beyond the (-60,60) degree range + attenuation *= 1.0 - smoothstep(camera_attenuation_lower_edge, camera_attenuation_upper_edge, dot(-ws_view_dir, ws_reflected)); + if (attenuation <= 0) { + return; + } +#endif + + vec3 jitt = vec3(0.0); +#ifndef SCREEN_SPACE_REFLECTIONS_BLUR + jitt = mix(vec3(0.0), hash(vs_origin) - vec3(0.5), roughness) * roughness_factor; // jittering of the reflection direction to simulate roughness +#endif + + vec2 uv2 = uv * getResolution(); + float c = (uv2.x + uv2.y) * 0.25; + float jitter = mod(c, 1.0); // jittering to hide artefacts when stepSize is > 1 + + // Outputs from the traceScreenSpaceRay function. + vec2 hitPixel; // not currently used + vec3 hitPoint; + float numIterations; + + vec3 reflected_color = vec3(0.0); + if (traceScreenSpaceRay( + vs_origin, + normalize(vs_ray_direction + jitt), + getViewToScreen(), + depth_texture, + getResolution(), + vs_thickness, + getCameraNearPlane(), + stride, + jitter, + max_steps, + vs_max_distance, + 0, + hitPixel, + hitPoint, + numIterations)) + { + vec3 base_color = texelFetch(base_color_texture, ivec2(hitPixel), 0).rgb; + + attenuation *= compute_attenuation(ivec2(hitPixel), + hitPixel / getResolution(), + vs_origin, + hitPoint, + vs_max_distance, + numIterations); + +#ifdef SCREEN_SPACE_REFLECTIONS_FRESNEL_ATTENUATION + vec3 F0 = computeF0(base_color, metallic, 1.0); + vec3 scatter = F_Schlick(F0, 1.0, max(dot(ws_normal, -ws_view_dir), 0.0)); + + vec3 reflection_attenuation = clamp(pow(scatter * reflection_strength, vec3(reflection_falloff_exp)), 0.0, 1.0); + reflected_color = base_color * (1.0 - reflection_attenuation) + base_color * attenuation * reflection_attenuation; +#else + float reflection_attenuation = clamp(pow(metallic * reflection_strength, reflection_falloff_exp), 0.0, 1.0); + reflected_color = base_color * (1.0 - reflection_attenuation) + base_color * attenuation * reflection_attenuation; +#endif + } + + color = reflected_color; +} \ No newline at end of file diff --git a/shaders_ref/postprocessing/ssr/ssr.vert b/shaders_ref/postprocessing/ssr/ssr.vert new file mode 100644 index 00000000..cc36e2df --- /dev/null +++ b/shaders_ref/postprocessing/ssr/ssr.vert @@ -0,0 +1,13 @@ +Limitless::GLSL_VERSION +Limitless::Extensions + +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 v_uv; + +out vec2 uv; + +void main() +{ + uv = v_uv; + gl_Position = vec4(position, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/shading/cloth.glsl b/shaders_ref/shading/cloth.glsl new file mode 100644 index 00000000..137bd798 --- /dev/null +++ b/shaders_ref/shading/cloth.glsl @@ -0,0 +1,16 @@ +vec3 clothShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { +// vec3 Fd = DiffuseBRDF_Cloth(sctx, lctx); +// vec3 Fr = SpecularBRDF_Cloth(sctx, lctx); +// +//#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) +// Fd *= saturate(sctx.subsurfaceColor + lctx.NoL); +// vec3 color = Fd + Fr * NoL; +// color *= light.color.rgb * (light.color.a * lctx.attenuation * lctx.visibility); +//#else +// vec3 color = Fd + Fr; +// color *= light.color.rgb * (light.color.a * lctx.attenuation * lctx.NoL * lctx.visibility); +//#endif +// +// return color; + return vec3(0.0); +} \ No newline at end of file diff --git a/shaders_ref/shading/cloth_shading.glsl b/shaders_ref/shading/cloth_shading.glsl deleted file mode 100644 index 0c76fa01..00000000 --- a/shaders_ref/shading/cloth_shading.glsl +++ /dev/null @@ -1,15 +0,0 @@ -vec3 clothShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { - vec3 Fd = DiffuseBRDF_Cloth(sctx, lctx); - vec3 Fr = SpecularBRDF_Cloth(sctx, lctx); - -#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) - Fd *= saturate(sctx.subsurfaceColor + lctx.NoL); - vec3 color = Fd + Fr * NoL; - color *= light.color.rgb * (light.color.a * light.attenuation * lctx.visibility); -#else - vec3 color = Fd + Fr; - color *= light.color.rgb * (light.color.a * light.attenuation * lctx.NoL * lctx.visibility); -#endif - - return color; -} \ No newline at end of file diff --git a/shaders_ref/shading/custom.glsl b/shaders_ref/shading/custom.glsl new file mode 100644 index 00000000..c5361431 --- /dev/null +++ b/shaders_ref/shading/custom.glsl @@ -0,0 +1,3 @@ +vec3 customShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { + return vec3(0.0); +} diff --git a/shaders_ref/shading/regular_shading.glsl b/shaders_ref/shading/regular.glsl similarity index 60% rename from shaders_ref/shading/regular_shading.glsl rename to shaders_ref/shading/regular.glsl index 88526c09..5b402927 100644 --- a/shaders_ref/shading/regular_shading.glsl +++ b/shaders_ref/shading/regular.glsl @@ -1,3 +1,5 @@ +#include "../functions/brdf.glsl" + /** * Computes color for lit material with regular PBR shading model. */ @@ -5,12 +7,11 @@ vec3 regularShading(const ShadingContext sctx, const LightingContext lctx, const vec3 Fd = DiffuseBRDF(sctx, lctx); vec3 Fr = SpecularBRDF(sctx, lctx); - vec3 color = Fd + Fr * sctx.energyCompensation; + vec3 color = Fd + Fr; -#if defined (ENGINE_MATERIAL_REFRACTION) - Fd *= (1.0 - sctx.transmission); -#endif +//#if defined (ENGINE_MATERIAL_REFRACTION) +// Fd *= (1.0 - sctx.transmission); +//#endif - //TODO: add emissive ??? - return (color * light.color.rgb) * (light.color.a * lctx.NoL * light.attenuation * lctx.visibility); + return (color * light.color.rgb) * (light.color.a * lctx.NoL * lctx.attenuation * lctx.visibility); } diff --git a/shaders_ref/shading/shade_for_light.glsl b/shaders_ref/shading/shade_for_light.glsl deleted file mode 100644 index dd2a584e..00000000 --- a/shaders_ref/shading/shade_for_light.glsl +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Shades current fragment with defined material model for specified light - */ -vec3 shadeForLight(const ShadingContext sctx, const LightingContext lctx, const Light light) { -#if defined (ENGINE_MATERIAL_SHADING_REGULAR_MODEL) - return regularShading(sctx, lctx, light); -#elif defined (ENGINE_MATERIAL_SHADING_CLOTH_MODEL) - return clothShading(sctx, lctx, light); -#elif defined (ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL) - return subsurfaceShading(sctx, lctx, light); -#elif defined (ENGINE_MATERIAL_SHADING_CUSTOM_MODEL) - return customShading(sctx, lctx, light); -#endif -} \ No newline at end of file diff --git a/shaders_ref/shading/shading_context.glsl b/shaders_ref/shading/shading_context.glsl index 04085a7c..626f0ec6 100644 --- a/shaders_ref/shading/shading_context.glsl +++ b/shaders_ref/shading/shading_context.glsl @@ -1,6 +1,12 @@ #include "../functions/common.glsl" #include "../scene.glsl" +#define ENGINE_SHADING_UNLIT 0u +#define ENGINE_SHADING_LIT 1u +#define ENGINE_SHADING_CLOTH 2u +#define ENGINE_SHADING_SUBSURFACE 3u +#define ENGINE_SHADING_CUSTOM 4u + struct ShadingContext { vec3 diffuseColor; float metallic; @@ -16,21 +22,40 @@ struct ShadingContext { vec3 F0; float ambientOcclusion; + + vec3 emissive_color; + + float alpha; + uint shading_model; }; ShadingContext computeShadingContext( - const vec3 baseColor, float metallic, - const vec3 worldPos, float roughness, - const vec3 N, float ambientOcclusion + const vec3 baseColor, + float alpha, + float metallic, + const vec3 worldPos, + float roughness, + const vec3 N, + float ambientOcclusion, + vec3 emissive_color, + uint shading_model ) { ShadingContext context; context.metallic = saturate(metallic); context.diffuseColor = computeDiffuseColor(baseColor, context.metallic); + context.alpha = alpha; + context.shading_model = shading_model; context.worldPos = worldPos; - float perceptualRoughness = clamp(roughness, MIN_PERCEPTUAL_ROUGHNESS, 1.0); + float perceptualRoughness = roughness; + +#if defined (ENGINE_SETTINGS_SPECULAR_AA) + perceptualRoughness = specularAA(N, perceptualRoughness, ENGINE_SETTINGS_SPECULAR_AA_THRESHOLD, ENGINE_SETTINGS_SPECULAR_AA_VARIANCE); +#endif + + perceptualRoughness = clamp(perceptualRoughness, MIN_PERCEPTUAL_ROUGHNESS, 1.0); context.roughness = perceptualRoughness * perceptualRoughness; context.N = N; @@ -41,6 +66,7 @@ ShadingContext computeShadingContext( context.F0 = computeF0(baseColor, context.metallic, 1.0); context.ambientOcclusion = ambientOcclusion; + context.emissive_color = emissive_color; #if defined (ENGINE_MATERIAL_ANISOTROPY) vec3 direction = material.anisotropyDirection; diff --git a/shaders_ref/shading/shading_context_from_gctx.glsl b/shaders_ref/shading/shading_context_from_gctx.glsl new file mode 100644 index 00000000..89e29d2b --- /dev/null +++ b/shaders_ref/shading/shading_context_from_gctx.glsl @@ -0,0 +1,16 @@ +#include "./shading_context.glsl" +#include "../pipeline/gbuffer_context.glsl" + +ShadingContext computeShadingContext(const GBufferContext gctx) { + return computeShadingContext( + gctx.color, + 1.0, // deferred shading, no alpha channel + gctx.metallic, + gctx.position, + gctx.roughness, + gctx.normal, + gctx.ao, + gctx.emissive_color, + gctx.shading_model + ); +} diff --git a/shaders_ref/shading/shading_context_from_material.glsl b/shaders_ref/shading/shading_context_from_mctx.glsl similarity index 66% rename from shaders_ref/shading/shading_context_from_material.glsl rename to shaders_ref/shading/shading_context_from_mctx.glsl index 2d29c2ec..283a0b17 100644 --- a/shaders_ref/shading/shading_context_from_material.glsl +++ b/shaders_ref/shading/shading_context_from_mctx.glsl @@ -5,13 +5,17 @@ ShadingContext computeShadingContext(const MaterialContext mctx) { vec4 color = computeMaterialColor(mctx); vec3 normal = computeMaterialNormal(mctx); float ao = computeMaterialAO(mctx); + vec3 emissive_color = computeMaterialEmissiveColor(mctx); return computeShadingContext( - color, + color.rgb, + color.a, mctx.metallic, - getVertexPosition(), //TODO: make an argument? + getVertexPosition(), mctx.roughness, normal, - ao + ao, + emissive_color, + mctx.shading_model ); } \ No newline at end of file diff --git a/shaders_ref/shading/shading_gctx.glsl b/shaders_ref/shading/shading_gctx.glsl new file mode 100644 index 00000000..29f3798e --- /dev/null +++ b/shaders_ref/shading/shading_gctx.glsl @@ -0,0 +1,20 @@ +#include "../lighting/lighting.glsl" + +#include "./shading_context_from_gctx.glsl" +#include "../lighting/ambient.glsl" + +/* [deferred pipeline] */ +vec3 shadeFragment(const GBufferContext gctx) { + const ShadingContext sctx = computeShadingContext(gctx); + + vec3 color = computeAmbientLighting(sctx.diffuseColor, sctx.ambientOcclusion); + + // if not unlit shading + if (sctx.shading_model != ENGINE_SHADING_UNLIT) { + color += computeLights(sctx); + } + + color.rgb += sctx.emissive_color; + + return color; +} diff --git a/shaders_ref/shading/shading_mctx.glsl b/shaders_ref/shading/shading_mctx.glsl new file mode 100644 index 00000000..d6e148d1 --- /dev/null +++ b/shaders_ref/shading/shading_mctx.glsl @@ -0,0 +1,29 @@ +#include "../lighting/lighting.glsl" + +#include "./shading_context_from_mctx.glsl" +#include "../lighting/refraction.glsl" +#include "../lighting/ambient.glsl" + +/* [forward pipeline] */ +vec4 shadeFragment(const MaterialContext mctx) { + const ShadingContext sctx = computeShadingContext(mctx); + +#if defined (ENGINE_MATERIAL_SHADING_CUSTOM_MODEL) + return customShading(sctx); +#else + vec3 ambient = computeAmbientLighting(sctx.diffuseColor, sctx.ambientOcclusion); + vec4 color = vec4(ambient, sctx.alpha); + +#if !defined (ENGINE_MATERIAL_SHADING_UNLIT_MODEL) + color.rgb += computeLights(sctx); +#endif + +#if defined (ENGINE_MATERIAL_REFRACTION) + color.rgb += computeRefraction(sctx, mctx.IoR, mctx.absorption); +#endif + + color.rgb += sctx.emissive_color; +#endif + + return color; +} diff --git a/shaders_ref/shading/subsurface.glsl b/shaders_ref/shading/subsurface.glsl new file mode 100644 index 00000000..5b3a7509 --- /dev/null +++ b/shaders_ref/shading/subsurface.glsl @@ -0,0 +1,17 @@ +vec3 subsurfaceShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { +// vec3 Fd = DiffuseBRDF(sctx, lctx); +// vec3 Fr = vec3(0.0); +// if (lctx.NoL > 0.0) { +// Fr = SpecularBRDF(sctx, lctx) * sctx.energyCompensation; +// } +// +// vec3 color = (Fd + Fr) * (lctx.NoL * lctx.occlusion); +// float scatterVoH = saturate(dot(sctx.V, -lctx.L)); +// float forwardScatter = exp2(scatterVoH * pixel.subsurfacePower - pixel.subsurfacePower); +// float backScatter = saturate(lctx.NoL * sctx.thickness + (1.0 - sctx.thickness)) * 0.5; +// float subsurface = mix(backScatter, 1.0, forwardScatter) * (1.0 - sctx.thickness); +// color += sctx.subsurfaceColor * (subsurface * Fd_Lambert()); +// +// return (color * lctx.color.rgb) * (lctx.color.a * light.attenuation); + return vec3(0.0); +} \ No newline at end of file diff --git a/shaders_ref/shading/subsurface_shading.glsl b/shaders_ref/shading/subsurface_shading.glsl deleted file mode 100644 index 12344fed..00000000 --- a/shaders_ref/shading/subsurface_shading.glsl +++ /dev/null @@ -1,16 +0,0 @@ -vec3 subsurfaceShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { - vec3 Fd = DiffuseBRDF(sctx, lctx); - vec3 Fr = vec3(0.0); - if (lctx.NoL > 0.0) { - Fr = SpecularBRDF(sctx, lctx) * sctx.energyCompensation; - } - - vec3 color = (Fd + Fr) * (lctx.NoL * lctx.occlusion); - float scatterVoH = saturate(dot(sctx.V, -lctx.L)); - float forwardScatter = exp2(scatterVoH * pixel.subsurfacePower - pixel.subsurfacePower); - float backScatter = saturate(lctx.NoL * sctx.thickness + (1.0 - sctx.thickness)) * 0.5; - float subsurface = mix(backScatter, 1.0, forwardScatter) * (1.0 - sctx.thickness); - color += sctx.subsurfaceColor * (subsurface * Fd_Lambert()); - - return (color * lctx.color.rgb) * (lctx.color.a * light.attenuation); -} \ No newline at end of file diff --git a/shaders_ref/text/text.frag b/shaders_ref/text/text.frag new file mode 100644 index 00000000..6fcc542a --- /dev/null +++ b/shaders_ref/text/text.frag @@ -0,0 +1,12 @@ +ENGINE::COMMON + +in vec2 vs_uv; + +out vec4 FragColor; + +uniform sampler2D bitmap; +uniform vec4 color; + +void main() { + FragColor = vec4(color.rgb, texture(bitmap, vs_uv).r * color.a); +} \ No newline at end of file diff --git a/shaders_ref/text/text.vert b/shaders_ref/text/text.vert new file mode 100644 index 00000000..95a4f8d5 --- /dev/null +++ b/shaders_ref/text/text.vert @@ -0,0 +1,16 @@ +ENGINE::COMMON + +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 uv; + +out vec2 vs_uv; + +uniform mat4 model; + +uniform mat4 proj; + +void main() +{ + gl_Position = proj * model * vec4(position, 0.0, 1.0); + vs_uv = uv; +} \ No newline at end of file diff --git a/shaders_ref/text/text_selection.frag b/shaders_ref/text/text_selection.frag new file mode 100644 index 00000000..42c2750e --- /dev/null +++ b/shaders_ref/text/text_selection.frag @@ -0,0 +1,10 @@ +ENGINE::COMMON + +out vec4 FragColor; + +uniform vec4 color; + +void main() +{ + FragColor = color; +} \ No newline at end of file diff --git a/shaders_ref/text/text_selection.vert b/shaders_ref/text/text_selection.vert new file mode 100644 index 00000000..1fb9b7d0 --- /dev/null +++ b/shaders_ref/text/text_selection.vert @@ -0,0 +1,12 @@ +ENGINE::COMMON + +layout (location = 0) in vec2 position; + +uniform mat4 model; + +uniform mat4 proj; + +void main() +{ + gl_Position = proj * model * vec4(position, 0.0, 1.0); +} \ No newline at end of file diff --git a/shaders_ref/vertex_streams/mesh_emitter.glsl b/shaders_ref/vertex_streams/mesh_emitter.glsl index 3e3e51de..ef4ea376 100644 --- a/shaders_ref/vertex_streams/mesh_emitter.glsl +++ b/shaders_ref/vertex_streams/mesh_emitter.glsl @@ -1,4 +1,41 @@ -#include "./model_mesh.glsl" +layout (location = 0) in vec3 _vertex_position; +layout (location = 1) in vec3 _vertex_normal; +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) + layout (location = 2) in vec3 _vertex_tangent; +#endif +layout (location = 3) in vec2 _vertex_uv; +#if defined (ENGINE_MATERIAL_SKELETAL_MODEL) + layout (location = 4) in ivec4 _vertex_bone_id; +layout (location = 5) in vec4 _vertex_bone_weight; +#endif + +vec3 getVertexPosition() { + return _vertex_position; +} + +vec3 getVertexNormal() { + return _vertex_normal; +} + +vec2 getVertexUV() { + return _vertex_uv; +} + +#if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) + vec3 getVertexTangent() { + return _vertex_tangent; +} +#endif + +#if defined (ENGINE_MATERIAL_SKELETAL_MODEL) + ivec4 getVertexBoneID() { + return _vertex_bone_id; +} + +vec4 getVertexBoneWeight() { + return _vertex_bone_weight; +} +#endif struct MeshParticle { mat4 model; diff --git a/src/limitless/core/shader/shader_compiler.cpp b/src/limitless/core/shader/shader_compiler.cpp index 39fff041..a8f38abe 100644 --- a/src/limitless/core/shader/shader_compiler.cpp +++ b/src/limitless/core/shader/shader_compiler.cpp @@ -5,7 +5,7 @@ #include "limitless/core/shader/shader_program.hpp" #include #include -#include +#include #include using namespace Limitless; @@ -44,7 +44,6 @@ void ShaderCompiler::checkStatus(const GLuint program_id) { ShaderCompiler& ShaderCompiler::operator<<(Shader&& shader) noexcept { shaders.emplace_back(std::move(shader)); - return *this; } @@ -70,11 +69,8 @@ std::shared_ptr ShaderCompiler::compile() { return std::shared_ptr(new ShaderProgram(program_id)); } -void ShaderCompiler::replaceEngineDefines(Shader& shader) const { - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::GLSLVersion], getVersionDefine()); - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Extensions], getExtensionsDefine()); - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Settings], getSettingsDefine()); - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::Common], getCommonDefine()); +void ShaderCompiler::replaceCommonDefines(Shader &shader) { + ShaderDefineReplacer::replaceCommon(shader, render_settings); } std::shared_ptr ShaderCompiler::compile(const fs::path& path, const ShaderAction& action) { @@ -83,14 +79,7 @@ std::shared_ptr ShaderCompiler::compile(const fs::path& path, con try { Shader shader { path.string() + extension.data(), type, action }; - replaceEngineDefines(shader); - - std::string e = type == Shader::Type::Vertex ? ".vert" : ".frag"; - // TODO: temp ref/remove - static int i = 0; - std::ofstream f {"D:/Dev/Projects/limitless-engine/glslang/" + std::to_string(i++) + e}; - f << shader.getSource(); - f.close(); + replaceCommonDefines(shader); *this << std::move(shader); @@ -101,52 +90,9 @@ std::shared_ptr ShaderCompiler::compile(const fs::path& path, con } if (shader_count == 0) { - throw shader_compilation_error("Shaders not found : " + path.string()); + throw shader_compilation_error("Shaders not found: " + path.string()); } return compile(); } -std::string ShaderCompiler::getVersionDefine() { - return "#version " + std::to_string(ContextInitializer::major_version) + std::to_string(ContextInitializer::minor_version) + "0 core\n"; -} - -std::string ShaderCompiler::getExtensionsDefine() { - std::string extensions; - - if (ContextInitializer::isExtensionSupported(shader_storage_buffer_object)) { - extensions.append(extension_shader_storage_buffer_object); - } - - if (ContextInitializer::isExtensionSupported(shading_language_420pack)) { - extensions.append(extension_shading_language_420pack); - } - - if (ContextInitializer::isExtensionSupported(explicit_uniform_location)) { - extensions.append(extension_explicit_uniform_location); - } - - if (ContextInitializer::isExtensionSupported(bindless_texture)) { - extensions.append(extension_bindless_texture); - extensions.append(bindless_texture_define); - extensions.append(bindless_samplers); - } - - return extensions; -} - -std::string ShaderCompiler::getSettingsDefine() const { - std::string define; - if (render_settings) { - RenderSettingsShaderDefiner settings {*render_settings}; - define = settings.define(); - } - return define; -} - -std::string ShaderCompiler::getCommonDefine() const { - std::string defines = getVersionDefine(); - defines.append(getExtensionsDefine()); - defines.append(getSettingsDefine()); - return defines; -} diff --git a/src/limitless/core/shader/shader_define_replacer.cpp b/src/limitless/core/shader/shader_define_replacer.cpp new file mode 100644 index 00000000..ce3acadf --- /dev/null +++ b/src/limitless/core/shader/shader_define_replacer.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include + +using namespace Limitless; + +std::string ShaderDefineReplacer::getVersionDefine() { + return "#version " + std::to_string(ContextInitializer::major_version) + std::to_string(ContextInitializer::minor_version) + "0 core\n"; +} + +std::string ShaderDefineReplacer::getExtensionDefine() { + std::string extensions; + + if (ContextInitializer::isExtensionSupported(shader_storage_buffer_object)) { + extensions.append(extension_shader_storage_buffer_object); + } + + if (ContextInitializer::isExtensionSupported(shading_language_420pack)) { + extensions.append(extension_shading_language_420pack); + } + + if (ContextInitializer::isExtensionSupported(explicit_uniform_location)) { + extensions.append(extension_explicit_uniform_location); + } + + if (ContextInitializer::isExtensionSupported(bindless_texture)) { + extensions.append(extension_bindless_texture); + extensions.append(bindless_texture_define); + extensions.append(bindless_samplers); + } + + return extensions; +} + +std::string ShaderDefineReplacer::getSettingsDefine(std::optional settings) { + return settings ? RenderSettingsShaderDefiner::getDefine(*settings) : std::string {}; +} + +std::string ShaderDefineReplacer::getCommonDefine(std::optional settings) { + std::string define = getVersionDefine(); + define.append(getExtensionDefine()); + define.append(getSettingsDefine(settings)); + return define; +} + +void ShaderDefineReplacer::replaceCommon(Shader& shader, std::optional settings) { + shader.replaceKey(DEFINE_NAMES.at(Define::GLSLVersion), getVersionDefine()); + shader.replaceKey(DEFINE_NAMES.at(Define::Extensions), getExtensionDefine()); + shader.replaceKey(DEFINE_NAMES.at(Define::Settings), getExtensionDefine()); + shader.replaceKey(DEFINE_NAMES.at(Define::Common), getCommonDefine(settings)); +} diff --git a/src/limitless/core/shader/shader_program.cpp b/src/limitless/core/shader/shader_program.cpp index e953cb09..498bd319 100644 --- a/src/limitless/core/shader/shader_program.cpp +++ b/src/limitless/core/shader/shader_program.cpp @@ -123,7 +123,7 @@ ShaderProgram& ShaderProgram::setUniform(const std::string& name, std::shared_pt ShaderProgram& ShaderProgram::setMaterial(const ms::Material& material) { // if not present for whatever reason just return - auto found = std::find_if(indexed_binds.begin(), indexed_binds.end(), [] (const auto& buf) { return buf.name == "material_buffer"; }); + auto found = std::find_if(indexed_binds.begin(), indexed_binds.end(), [] (const auto& buf) { return buf.name == "MATERIAL_BUFFER"; }); if (found == indexed_binds.end()) { return *this; } diff --git a/src/limitless/fx/effect_compiler.cpp b/src/limitless/fx/effect_compiler.cpp index 68e3fd87..712cf207 100644 --- a/src/limitless/fx/effect_compiler.cpp +++ b/src/limitless/fx/effect_compiler.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace Limitless::fx; using namespace Limitless; @@ -14,105 +15,11 @@ EffectCompiler::EffectCompiler(Context& context, Assets& assets, const RenderSet : MaterialCompiler(context, assets, settings) { } -std::string EffectCompiler::getEmitterDefines(const AbstractEmitter& emitter) noexcept { - std::string defines; - - switch (emitter.getType()) { - case AbstractEmitter::Type::Sprite: - defines.append("#define SpriteEmitter\n"); - break; - case AbstractEmitter::Type::Mesh: - defines.append("#define MeshEmitter\n"); - break; - case AbstractEmitter::Type::Beam: - defines.append("#define BeamEmitter\n"); - break; - } - - for (const auto& type : emitter.getUniqueShaderType().module_type) { - switch (type) { - case fx::ModuleType::InitialLocation: - defines.append("#define InitialLocation_MODULE\n"); - break; - case fx::ModuleType ::InitialRotation: - defines.append("#define InitialRotation_MODULE\n"); - break; - case fx::ModuleType ::InitialVelocity: - defines.append("#define InitialVelocity_MODULE\n"); - break; - case fx::ModuleType ::InitialColor: - defines.append("#define InitialColor_MODULE\n"); - break; - case fx::ModuleType ::InitialSize: - defines.append("#define InitialSize_MODULE\n"); - break; - case fx::ModuleType ::InitialAcceleration: - defines.append("#define InitialAcceleration_MODULE\n"); - break; - case fx::ModuleType ::InitialMeshLocation: - defines.append("#define InitialMeshLocation_MODULE\n"); - break; - case fx::ModuleType ::MeshLocationAttachment: - defines.append("#define MeshLocationAttachment_MODULE\n"); - break; - case fx::ModuleType ::Lifetime: - defines.append("#define Lifetime_MODULE\n"); - break; - case fx::ModuleType ::SubUV: - defines.append("#define SubUV_MODULE\n"); - break; - case fx::ModuleType ::ColorByLife: - defines.append("#define ColorByLife_MODULE\n"); - break; - case fx::ModuleType ::RotationRate: - defines.append("#define RotationRate_MODULE\n"); - break; - case fx::ModuleType ::SizeByLife: - defines.append("#define SizeByLife_MODULE\n"); - break; - case fx::ModuleType::CustomMaterial: - defines.append("#define CustomMaterial_MODULE\n"); - break; - case fx::ModuleType::CustomMaterialByLife: - defines.append("#define CustomMaterialByLife_MODULE\n"); - break; - case fx::ModuleType::VelocityByLife: - defines.append("#define VelocityByLife_MODULE\n"); - break; - case ModuleType::Beam_InitialDisplacement: - defines.append("#define Beam_InitialDisplacement_MODULE\n"); - break; - case ModuleType::Beam_InitialOffset: - defines.append("#define Beam_InitialOffset_MODULE\n"); - break; - case ModuleType::Beam_InitialRebuild: - defines.append("#define Beam_InitialRebuild_MODULE\n"); - break; - case ModuleType::Beam_InitialTarget: - defines.append("#define Beam_InitialTarget_MODULE\n"); - break; - case ModuleType::BeamBuilder: - defines.append("#define BeamBuilder_MODULE\n"); - break; - case ModuleType::BeamSpeed: - defines.append("#define BeamSpeed_MODULE\n"); - break; - case ModuleType::Time: - defines.append("#define Time_MODULE\n"); - break; - } - } - return defines; -} - template void EffectCompiler::compile(ShaderType shader_type, const T& emitter) { if (!assets.shaders.reserveIfNotContains({emitter.getUniqueShaderType(), shader_type})) { const auto props = [&] (Shader& shader) { - shader.replaceKey("Limitless::EmitterType", getEmitterDefines(emitter)); - - replaceMaterialSettings(shader, emitter.getMaterial(), InstanceType::Effect); - replaceEngineDefines(shader); + EffectShaderDefineReplacer::replaceMaterialDependentDefine(shader, emitter.getMaterial(), InstanceType::Effect, emitter); }; assets.shaders.add({emitter.getUniqueShaderType(), shader_type}, compile(assets.getShaderDir() / SHADER_PASS_PATH.at(shader_type), props)); diff --git a/src/limitless/fx/effect_shader_define_replacer.cpp b/src/limitless/fx/effect_shader_define_replacer.cpp new file mode 100644 index 00000000..861181f0 --- /dev/null +++ b/src/limitless/fx/effect_shader_define_replacer.cpp @@ -0,0 +1,110 @@ +#include + +#include +#include +#include +#include + +using namespace Limitless::fx; + +std::string EffectShaderDefineReplacer::getEmitterDefines(const AbstractEmitter& emitter) noexcept { + std::string defines; + + switch (emitter.getType()) { + case AbstractEmitter::Type::Sprite: + defines.append("#define SpriteEmitter\n"); + break; + case AbstractEmitter::Type::Mesh: + defines.append("#define MeshEmitter\n"); + break; + case AbstractEmitter::Type::Beam: + defines.append("#define BeamEmitter\n"); + break; + } + + for (const auto& type : emitter.getUniqueShaderType().module_type) { + switch (type) { + case fx::ModuleType::InitialLocation: + defines.append("#define InitialLocation_MODULE\n"); + break; + case fx::ModuleType ::InitialRotation: + defines.append("#define InitialRotation_MODULE\n"); + break; + case fx::ModuleType ::InitialVelocity: + defines.append("#define InitialVelocity_MODULE\n"); + break; + case fx::ModuleType ::InitialColor: + defines.append("#define InitialColor_MODULE\n"); + break; + case fx::ModuleType ::InitialSize: + defines.append("#define InitialSize_MODULE\n"); + break; + case fx::ModuleType ::InitialAcceleration: + defines.append("#define InitialAcceleration_MODULE\n"); + break; + case fx::ModuleType ::InitialMeshLocation: + defines.append("#define InitialMeshLocation_MODULE\n"); + break; + case fx::ModuleType ::MeshLocationAttachment: + defines.append("#define MeshLocationAttachment_MODULE\n"); + break; + case fx::ModuleType ::Lifetime: + defines.append("#define Lifetime_MODULE\n"); + break; + case fx::ModuleType ::SubUV: + defines.append("#define SubUV_MODULE\n"); + break; + case fx::ModuleType ::ColorByLife: + defines.append("#define ColorByLife_MODULE\n"); + break; + case fx::ModuleType ::RotationRate: + defines.append("#define RotationRate_MODULE\n"); + break; + case fx::ModuleType ::SizeByLife: + defines.append("#define SizeByLife_MODULE\n"); + break; + case fx::ModuleType::CustomMaterial: + defines.append("#define CustomMaterial_MODULE\n"); + break; + case fx::ModuleType::CustomMaterialByLife: + defines.append("#define CustomMaterialByLife_MODULE\n"); + break; + case fx::ModuleType::VelocityByLife: + defines.append("#define VelocityByLife_MODULE\n"); + break; + case ModuleType::Beam_InitialDisplacement: + defines.append("#define Beam_InitialDisplacement_MODULE\n"); + break; + case ModuleType::Beam_InitialOffset: + defines.append("#define Beam_InitialOffset_MODULE\n"); + break; + case ModuleType::Beam_InitialRebuild: + defines.append("#define Beam_InitialRebuild_MODULE\n"); + break; + case ModuleType::Beam_InitialTarget: + defines.append("#define Beam_InitialTarget_MODULE\n"); + break; + case ModuleType::BeamBuilder: + defines.append("#define BeamBuilder_MODULE\n"); + break; + case ModuleType::BeamSpeed: + defines.append("#define BeamSpeed_MODULE\n"); + break; + case ModuleType::Time: + defines.append("#define Time_MODULE\n"); + break; + } + } + return defines; +} + +void EffectShaderDefineReplacer::replaceMaterialDependentDefine(Shader& shader, const ms::Material& material, InstanceType model_shader, const AbstractEmitter& emitter) { + shader.replaceKey(DEFINE_NAMES.at(Define::MaterialDependent), getMaterialDependentDefine(material, model_shader) + getEmitterDefines(emitter)); + + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Vertex], material.getVertexSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Tesselation], material.getTessellationSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Fragment], material.getFragmentSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Global], material.getGlobalSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomScalar], getScalarUniformDefines(material)); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomSamplers], getSamplerUniformDefines(material)); +} diff --git a/src/limitless/lighting/cascade_shadows.cpp b/src/limitless/lighting/cascade_shadows.cpp index b5296833..94827c38 100644 --- a/src/limitless/lighting/cascade_shadows.cpp +++ b/src/limitless/lighting/cascade_shadows.cpp @@ -30,14 +30,9 @@ void CascadeShadows::initBuffers(Context& context) { .setFormat(Texture::Format::DepthComponent) .setDataType(Texture::DataType::Float) .setMipMap(false) -// .setBorder(true) .setLevels(1) -// .setBorderColor({ 1.0f, 1.0f, 1.0f, 1.0f }) .setMinFilter(Texture::Filter::Nearest) .setMagFilter(Texture::Filter::Nearest) -// .setWrapS(Texture::Wrap::ClampToBorder) -// .setWrapT(Texture::Wrap::ClampToBorder) -// .setWrapR(Texture::Wrap::ClampToBorder) .setWrapS(Texture::Wrap::ClampToEdge) .setWrapT(Texture::Wrap::ClampToEdge) .setWrapR(Texture::Wrap::ClampToEdge) diff --git a/src/limitless/lighting/light_container.cpp b/src/limitless/lighting/light_container.cpp index ec40c122..8967245a 100644 --- a/src/limitless/lighting/light_container.cpp +++ b/src/limitless/lighting/light_container.cpp @@ -60,4 +60,5 @@ void LightContainer::update() { namespace Limitless { template class LightContainer; template class LightContainer; + template class LightContainer; } diff --git a/src/limitless/lighting/lighting.cpp b/src/limitless/lighting/lighting.cpp index 04bca77d..aadb46f4 100644 --- a/src/limitless/lighting/lighting.cpp +++ b/src/limitless/lighting/lighting.cpp @@ -9,9 +9,7 @@ namespace { struct SceneLighting { DirectionalLight directional_light {}; glm::vec4 ambient_color {}; - uint32_t point_lights_count {}; - uint32_t dir_lights_count {}; - uint32_t spot_lights_count {}; + uint32_t light_count {}; }; constexpr auto SCENE_LIGHTING_BUFFER_NAME = "scene_lighting"; @@ -35,18 +33,14 @@ void Lighting::updateLightBuffer() { SceneLighting light_info { directional_light, ambient_color, - static_cast(point_lights.size()), - directional_light.direction != glm::vec4(0.0f), - static_cast(spot_lights.size()) + static_cast(lights.size()) }; //TODO update changed? buffer->mapData(&light_info, sizeof(SceneLighting)); } void Lighting::update() { - // maps point lights buffer - point_lights.update(); - spot_lights.update(); + lights.update(); // maps global scene light buffer updateLightBuffer(); @@ -58,15 +52,12 @@ void Lighting::update() { template Lighting::operator LightContainer&() noexcept { - if constexpr (std::is_same_v) - return point_lights; - else if constexpr (std::is_same_v) - return spot_lights; + if constexpr (std::is_same_v) + return lights; else static_assert(!std::is_same_v, "No such light container for T type"); } namespace Limitless { - template Lighting::operator LightContainer&() noexcept; - template Lighting::operator LightContainer&() noexcept; + template Lighting::operator LightContainer&() noexcept; } diff --git a/src/limitless/ms/material_builder.cpp b/src/limitless/ms/material_builder.cpp index ead5eec1..fa5e5fb9 100644 --- a/src/limitless/ms/material_builder.cpp +++ b/src/limitless/ms/material_builder.cpp @@ -73,16 +73,16 @@ MaterialBuilder& MaterialBuilder::set(decltype(material->uniforms)&& uniforms) { MaterialBuilder& MaterialBuilder::add(Property type, float value) { switch (type) { case Property::Absorption: - material->properties[type] = std::make_unique>("material_absorption", value); + material->properties[type] = std::make_unique>("_material_absorption", value); break; case Property::IoR: - material->properties[type] = std::make_unique>("material_ior", value); + material->properties[type] = std::make_unique>("_material_ior", value); break; case Property::Metallic: - material->properties[type] = std::make_unique>("material_metallic", value); + material->properties[type] = std::make_unique>("_material_metallic", value); break; case Property::Roughness: - material->properties[type] = std::make_unique>("material_roughness", value); + material->properties[type] = std::make_unique>("_material_roughness", value); break; case Property::TessellationFactor: case Property::Color: @@ -103,10 +103,10 @@ MaterialBuilder& MaterialBuilder::add(Property type, float value) { MaterialBuilder& MaterialBuilder::add(Property type, const glm::vec4& value) { switch (type) { case Property::Color: - material->properties[type] = std::make_unique>("material_color", value); + material->properties[type] = std::make_unique>("_material_color", value); break; case Property::EmissiveColor: - material->properties[type] = std::make_unique>("material_emissive_color", value); + material->properties[type] = std::make_unique>("_material_emissive_color", value); break; case Property::TessellationFactor: case Property::IoR: @@ -141,28 +141,28 @@ MaterialBuilder& MaterialBuilder::add(Property type, std::shared_ptr te case Property::EmissiveColor: throw material_builder_error{"Wrong data for material property."}; case Property::Diffuse: - material->properties[type] = std::make_unique("material_diffuse", std::move(texture)); + material->properties[type] = std::make_unique("_material_diffuse_texture", std::move(texture)); break; case Property::Normal: - material->properties[type] = std::make_unique("material_normal", std::move(texture)); + material->properties[type] = std::make_unique("_material_normal_texture", std::move(texture)); break; case Property::EmissiveMask: - material->properties[type] = std::make_unique("material_emissive_mask", std::move(texture)); + material->properties[type] = std::make_unique("_material_emissive_mask_texture", std::move(texture)); break; case Property::BlendMask: - material->properties[type] = std::make_unique("material_blend_mask", std::move(texture)); + material->properties[type] = std::make_unique("_material_blend_mask_texture", std::move(texture)); break; case Property::MetallicTexture: - material->properties[type] = std::make_unique("material_metallic_texture", std::move(texture)); + material->properties[type] = std::make_unique("_material_metallic_texture", std::move(texture)); break; case Property::RoughnessTexture: - material->properties[type] = std::make_unique("material_roughness_texture", std::move(texture)); + material->properties[type] = std::make_unique("_material_roughness_texture", std::move(texture)); break; case Property::AmbientOcclusionTexture: - material->properties[type] = std::make_unique("material_ambient_occlusion_texture", std::move(texture)); + material->properties[type] = std::make_unique("_material_ambient_occlusion_texture", std::move(texture)); break; case Property::ORM: - material->properties[type] = std::make_unique("material_orm_texture", std::move(texture)); + material->properties[type] = std::make_unique("_material_orm_texture", std::move(texture)); break; } return *this; @@ -171,7 +171,7 @@ MaterialBuilder& MaterialBuilder::add(Property type, std::shared_ptr te MaterialBuilder& MaterialBuilder::add(Property type, const glm::vec2& value) { switch (type) { case Property::TessellationFactor: - material->properties[type] = std::make_unique>("material_tessellation", value); + material->properties[type] = std::make_unique>("_material_tessellation", value); break; case Property::Color: case Property::IoR: diff --git a/src/limitless/ms/material_compiler.cpp b/src/limitless/ms/material_compiler.cpp index 6ad303bc..230de7ec 100644 --- a/src/limitless/ms/material_compiler.cpp +++ b/src/limitless/ms/material_compiler.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include using namespace Limitless::ms; @@ -13,23 +13,14 @@ MaterialCompiler::MaterialCompiler(Context& context, Assets& _assets, const Rend } void MaterialCompiler::replaceMaterialSettings(Shader& shader, const Material& material, InstanceType model_shader) noexcept { - MaterialShaderDefiner::define(shader, material, model_shader); + MaterialShaderDefineReplacer::replaceMaterialDependentDefine(shader, material, model_shader); } void MaterialCompiler::compile(const Material& material, ShaderType pass_shader, InstanceType model_shader) { const auto props = [&] (Shader& shader) { replaceMaterialSettings(shader, material, model_shader); - replaceEngineDefines(shader); }; -// if (material.contains(Property::TessellationFactor)) { -// auto tesc = Shader { assets.getShaderDir() / "tesselation" / "tesselation.tesc", Shader::Type::TessControl, props }; -// auto tese = Shader { assets.getShaderDir() / "tesselation" / "tesselation.tese", Shader::Type::TessEval, props }; -// -// *this << std::move(tesc) -// << std::move(tese); -// } - try { auto shader = compile(assets.getShaderDir() / SHADER_PASS_PATH.at(pass_shader), props); assets.shaders.add(pass_shader, model_shader, material.getShaderIndex(), shader); diff --git a/src/limitless/ms/material_shader_define_replacer.cpp b/src/limitless/ms/material_shader_define_replacer.cpp new file mode 100644 index 00000000..20369725 --- /dev/null +++ b/src/limitless/ms/material_shader_define_replacer.cpp @@ -0,0 +1,75 @@ +#include + +#include +#include +#include + +using namespace Limitless::ms; + +std::string MaterialShaderDefineReplacer::getPropertyDefines(const Material& material) { + std::string defines; + + for (const auto& [property, _] : material.getProperties()) { + auto define = "#define " + PROPERTY_DEFINE.at(property) + '\n'; + defines.append(define); + } + + if (material.getRefraction()) { + defines.append("#define ENGINE_MATERIAL_REFRACTION\n"); + } + + return defines; +} + +std::string MaterialShaderDefineReplacer::getShadingDefines(const Material& material) { + return "#define " + SHADING_DEFINE[material.getShading()] + '\n'; +} + +std::string MaterialShaderDefineReplacer::getModelDefines(InstanceType model_shader) { + return "#define " + MODEL_DEFINE[model_shader] + '\n'; +} + +void MaterialShaderDefineReplacer::replaceMaterialDependentDefine(Shader &shader, const Material &material, InstanceType model_shader) { + shader.replaceKey(DEFINE_NAMES.at(Define::MaterialDependent), getMaterialDependentDefine(material, model_shader)); + + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Vertex], material.getVertexSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Tesselation], material.getTessellationSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Fragment], material.getFragmentSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Global], material.getGlobalSnippet()); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomScalar], getScalarUniformDefines(material)); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomSamplers], getSamplerUniformDefines(material)); +} + +std::string MaterialShaderDefineReplacer::getScalarUniformDefines(const Material &material) { + std::string uniforms; + for (const auto& [name, uniform] : material.getUniforms()) { + if (uniform->getType() == UniformType::Value || uniform->getType() == UniformType::Time) { + auto decl = getUniformDeclaration(*uniform); + decl.erase(decl.find("uniform"), 7); + uniforms.append(decl); + } + } + return uniforms; +} + +std::string MaterialShaderDefineReplacer::getSamplerUniformDefines(const Material &material) { + std::string uniforms; + for (const auto& [name, uniform] : material.getUniforms()) { + if (uniform->getType() == UniformType::Sampler) { + uniforms.append(getUniformDeclaration(*uniform)); + } + } + return uniforms; +} + +std::string MaterialShaderDefineReplacer::getMaterialDefines(const Material &material) { + std::string define = getPropertyDefines(material); + define.append(getShadingDefines(material)); + return define; +} + +std::string MaterialShaderDefineReplacer::getMaterialDependentDefine(const Material &material, InstanceType model_shader) { + std::string define = getMaterialDefines(material); + define.append(getModelDefines(model_shader)); + return define; +} diff --git a/src/limitless/ms/material_shader_definer.cpp b/src/limitless/ms/material_shader_definer.cpp deleted file mode 100644 index 7d9cd068..00000000 --- a/src/limitless/ms/material_shader_definer.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include - -#include -#include -#include - -using namespace Limitless::ms; - -std::string MaterialShaderDefiner::getPropertyDefines(const Material& material) { - std::string defines; - - for (const auto& [property, _] : material.getProperties()) { - defines.append(SHADER_PROPERTY_DEFINE[property]); - } - - if (material.getRefraction()) { - defines.append("#define ENGINE_MATERIAL_REFRACTION\n"); - } -} - -std::string MaterialShaderDefiner::getShadingDefines(const Material& material) { - return SHADER_SHADING_DEFINE[material.getShading()]; -} - -std::string MaterialShaderDefiner::getModelDefines(InstanceType model_shader) { - return SHADER_MODEL_DEFINE[model_shader]; -} - -void MaterialShaderDefiner::define(Shader &shader, const Material &material, InstanceType model_shader) { - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::MaterialType], getMaterialDefines(material)); - shader.replaceKey(ENGINE_SHADER_DEFINE_NAMES[EngineShaderDefine::ModelType], getModelDefines(model_shader)); - shader.replaceKey("Limitless::EmitterType", ""); - - shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Vertex], material.getVertexSnippet()); - shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Tesselation], material.getTessellationSnippet()); - shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Fragment], material.getFragmentSnippet()); - shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::Global], material.getGlobalSnippet()); - shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::CustomScalar], getScalarUniformDefines(material)); - shader.replaceKey(SHADER_SNIPPET_DEFINE[SnippetDefineType::CustomSamplers], getSamplerUniformDefines(material)); -} - -std::string MaterialShaderDefiner::getScalarUniformDefines(const Material &material) { - std::string uniforms; - for (const auto& [name, uniform] : material.getUniforms()) { - if (uniform->getType() == UniformType::Value || uniform->getType() == UniformType::Time) { - auto decl = getUniformDeclaration(*uniform); - decl.erase(decl.find("uniform"), 7); - uniforms.append(decl); - } - } - return uniforms; -} - -std::string MaterialShaderDefiner::getSamplerUniformDefines(const Material &material) { - std::string uniforms; - for (const auto& [name, uniform] : material.getUniforms()) { - if (uniform->getType() == UniformType::Sampler) { - uniforms.append(getUniformDeclaration(*uniform)); - } - } - return uniforms; -} - -std::string MaterialShaderDefiner::getMaterialDefines(const Material &material) { - std::string defines = getPropertyDefines(material); - defines.append(getShadingDefines(material)); - return defines; -} diff --git a/src/limitless/pipeline/common/render_debug_pass.cpp b/src/limitless/pipeline/common/render_debug_pass.cpp index 0cf864e7..1d812656 100644 --- a/src/limitless/pipeline/common/render_debug_pass.cpp +++ b/src/limitless/pipeline/common/render_debug_pass.cpp @@ -10,18 +10,18 @@ #include using namespace Limitless; -//RenderDebugPass::RenderDebugPass(Pipeline& pipeline, const RenderSettings& settings) -// : PipelinePass(pipeline) -// , helper {settings} { -//} -// -//void RenderDebugPass::draw(Instances& instances, Context& ctx, const Assets& assets, const Camera& camera, [[maybe_unused]] UniformSetter& setter) { -// if (lighting) { -// helper.render(ctx, assets, camera, *lighting, instances); -// } -//} -// -//void RenderDebugPass::update(Scene& scene, [[maybe_unused]] Instances& instances, [[maybe_unused]] Context& ctx, [[maybe_unused]] const Camera& camera) { -// lighting = &scene.lighting; -//} +RenderDebugPass::RenderDebugPass(Pipeline& pipeline, const RenderSettings& settings) + : PipelinePass(pipeline) + , helper {settings} { +} + +void RenderDebugPass::draw(Instances& instances, Context& ctx, const Assets& assets, const Camera& camera, [[maybe_unused]] UniformSetter& setter) { + if (lighting) { + helper.render(ctx, assets, camera, *lighting, instances); + } +} + +void RenderDebugPass::update(Scene& scene, [[maybe_unused]] Instances& instances, [[maybe_unused]] Context& ctx, [[maybe_unused]] const Camera& camera) { + lighting = &scene.lighting; +} diff --git a/src/limitless/pipeline/deferred/deferred.cpp b/src/limitless/pipeline/deferred/deferred.cpp index dce75dd1..97be3a20 100644 --- a/src/limitless/pipeline/deferred/deferred.cpp +++ b/src/limitless/pipeline/deferred/deferred.cpp @@ -80,7 +80,9 @@ void Deferred::build(ContextEventObserver& ctx, const RenderSettings& settings) add(ctx, size); } - add(ctx, size); + if (settings.screen_space_reflections) { + add(ctx, size); + } /* * Makes lighting calculations (with AO) from GBUFFER and renders result in another framebuffer @@ -117,4 +119,6 @@ void Deferred::build(ContextEventObserver& ctx, const RenderSettings& settings) // } add(*target); + + add(settings); } diff --git a/src/limitless/pipeline/deferred/deferred_lighting_pass.cpp b/src/limitless/pipeline/deferred/deferred_lighting_pass.cpp index c8f58fa6..30f8c22e 100644 --- a/src/limitless/pipeline/deferred/deferred_lighting_pass.cpp +++ b/src/limitless/pipeline/deferred/deferred_lighting_pass.cpp @@ -30,11 +30,11 @@ void DeferredLightingPass::draw([[maybe_unused]] Instances& instances, Context& auto& shader = assets.shaders.get("deferred"); - shader .setUniform("base_texture", gbuffer.getAlbedo()) - .setUniform("normal_texture", gbuffer.getNormal()) - .setUniform("props_texture", gbuffer.getProperties()) - .setUniform("depth_texture", gbuffer.getDepth()) - .setUniform("emissive_texture", gbuffer.getEmissive()); + shader .setUniform("_base_texture", gbuffer.getAlbedo()) + .setUniform("_normal_texture", gbuffer.getNormal()) + .setUniform("_props_texture", gbuffer.getProperties()) + .setUniform("_depth_texture", gbuffer.getDepth()) + .setUniform("_emissive_texture", gbuffer.getEmissive()); setter(shader); diff --git a/src/limitless/pipeline/deferred/translucent_pass.cpp b/src/limitless/pipeline/deferred/translucent_pass.cpp index c0b02ea0..4517d5d8 100644 --- a/src/limitless/pipeline/deferred/translucent_pass.cpp +++ b/src/limitless/pipeline/deferred/translucent_pass.cpp @@ -49,7 +49,7 @@ void TranslucentPass::draw(Instances& instances, Context& ctx, const Assets& ass framebuffer.blit(background_fb, Texture::Filter::Nearest); setter.add([&] (ShaderProgram& shader) { - shader.setUniform("refraction_texture", getPreviousResult()); + shader.setUniform("_refraction_texture", getPreviousResult()); }); for (const auto& blending : transparent) { diff --git a/src/limitless/renderer/render_settings_shader_definer.cpp b/src/limitless/renderer/render_settings_shader_definer.cpp index 33c6a4f5..ca3a3953 100644 --- a/src/limitless/renderer/render_settings_shader_definer.cpp +++ b/src/limitless/renderer/render_settings_shader_definer.cpp @@ -1,16 +1,11 @@ #include #include #include -#include +#include using namespace Limitless; -RenderSettingsShaderDefiner::RenderSettingsShaderDefiner(const RenderSettings& settings) noexcept - : settings {settings} { - -} - -std::string RenderSettingsShaderDefiner::define() { +std::string RenderSettingsShaderDefiner::getDefine(const RenderSettings &settings) { std::string s; if (settings.normal_mapping) { @@ -23,7 +18,7 @@ std::string RenderSettingsShaderDefiner::define() { s.append("#define ENGINE_SETTINGS_CSM_SPLIT_COUNT " + std::to_string(settings.csm_split_count) + '\n'); if (settings.csm_pcf) { - s.append("#define ENGINE_SETTINGS_PFC\n"); + s.append("#define ENGINE_SETTINGS_PCF\n"); } } @@ -67,5 +62,11 @@ std::string RenderSettingsShaderDefiner::define() { s.append("#define ENGINE_SETTINGS_MICRO_SHADOWING\n"); } + if (settings.specular_aa) { + s.append("#define ENGINE_SETTINGS_SPECULAR_AA\n"); + s.append("#define ENGINE_SETTINGS_SPECULAR_AA_THRESHOLD " + std::to_string(settings.specular_aa_threshold) + '\n'); + s.append("#define ENGINE_SETTINGS_SPECULAR_AA_VARIANCE " + std::to_string(settings.specular_aa_variance) + '\n'); + } + return s; } diff --git a/src/limitless/shader_storage.cpp b/src/limitless/shader_storage.cpp index 51a2f3a1..c9aaaff2 100644 --- a/src/limitless/shader_storage.cpp +++ b/src/limitless/shader_storage.cpp @@ -104,12 +104,18 @@ void ShaderStorage::add(const fx::UniqueEmitterShaderKey& emitter_type, std::sha void ShaderStorage::initialize(Context& ctx, const RenderSettings& settings, const fs::path& shader_dir) { ShaderCompiler compiler {ctx, settings}; + + if (settings.bloom) { + add("blur_downsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_downsample")); + add("blur_upsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_upsample")); + add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); + } + //TODO: check - if (settings.pipeline == RenderPipeline::Forward) { +// if (settings.pipeline == RenderPipeline::Forward) { // add("blur", compiler.compile(shader_dir / "postprocessing/blur")); -// add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); // add("postprocess", compiler.compile(shader_dir / "postprocessing/postprocess")); - } +// } if (settings.pipeline == RenderPipeline::Deferred) { add("deferred", compiler.compile(shader_dir / "pipeline/deferred")); @@ -117,9 +123,7 @@ void ShaderStorage::initialize(Context& ctx, const RenderSettings& settings, con // add("ssao", compiler.compile(shader_dir / "postprocessing/ssao/ssao")); // add("ssao_blur", compiler.compile(shader_dir / "postprocessing/ssao/ssao_blur")); -// add("blur_downsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_downsample")); -// add("blur_upsample", compiler.compile(shader_dir / "postprocessing/bloom/blur_upsample")); -// add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); +// } if (settings.fast_approximate_antialiasing) { @@ -130,9 +134,10 @@ void ShaderStorage::initialize(Context& ctx, const RenderSettings& settings, con add("dof", compiler.compile(shader_dir / "postprocessing/dof")); } - add("ssr", compiler.compile(shader_dir / "postprocessing/ssr/ssr")); +// add("ssr", compiler.compile(shader_dir / "postprocessing/ssr/ssr")); add("quad", compiler.compile(shader_dir / "pipeline/quad")); + add("text", compiler.compile(shader_dir / "text/text")); add("text_selection", compiler.compile(shader_dir / "text/text_selection")); } diff --git a/src/limitless/skybox/skybox.cpp b/src/limitless/skybox/skybox.cpp index acefe12a..6073eb2d 100644 --- a/src/limitless/skybox/skybox.cpp +++ b/src/limitless/skybox/skybox.cpp @@ -21,7 +21,7 @@ Skybox::Skybox(Assets& assets, const fs::path& path, const TextureLoaderFlags& f material = material_builder .setName(path.stem().string()) .addUniform(std::make_unique("skybox", cube_map_texture)) - .setFragmentSnippet("data.color.rgb = texture(skybox, skybox_uv).rgb;\n") + .setFragmentSnippet("mctx.color.rgb = texture(skybox, skybox_uv).rgb;\n") .add(Property::Color, glm::vec4(1.0f)) .setTwoSided(true) .setShading(Shading::Unlit) diff --git a/src/limitless/util/renderer_helper.cpp b/src/limitless/util/renderer_helper.cpp index 43d75417..43b868d3 100644 --- a/src/limitless/util/renderer_helper.cpp +++ b/src/limitless/util/renderer_helper.cpp @@ -21,38 +21,41 @@ RendererHelper::RendererHelper(const RenderSettings& _settings) } void RendererHelper::renderLightsVolume(Context& context, const Lighting& lighting, const Assets& assets, const Camera& camera) { - if (lighting.point_lights.empty() && lighting.spot_lights.empty()) { + if (lighting.lights.empty()) { return; } context.enable(Capabilities::DepthTest); context.setDepthFunc(DepthFunc::Less); context.setDepthMask(DepthMask::False); - context.disable(Capabilities::DepthTest); +// context.disable(Capabilities::DepthTest); auto sphere_instance = ModelInstance(assets.models.at("sphere"), assets.materials.at("default"), glm::vec3(0.0f)); context.setPolygonMode(CullFace::FrontBack, PolygonMode::Line); - for (const auto& light : lighting.point_lights) { - sphere_instance.setPosition(light.position); - sphere_instance.setScale(glm::vec3(light.radius)); - sphere_instance.update(context, camera); - sphere_instance.draw(context, assets, ShaderType::Forward, ms::Blending::Opaque); - } + for (const auto& light : lighting.lights) { + if (light.type == 1u) { + sphere_instance.setPosition(light.position); + sphere_instance.setScale(glm::vec3(light.getRadius())); + sphere_instance.update(context, camera); + sphere_instance.draw(context, assets, ShaderType::Forward, ms::Blending::Opaque); + } + if (light.type == 2u) { + auto cone = std::make_shared(0.0f, light.getRadius() * std::sin(glm::acos(light.scale_offset.x)), light.getRadius()); + auto cone_instance = ModelInstance(cone, assets.materials.at("default"), glm::vec3(0.0f)); + + cone_instance.setPosition(light.position); - for (const auto& light : lighting.spot_lights) { - auto cone = std::make_shared(0.0f, light.radius * std::sin(glm::acos(light.cutoff)), light.radius); - auto cone_instance = ModelInstance(cone, assets.materials.at("default"), glm::vec3(0.0f)); + auto y = glm::vec3{0.0f, 1.0f, 0.0f}; + auto a = glm::cross(y, glm::vec3{light.direction}); + auto angle = glm::acos(glm::dot(y, glm::vec3{light.direction})); - cone_instance.setPosition(light.position); + cone_instance.setRotation(a * angle); + cone_instance.update(context, camera); + cone_instance.draw(context, assets, ShaderType::Forward, ms::Blending::Opaque); + } - auto y = glm::vec3{0.0f, 1.0f, 0.0f}; - auto a = glm::cross(y, glm::vec3{light.direction}); - auto angle = glm::acos(glm::dot(y, glm::vec3{light.direction})); - cone_instance.setRotation(a * angle); - cone_instance.update(context, camera); - cone_instance.draw(context, assets, ShaderType::Forward, ms::Blending::Opaque); } context.setPolygonMode(CullFace::FrontBack, PolygonMode::Fill); @@ -68,7 +71,7 @@ void RendererHelper::renderCoordinateSystemAxes(Context& context, const Assets& static const auto x = std::make_shared(glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{1.0f, 0.0f, 0.0f}); static const auto y = std::make_shared(glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{0.0f, 1.0f, 0.0f}); - static const auto z = std::make_shared(glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{0.0f, 0.0f, 1.0f}); + static const auto z = std::make_shared(glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{0.0f, 0.0f, -5.0f}); static ModelInstance x_i {x, assets.materials.at("green"), {5.0f, 1.0f, 0.0f}}; static ModelInstance y_i {y, assets.materials.at("blue"), {5.0f, 1.0f, 0.0f}}; diff --git a/src/limitless/util/stack_trace.cpp b/src/limitless/util/stack_trace.cpp new file mode 100644 index 00000000..77424c63 --- /dev/null +++ b/src/limitless/util/stack_trace.cpp @@ -0,0 +1,147 @@ +#include + +#define WIN32_LEAN_AND_MEAN +#ifndef NOMINMAX +#define NOMINMAX +#endif +#define NOKERNEL +#define NOUSER +#define NOSERVICE +#define NOSOUND +#define NOMCX +#define NOGDI +#define NOMSG +#define NOMB +#define NOCLIPBOARD + +#include + +#include +#include +#include + +#ifdef __MINGW32__ +#include +#include + +class FreeDeleter { +public: + void operator()(void* ptr) { + free(ptr); + } +}; + +static std::string demangle(const std::string& mangled_func_name) { + int status {-1}; + std::unique_ptr demangled_cstr {abi::__cxa_demangle(mangled_func_name.c_str(), nullptr, nullptr, &status)}; + + if (status == 0) { + return std::string(demangled_cstr.get()); + } + + return mangled_func_name; +} + +#endif + +#if __clang__ +static std::string demangle(const std::string& mangled_func_name) { + // TODO: not supported yet + return mangled_func_name; +} +#endif + +using namespace Limitless; + +class SymbolHelper { +public: + static SymbolHelper& getInstance() { + static SymbolHelper instance; + return instance; + } + + bool isInited() const noexcept { return inited; } + HANDLE getProcess() const noexcept { return process; } +private: + bool inited {false}; + HANDLE process; + + SymbolHelper() { + process = GetCurrentProcess(); + DWORD flags = SymGetOptions(); + SymSetOptions(flags | SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME); + inited = SymInitialize(process, nullptr, TRUE); + } + + ~SymbolHelper() { + if (inited) { + SymCleanup(process); + } + } +}; + +static std::string getModuleBaseName(void* addr) { + HMODULE h_module; + const int max_name_len = 256; + char module[max_name_len]; + strcpy(module, ""); + + GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)addr, + &h_module + ); + + if (h_module != nullptr) { + GetModuleFileNameA(h_module, module, max_name_len); + } + + char* last_slash_pos = strrchr(module, '\\'); + if (last_slash_pos) { + return std::string{last_slash_pos + 1}; + } else { + return std::string{module}; + } +} + +StackTrace Limitless::getStackTrace(size_t frames_to_skip, size_t max_frames) { + StackTrace result; + ++frames_to_skip; + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; + auto* p_symbol = reinterpret_cast(buffer); + + std::unique_ptr back_trace(new void*[max_frames]); + + const USHORT frame_num = CaptureStackBackTrace( + static_cast(frames_to_skip), + static_cast(max_frames), + back_trace.get(), + nullptr + ); + + auto& sym = SymbolHelper::getInstance(); + + for (USHORT i = 0; i < frame_num; ++i) { + DWORD64 displacement; + DWORD disp; + bool has_symbol {false}; + // bool has_line {false}; + + if (sym.isInited()) { + p_symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + p_symbol->MaxNameLen = MAX_SYM_NAME; + has_symbol = SymFromAddr(sym.getProcess(), (ULONG64)back_trace[i], &displacement, p_symbol); + + // auto line = std::make_unique(); + // line->SizeOfStruct = sizeof(IMAGEHLP_LINE64); + // has_line = SymGetLineFromAddr64(sym.getProcess(), (ULONG64)back_trace[i], &disp, line.get()); + } + + auto module_name = getModuleBaseName(back_trace[i]); + + result.emplace_back(StackFrame{module_name, demangle(std::string{has_symbol ? p_symbol->Name : ""}), std::to_string(p_symbol->Address)}); + } + + return result; +} \ No newline at end of file From 5d98202adc946603f054f65719aec2993d531e80 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Thu, 23 Nov 2023 01:00:06 +0300 Subject: [PATCH 07/15] ref --- demo/effects_demoscene.cpp | 2 + .../limitless/lighting/cascade_shadows.hpp | 6 +- .../limitless/lighting/light_container.hpp | 7 +- include/limitless/lighting/lighting.hpp | 16 +- include/limitless/lighting/lights.hpp | 154 +++++++++++++++--- shaders_ref/lighting/lighting_context.glsl | 2 +- src/limitless/lighting/cascade_shadows.cpp | 6 +- src/limitless/lighting/light_container.cpp | 2 - src/limitless/lighting/lighting.cpp | 3 +- 9 files changed, 155 insertions(+), 43 deletions(-) diff --git a/demo/effects_demoscene.cpp b/demo/effects_demoscene.cpp index 6baa0b08..b319a440 100644 --- a/demo/effects_demoscene.cpp +++ b/demo/effects_demoscene.cpp @@ -45,6 +45,8 @@ EffectsScene::EffectsScene(Limitless::Context& ctx, Limitless::Assets& assets) : Limitless::Scene(ctx) { addInstances(assets); + + setSkybox(assets.skyboxes.at("skybox")); lighting.ambient_color *= 0.5; lighting.directional_light = {glm::vec4(2.0, -2.0, 1.5, 1.0f), glm::vec4{1.0f}}; diff --git a/include/limitless/lighting/cascade_shadows.hpp b/include/limitless/lighting/cascade_shadows.hpp index 47c72fb9..d49738a0 100644 --- a/include/limitless/lighting/cascade_shadows.hpp +++ b/include/limitless/lighting/cascade_shadows.hpp @@ -8,7 +8,7 @@ namespace Limitless::fx { } namespace Limitless { - struct DirectionalLight; + class Light; class AbstractInstance; class ShaderProgram; class Renderer; @@ -44,7 +44,7 @@ namespace Limitless { void initBuffers(Context& context); void updateFrustums(Context& ctx, const Camera& camera); - void updateLightMatrices(const DirectionalLight& light); + void updateLightMatrices(const Light& light); public: explicit CascadeShadows(Context& context, const RenderSettings& settings); ~CascadeShadows(); @@ -52,7 +52,7 @@ namespace Limitless { void update(Context& ctx, const RenderSettings& settings); void draw(Instances& instances, - const DirectionalLight& light, + const Light& light, Context& ctx, const Assets& assets, const Camera& camera, diff --git a/include/limitless/lighting/light_container.hpp b/include/limitless/lighting/light_container.hpp index 6c59031a..a7f062f6 100644 --- a/include/limitless/lighting/light_container.hpp +++ b/include/limitless/lighting/light_container.hpp @@ -7,16 +7,11 @@ namespace Limitless { class Buffer; - template class LightContainer { - /** - * requirement for shader buffer object name in type T - **/ - static_assert(sizeof(T::SHADER_STORAGE_NAME), "value_type must implement static shader_storage_name variable"); private: std::unordered_map lights_map; std::shared_ptr buffer; - std::vector lights; + std::vector lights; uint64_t next_id {}; bool modified {}; public: diff --git a/include/limitless/lighting/lighting.hpp b/include/limitless/lighting/lighting.hpp index 3db05811..4db6b9c2 100644 --- a/include/limitless/lighting/lighting.hpp +++ b/include/limitless/lighting/lighting.hpp @@ -11,18 +11,22 @@ namespace Limitless { std::shared_ptr buffer; Context& context; + Light directional_light; + LightContainer lights; + void createLightBuffer(); void updateLightBuffer(); public: - // ambient lighting - glm::vec4 ambient_color {1.0f, 1.0f, 1.0f, 1.0f}; + explicit Lighting(Context& ctx); - // global lighting - DirectionalLight directional_light; + Lighting& addLight(const Light& light) { + lights. + } - LightContainer lights; - explicit Lighting(Context& ctx); + // ambient lighting + glm::vec4 ambient_color {1.0f, 1.0f, 1.0f, 1.0f}; + ~Lighting() = default; Lighting(const Lighting&) = delete; diff --git a/include/limitless/lighting/lights.hpp b/include/limitless/lighting/lights.hpp index 89883213..832b8383 100644 --- a/include/limitless/lighting/lights.hpp +++ b/include/limitless/lighting/lights.hpp @@ -1,42 +1,154 @@ #pragma once #include +#include namespace Limitless { - struct DirectionalLight final { - glm::vec4 direction {}; - glm::vec4 color {}; - - DirectionalLight() = default; - ~DirectionalLight() = default; - - DirectionalLight(const glm::vec4& _direction, const glm::vec4& _color) noexcept - : direction {_direction} - , color {_color} { - } + class light_builder_exception final : public std::runtime_error { + public: + using std::runtime_error::runtime_error; }; - struct Light final { + class Light final { + public: static constexpr auto SHADER_STORAGE_NAME = "LIGHTS_BUFFER"; + enum class Type : uint32_t { + DirectionalLight, + Point, + Spot + }; + private: glm::vec4 color {}; glm::vec4 position {}; glm::vec4 direction {}; glm::vec2 scale_offset {}; float falloff {}; - uint32_t type {1u}; + Type type {1u}; + + static float radiusToFalloff(float r) { + return 1.0f / (r * r); + } + + static float falloffToRadius(float f) { + return glm::sqrt(1.0f / f); + } + + static glm::vec2 anglesToScaleOffset(float inner_angle, float outer_angle) { + const auto inner = glm::radians(inner_angle); + const auto outer = glm::radians(outer_angle); + + const auto inner_cos = glm::cos(inner); + const auto outer_cos = glm::cos(outer); + const auto scale = 1.0f / glm::max(1.0f / 1024.0f, inner_cos - outer_cos); + const auto offset = -outer_cos * scale; + + return { scale, offset }; + } + + static glm::vec2 scaleOffsetToAngles(const glm::vec2& scale_offset) { + const auto outer_cos = -scale_offset.y / scale_offset.x; + const auto inner_cos = 1.0f / (scale_offset.x + 1.0f / 1024.0f); + + const auto outer_angle = glm::degrees(glm::acos(outer_cos)); + const auto inner_angle = glm::degrees(glm::acos(inner_cos)); + + return { inner_angle, outer_angle }; + } - Light() = default; - ~Light() = default; + Light(const glm::vec4& color, const glm::vec3& position, float radius) noexcept + : color {color} + , position {position, 0.0f} + , direction {} + , scale_offset {} + , falloff {radiusToFalloff(radius)} + , type {Type::Point} { + } - auto getRadius() const { - return sqrt(1.0 / falloff); + Light(const glm::vec4& color, const glm::vec3& position, const glm::vec3& direction, float inner_angle, float outer_angle, float radius) noexcept + : color {color} + , position {position, 0.0f} + , direction {direction, 0.0f} + , scale_offset {anglesToScaleOffset(inner_angle, outer_angle)} + , falloff {radiusToFalloff(radius)} + , type {Type::Spot} { } - Light(const glm::vec3& position, const glm::vec4& _color, const float radius) noexcept - : position {position, 1.0} - , color {_color} - , falloff {1.0f / (radius * radius)} { + Light(const glm::vec4& color, const glm::vec3& direction) noexcept + : color {color} + , position {} + , direction {direction, 0.0f} + , scale_offset {} + , falloff {} + , type {Type::DirectionalLight} { } + public: + [[nodiscard]] const glm::vec4& getColor() const noexcept { return color; } + void setColor(const glm::vec4& _color) noexcept { color = _color; } + + [[nodiscard]] glm::vec3 getPosition() const noexcept { return position; } + void setPosition(const glm::vec3& _position) noexcept { position = glm::vec4(_position, 0.0f); } + + [[nodiscard]] glm::vec3 getDirection() const noexcept { return direction; } + void setDirection(const glm::vec3& _direction) noexcept { direction = glm::vec4(_direction, 0.0f); } + + [[nodiscard]] glm::vec2 getCone() const noexcept { return scaleOffsetToAngles(scale_offset); } + void setCone(float inner_angle, float outer_angle) noexcept { scale_offset = anglesToScaleOffset(inner_angle, outer_angle); } + + [[nodiscard]] float getRadius() const noexcept { return glm::sqrt(1.0f / falloff); } + void setRadius(float _radius) noexcept { falloff = 1.0f / (_radius * _radius); } + + [[nodiscard]] Type getType() const noexcept { return type; } + + class Builder { + private: + glm::vec4 color_ {0.0f}; + glm::vec3 position_ {0.0f}; + float outer_angle_ {0.0f}; + float inner_angle_ {0.0f}; + glm::vec3 direction_ {0.0f}; + float radius_ {0.0f}; + + bool isSpot() { + return color_ != glm::vec4(0.0f) && position_ != glm::vec3(0.0) && inner_angle_ != 0.0f && outer_angle_ != 0.0f && direction_ != glm::vec3(0.0f) && radius_ != 0.0f; + } + + bool isPoint() { + return color_ != glm::vec4(0.0f) && position_ != glm::vec3(0.0) && radius_ != 0.0f; + } + + bool isDirectional() { + return color_ != glm::vec4(0.0f) && direction_ != glm::vec3(0.0f); + } + public: + Builder& color(const glm::vec4& _color) { color_ = _color; return *this; } + Builder& position(const glm::vec3& _position) { position_ = _position; return *this; } + Builder& direction(const glm::vec3& _direction) { direction_ = _direction; return *this; } + Builder& cone(float outer_angle, float inner_angle) { outer_angle_ = outer_angle; inner_angle_ = inner_angle; return *this; } + Builder& radius(float _radius) { radius_ = _radius; return *this; } + + Light build() { + if (isSpot()) { + if (inner_angle_ < 0.00872665f || inner_angle_ > 90.0f || outer_angle_ < inner_angle_ || outer_angle_ > 90.0f) { + throw light_builder_exception {"Inner/Outer angles are out of range!"}; + } + return {color_, position_, direction_, inner_angle_, outer_angle_, radius_}; + } + + if (isPoint()) { + return {color_, position_, radius_}; + } + + if (isDirectional()) { + return {color_, direction_}; + } + + throw light_builder_exception {"Required parameters are not set!"}; + } + + static Builder builder() { + return {}; + } + }; }; } diff --git a/shaders_ref/lighting/lighting_context.glsl b/shaders_ref/lighting/lighting_context.glsl index 3f5357f8..874ebb41 100644 --- a/shaders_ref/lighting/lighting_context.glsl +++ b/shaders_ref/lighting/lighting_context.glsl @@ -31,7 +31,7 @@ float getAttenuation(const ShadingContext sctx, const Light light) { if (light.type == LIGHT_TYPE_SPOT) { float cd = dot(-light.direction.xyz, L); float att = saturate(cd * light.scale_offset.x + light.scale_offset.y); - float att2 = att * att; + float att2 = att * att; attenuation *= att2; } diff --git a/src/limitless/lighting/cascade_shadows.cpp b/src/limitless/lighting/cascade_shadows.cpp index 94827c38..a074febb 100644 --- a/src/limitless/lighting/cascade_shadows.cpp +++ b/src/limitless/lighting/cascade_shadows.cpp @@ -126,11 +126,11 @@ void CascadeShadows::updateFrustums(Context& ctx, const Camera& camera) { } } -void CascadeShadows::updateLightMatrices(const DirectionalLight& light) { +void CascadeShadows::updateLightMatrices(const Light& light) { // clear matrices light_space.clear(); - const auto view = glm::lookAt(-glm::vec3(light.direction), { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }); + const auto view = glm::lookAt(-light.getDirection(), { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }); for (auto& frustum : frustums) { glm::vec3 max = {std::numeric_limits::min(), std::numeric_limits::min(), 0.0f}; glm::vec3 min = {std::numeric_limits::max(), std::numeric_limits::max(), 0.0f}; @@ -179,7 +179,7 @@ void CascadeShadows::updateLightMatrices(const DirectionalLight& light) { } void CascadeShadows::draw(Instances& instances, - const DirectionalLight& light, + const Light& light, Context& ctx, const Assets& assets, const Camera& camera, diff --git a/src/limitless/lighting/light_container.cpp b/src/limitless/lighting/light_container.cpp index 8967245a..4c34c547 100644 --- a/src/limitless/lighting/light_container.cpp +++ b/src/limitless/lighting/light_container.cpp @@ -58,7 +58,5 @@ void LightContainer::update() { } namespace Limitless { - template class LightContainer; - template class LightContainer; template class LightContainer; } diff --git a/src/limitless/lighting/lighting.cpp b/src/limitless/lighting/lighting.cpp index aadb46f4..e84d160b 100644 --- a/src/limitless/lighting/lighting.cpp +++ b/src/limitless/lighting/lighting.cpp @@ -7,7 +7,8 @@ using namespace Limitless; namespace { struct SceneLighting { - DirectionalLight directional_light {}; + glm::vec4 direction; + glm::vec4 color; glm::vec4 ambient_color {}; uint32_t light_count {}; }; From bfe7140079d50985e312845aa13097d2717af612 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Fri, 24 Nov 2023 13:01:03 +0300 Subject: [PATCH 08/15] ref --- CMakeLists.txt | 4 +- demo/demo.cpp | 2 +- demo/effects_demoscene.cpp | 10 +- demo/lighting_demoscene.cpp | 39 ++- demo/materials_demoscene.cpp | 36 ++- demo/models_demoscene.cpp | 10 +- demo/sponza_demoscene.cpp | 6 +- docs/materials.md | 6 + docs/shaders.md | 0 .../limitless/core/uniform/uniform_value.hpp | 4 +- include/limitless/lighting/light.hpp | 101 +++++++ .../limitless/lighting/light_container.hpp | 84 +++--- include/limitless/lighting/lighting.hpp | 78 +++-- include/limitless/lighting/lights.hpp | 154 ---------- include/limitless/ms/blending.hpp | 19 +- include/limitless/ms/colors.hpp | 8 - include/limitless/ms/material.hpp | 124 +++----- include/limitless/ms/material_buffer.hpp | 44 +++ include/limitless/ms/material_builder.hpp | 37 ++- .../ms/material_shader_define_replacer.hpp | 14 +- include/limitless/ms/property.hpp | 165 +++++++++-- include/limitless/ms/shading.hpp | 15 +- .../limitless/pipeline/common/shadow_pass.hpp | 2 +- shaders_ref/material/material.glsl | 50 +++- shaders_ref/material/material_context.glsl | 12 +- shaders_ref/shading/custom.glsl | 2 +- src/limitless/core/uniform/uniform_value.cpp | 6 + src/limitless/lighting/cascade_shadows.cpp | 2 +- src/limitless/lighting/light.cpp | 267 ++++++++++++++++++ src/limitless/lighting/light_container.cpp | 121 +++++--- src/limitless/lighting/lighting.cpp | 115 ++++++-- src/limitless/ms/blending.cpp | 84 +++--- src/limitless/ms/material.cpp | 217 ++++---------- src/limitless/ms/material_buffer.cpp | 88 ++++++ src/limitless/ms/material_instance.cpp | 11 +- .../ms/material_shader_define_replacer.cpp | 6 +- src/limitless/pipeline/common/shadow_pass.cpp | 2 +- src/limitless/util/renderer_helper.cpp | 18 +- 38 files changed, 1256 insertions(+), 707 deletions(-) create mode 100644 docs/materials.md create mode 100644 docs/shaders.md create mode 100644 include/limitless/lighting/light.hpp delete mode 100644 include/limitless/lighting/lights.hpp delete mode 100644 include/limitless/ms/colors.hpp create mode 100644 include/limitless/ms/material_buffer.hpp create mode 100644 src/limitless/lighting/light.cpp create mode 100644 src/limitless/ms/material_buffer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fd22984..6c63fa6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,7 @@ set(ENGINE_LIGHTING src/limitless/lighting/lighting.cpp src/limitless/lighting/light_container.cpp src/limitless/lighting/cascade_shadows.cpp + src/limitless/lighting/light.cpp ) set(ENGINE_LOADERS @@ -178,7 +179,8 @@ set(ENGINE_MS src/limitless/ms/material_builder.cpp src/limitless/ms/material_compiler.cpp src/limitless/ms/material_instance.cpp - src/limitless/ms/material_shader_define_replacer.cpp + src/limitless/ms/material_buffer.cpp + src/limitless/ms/material_shader_define_replacer.cpp ) set(ENGINE_TEXT diff --git a/demo/demo.cpp b/demo/demo.cpp index 3817eda7..0ee79702 100644 --- a/demo/demo.cpp +++ b/demo/demo.cpp @@ -195,7 +195,7 @@ class Game : public MouseMoveObserver, public KeyObserver, public FramebufferObs }; int main() { - std::set_terminate(terminationHandler); +// std::set_terminate(terminationHandler); Game game; game.gameLoop(); return 0; diff --git a/demo/effects_demoscene.cpp b/demo/effects_demoscene.cpp index b319a440..da430669 100644 --- a/demo/effects_demoscene.cpp +++ b/demo/effects_demoscene.cpp @@ -45,11 +45,15 @@ EffectsScene::EffectsScene(Limitless::Context& ctx, Limitless::Assets& assets) : Limitless::Scene(ctx) { addInstances(assets); + setSkybox(assets.skyboxes.at("skybox")); + lighting.getAmbientColor().a *= 0.5; - setSkybox(assets.skyboxes.at("skybox")); - lighting.ambient_color *= 0.5; - lighting.directional_light = {glm::vec4(2.0, -2.0, 1.5, 1.0f), glm::vec4{1.0f}}; + lighting.add(Light::builder() + .color({2.0, -2.0, 1.5, 1.0f}) + .direction(glm::vec3{-1.0f}) + .build() + ); auto& floor = add>(glm::vec3{0.0f}); for (int i = 0; i < 30; ++i) { diff --git a/demo/lighting_demoscene.cpp b/demo/lighting_demoscene.cpp index db65bbad..9566e84f 100644 --- a/demo/lighting_demoscene.cpp +++ b/demo/lighting_demoscene.cpp @@ -5,6 +5,7 @@ #include using namespace LimitlessDemo; +using namespace Limitless; void LightingScene::addFloor(const Limitless::Assets& assets) { using namespace Limitless; @@ -53,10 +54,11 @@ bool LightingScene::isInsideFloor(const glm::vec3& position) { void LightingScene::addLights() { for (int i = 0; i < LIGHT_COUNT; ++i) { - lighting.lights.emplace_back( - glm::vec4{FLOOR_INSTANCE_COUNT / 4.0f, 1.0f, FLOOR_INSTANCE_COUNT / 4.0f, 1.0f}, - glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}, - 2.0f + lighting.add(Light::builder() + .position({FLOOR_INSTANCE_COUNT / 4.0f, 1.0f, FLOOR_INSTANCE_COUNT / 4.0f}) + .color({1.0f, 1.0f, 1.0f, 1.0f}) + .radius(2.0f) + .build() ); } } @@ -69,8 +71,19 @@ LightingScene::LightingScene(Limitless::Context& ctx, const Limitless::Assets& a setSkybox(assets.skyboxes.at("skybox")); - lighting.ambient_color.a = 0.5f; - lighting.directional_light = {glm::vec4(1.0, -1.0, 0.5, 1.0f), glm::vec4{1.0f}}; + lighting.getAmbientColor().a = 0.5f; + + lighting.add(Light::builder() + .color(glm::vec4(1.0, 1.0, 0.5, 1.0f)) + .direction(glm::vec3{1.0f}) + .build() + ); + + lighting.add(Light::builder() + .color({1.0, -1.0, 0.5, 1.0f}) + .direction(glm::vec3{-1.0f}) + .build() + ); } void LightingScene::update(Limitless::Context& context, const Limitless::Camera& camera) { @@ -87,22 +100,22 @@ void LightingScene::update(Limitless::Context& context, const Limitless::Camera& std::uniform_real_distribution<> dis_duration(1.0, 2.0); std::uniform_real_distribution<> dis_color(0.0, 1.0); - for (std::size_t i = 0; i < data.size(); ++i) { - auto& light = lighting.lights.at(i); - auto& light_data = data[i]; + uint32_t i = 0; + for (auto& [_, light]: lighting.getLights()) { + auto& light_data = data[i++]; - light.position += glm::vec4(light_data.direction, 1.0) * delta_time * 10.0f; - light.position = glm::clamp(light.position, glm::vec4(0.0f), glm::vec4(FLOOR_INSTANCE_COUNT / 2.0f)); + light.getPosition() += glm::vec3(light_data.direction) * delta_time * 10.0f; + light.getPosition() = glm::clamp(light.getPosition(), glm::vec3(0.0f), glm::vec3(FLOOR_INSTANCE_COUNT / 2.0f)); if (light_data.duration <= 0.0f) { light_data.direction = glm::vec3(dis_direction(e), 0.0f, dis_direction(e)); light_data.duration = dis_duration(e); - light.color = glm::vec4(dis_color(e), dis_color(e), dis_color(e), 1.0f); + light.setColor(glm::vec4(dis_color(e), dis_color(e), dis_color(e), 1.0f)); } else { light_data.duration -= delta_time; } - if (!isInsideFloor(light.position)) { + if (!isInsideFloor(light.getPosition())) { light_data.direction *= -0.3f; } } diff --git a/demo/materials_demoscene.cpp b/demo/materials_demoscene.cpp index 1bb1b6bf..678f4007 100644 --- a/demo/materials_demoscene.cpp +++ b/demo/materials_demoscene.cpp @@ -3,31 +3,41 @@ #include #include #include +#include using namespace LimitlessDemo; +using namespace Limitless; MaterialsScene::MaterialsScene(Limitless::Context& ctx, Limitless::Assets& assets) : Limitless::Scene(ctx) { addModels(assets); setSkybox(assets.skyboxes.at("skybox")); - lighting.directional_light = {glm::vec4(1.0, -1.0, 0.5, 1.0f), glm::vec4{1.0f}}; - lighting.lights.emplace_back( - glm::vec4{0.0f, 0.5f, 0.0f, 1.0f}, - glm::vec4{1.0f, 0.0f, 0.0f, 2.0f}, - 2.0f + lighting.add(Light::builder() + .color(glm::vec4(1.0, 1.0, 0.5, 1.0f)) + .direction(glm::vec3{-1.0f}) + .build() ); - lighting.lights.emplace_back( - glm::vec4{5.0f, 0.5f, 0.0f, 1.0f}, - glm::vec4{0.0f, 1.0f, 0.0f, 2.0f}, - 2.0f + lighting.add(Light::builder() + .position({0.0f, 0.5f, 0.0f}) + .color({1.0f, 0.0f, 0.0f, 2.0f}) + .radius(2.0f) + .build() ); - lighting.lights.emplace_back( - glm::vec4{0.0f, 0.5f, 5.0f, 1.0f}, - glm::vec4{0.0f, 0.0f, 1.0f, 2.0f}, - 2.0f + lighting.add(Light::builder() + .position({5.0f, 0.5f, 0.0f}) + .color({0.0f, 1.0f, 0.0f, 2.0f}) + .radius(2.0f) + .build() + ); + + lighting.add(Light::builder() + .position({0.0f, 0.5f, 5.0f}) + .color({0.0f, 0.0f, 1.0f, 2.0f}) + .radius(2.0f) + .build() ); } diff --git a/demo/models_demoscene.cpp b/demo/models_demoscene.cpp index 34ecee00..f0e23f08 100644 --- a/demo/models_demoscene.cpp +++ b/demo/models_demoscene.cpp @@ -10,12 +10,18 @@ #include using namespace LimitlessDemo; +using namespace Limitless; ModelsScene::ModelsScene(Limitless::Context& ctx, Limitless::Assets& assets) : Limitless::Scene(ctx) { setSkybox(assets.skyboxes.at("skybox")); - lighting.ambient_color.a = 1.0f; - lighting.directional_light = {glm::vec4(1.0, -1.0, 1.5, 1.0f), glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}; + + lighting.add(Light::builder() + .color({1.0, -1.0, 1.5, 1.0f}) + .direction({-1.0f, -1.0f, -1.0f}) + .build() + ); + addInstances(assets); } diff --git a/demo/sponza_demoscene.cpp b/demo/sponza_demoscene.cpp index 912b1c4c..9722679f 100644 --- a/demo/sponza_demoscene.cpp +++ b/demo/sponza_demoscene.cpp @@ -11,7 +11,11 @@ SponzaScene::SponzaScene(Limitless::Context& ctx, Limitless::Assets& assets) setSkybox(assets.skyboxes.at("skybox")); - lighting.directional_light = {glm::vec4(0.0, -1.0, 0.25, 1.0f), glm::vec4{0.5f, 1.1f, 1.0f, 1.0f}}; + lighting.add(Light::builder() + .color(glm::vec4(0.0, -1.0, 0.25, 1.0f)) + .direction(glm::vec3(0.5f, -1.1f, 1.0f)) + .build() + ); auto& sponza = dynamic_cast(add(assets.models.at("sponza"), glm::vec3(17.0f, 8.0f, 15.0f)) .setScale(glm::vec3(0.005f))); diff --git a/docs/materials.md b/docs/materials.md new file mode 100644 index 00000000..e2b7215e --- /dev/null +++ b/docs/materials.md @@ -0,0 +1,6 @@ +materials + +properties + + + diff --git a/docs/shaders.md b/docs/shaders.md new file mode 100644 index 00000000..e69de29b diff --git a/include/limitless/core/uniform/uniform_value.hpp b/include/limitless/core/uniform/uniform_value.hpp index 2b3def08..ad9f258e 100644 --- a/include/limitless/core/uniform/uniform_value.hpp +++ b/include/limitless/core/uniform/uniform_value.hpp @@ -33,8 +33,8 @@ namespace Limitless { [[nodiscard]] std::unique_ptr clone() noexcept override; void set() override; - void setValue(const T& val) noexcept; [[nodiscard]] const T& getValue() const noexcept; - + [[nodiscard]] T& getValue() noexcept; + void setValue(const T& val) noexcept; }; } diff --git a/include/limitless/lighting/light.hpp b/include/limitless/lighting/light.hpp new file mode 100644 index 00000000..6ca5b40d --- /dev/null +++ b/include/limitless/lighting/light.hpp @@ -0,0 +1,101 @@ +#pragma once + +#include +#include + +namespace Limitless { + class light_builder_exception final : public std::runtime_error { + public: + using std::runtime_error::runtime_error; + }; + + class Light final { + public: + enum class Type { + DirectionalLight, + Point, + Spot + }; + private: + static inline uint64_t next_id = 0u; + glm::vec4 color; + glm::vec3 position; + glm::vec3 direction; + glm::vec2 inner_outer_angles; + uint64_t id; + float radius; + Type type; + bool changed; + bool removed; + bool hidden; + + Light(const glm::vec4& color, const glm::vec3& position, float radius) noexcept; + Light(const glm::vec4& color, const glm::vec3& position, const glm::vec3& direction, const glm::vec2& inner_outer_angles, float radius) noexcept; + Light(const glm::vec4& color, const glm::vec3& direction) noexcept; + public: + Light(const Light& light) noexcept; + Light(Light&& light) noexcept; + + Light& operator=(const Light& light) noexcept; + Light& operator=(Light&& light) noexcept; + + [[nodiscard]] const glm::vec4& getColor() const noexcept; + void setColor(const glm::vec4& _color) noexcept; + + [[nodiscard]] glm::vec3 getPosition() const noexcept; + [[nodiscard]] glm::vec3& getPosition() noexcept; + void setPosition(const glm::vec3& _position) noexcept; + + [[nodiscard]] glm::vec3 getDirection() const noexcept; + void setDirection(const glm::vec3& _direction) noexcept; + + [[nodiscard]] glm::vec2 getCone() const noexcept; + void setCone(const glm::vec2& _inner_outer_angles) noexcept; + + [[nodiscard]] float getRadius() const noexcept; + void setRadius(float _radius) noexcept; + + [[nodiscard]] Type getType() const noexcept; + [[nodiscard]] bool isDirectional() const noexcept; + [[nodiscard]] bool isPoint() const noexcept; + [[nodiscard]] bool isSpot() const noexcept; + + [[nodiscard]] uint64_t getId() const noexcept; + + [[nodiscard]] bool isChanged() const noexcept; + void resetChanged() noexcept; + void change() noexcept; + + [[nodiscard]] bool isRemoved() const noexcept; + void remove() noexcept; + + [[nodiscard]] bool isHidden() const noexcept; + void hide() noexcept; + void reveal() noexcept; + + class Builder { + private: + glm::vec4 color_ {0.0f}; + glm::vec3 position_ {0.0f}; + float outer_angle_ {0.0f}; + float inner_angle_ {0.0f}; + glm::vec3 direction_ {0.0f}; + float radius_ {0.0f}; + + bool isSpot(); + bool isPoint(); + bool isDirectional(); + public: + Builder& color(const glm::vec4& color) noexcept; + Builder& position(const glm::vec3& position) noexcept; + Builder& direction(const glm::vec3& direction) noexcept; + Builder& cone(float outer_angle, float inner_angle) noexcept; + Builder& radius(float radius) noexcept; + + Light build(); + Light buildDefaultDirectional(); + }; + + static Builder builder(); + }; +} diff --git a/include/limitless/lighting/light_container.hpp b/include/limitless/lighting/light_container.hpp index a7f062f6..4e41e0cf 100644 --- a/include/limitless/lighting/light_container.hpp +++ b/include/limitless/lighting/light_container.hpp @@ -1,65 +1,61 @@ #pragma once +#include #include #include #include +#include namespace Limitless { class Buffer; class LightContainer { private: - std::unordered_map lights_map; + /** + * Internal light buffer presentation + */ + class InternalLight { + private: + glm::vec4 color; + glm::vec4 position; + glm::vec4 direction; + glm::vec2 scale_offset; + float falloff; + uint32_t type; + + static float radiusToFalloff(float r); + static float falloffToRadius(float f); + static glm::vec2 anglesToScaleOffset(const glm::vec2& angles); + static glm::vec2 scaleOffsetToAngles(const glm::vec2& scale_offset); + public: + explicit InternalLight(const Light& light) noexcept; + InternalLight(const InternalLight& light) noexcept = default; + + void update(const Light& light) noexcept; + }; + + std::map lights; + + // corresponding internal presentation + std::map internal_lights; + + // lights to be mapped into the buffer + std::vector visible_lights; + + // visible lights buffer std::shared_ptr buffer; - std::vector lights; - uint64_t next_id {}; - bool modified {}; public: - explicit LightContainer(uint64_t reserve_count); LightContainer(); ~LightContainer() = default; - LightContainer(const LightContainer&) = delete; - LightContainer& operator=(const LightContainer&) = delete; + [[nodiscard]] auto& getLights() noexcept { return lights; } + [[nodiscard]] const auto& getLights() const noexcept { return lights; } + [[nodiscard]] uint64_t size() const noexcept { return lights.size(); } + [[nodiscard]] uint64_t visibleSize() const noexcept { return visible_lights.size(); } - LightContainer(LightContainer&&) noexcept = default; - LightContainer& operator=(LightContainer&&) noexcept = default; - - [[nodiscard]] auto begin() noexcept { modified = true; return lights.begin(); } - [[nodiscard]] auto begin() const noexcept { return lights.begin(); } - - [[nodiscard]] auto end() noexcept { modified = true; return lights.end(); } - [[nodiscard]] auto end() const noexcept { return lights.end(); } - - [[nodiscard]] auto size() const noexcept { return lights.size(); } - - void reserve(size_t n); - - [[nodiscard]] auto capacity() const noexcept { return lights.capacity(); } - [[nodiscard]] auto empty() const noexcept { return lights.begin() == lights.end(); } - - T& operator[](size_t id) noexcept { modified = true; return lights[lights_map[id]]; } - [[nodiscard]] const T& operator[](size_t id) const noexcept { return lights[lights_map.at(id)]; } - - T& at(size_t id) { modified = true; return lights.at(lights_map.at(id)); } - [[nodiscard]] const T& at(size_t id) const { return lights.at(lights_map.at(id)); } - - T& back() noexcept { modified = true; return lights.back(); } - const T& back() const noexcept { return lights.back(); } - - void erase(uint64_t id); + Light& add(Light&& light); + Light& add(const Light& light); void update(); - - template - auto emplace_back(Args&&... args) { - if (capacity() == size()) { - reserve(size() + 1); - } - lights.emplace_back(std::forward(args)...); - lights_map.emplace(next_id, lights.size() - 1); - modified = true; - return next_id++; - } }; } diff --git a/include/limitless/lighting/lighting.hpp b/include/limitless/lighting/lighting.hpp index 4db6b9c2..167fbc02 100644 --- a/include/limitless/lighting/lighting.hpp +++ b/include/limitless/lighting/lighting.hpp @@ -1,40 +1,86 @@ #pragma once #include -#include +#include namespace Limitless { class Context; + /** + * light = Light::builder() + * .pos(p) + * .col(l) + * .build() + * + * Light& l = scene.add(light) + * Light* l = &scene.add(light) + */ + class Lighting final { private: - std::shared_ptr buffer; - Context& context; + /** + * Internal buffer for scene lighting + */ + class SceneLighting final { + public: + glm::vec4 direction; + glm::vec4 color; + glm::vec4 ambient_color; + uint32_t light_count; + }; + /** + * Scene ambient lighting + * + * rgb - color + * a - intensity + */ + glm::vec4 ambient_color {1.0f, 1.0f, 1.0f, 1.0f}; + + /** + * Scene directional lighting + * + * scene has only one + */ Light directional_light; - LightContainer lights; + + /** + * Scene punctual lighting + * + * contains Point and Spot lights + */ + LightContainer punctual_lights; + + std::shared_ptr buffer; + Context& context; void createLightBuffer(); - void updateLightBuffer(); + void updateSceneLightBuffer(); + + bool changed; public: explicit Lighting(Context& ctx); + ~Lighting() = default; - Lighting& addLight(const Light& light) { - lights. - } + [[nodiscard]] const glm::vec4& getAmbientColor() const noexcept; + [[nodiscard]] glm::vec4& getAmbientColor() noexcept; + void setAmbientColor(const glm::vec4& ambient_color) noexcept; + [[nodiscard]] const Light& getDirectionalLight() const noexcept; + [[nodiscard]] Light& getDirectionalLight() noexcept; + void setDirectionalLight(const Light& directional_light); - // ambient lighting - glm::vec4 ambient_color {1.0f, 1.0f, 1.0f, 1.0f}; + [[nodiscard]] bool isChanged() const noexcept; + void resetChanged() noexcept; + void change() noexcept; - ~Lighting() = default; + [[nodiscard]] const std::map& getLights() const noexcept; + [[nodiscard]] std::map& getLights() noexcept; + [[nodiscard]] LightContainer& getLightContainer() noexcept; - Lighting(const Lighting&) = delete; - Lighting(Lighting&&) = delete; + Light& add(Light&& light); + Light& add(const Light& light); void update(); - - template - explicit operator LightContainer&() noexcept; }; } diff --git a/include/limitless/lighting/lights.hpp b/include/limitless/lighting/lights.hpp deleted file mode 100644 index 832b8383..00000000 --- a/include/limitless/lighting/lights.hpp +++ /dev/null @@ -1,154 +0,0 @@ -#pragma once - -#include -#include - -namespace Limitless { - class light_builder_exception final : public std::runtime_error { - public: - using std::runtime_error::runtime_error; - }; - - class Light final { - public: - static constexpr auto SHADER_STORAGE_NAME = "LIGHTS_BUFFER"; - - enum class Type : uint32_t { - DirectionalLight, - Point, - Spot - }; - private: - glm::vec4 color {}; - glm::vec4 position {}; - glm::vec4 direction {}; - glm::vec2 scale_offset {}; - float falloff {}; - Type type {1u}; - - static float radiusToFalloff(float r) { - return 1.0f / (r * r); - } - - static float falloffToRadius(float f) { - return glm::sqrt(1.0f / f); - } - - static glm::vec2 anglesToScaleOffset(float inner_angle, float outer_angle) { - const auto inner = glm::radians(inner_angle); - const auto outer = glm::radians(outer_angle); - - const auto inner_cos = glm::cos(inner); - const auto outer_cos = glm::cos(outer); - const auto scale = 1.0f / glm::max(1.0f / 1024.0f, inner_cos - outer_cos); - const auto offset = -outer_cos * scale; - - return { scale, offset }; - } - - static glm::vec2 scaleOffsetToAngles(const glm::vec2& scale_offset) { - const auto outer_cos = -scale_offset.y / scale_offset.x; - const auto inner_cos = 1.0f / (scale_offset.x + 1.0f / 1024.0f); - - const auto outer_angle = glm::degrees(glm::acos(outer_cos)); - const auto inner_angle = glm::degrees(glm::acos(inner_cos)); - - return { inner_angle, outer_angle }; - } - - Light(const glm::vec4& color, const glm::vec3& position, float radius) noexcept - : color {color} - , position {position, 0.0f} - , direction {} - , scale_offset {} - , falloff {radiusToFalloff(radius)} - , type {Type::Point} { - } - - Light(const glm::vec4& color, const glm::vec3& position, const glm::vec3& direction, float inner_angle, float outer_angle, float radius) noexcept - : color {color} - , position {position, 0.0f} - , direction {direction, 0.0f} - , scale_offset {anglesToScaleOffset(inner_angle, outer_angle)} - , falloff {radiusToFalloff(radius)} - , type {Type::Spot} { - } - - Light(const glm::vec4& color, const glm::vec3& direction) noexcept - : color {color} - , position {} - , direction {direction, 0.0f} - , scale_offset {} - , falloff {} - , type {Type::DirectionalLight} { - } - public: - [[nodiscard]] const glm::vec4& getColor() const noexcept { return color; } - void setColor(const glm::vec4& _color) noexcept { color = _color; } - - [[nodiscard]] glm::vec3 getPosition() const noexcept { return position; } - void setPosition(const glm::vec3& _position) noexcept { position = glm::vec4(_position, 0.0f); } - - [[nodiscard]] glm::vec3 getDirection() const noexcept { return direction; } - void setDirection(const glm::vec3& _direction) noexcept { direction = glm::vec4(_direction, 0.0f); } - - [[nodiscard]] glm::vec2 getCone() const noexcept { return scaleOffsetToAngles(scale_offset); } - void setCone(float inner_angle, float outer_angle) noexcept { scale_offset = anglesToScaleOffset(inner_angle, outer_angle); } - - [[nodiscard]] float getRadius() const noexcept { return glm::sqrt(1.0f / falloff); } - void setRadius(float _radius) noexcept { falloff = 1.0f / (_radius * _radius); } - - [[nodiscard]] Type getType() const noexcept { return type; } - - class Builder { - private: - glm::vec4 color_ {0.0f}; - glm::vec3 position_ {0.0f}; - float outer_angle_ {0.0f}; - float inner_angle_ {0.0f}; - glm::vec3 direction_ {0.0f}; - float radius_ {0.0f}; - - bool isSpot() { - return color_ != glm::vec4(0.0f) && position_ != glm::vec3(0.0) && inner_angle_ != 0.0f && outer_angle_ != 0.0f && direction_ != glm::vec3(0.0f) && radius_ != 0.0f; - } - - bool isPoint() { - return color_ != glm::vec4(0.0f) && position_ != glm::vec3(0.0) && radius_ != 0.0f; - } - - bool isDirectional() { - return color_ != glm::vec4(0.0f) && direction_ != glm::vec3(0.0f); - } - public: - Builder& color(const glm::vec4& _color) { color_ = _color; return *this; } - Builder& position(const glm::vec3& _position) { position_ = _position; return *this; } - Builder& direction(const glm::vec3& _direction) { direction_ = _direction; return *this; } - Builder& cone(float outer_angle, float inner_angle) { outer_angle_ = outer_angle; inner_angle_ = inner_angle; return *this; } - Builder& radius(float _radius) { radius_ = _radius; return *this; } - - Light build() { - if (isSpot()) { - if (inner_angle_ < 0.00872665f || inner_angle_ > 90.0f || outer_angle_ < inner_angle_ || outer_angle_ > 90.0f) { - throw light_builder_exception {"Inner/Outer angles are out of range!"}; - } - return {color_, position_, direction_, inner_angle_, outer_angle_, radius_}; - } - - if (isPoint()) { - return {color_, position_, radius_}; - } - - if (isDirectional()) { - return {color_, direction_}; - } - - throw light_builder_exception {"Required parameters are not set!"}; - } - - static Builder builder() { - return {}; - } - }; - }; -} diff --git a/include/limitless/ms/blending.hpp b/include/limitless/ms/blending.hpp index f8c83ba8..0ccd96a0 100644 --- a/include/limitless/ms/blending.hpp +++ b/include/limitless/ms/blending.hpp @@ -12,16 +12,10 @@ namespace Limitless::ms { */ enum class Blending { /** - * Do not mix, use last + * Opaque material */ Opaque, - //TODO: ? - /** - * - */ - MultipleOpaque, - /** * Mix based on alpha channel * @@ -45,23 +39,14 @@ namespace Limitless::ms { /** * Used for text rendering - * */ Text }; - /** * Sets context functions to match specified blending state to the current state * * @param blending - blending mode */ void setBlendingMode(Blending blending) noexcept; - - /** - * Sets context functions to match specified blending state - * - * @param blending - blending mode - */ - void setBlendingMode(ContextState& ctx, Blending blending, uint32_t opaque_count = 1) noexcept; -} \ No newline at end of file +} diff --git a/include/limitless/ms/colors.hpp b/include/limitless/ms/colors.hpp deleted file mode 100644 index cbbd1caf..00000000 --- a/include/limitless/ms/colors.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -//namespace Limitless::ms { -// class Colors { -// public: -// static glm::vec4 -// }; -//} \ No newline at end of file diff --git a/include/limitless/ms/material.hpp b/include/limitless/ms/material.hpp index 0d9ef55a..14eb479c 100644 --- a/include/limitless/ms/material.hpp +++ b/include/limitless/ms/material.hpp @@ -1,26 +1,24 @@ #pragma once #include -#include -#include -#include #include +#include #include #include #include -#include #include #include -#include #include +#include +#include namespace Limitless { class Buffer; } namespace Limitless::ms { - class material_property_not_found : public std::runtime_error { + class material_exception : public std::runtime_error { public: using std::runtime_error::runtime_error; }; @@ -66,45 +64,20 @@ namespace Limitless::ms { bool refraction {}; /** - * Describes whether material is using specular anti-aliasing - */ - bool specular_antialiasing {true}; - - /** - * Describes specular anti-aliasing variance - */ - float specular_antialiasing_variance {0.15f}; - - /** - * Describes specular anti-aliasing threshold - */ - float specular_antialiasing_threshold {0.1f}; - - /** - * Unique material name + * Unique material name */ std::string name; /** - * Describes which shader is compiled for this material + * Describes which shader is compiled for this material */ uint64_t shader_index {}; /** - * Describes for which ModelShader types this material is used and compiled + * Describes for which ModelShader types this material is used and compiled */ InstanceTypes model_shaders; - /** - * Corresponding OpenGL buffer to store properties on GPU - */ - std::shared_ptr material_buffer; - - /** - * Run-time fetched property offsets in buffer - */ - std::unordered_map uniform_offsets; - /** * Custom user-defined properties */ @@ -126,25 +99,9 @@ namespace Limitless::ms { std::string global_snippet; /** - * Tessellation shader code to allow customization - */ - std::string tessellation_snippet; - - /** - * Adds uniform typed value at specific offset in block so it can be mapped to GPU + * Shading shader code to allow customization */ - template - void map(std::vector& block, const Uniform& uniform) const; - - /** - * Adds any uniform to block - */ - void map(std::vector& block, Uniform& uniform); - - /** - * Maps material to GPU uniform buffer - */ - void map(); + std::string shading_snippet; friend void swap(Material&, Material&) noexcept; Material() = default; @@ -181,37 +138,34 @@ namespace Limitless::ms { */ void update(); - [[nodiscard]] const UniformValue& getColor() const; - [[nodiscard]] const UniformValue& getEmissiveColor() const; - [[nodiscard]] const UniformValue& getTesselationFactor() const; - [[nodiscard]] const UniformValue& getMetallic() const; - [[nodiscard]] const UniformValue& getRoughness() const; - [[nodiscard]] const UniformValue& getIoR() const; - [[nodiscard]] const UniformValue& getAbsorption() const; - [[nodiscard]] const UniformSampler& getMetallicTexture() const; - [[nodiscard]] const UniformSampler& getRoughnessTexture() const; - [[nodiscard]] const UniformSampler& getDiffuse() const; - [[nodiscard]] const UniformSampler& getNormal() const; - [[nodiscard]] const UniformSampler& getEmissiveMask() const; - [[nodiscard]] const UniformSampler& getBlendMask() const; - [[nodiscard]] const UniformSampler& getAmbientOcclusionTexture() const; - [[nodiscard]] const UniformSampler& getORMTexture() const; - - UniformValue& getColor(); - UniformValue& getEmissiveColor(); - UniformValue& getTesselationFactor(); - UniformValue& getMetallic(); - UniformValue& getRoughness(); - UniformValue& getIoR(); - UniformValue& getAbsorption(); - UniformSampler& getMetallicTexture(); - UniformSampler& getRoughnessTexture(); - UniformSampler& getDiffuse(); - UniformSampler& getNormal(); - UniformSampler& getEmissiveMask(); - UniformSampler& getBlendMask(); - UniformSampler& getAmbientOcclusionTexture(); - UniformSampler& getORMTexture(); + /** + * Const-context property getters + */ + [[nodiscard]] const glm::vec4& getColor() const; + [[nodiscard]] const glm::vec4& getEmissiveColor() const; + [[nodiscard]] float getMetallic() const; + [[nodiscard]] float getRoughness() const; + [[nodiscard]] float getIoR() const; + [[nodiscard]] float getAbsorption() const; + [[nodiscard]] const std::shared_ptr& getMetallicTexture() const; + [[nodiscard]] const std::shared_ptr& getRoughnessTexture() const; + [[nodiscard]] const std::shared_ptr& getDiffuseTexture() const; + [[nodiscard]] const std::shared_ptr& getNormalTexture() const; + [[nodiscard]] const std::shared_ptr& getEmissiveMaskTexture() const; + [[nodiscard]] const std::shared_ptr& getBlendMaskTexture() const; + [[nodiscard]] const std::shared_ptr& getAmbientOcclusionTexture() const; + [[nodiscard]] const std::shared_ptr& getORMTexture() const; + + /** + * Mutable property getters + */ + glm::vec4& getColor(); + glm::vec4& getEmissiveColor(); + glm::vec2& getTesselationFactor(); + float& getMetallic(); + float& getRoughness(); + float& getIoR(); + float& getAbsorption(); [[nodiscard]] const auto& getModelShaders() const noexcept { return model_shaders; } [[nodiscard]] auto getBlending() const noexcept { return blending; } @@ -251,6 +205,10 @@ namespace Limitless::ms { throw material_property_not_found(uniform_name); } } + + class Builder; + + static Builder builder(); }; void swap(Material& lhs, Material& rhs) noexcept; diff --git a/include/limitless/ms/material_buffer.hpp b/include/limitless/ms/material_buffer.hpp new file mode 100644 index 00000000..99b34daf --- /dev/null +++ b/include/limitless/ms/material_buffer.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include +#include +#include + +namespace Limitless { + class Uniform; +} + +namespace Limitless::ms { + class Material; + + class MaterialBuffer final { + private: + /** + * Corresponding OpenGL buffer to store properties on GPU + */ + std::shared_ptr material_buffer; + + /** + * Property offsets in buffer + */ + std::unordered_map uniform_offsets; + + /** + * Adds uniform typed value at specific offset in block so it can be mapped to GPU + */ + template + void map(std::vector& block, const Uniform& uniform) const; + + /** + * Adds any uniform to block + */ + void map(std::vector& block, Uniform& uniform); + + /** + * Maps material to GPU uniform buffer + */ + void map(const Material& material); + }; +} \ No newline at end of file diff --git a/include/limitless/ms/material_builder.hpp b/include/limitless/ms/material_builder.hpp index bd37bb9f..ff00d116 100644 --- a/include/limitless/ms/material_builder.hpp +++ b/include/limitless/ms/material_builder.hpp @@ -17,7 +17,7 @@ namespace Limitless::ms { using std::runtime_error::runtime_error; }; - class MaterialBuilder { + class Material::Builder { private: static inline std::map unique_materials; static inline uint64_t next_shader_index {}; @@ -43,6 +43,41 @@ namespace Limitless::ms { MaterialBuilder(MaterialBuilder&&) = delete; MaterialBuilder& operator=(MaterialBuilder&&) = delete; + Builder& color(const glm::vec4& color) noexcept; + Builder& emissive_color(const glm::vec4& color) noexcept; + Builder& diffuse(const glm::vec4& color) noexcept; + Builder& normal(const glm::vec4& color) noexcept; + Builder& emissive_mask(const glm::vec4& color) noexcept; + Builder& blend_mask(const glm::vec4& color) noexcept; + Builder& metallic(const glm::vec4& color) noexcept; + Builder& metallic(const glm::vec4& color) noexcept; + Builder& roughness(const glm::vec4& color) noexcept; + Builder& roughness(const glm::vec4& color) noexcept; + Builder& ao(const glm::vec4& color) noexcept; + Builder& orm(const glm::vec4& color) noexcept; + Builder& ior(const glm::vec4& color) noexcept; + Builder& absorption(const glm::vec4& color) noexcept; + Builder& microthickness(const glm::vec4& color) noexcept; + Builder& reflectance(const glm::vec4& color) noexcept; + Builder& transmission(const glm::vec4& color) noexcept; + + Builder& blending(const glm::vec4& color) noexcept; + Builder& shading(const glm::vec4& color) noexcept; + Builder& two_sided(const glm::vec4& color) noexcept; + Builder& refraction(const glm::vec4& color) noexcept; + Builder& name(const glm::vec4& color) noexcept; + + Builder& vertex(const glm::vec4& color) noexcept; + Builder& fragment(const glm::vec4& color) noexcept; + Builder& global(const glm::vec4& color) noexcept; + Builder& shading(const glm::vec4& color) noexcept; + Builder& model(const glm::vec4& color) noexcept; + Builder& models(const glm::vec4& color) noexcept; + + + + + MaterialBuilder& add(Property type, std::shared_ptr texture); MaterialBuilder& add(Property type, const glm::vec4& value); MaterialBuilder& add(Property type, const glm::vec2& value); diff --git a/include/limitless/ms/material_shader_define_replacer.hpp b/include/limitless/ms/material_shader_define_replacer.hpp index 6fa28330..456f90e0 100644 --- a/include/limitless/ms/material_shader_define_replacer.hpp +++ b/include/limitless/ms/material_shader_define_replacer.hpp @@ -27,19 +27,20 @@ namespace Limitless { { Property::RoughnessTexture, "ENGINE_MATERIAL_ROUGHNESS_TEXTURE" }, { Property::AmbientOcclusionTexture, "ENGINE_MATERIAL_AMBIENT_OCCLUSION_TEXTURE" }, { Property::ORM, "ENGINE_MATERIAL_ORM_TEXTURE" }, - { Property::TessellationFactor, "ENGINE_MATERIAL_TESSELLATION_FACTOR" }, { Property::Metallic, "ENGINE_MATERIAL_METALLIC" }, { Property::Roughness, "ENGINE_MATERIAL_ROUGHNESS" }, { Property::IoR, "ENGINE_MATERIAL_IOR" }, { Property::Absorption, "ENGINE_MATERIAL_ABSORPTION" }, + { Property::MicroThickness, "ENGINE_MATERIAL_MICROTHICKNESS" }, + { Property::Thickness, "ENGINE_MATERIAL_THICKNESS" }, + { Property::Transmission, "ENGINE_MATERIAL_TRANSMISSION" }, + { Property::Reflectance, "ENGINE_MATERIAL_REFLECTANCE" }, }; static inline std::unordered_map SHADING_DEFINE = { { Shading::Lit, "ENGINE_MATERIAL_SHADING_REGULAR_MODEL" }, { Shading::Unlit, "ENGINE_MATERIAL_SHADING_UNLIT_MODEL" }, - { Shading::Cloth, "ENGINE_MATERIAL_SHADING_CLOTH_MODEL" }, - { Shading::Subsurface, "ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL" }, { Shading::Custom, "ENGINE_MATERIAL_SHADING_CUSTOM_MODEL" }, }; @@ -54,21 +55,22 @@ namespace Limitless { enum class SnippetDefineType { Vertex, - Tesselation, Fragment, Global, CustomScalar, - CustomSamplers + CustomSamplers, + CustomShading }; static inline std::unordered_map SNIPPET_DEFINE = { { SnippetDefineType::Vertex, "ENGINE_MATERIAL_VERTEX_SNIPPET" }, - { SnippetDefineType::Tesselation, "ENGINE_MATERIAL_TESSELATION_SNIPPET" }, { SnippetDefineType::Fragment, "ENGINE_MATERIAL_FRAGMENT_SNIPPET" }, { SnippetDefineType::Global, "ENGINE_MATERIAL_GLOBAL_DEFINITIONS" }, { SnippetDefineType::CustomScalar, "ENGINE_MATERIAL_CUSTOM_SCALARS" }, { SnippetDefineType::CustomSamplers, "ENGINE_MATERIAL_CUSTOM_SAMPLERS" }, + { SnippetDefineType::CustomShading, "ENGINE_MATERIAL_CUSTOM_SAMPLERS" }, + { SnippetDefineType::CustomShading, "ENGINE_MATERIAL_SHADING_CUSTOM_SNIPPET" }, }; static std::string getPropertyDefines(const Material& material); diff --git a/include/limitless/ms/property.hpp b/include/limitless/ms/property.hpp index 3f2651d8..985a149f 100644 --- a/include/limitless/ms/property.hpp +++ b/include/limitless/ms/property.hpp @@ -1,52 +1,181 @@ #pragma once namespace Limitless::ms { + /** + * Describes property of the material + * + * check properties order in material.glsl + */ enum class Property { - // vec4; rgb - color; a - intensity; linear space; [0 - 1] + /** + * Surface color + * + * linear space + * + * vec4 - [0, 1] + * + * rgb - color, a - alpha + */ Color, - // vec4; rgb - color; a - intensity; linear space; [0 - n] + + /** + * Surface emissive color to simulate light emission + * + * (should be used in HDR pipeline) + * + * linear space + * + * vec3 - [0, n] + * + * rgb - color + */ EmissiveColor, - // texture + + /** + * Surface color from texture + * + * vec4 - [0, 1] + * + * if Color is present, gets multiplied + */ Diffuse, - // texture + + /** + * Surface normal map from texture + * + * vec3 - [0, 1] + * + * used by normal mapping + */ Normal, + + /** + * EmissiveMask describes whether some part of the surface emits light + * + * vec3 - [0, 1] + * + * '0' is used for not emissive texel + * '1' is used for emissive texel + * + * if EmissiveColor is present, gets multiplied + */ EmissiveMask, + + /** + * BlendMask describes whether rendering fragment should be discarded and not rendered + * + * float - [0, 1] + * + * if value is 0, fragment is discarded + */ BlendMask, + + /** + * MetallicTexture describes metalness of the surface from texture + * + * float - [0, 1] + * + * gets priority over Metallic + */ MetallicTexture, + + /** + * RoughnessTexture describes roughness of the surface from texture + * + * float - [0, 1] + * + * gets priority over Roughness + */ RoughnessTexture, + + /** + * AmbientOcclusionTexture describes ambient shadowing of the surface from texture + * + * float - [0, 1] + */ AmbientOcclusionTexture, - /* - * Ambient Occlusion, Roughness, and Metallic + /** + * ORM - Occlusion, Roughness, Metallic + * + * vec3 - [0, 1] + * + * describes 3 properties in one backed texture + * + * used channels as follows: * * Red: Ambient Occlusion * Green: Roughness * Blue: Metallic * - * overrides other orm properties + * gets highest priority over other properties */ ORM, - // vec2 - TessellationFactor, - - // float + /** + * Metallic value of the surface + * + * float - [0, 1] + * + * lowest priority + */ Metallic, + + /** + * Roughness value of the surface + * + * float - [0, 1] + * + * lowest priority + */ Roughness, + /** + * Index of Refraction of transparent surface + * + * float - [1, n] + * + * Used only when Blending is set to 'NOT' Opaque + */ IoR, - Absorption, + /** + * Absorption factor of refractive objects + * + * float - [1, n] + * + * Used only when Blending is set to 'NOT' Opaque + */ + Absorption, - Reflectance, - Transmission, + /** + * Thickness of the thin layer of refractive objects + * + * float - [0, n] + */ MicroThickness, - Thickness, - SubsurfaceColor, - SubsurfacePower, + /** + * Thickness of the solid volume of refractive objects + * + * float - [0, n] + */ + Thickness, - SheenColor + /** + * Reflectance describes the strength of reflections + * + * float - [0, 1] + */ + Reflectance, + /** + * Transmission describes how transparent material is + * + * float - [0, 1] + * + * Used only when Blending is set to 'NOT' Opaque + */ + Transmission, }; } \ No newline at end of file diff --git a/include/limitless/ms/shading.hpp b/include/limitless/ms/shading.hpp index 462da4bb..6cd95a7c 100644 --- a/include/limitless/ms/shading.hpp +++ b/include/limitless/ms/shading.hpp @@ -2,9 +2,9 @@ namespace Limitless::ms { /** - * Shading describes intrinsic properties of a surface + * Shading describes intrinsic properties of a surface * - * defines how lighting is computed + * defines how lighting is computed */ enum class Shading { /** @@ -15,16 +15,15 @@ namespace Limitless::ms { Unlit, /** - * Standard model + * Standard model * - * used to describe metallic and non-metallic surfaces + * Used to describe metallic and non-metallic surfaces */ Lit, - Cloth, - - Subsurface, - + /** + * Custom shading model defined by user + */ Custom, }; } \ No newline at end of file diff --git a/include/limitless/pipeline/common/shadow_pass.hpp b/include/limitless/pipeline/common/shadow_pass.hpp index 98d8ccc5..f97d5704 100644 --- a/include/limitless/pipeline/common/shadow_pass.hpp +++ b/include/limitless/pipeline/common/shadow_pass.hpp @@ -21,7 +21,7 @@ namespace Limitless { /** * Current direction light used to shadow cast */ - DirectionalLight* light {}; + Light* light {}; /** * EffectRenderer diff --git a/shaders_ref/material/material.glsl b/shaders_ref/material/material.glsl index 0b146c0a..6a58c2ee 100644 --- a/shaders_ref/material/material.glsl +++ b/shaders_ref/material/material.glsl @@ -41,10 +41,6 @@ layout (std140) uniform MATERIAL_BUFFER { #endif #endif -#if defined (ENGINE_MATERIAL_TESSELLATION_FACTOR) - vec2 _material_tessellation_factor; -#endif - #if defined (ENGINE_MATERIAL_METALLIC) float _material_metallic; #endif @@ -61,6 +57,22 @@ layout (std140) uniform MATERIAL_BUFFER { #if defined (ENGINE_MATERIAL_ABSORPTION) float _material_absorption; #endif + +#if defined (ENGINE_MATERIAL_MICROTHICKNESS) + float _material_microthickness; +#endif + +#if defined (ENGINE_MATERIAL_THICKNESS) + float _material_thickness; +#endif +#endif + +#if defined (ENGINE_MATERIAL_REFLECTANCE) + float _material_reflectance; +#endif + +#if defined (ENGINE_MATERIAL_TRANSMISSION) + float _material_transmission; #endif #if defined (ENGINE_EXT_BINDLESS_TEXTURE) @@ -127,12 +139,6 @@ ENGINE_MATERIAL_GLOBAL_DEFINITIONS } #endif -#if defined (ENGINE_MATERIAL_TESSELLATION_FACTOR) - vec2 getMaterialTesselationFactor() { - return _material_tessellation_factor; - } -#endif - #if defined (ENGINE_MATERIAL_METALLIC) float getMaterialMetallic() { return _material_metallic; @@ -169,6 +175,18 @@ ENGINE_MATERIAL_GLOBAL_DEFINITIONS return _material_absorption; } #endif + +#if defined (ENGINE_MATERIAL_MICROTHICKNESS) + float getMaterialMicrothickness() { + return _material_microthickness; + } +#endif + +#if defined (ENGINE_MATERIAL_THICKNESS) + float getMaterialThickness() { + return _material_thickness; + } +#endif #endif #if defined (ENGINE_MATERIAL_DIFFUSE_TEXTURE) @@ -207,6 +225,18 @@ ENGINE_MATERIAL_GLOBAL_DEFINITIONS } #endif +#if defined (ENGINE_MATERIAL_REFLECTANCE) + float getMaterialReflectance() { + return _material_reflectance; + } +#endif + +#if defined (ENGINE_MATERIAL_TRANSMISSION) + float getMaterialTransmission() { + return _material_transmission; + } +#endif + uint getMaterialShadingModel() { return _material_shading_model; } diff --git a/shaders_ref/material/material_context.glsl b/shaders_ref/material/material_context.glsl index 65ebf1b5..932b9e23 100644 --- a/shaders_ref/material/material_context.glsl +++ b/shaders_ref/material/material_context.glsl @@ -188,8 +188,18 @@ vec3 computeMaterialNormal(const MaterialContext mctx) { #else #if defined (ENGINE_MATERIAL_NORMAL_TEXTURE) && defined (ENGINE_SETTINGS_NORMAL_MAPPING) vec3 normal = mctx.normal; +#if defined (ENGINE_MATERIAL_TWO_SIDED) + normal = gl_FrontFacing ? normal : -normal; +#endif normal = normalize(normal * 2.0 - 1.0); - normal = normalize(getVertexTBN() * normal); + + mat3 TBN = getVertexTBN(); +#if defined (ENGINE_MATERIAL_TWO_SIDED) + TBN[0] = gl_FrontFacing ? TBN[0] : -TBN[0]; + TBN[1] = gl_FrontFacing ? TBN[1] : -TBN[1]; + TBN[1] = gl_FrontFacing ? TBN[2] : -TBN[2]; +#endif + normal = normalize(TBN * normal); #else vec3 normal = normalize(getVertexNormal()); #endif diff --git a/shaders_ref/shading/custom.glsl b/shaders_ref/shading/custom.glsl index c5361431..ae200422 100644 --- a/shaders_ref/shading/custom.glsl +++ b/shaders_ref/shading/custom.glsl @@ -1,3 +1,3 @@ vec3 customShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { - return vec3(0.0); + ENGINE_MATERIAL_SHADING_CUSTOM_SNIPPET } diff --git a/src/limitless/core/uniform/uniform_value.cpp b/src/limitless/core/uniform/uniform_value.cpp index 878d4b63..66d6130a 100644 --- a/src/limitless/core/uniform/uniform_value.cpp +++ b/src/limitless/core/uniform/uniform_value.cpp @@ -102,6 +102,12 @@ const T& UniformValue::getValue() const noexcept { return value; } +template +T& UniformValue::getValue() noexcept { + changed = true; + return value; +} + namespace Limitless { template class UniformValue; template class UniformValue; diff --git a/src/limitless/lighting/cascade_shadows.cpp b/src/limitless/lighting/cascade_shadows.cpp index a074febb..b084cd68 100644 --- a/src/limitless/lighting/cascade_shadows.cpp +++ b/src/limitless/lighting/cascade_shadows.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/limitless/lighting/light.cpp b/src/limitless/lighting/light.cpp new file mode 100644 index 00000000..86d7df13 --- /dev/null +++ b/src/limitless/lighting/light.cpp @@ -0,0 +1,267 @@ +#include + +using namespace Limitless; + +Light::Light(const glm::vec4& color, const glm::vec3& position, float radius) noexcept + : color {color} + , position {position} + , direction {} + , inner_outer_angles {} + , id {next_id++} + , radius {radius} + , type {Type::Point} + , changed {true} + , removed {} + , hidden {} { +} + +Light::Light(const glm::vec4& color, const glm::vec3& position, const glm::vec3& direction, const glm::vec2& inner_outer_angles, float radius) noexcept + : color {color} + , position {position} + , direction {direction} + , inner_outer_angles {inner_outer_angles} + , id {next_id++} + , radius {radius} + , type {Type::Spot} + , changed {true} + , removed {} + , hidden {} { +} + +Light::Light(const glm::vec4& color, const glm::vec3& direction) noexcept + : color {color} + , position {} + , direction {direction} + , inner_outer_angles {} + , id {next_id++} + , radius {} + , type {Type::DirectionalLight} + , changed {true} + , removed {} + , hidden {} { +} + +Light::Light(const Light& light) noexcept + : color {light.color} + , position {light.position} + , direction {light.direction} + , inner_outer_angles {light.inner_outer_angles} + , id {next_id++} + , radius {light.radius} + , type {light.type} + , changed {true} + , removed {light.removed} + , hidden {light.hidden} { +} + +Light::Light(Light&& light) noexcept + : color {light.color} + , position {light.position} + , direction {light.direction} + , inner_outer_angles {light.inner_outer_angles} + , id {light.id} + , radius {light.radius} + , type {light.type} + , changed {true} + , removed {light.removed} + , hidden {light.hidden} { +} + +Light& Light::operator=(const Light& light) noexcept { + color = light.color; + position = light.position; + direction = light.direction; + inner_outer_angles = light.inner_outer_angles; + id = next_id++; + radius = light.radius; + type = light.type; + changed = true; + removed = light.removed; + hidden = light.hidden; + return *this; +} + +Light& Light::operator=(Light&& light) noexcept { + color = light.color; + position = light.position; + direction = light.direction; + inner_outer_angles = light.inner_outer_angles; + id = light.id; + radius = light.radius; + type = light.type; + changed = true; + removed = light.removed; + hidden = light.hidden; + return *this; +} + +const glm::vec4& Light::getColor() const noexcept { + return color; +} + +void Light::setColor(const glm::vec4& _color) noexcept { + color = _color; + change(); +} + +glm::vec3 Light::getPosition() const noexcept { + return position; +} + +glm::vec3 &Light::getPosition() noexcept { + change(); + return position; +} + +void Light::setPosition(const glm::vec3& _position) noexcept { + position = _position; + change(); +} + +glm::vec3 Light::getDirection() const noexcept { + return direction; +} + +void Light::setDirection(const glm::vec3& _direction) noexcept { + direction = _direction; + change(); +} + +glm::vec2 Light::getCone() const noexcept { + return inner_outer_angles; +} + +void Light::setCone(const glm::vec2& _inner_outer_angles) noexcept { + inner_outer_angles = _inner_outer_angles; change(); +} + +float Light::getRadius() const noexcept { + return radius; +} + +void Light::setRadius(float _radius) noexcept { + radius = _radius; + change(); +} + +Light::Type Light::getType() const noexcept { + return type; +} + +bool Light::isDirectional() const noexcept { + return type == Type::DirectionalLight; +} + +bool Light::isPoint() const noexcept { + return type == Type::Point; +} + +bool Light::isSpot() const noexcept { + return type == Type::Spot; +} + +uint64_t Light::getId() const noexcept { + return id; +} + +bool Light::isChanged() const noexcept { + return changed; +} + +void Light::resetChanged() noexcept { + changed = false; +} + +void Light::change() noexcept { + changed = true; +} + +bool Light::isRemoved() const noexcept { + return removed; +} + +void Light::remove() noexcept { + removed = true; + change(); +} + +bool Light::isHidden() const noexcept { + return hidden; +} + +void Light::hide() noexcept { + hidden = true; + change(); +} + +void Light::reveal() noexcept { + hidden = false; + change(); +} + +bool Light::Builder::isSpot() { + return color_ != glm::vec4(0.0f) && position_ != glm::vec3(0.0) && inner_angle_ != 0.0f && outer_angle_ != 0.0f && direction_ != glm::vec3(0.0f) && radius_ != 0.0f; +} + +bool Light::Builder::isPoint() { + return color_ != glm::vec4(0.0f) && position_ != glm::vec3(0.0) && radius_ != 0.0f; +} + +bool Light::Builder::isDirectional() { + return color_ != glm::vec4(0.0f) && direction_ != glm::vec3(0.0f); +} + +Light::Builder& Light::Builder::color(const glm::vec4& _color) noexcept { + color_ = _color; + return *this; +} + +Light::Builder& Light::Builder::position(const glm::vec3& _position) noexcept { + position_ = _position; + return *this; +} + +Light::Builder& Light::Builder::direction(const glm::vec3& _direction) noexcept { + direction_ = _direction; + return *this; +} + +Light::Builder& Light::Builder::cone(float outer_angle, float inner_angle) noexcept { + outer_angle_ = outer_angle; + inner_angle_ = inner_angle; + return *this; +} + +Light::Builder& Light::Builder::radius(float _radius) noexcept { + radius_ = _radius; + return *this; +} + +Light Light::Builder::build() { + if (isSpot()) { + if (inner_angle_ < 0.00872665f || inner_angle_ > 90.0f || outer_angle_ < inner_angle_ || outer_angle_ > 90.0f) { + throw light_builder_exception {"Inner/Outer angles are out of range!"}; + } + return {color_, position_, direction_, {inner_angle_, outer_angle_}, radius_}; + } + + if (isPoint()) { + return {color_, position_, radius_}; + } + + if (isDirectional()) { + return {color_, direction_}; + } + + throw light_builder_exception {"Required parameters are not set!"}; +} + +Light Light::Builder::buildDefaultDirectional() { + direction({-1.0f, -1.0f, -1.0f}); + color({1.0f, 1.0f, 1.0f, 1.0f}); + return build(); +} + +Light::Builder Light::builder() { + return {}; +} diff --git a/src/limitless/lighting/light_container.cpp b/src/limitless/lighting/light_container.cpp index 4c34c547..4631488f 100644 --- a/src/limitless/lighting/light_container.cpp +++ b/src/limitless/lighting/light_container.cpp @@ -1,62 +1,113 @@ #include #include -#include +#include #include using namespace Limitless; -template -LightContainer::LightContainer() - : LightContainer {1} { +static constexpr auto SHADER_STORAGE_NAME = "LIGHTS_BUFFER"; + +float LightContainer::InternalLight::radiusToFalloff(float r) { + return 1.0f / (r * r); +} + +float LightContainer::InternalLight::falloffToRadius(float f) { + return glm::sqrt(1.0f / f); } -template -LightContainer::LightContainer(uint64_t reserve_count) { - reserve(reserve_count); +glm::vec2 LightContainer::InternalLight::anglesToScaleOffset(const glm::vec2& angles) { + const auto inner = glm::radians(angles.x); + const auto outer = glm::radians(angles.y); + + const auto inner_cos = glm::cos(inner); + const auto outer_cos = glm::cos(outer); + const auto scale = 1.0f / glm::max(1.0f / 1024.0f, inner_cos - outer_cos); + const auto offset = -outer_cos * scale; + + return { scale, offset }; } -template -void LightContainer::reserve(size_t n) { - lights.reserve(n); - lights_map.reserve(n); +glm::vec2 LightContainer::InternalLight::scaleOffsetToAngles(const glm::vec2& scale_offset) { + const auto outer_cos = -scale_offset.y / scale_offset.x; + const auto inner_cos = 1.0f / (scale_offset.x + 1.0f / 1024.0f); - auto& buffers = ContextState::getState(glfwGetCurrentContext())->getIndexedBuffers(); + const auto outer_angle = glm::degrees(glm::acos(outer_cos)); + const auto inner_angle = glm::degrees(glm::acos(inner_cos)); - buffers.remove(T::SHADER_STORAGE_NAME, buffer); + return { inner_angle, outer_angle }; +} + +LightContainer::InternalLight::InternalLight(const Light& light) noexcept + : color {light.getColor()} + , position {light.getPosition(), 0.0f} + , direction {light.getDirection(), 0.0f} + , scale_offset {anglesToScaleOffset(light.getCone())} + , falloff {radiusToFalloff(light.getRadius())} + , type {static_cast(light.getType())} { +} + +void LightContainer::InternalLight::update(const Light& light) noexcept { + color = light.getColor(); + position = {light.getPosition(), 0.0f}; + direction = {light.getDirection(), 0.0f}; + scale_offset = anglesToScaleOffset(light.getCone()); + falloff = radiusToFalloff(light.getRadius()); +} +LightContainer::LightContainer() { BufferBuilder builder; buffer = builder.setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(T) * n) - .build(T::SHADER_STORAGE_NAME, *ContextState::getState(glfwGetCurrentContext())); - - modified = true; + .setUsage(Buffer::Usage::DynamicDraw) + .setAccess(Buffer::MutableAccess::WriteOrphaning) + .setDataSize(sizeof(InternalLight) * 1024) + .build(SHADER_STORAGE_NAME, *ContextState::getState(glfwGetCurrentContext())); } -template -void LightContainer::erase(uint64_t id) { - modified = true; +Light& LightContainer::add(Light&& light) { + // add new light to all lights + lights.emplace(light.getId(), std::move(light)); + + // add corresponding internal presentation + internal_lights.emplace(light.getId(), light); - auto del_index = lights_map.at(id); + return lights.at(light.getId()); +} - lights.erase(lights.begin() + del_index); +Light& LightContainer::add(const Light& light) { + // add new light to all lights + auto copy = light; + lights.emplace(light.getId(), std::move(copy)); - for (auto& [id, index] : lights_map) - if (index > del_index) --index; + // add corresponding internal presentation + internal_lights.emplace(copy.getId(), light); + + return lights.at(copy.getId()); } -template -void LightContainer::update() { - if (modified) { - buffer->mapData(lights.data(), sizeof(T) * size()); - modified = false; +void LightContainer::update() { + // check if there were an update to lights + bool changed {}; + for (auto& [id, light]: lights) { + // if changed since last update + if (light.isChanged()) { + // update corresponding internal presentation + internal_lights.at(id).update(light); + changed = true; + } + } + + if (changed) { + visible_lights.clear(); + visible_lights.reserve(internal_lights.size()); + + for (const auto& [_, light]: internal_lights) { + visible_lights.emplace_back(light); + } + + buffer->mapData(visible_lights.data(), sizeof(InternalLight) * visible_lights.size()); } - buffer->bindBase(ContextState::getState(glfwGetCurrentContext())->getIndexedBuffers().getBindingPoint(IndexedBuffer::Type::ShaderStorage, T::SHADER_STORAGE_NAME)); -} -namespace Limitless { - template class LightContainer; + buffer->bindBase(ContextState::getState(glfwGetCurrentContext())->getIndexedBuffers().getBindingPoint(IndexedBuffer::Type::ShaderStorage, SHADER_STORAGE_NAME)); } diff --git a/src/limitless/lighting/lighting.cpp b/src/limitless/lighting/lighting.cpp index e84d160b..0332d99a 100644 --- a/src/limitless/lighting/lighting.cpp +++ b/src/limitless/lighting/lighting.cpp @@ -5,16 +5,7 @@ using namespace Limitless; -namespace { - struct SceneLighting { - glm::vec4 direction; - glm::vec4 color; - glm::vec4 ambient_color {}; - uint32_t light_count {}; - }; - - constexpr auto SCENE_LIGHTING_BUFFER_NAME = "scene_lighting"; -} +constexpr auto SCENE_LIGHTING_BUFFER_NAME = "scene_lighting"; void Lighting::createLightBuffer() { BufferBuilder builder; @@ -26,39 +17,103 @@ void Lighting::createLightBuffer() { } Lighting::Lighting(Context& ctx) - : context {ctx} { + : directional_light {Light::builder().buildDefaultDirectional()} + , context {ctx} + , changed {true} { createLightBuffer(); } -void Lighting::updateLightBuffer() { +const glm::vec4& Lighting::getAmbientColor() const noexcept { + return ambient_color; +} + +glm::vec4& Lighting::getAmbientColor() noexcept { + change(); + return ambient_color; +} + +void Lighting::setAmbientColor(const glm::vec4& _ambient_color) noexcept { + ambient_color = _ambient_color; + change(); +} + +const Light& Lighting::getDirectionalLight() const noexcept { + return directional_light; +} + +Light& Lighting::getDirectionalLight() noexcept { + return directional_light; +} + +void Lighting::setDirectionalLight(const Light& _directional_light) { + directional_light = _directional_light; + change(); +} + +bool Lighting::isChanged() const noexcept { + return changed; +} + +void Lighting::resetChanged() noexcept { + changed = false; +} + +void Lighting::change() noexcept { + changed = true; +} + +const std::map& Lighting::getLights() const noexcept { + return punctual_lights.getLights();; +} + +std::map& Lighting::getLights() noexcept { + return punctual_lights.getLights(); +} + +LightContainer& Lighting::getLightContainer() noexcept { + return punctual_lights; +} + +Light& Lighting::add(Light&& light) { + if (light.isDirectional()) { + directional_light = std::move(light); + return directional_light; + } + + return punctual_lights.add(std::move(light)); +} + +Light& Lighting::add(const Light& light) { + if (light.isDirectional()) { + directional_light = light; + return directional_light; + } + + return punctual_lights.add(light); +} + + +void Lighting::updateSceneLightBuffer() { SceneLighting light_info { - directional_light, + { directional_light.getDirection(), 0.0f }, + directional_light.getColor(), ambient_color, - static_cast(lights.size()) + static_cast(punctual_lights.visibleSize()) }; - //TODO update changed? + buffer->mapData(&light_info, sizeof(SceneLighting)); } void Lighting::update() { - lights.update(); + punctual_lights.update(); - // maps global scene light buffer - updateLightBuffer(); + if (isChanged() || directional_light.isChanged()) { + updateSceneLightBuffer(); + resetChanged(); + directional_light.resetChanged(); + } // binds light buffer to the context // in case if there are many scenes or lighting classes buffer->bindBase(context.getIndexedBuffers().getBindingPoint(IndexedBuffer::Type::ShaderStorage, SCENE_LIGHTING_BUFFER_NAME)); } - -template -Lighting::operator LightContainer&() noexcept { - if constexpr (std::is_same_v) - return lights; - else - static_assert(!std::is_same_v, "No such light container for T type"); -} - -namespace Limitless { - template Lighting::operator LightContainer&() noexcept; -} diff --git a/src/limitless/ms/blending.cpp b/src/limitless/ms/blending.cpp index 1f8303ee..b1918644 100644 --- a/src/limitless/ms/blending.cpp +++ b/src/limitless/ms/blending.cpp @@ -4,57 +4,41 @@ using namespace Limitless::ms; -void Limitless::ms::setBlendingMode(ContextState& context, Blending blending, [[maybe_unused]] uint32_t opaque_count) noexcept { - switch (blending) { - case Blending::Opaque: -// context.enable(Capabilities::DepthTest); -// context.setDepthFunc(DepthFunc::Less); -// context.setDepthMask(DepthMask::True); - context.disable(Capabilities::Blending); - break; - case Blending::Additive: - context.enable(Capabilities::DepthTest); - context.setDepthFunc(DepthFunc::Less); - context.setDepthMask(DepthMask::False); - context.enable(Capabilities::Blending); - context.setBlendFunc(BlendFactor::One, BlendFactor::One); - break; - case Blending::Modulate: - context.enable(Capabilities::DepthTest); - context.setDepthFunc(DepthFunc::Less); - context.setDepthMask(DepthMask::False); - context.enable(Capabilities::Blending); - context.setBlendFunc(BlendFactor::DstColor, BlendFactor::Zero); - break; - case Blending::Translucent: - context.enable(Capabilities::DepthTest); - context.setDepthFunc(DepthFunc::Less); - context.setDepthMask(DepthMask::False); - context.enable(Capabilities::Blending); - context.setBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha); - break; - case Blending::MultipleOpaque: - context.enable(Capabilities::DepthTest); - context.setDepthFunc(DepthFunc::Lequal); - context.setDepthMask(DepthMask::True); - context.enable(Capabilities::Blending); - //TODO: refactor; does not work quite well w/ RTO normals write? only unlit? - // shading models for layering unreal? multi-pass rendering material then for lit? - // additive for now -// context.setBlendColor(glm::vec4(glm::vec3(1.0f / static_cast(opaque_count)), 1.0f)); -// context.setBlendFunc(BlendFactor::BlendColor, BlendFactor::One); - context.setBlendFunc(BlendFactor::One, BlendFactor::One); - break; - case Blending::Text: - context.disable(Capabilities::DepthTest); - context.enable(Capabilities::Blending); - context.setBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha); - break; - } -} - void Limitless::ms::setBlendingMode(Blending blending) noexcept { if (auto* state = ContextState::getState(glfwGetCurrentContext()); state) { - setBlendingMode(*state, blending); + switch (blending) { + case Blending::Opaque: +// state->enable(Capabilities::DepthTest); +// state->setDepthFunc(DepthFunc::Less); +// state->setDepthMask(DepthMask::True); + state->disable(Capabilities::Blending); + break; + case Blending::Additive: + state->enable(Capabilities::DepthTest); + state->setDepthFunc(DepthFunc::Less); + state->setDepthMask(DepthMask::False); + state->enable(Capabilities::Blending); + state->setBlendFunc(BlendFactor::One, BlendFactor::One); + break; + case Blending::Modulate: + state->enable(Capabilities::DepthTest); + state->setDepthFunc(DepthFunc::Less); + state->setDepthMask(DepthMask::False); + state->enable(Capabilities::Blending); + state->setBlendFunc(BlendFactor::DstColor, BlendFactor::Zero); + break; + case Blending::Translucent: + state->enable(Capabilities::DepthTest); + state->setDepthFunc(DepthFunc::Less); + state->setDepthMask(DepthMask::False); + state->enable(Capabilities::Blending); + state->setBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha); + break; + case Blending::Text: + state->disable(Capabilities::DepthTest); + state->enable(Capabilities::Blending); + state->setBlendFunc(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha); + break; + } } } \ No newline at end of file diff --git a/src/limitless/ms/material.cpp b/src/limitless/ms/material.cpp index 8eb0c4c8..ea14b07e 100644 --- a/src/limitless/ms/material.cpp +++ b/src/limitless/ms/material.cpp @@ -28,7 +28,7 @@ void Limitless::ms::swap(Material& lhs, Material& rhs) noexcept { swap(lhs.vertex_snippet, rhs.vertex_snippet); swap(lhs.fragment_snippet, rhs.fragment_snippet); swap(lhs.global_snippet, rhs.global_snippet); - swap(lhs.tessellation_snippet, rhs.tessellation_snippet); + swap(lhs.shading_snippet, rhs.shading_snippet); } Material& Material::operator=(Material material) { @@ -118,61 +118,6 @@ Material::Material(const Material& material) map(); } -template -void Material::map(std::vector& block, const Uniform& uniform) const { - const auto& uni = static_cast&>(uniform); - const auto offset = uniform_offsets.at(uniform.getName()); - std::memcpy(block.data() + offset, &uni.getValue(), sizeof(V)); -} - -void Material::map(std::vector& block, Uniform& uniform) { - switch (uniform.getType()) { - case UniformType::Value: - switch (uniform.getValueType()) { - case UniformValueType::Uint: - map(block, uniform); - break; - case UniformValueType::Int: - map(block, uniform); - break; - case UniformValueType::Float: - map(block, uniform); - break; - case UniformValueType::Vec2: - map(block, uniform); - break; - case UniformValueType::Vec3: - map(block, uniform); - break; - case UniformValueType::Vec4: - map(block, uniform); - break; - case UniformValueType::Mat4: - map(block, uniform); - break; - case UniformValueType::Mat3: - map(block, uniform); - break; - } - break; - case UniformType::Sampler: - if (ContextInitializer::isBindlessTextureSupported()) { - const auto& uni = static_cast(uniform); //NOLINT - const auto offset = uniform_offsets.at(uniform.getName()); - auto& bindless_texture = static_cast(uni.getSampler()->getExtensionTexture()); //NOLINT - bindless_texture.makeResident(); - std::memcpy(block.data() + offset, &bindless_texture.getHandle(), sizeof(uint64_t)); - } - break; - case UniformType::Time: { - auto& time = static_cast(uniform); //NOLINT - time.update(); - map(block, uniform); - break; - } - } -} - void Material::map() { std::vector block(material_buffer->getSize()); @@ -214,179 +159,123 @@ void Material::update() { } } -const UniformValue& Material::getColor() const { - try { - return static_cast&>(*properties.at(Property::Color)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No color in material."); - } -} - -const UniformValue& Material::getEmissiveColor() const { - try { - return static_cast&>(*properties.at(Property::EmissiveColor)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No emissive color in material."); - } -} - -const UniformValue& Material::getMetallic() const { - try { - return static_cast&>(*properties.at(Property::Metallic)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No metallic in material."); - } -} - -const UniformValue& Material::getRoughness() const { - try { - return static_cast&>(*properties.at(Property::Roughness)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No roughness in material."); - } -} - -const UniformSampler& Material::getDiffuse() const { - try { - return static_cast(*properties.at(Property::Diffuse)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No diffuse in material."); - } -} - -const UniformSampler& Material::getNormal() const { - try { - return static_cast(*properties.at(Property::Normal)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No normal in material."); - } -} - -const UniformSampler& Material::getEmissiveMask() const { - try { - return static_cast(*properties.at(Property::EmissiveMask)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No emissive mask in material."); - } -} - -const UniformSampler& Material::getBlendMask() const { +const glm::vec4& Material::getColor() const { try { - return static_cast(*properties.at(Property::BlendMask)); //NOLINT + return static_cast&>(*properties.at(Property::Color)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No blend mask in material."); + throw material_exception("Material property not found - Color"); } } -const UniformSampler& Material::getMetallicTexture() const { +const glm::vec4& Material::getEmissiveColor() const { try { - return static_cast(*properties.at(Property::MetallicTexture)); //NOLINT + return static_cast&>(*properties.at(Property::EmissiveColor)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No MetallicTexture in material."); + throw material_exception("Material property not found - Emissive Color"); } } -const UniformSampler& Material::getRoughnessTexture() const { +float Material::getMetallic() const { try { - return static_cast(*properties.at(Property::RoughnessTexture)); //NOLINT + return static_cast&>(*properties.at(Property::Metallic)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No RoughnessTexture in material."); + throw material_exception("Material property not found - Metallic"); } } -const UniformValue& Material::getTesselationFactor() const { +float Material::getRoughness() const { try { - return static_cast&>(*properties.at(Property::TessellationFactor)); //NOLINT + return static_cast&>(*properties.at(Property::Roughness)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No RoughnessTexture in material."); + throw material_exception("Material property not found - Roughness"); } } -UniformValue& Material::getColor() { +const std::shared_ptr& Material::getDiffuseTexture() const { try { - return static_cast&>(*properties.at(Property::Color)); //NOLINT + return static_cast(*properties.at(Property::Diffuse)).getSampler(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No color in material."); + throw material_exception("Material property not found - Diffuse"); } } -UniformValue& Material::getEmissiveColor() { +const std::shared_ptr& Material::getNormalTexture() const { try { - return static_cast&>(*properties.at(Property::EmissiveColor)); //NOLINT + return static_cast(*properties.at(Property::Normal)).getSampler(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No emissive color in material."); + throw material_exception("Material property not found - Normal"); } } -UniformValue& Material::getTesselationFactor() { +const std::shared_ptr& Material::getEmissiveMaskTexture() const { try { - return static_cast&>(*properties.at(Property::TessellationFactor)); //NOLINT + return static_cast(*properties.at(Property::EmissiveMask)).getSampler(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No RoughnessTexture in material."); + throw material_exception("Material property not found - EmissiveMask"); } } -UniformValue& Material::getMetallic() { +const std::shared_ptr& Material::getBlendMaskTexture() const { try { - return static_cast&>(*properties.at(Property::Metallic)); //NOLINT + return static_cast(*properties.at(Property::BlendMask)).getSampler(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No metallic in material."); + throw material_exception("Material property not found - BlendMask"); } } -UniformValue& Material::getRoughness() { +const std::shared_ptr& Material::getMetallicTexture() const { try { - return static_cast&>(*properties.at(Property::Roughness)); //NOLINT + return static_cast(*properties.at(Property::MetallicTexture)).getSampler(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No roughness in material."); + throw material_exception("Material property not found - MetallicTexture"); } } -UniformSampler& Material::getMetallicTexture() { +const std::shared_ptr& Material::getRoughnessTexture() const { try { - return static_cast(*properties.at(Property::MetallicTexture)); //NOLINT + return static_cast(*properties.at(Property::RoughnessTexture)).getSampler(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No MetallicTexture in material."); + throw material_exception("Material property not found - RoughnessTexture"); } } -UniformSampler& Material::getRoughnessTexture() { +glm::vec4& Material::getColor() { try { - return static_cast(*properties.at(Property::RoughnessTexture)); //NOLINT + return static_cast&>(*properties.at(Property::Color)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No RoughnessTexture in material."); + throw material_exception("Material property not found - Color"); } } -UniformSampler& Material::getDiffuse() { +glm::vec4& Material::getEmissiveColor() { try { - return static_cast(*properties.at(Property::Diffuse)); //NOLINT + return static_cast&>(*properties.at(Property::EmissiveColor)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No diffuse in material."); + throw material_exception("Material property not found - EmissiveColor"); } } -UniformSampler& Material::getNormal() { +float& Material::getMetallic() { try { - return static_cast(*properties.at(Property::Normal)); //NOLINT + return static_cast&>(*properties.at(Property::Metallic)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No normal in material."); + throw material_exception("Material property not found - Metallic"); } } -UniformSampler& Material::getEmissiveMask() { +float& Material::getRoughness() { try { - return static_cast(*properties.at(Property::EmissiveMask)); //NOLINT + return static_cast&>(*properties.at(Property::Roughness)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No emissive mask in material."); + throw material_exception("Material property not found - Roughness"); } } -UniformSampler& Material::getBlendMask() { +float& Material::getAbsorption() { try { - return static_cast(*properties.at(Property::BlendMask)); //NOLINT + return static_cast&>(*properties.at(Property::Absorption)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No blend mask in material."); + throw material_exception("Material property not found - Absorption"); } } @@ -398,19 +287,11 @@ bool Material::contains(const std::string& uniform_name) const { return uniforms.count(uniform_name); } -const UniformValue& Material::getAbsorption() const { +float& Material::getIoR() { try { - return static_cast&>(*properties.at(Property::Absorption)); //NOLINT + return static_cast&>(*properties.at(Property::IoR)).getValue(); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No absorption in material."); - } -} - -UniformValue& Material::getIoR() { - try { - return static_cast&>(*properties.at(Property::IoR)); //NOLINT - } catch (const std::out_of_range& e) { - throw material_property_not_found("No IoR in material."); + throw material_exception("Material property not found - IoR"); } } diff --git a/src/limitless/ms/material_buffer.cpp b/src/limitless/ms/material_buffer.cpp new file mode 100644 index 00000000..1029f56e --- /dev/null +++ b/src/limitless/ms/material_buffer.cpp @@ -0,0 +1,88 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace Limitless; +using namespace Limitless::ms; + +template +void MaterialBuffer::map(std::vector& block, const Uniform& uniform) const { + const auto& uni = static_cast&>(uniform); + const auto offset = uniform_offsets.at(uniform.getName()); + std::memcpy(block.data() + offset, &uni.getValue(), sizeof(V)); +} + +void MaterialBuffer::map(std::vector& block, Uniform& uniform) { + switch (uniform.getType()) { + case UniformType::Value: + switch (uniform.getValueType()) { + case UniformValueType::Uint: + map(block, uniform); + break; + case UniformValueType::Int: + map(block, uniform); + break; + case UniformValueType::Float: + map(block, uniform); + break; + case UniformValueType::Vec2: + map(block, uniform); + break; + case UniformValueType::Vec3: + map(block, uniform); + break; + case UniformValueType::Vec4: + map(block, uniform); + break; + case UniformValueType::Mat4: + map(block, uniform); + break; + case UniformValueType::Mat3: + map(block, uniform); + break; + } + break; + case UniformType::Sampler: + if (ContextInitializer::isBindlessTextureSupported()) { + const auto& uni = static_cast(uniform); //NOLINT + const auto offset = uniform_offsets.at(uniform.getName()); + auto& bindless_texture = static_cast(uni.getSampler()->getExtensionTexture()); //NOLINT + bindless_texture.makeResident(); + std::memcpy(block.data() + offset, &bindless_texture.getHandle(), sizeof(uint64_t)); + } + break; + case UniformType::Time: { + auto& time = static_cast(uniform); //NOLINT + time.update(); + map(block, uniform); + break; + } + } +} + +void MaterialBuffer::map(const Material& material) { + std::vector block(material_buffer->getSize()); + + for (const auto& [_, uniform] : material.getProperties()) { + map(block, *uniform); + } + + for (const auto& [_, uniform] : material.getUniforms()) { + map(block, *uniform); + } + + // adding shading in the end + auto shading = material.getShading(); + std::memcpy(block.data() + block.size() - sizeof(uint32_t), &shading, sizeof(uint32_t)); + + material_buffer->mapData(block.data(), block.size()); +} \ No newline at end of file diff --git a/src/limitless/ms/material_instance.cpp b/src/limitless/ms/material_instance.cpp index f13dcc82..eebd4c9a 100644 --- a/src/limitless/ms/material_instance.cpp +++ b/src/limitless/ms/material_instance.cpp @@ -62,17 +62,12 @@ void MaterialInstance::setMaterialState(Context& ctx, uint64_t id, ShaderType pa return pair.second->getBlending() == Blending::Opaque; }); - if (opaque_count == 1) { - setBlendingMode(ctx, Blending::Opaque); - } else { - setBlendingMode(ctx, Blending::MultipleOpaque, opaque_count); - } + setBlendingMode(Blending::Opaque); } else { - if (material->getRefraction()) { - setBlendingMode(ctx, Blending::Opaque); + setBlendingMode(Blending::Opaque); //TODO: ???? wtf? } else { - setBlendingMode(ctx, material->getBlending()); + setBlendingMode(material->getBlending()); } } diff --git a/src/limitless/ms/material_shader_define_replacer.cpp b/src/limitless/ms/material_shader_define_replacer.cpp index 20369725..0dcdf671 100644 --- a/src/limitless/ms/material_shader_define_replacer.cpp +++ b/src/limitless/ms/material_shader_define_replacer.cpp @@ -18,6 +18,10 @@ std::string MaterialShaderDefineReplacer::getPropertyDefines(const Material& mat defines.append("#define ENGINE_MATERIAL_REFRACTION\n"); } + if (material.getTwoSided()) { + defines.append("#define ENGINE_MATERIAL_TWO_SIDED\n"); + } + return defines; } @@ -33,11 +37,11 @@ void MaterialShaderDefineReplacer::replaceMaterialDependentDefine(Shader &shader shader.replaceKey(DEFINE_NAMES.at(Define::MaterialDependent), getMaterialDependentDefine(material, model_shader)); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Vertex], material.getVertexSnippet()); - shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Tesselation], material.getTessellationSnippet()); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Fragment], material.getFragmentSnippet()); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Global], material.getGlobalSnippet()); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomScalar], getScalarUniformDefines(material)); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomSamplers], getSamplerUniformDefines(material)); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomShading], material.getShadingSnippet()); } std::string MaterialShaderDefineReplacer::getScalarUniformDefines(const Material &material) { diff --git a/src/limitless/pipeline/common/shadow_pass.cpp b/src/limitless/pipeline/common/shadow_pass.cpp index 6070d9f6..e48f6542 100644 --- a/src/limitless/pipeline/common/shadow_pass.cpp +++ b/src/limitless/pipeline/common/shadow_pass.cpp @@ -30,5 +30,5 @@ void DirectionalShadowPass::addSetter(UniformSetter& setter) { } void DirectionalShadowPass::update(Scene& scene, [[maybe_unused]] Instances& instances, [[maybe_unused]] Context& ctx, [[maybe_unused]] const Camera& camera) { - light = &scene.lighting.directional_light; + light = &scene.lighting.getDirectionalLight(); } diff --git a/src/limitless/util/renderer_helper.cpp b/src/limitless/util/renderer_helper.cpp index 43b868d3..186aafe7 100644 --- a/src/limitless/util/renderer_helper.cpp +++ b/src/limitless/util/renderer_helper.cpp @@ -21,7 +21,7 @@ RendererHelper::RendererHelper(const RenderSettings& _settings) } void RendererHelper::renderLightsVolume(Context& context, const Lighting& lighting, const Assets& assets, const Camera& camera) { - if (lighting.lights.empty()) { + if (lighting.getLights().size() != 0) { return; } @@ -33,22 +33,22 @@ void RendererHelper::renderLightsVolume(Context& context, const Lighting& lighti auto sphere_instance = ModelInstance(assets.models.at("sphere"), assets.materials.at("default"), glm::vec3(0.0f)); context.setPolygonMode(CullFace::FrontBack, PolygonMode::Line); - for (const auto& light : lighting.lights) { - if (light.type == 1u) { - sphere_instance.setPosition(light.position); + for (const auto& [_, light] : lighting.getLights()) { + if (light.isPoint()) { + sphere_instance.setPosition(light.getPosition()); sphere_instance.setScale(glm::vec3(light.getRadius())); sphere_instance.update(context, camera); sphere_instance.draw(context, assets, ShaderType::Forward, ms::Blending::Opaque); } - if (light.type == 2u) { - auto cone = std::make_shared(0.0f, light.getRadius() * std::sin(glm::acos(light.scale_offset.x)), light.getRadius()); + if (light.isSpot()) { + auto cone = std::make_shared(0.0f, light.getRadius() * std::sin(glm::acos(light.getCone().x)), light.getRadius()); auto cone_instance = ModelInstance(cone, assets.materials.at("default"), glm::vec3(0.0f)); - cone_instance.setPosition(light.position); + cone_instance.setPosition(light.getPosition()); auto y = glm::vec3{0.0f, 1.0f, 0.0f}; - auto a = glm::cross(y, glm::vec3{light.direction}); - auto angle = glm::acos(glm::dot(y, glm::vec3{light.direction})); + auto a = glm::cross(y, light.getDirection()); + auto angle = glm::acos(glm::dot(y, light.getDirection())); cone_instance.setRotation(a * angle); cone_instance.update(context, camera); From 177019ab315c32796fd3219c560b69438d04d517 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Fri, 24 Nov 2023 23:32:14 +0300 Subject: [PATCH 09/15] ref --- CMakeLists.txt | 2 +- demo/assets.cpp | 1039 ++++++++--------- demo/materials_demoscene.cpp | 4 +- demo/models_demoscene.cpp | 2 - demo/sponza_demoscene.cpp | 2 +- .../limitless/core/shader/shader_program.hpp | 3 +- .../fx/renderers/beam_emitter_renderer.hpp | 2 +- .../fx/renderers/mesh_emitter_renderer.hpp | 2 +- .../fx/renderers/sprite_emitter_renderer.hpp | 2 +- include/limitless/ms/material.hpp | 177 ++- include/limitless/ms/material_buffer.hpp | 27 - include/limitless/ms/material_builder.hpp | 152 ++- .../ms/material_shader_define_replacer.hpp | 1 - .../serialization/material_serializer.hpp | 10 +- shaders_ref/lighting/lighting.glsl | 10 +- shaders_ref/material/material.glsl | 2 - shaders_ref/material/material_context.glsl | 2 + shaders_ref/shading/cloth.glsl | 16 - shaders_ref/shading/custom.glsl | 8 +- shaders_ref/shading/shading_context.glsl | 4 +- shaders_ref/shading/subsurface.glsl | 17 - src/limitless/assets.cpp | 40 +- src/limitless/core/shader/shader_program.cpp | 2 +- src/limitless/fx/effect_builder.cpp | 6 +- .../fx/effect_shader_define_replacer.cpp | 2 +- src/limitless/instances/mesh_instance.cpp | 22 +- src/limitless/loaders/model_loader.cpp | 39 +- src/limitless/ms/material.cpp | 542 +++++++-- src/limitless/ms/material_buffer.cpp | 88 -- src/limitless/ms/material_builder.cpp | 448 +++---- src/limitless/ms/material_instance.cpp | 6 +- .../ms/material_shader_define_replacer.cpp | 1 + .../pipeline/deferred/translucent_pass.cpp | 1 - src/limitless/pipeline/forward/color_pass.cpp | 1 - .../serialization/material_serializer.cpp | 134 ++- src/limitless/skybox/skybox.cpp | 20 +- test/limitless/ms/material_builder_test.cpp | 6 +- 37 files changed, 1536 insertions(+), 1306 deletions(-) delete mode 100644 shaders_ref/shading/cloth.glsl delete mode 100644 shaders_ref/shading/subsurface.glsl diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c63fa6d..638a74f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,8 +247,8 @@ set(ENGINE_SRC ${ENGINE_INSTANCES} ${ENGINE_LIGHTING} ${ENGINE_LOADERS} - ${ENGINE_MODELS} ${ENGINE_SERIALIZATION} + ${ENGINE_MODELS} ${ENGINE_UTIL} ${ENGINE_TEXT} ${ENGINE_PIPELINE} diff --git a/demo/assets.cpp b/demo/assets.cpp index 8b56d9b7..21f6dc2b 100644 --- a/demo/assets.cpp +++ b/demo/assets.cpp @@ -19,250 +19,252 @@ using namespace Limitless; void DemoAssets::loadLightingScene() { { - MaterialBuilder builder {*this}; const fs::path assets_dir {getAssetsDir()}; - builder.setName("PBR") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/rustediron2_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/rustediron2_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/rustediron2_basecolor.png", {::TextureLoaderFlags::Space::sRGB})) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/rustediron2_normal.png")) - .setShading(Shading::Lit) - .addModelShader(::InstanceType::Instanced) - .addModelShader(::InstanceType::Model) - .build(); + Material::builder() + .name("PBR") + .metallic(TextureLoader::load(*this, assets_dir / "textures/rustediron2_metallic.png")) + .roughness(TextureLoader::load(*this, assets_dir / "textures/rustediron2_roughness.png")) + .diffuse(TextureLoader::load(*this, assets_dir / "textures/rustediron2_basecolor.png", {::TextureLoaderFlags::Space::sRGB})) + .normal(TextureLoader::load(*this, assets_dir / "textures/rustediron2_normal.png")) + .shading(Shading::Lit) + .models({::InstanceType::Instanced, ::InstanceType::Model}) + .build(*this); } { - MaterialBuilder builder {*this}; const fs::path assets_dir {getAssetsDir()}; - builder.setName("floor") - .setShading(Shading::Lit) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/wood.jpg", {::TextureLoaderFlags::Space::sRGB})) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/wood_normal.png")) - .setShading(Shading::Lit) - .setTwoSided(true) - .addModelShader(InstanceType::Model) - .addModelShader(InstanceType::Instanced) - .build(); + Material::builder() + .name("floor") + .shading(Shading::Lit) + .diffuse(TextureLoader::load(*this, assets_dir / "textures/wood.jpg", {::TextureLoaderFlags::Space::sRGB})) + .normal(TextureLoader::load(*this, assets_dir / "textures/wood_normal.png")) + .two_sided(true) + .models({::InstanceType::Instanced, ::InstanceType::Model}) + .build(*this); } } void DemoAssets::loadMaterialsScene() { - MaterialBuilder builder {*this}; const fs::path assets_dir {getAssetsDir()}; - builder .setName("color") - .add(Property::Color, glm::vec4(1.0f, 0.5f, 1.0f, 1.0f)) - .setShading(Shading::Unlit) - .build(); - - builder .setName("albedo") - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/albedo.jpg", { - TextureLoaderFlags::Space::sRGB - })) - .setShading(Shading::Unlit) - .build(); - - builder .setName("emissive_color") - .add(Property::EmissiveColor, glm::vec4(5.0f, 5.1f, 0.0f, 1.0f)) - .setShading(Shading::Unlit) - .build(); - - builder .setName("emissive_mask") - .add(Property::EmissiveColor, glm::vec4(2.5f, 0.0f, 5.0f, 1.0f)) - .add(Property::Color, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) - .add(Property::EmissiveMask, TextureLoader::load(*this, assets_dir / "textures/open_mask.jpg", { - TextureLoaderFlags::Filter::Nearest - })) - .setShading(Shading::Unlit) - .setBlending(::Blending::Additive) - .setTwoSided(true) - .build(); - - builder .setName("blend_mask") - .add(Property::BlendMask, TextureLoader::load(*this, assets_dir / "textures/blend_mask.jpg", { - TextureLoaderFlags::Filter::Nearest - })) - .add(Property::Color, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)) - .setShading(Shading::Unlit) - .setTwoSided(true) - .build(); - - builder .setName("basic1") - .add(Property::Metallic, 0.0f) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/stonework_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/stonework_albedo.png")) - .add(Property::AmbientOcclusionTexture, TextureLoader::load(*this, assets_dir / "textures/stonework_ao.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/stonework_normal.png")) - .setShading(Shading::Lit) - .build(); - - builder .setName("basic2") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/metall_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/metall_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/metall_albedo.png")) - .add(Property::AmbientOcclusionTexture, TextureLoader::load(*this, assets_dir / "textures/metall_ao.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/metall_normal.png")) - .setShading(Shading::Lit) - .build(); - - builder .setName("basic3") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/green_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/green_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/green_albedo.png")) - .add(Property::AmbientOcclusionTexture, TextureLoader::load(*this, assets_dir / "textures/green_ao.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/green_normal.png")) - .setShading(Shading::Lit) - .build(); - - builder .setName("basic4") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/charcoal_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/charcoal_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/charcoal_albedo.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/charcoal_normal.png")) - .setShading(Shading::Lit) - .setTwoSided(true) - .build(); - - builder .setName("basic5") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/pirate_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/pirate_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/pirate_albedo.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/pirate_normal.png")) - .setShading(Shading::Lit) - .setTwoSided(true) - .build(); - - builder .setName("basic6") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/ornate_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/ornate_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/ornate_albedo.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/ornate_normal.png")) - .setShading(Shading::Lit) - .build(); - - builder .setName("basic7") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/streaked_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/streaked_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/streaked_albedo.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/streaked_normal.png")) - .setShading(Shading::Lit) - .build(); - - builder .setName("basic8") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/fabric_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/fabric_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/fabric_albedo.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/fabric_normal.png")) - .setShading(Shading::Lit) - .build(); - - builder .setName("refraction") - .setBlending(Blending::Translucent) - .setRefraction(true) - .add(Property::IoR, 1.5) - .addUniform(std::make_unique("time")) - .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga"))) - .setFragmentSnippet("mctx.IoR = texture(noise, vec2(getVertexUV().x, getVertexUV().y + time * 0.1)).r;" + Material::builder() + .name("color") + .color({1.0f, 0.5f, 1.0f, 1.0f}) + .shading(Shading::Unlit) + .build(*this); + + Material::builder() + .name("albedo") + .diffuse(TextureLoader::load(*this, assets_dir / "textures/albedo.jpg", {TextureLoaderFlags::Space::sRGB })) + .shading(Shading::Unlit) + .build(*this); + + Material::builder() + .name("emissive_color") + .emissive_color({5.0f, 5.1f, 0.0f}) + .shading(Shading::Unlit) + .build(*this); + + Material::builder() + .name("emissive_mask") + .emissive_color({2.5f, 0.0f, 5.0f}) + .color({0.0f, 0.0f, 0.0f, 1.0f}) + .emissive_mask(TextureLoader::load(*this, assets_dir / "textures/open_mask.jpg", {TextureLoaderFlags::Filter::Nearest})) + .shading(Shading::Unlit) + .blending(::Blending::Additive) + .two_sided(true) + .build(*this); + + Material::builder() + .name("blend_mask") + .blend_mask(TextureLoader::load(*this, assets_dir / "textures/blend_mask.jpg", {TextureLoaderFlags::Filter::Nearest})) + .color({1.0f, 0.0f, 0.0f, 1.0f}) + .shading(Shading::Unlit) + .two_sided(true) + .build(*this); + + Material::builder() + .name("basic1") + .metallic(0.3f) + .roughness(TextureLoader::load(*this, assets_dir / "textures/stonework_roughness.png")) + .diffuse(TextureLoader::load(*this, assets_dir / "textures/stonework_albedo.png")) + .ao(TextureLoader::load(*this, assets_dir / "textures/stonework_ao.png")) + .normal(TextureLoader::load(*this, assets_dir / "textures/stonework_normal.png")) + .shading(Shading::Lit) + .build(*this); + + Material::builder() + .name("basic2") + .metallic(TextureLoader::load(*this, assets_dir / "textures/metall_metallic.png")) + .roughness(TextureLoader::load(*this, assets_dir / "textures/metall_roughness.png")) + .diffuse(TextureLoader::load(*this, assets_dir / "textures/metall_albedo.png")) + .ao(TextureLoader::load(*this, assets_dir / "textures/metall_ao.png")) + .normal(TextureLoader::load(*this, assets_dir / "textures/metall_normal.png")) + .shading(Shading::Lit) + .build(*this); + + Material::builder() + .name("basic3") + .metallic(TextureLoader::load(*this, assets_dir / "textures/green_metallic.png")) + .roughness(TextureLoader::load(*this, assets_dir / "textures/green_roughness.png")) + .diffuse(TextureLoader::load(*this, assets_dir / "textures/green_albedo.png")) + .ao(TextureLoader::load(*this, assets_dir / "textures/green_ao.png")) + .normal(TextureLoader::load(*this, assets_dir / "textures/green_normal.png")) + .shading(Shading::Lit) + .build(*this); + + Material::builder() + .name("basic4") + .metallic(TextureLoader::load(*this, assets_dir / "textures/charcoal_metallic.png")) + .roughness( TextureLoader::load(*this, assets_dir / "textures/charcoal_roughness.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/charcoal_albedo.png")) + .normal( TextureLoader::load(*this, assets_dir / "textures/charcoal_normal.png")) + .shading(Shading::Lit) + .two_sided(true) + .build(*this); + + Material::builder() + .name("basic5") + .metallic(TextureLoader::load(*this, assets_dir / "textures/pirate_metallic.png")) + .roughness( TextureLoader::load(*this, assets_dir / "textures/pirate_roughness.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/pirate_albedo.png")) + .normal( TextureLoader::load(*this, assets_dir / "textures/pirate_normal.png")) + .shading(Shading::Lit) + .two_sided(true) + .build(*this); + + Material::builder() + .name("basic6") + .metallic(TextureLoader::load(*this, assets_dir / "textures/ornate_metallic.png")) + .roughness( TextureLoader::load(*this, assets_dir / "textures/ornate_roughness.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/ornate_albedo.png")) + .normal( TextureLoader::load(*this, assets_dir / "textures/ornate_normal.png")) + .shading(Shading::Lit) + .build(*this); + + Material::builder().name("basic7") + .metallic(TextureLoader::load(*this, assets_dir / "textures/streaked_metallic.png")) + .roughness( TextureLoader::load(*this, assets_dir / "textures/streaked_roughness.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/streaked_albedo.png")) + .normal( TextureLoader::load(*this, assets_dir / "textures/streaked_normal.png")) + .shading(Shading::Lit) + .build(*this); + + Material::builder().name("basic8") + .metallic(TextureLoader::load(*this, assets_dir / "textures/fabric_metallic.png")) + .roughness( TextureLoader::load(*this, assets_dir / "textures/fabric_roughness.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/fabric_albedo.png")) + .normal( TextureLoader::load(*this, assets_dir / "textures/fabric_normal.png")) + .shading(Shading::Lit) + .build(*this); + + Material::builder().name("refraction") + .blending(Blending::Translucent) + .refraction(true) + .ior(1.5) + .time() + .custom("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga")) + .fragment("mctx.IoR = texture(noise, vec2(getVertexUV().x, getVertexUV().y + time * 0.1)).r;" "mctx.IoR = clamp(mctx.IoR, 0.0, 1.0);" ) - .setShading(Shading::Unlit) - .build(); - - builder .setName("blending1") - .add(Property::Color, glm::vec4(2.0f, 0.0f, 0.0f, 0.5f)) - .setShading(Shading::Unlit) - .setBlending(Blending::Translucent) - .setTwoSided(true) - .build(); - - builder .setName("blending2") - .add(Property::Color, glm::vec4(0.0f, 2.0f, 0.0f, 0.4f)) - .setShading(Shading::Unlit) - .setBlending(Blending::Translucent) - .setTwoSided(true) - .build(); - - builder .setName("blending3") - .add(Property::Color, glm::vec4(0.0f, 0.0f, 2.0f, 0.3f)) - .setShading(Shading::Unlit) - .setBlending(Blending::Translucent) - .setTwoSided(true) - .build(); - - builder .setName("blending4") - .add(Property::Color, glm::vec4(1.0f, 0.5f, 0.5f, 1.0f)) - .setShading(Shading::Unlit) - .setBlending(Blending::Additive) - .setTwoSided(true) - .build(); - - builder .setName("blending5") - .add(Property::Color, glm::vec4(2.0f, 0.3f, 0.3f, 1.0f)) - .setShading(Shading::Unlit) - .setBlending(Blending::Modulate) - .setTwoSided(true) - .build(); - - builder .setName("lava") - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/lava.png", { + .shading(Shading::Unlit) + .build(*this); + + Material::builder().name("blending1") + .color(glm::vec4(2.0f, 0.0f, 0.0f, 0.5f)) + .shading(Shading::Unlit) + .blending(Blending::Translucent) + .two_sided(true) + .build(*this); + + Material::builder().name("blending2") + .color(glm::vec4(0.0f, 2.0f, 0.0f, 0.4f)) + .shading(Shading::Unlit) + .blending(Blending::Translucent) + .two_sided(true) + .build(*this); + + Material::builder().name("blending3") + .color(glm::vec4(0.0f, 0.0f, 2.0f, 0.3f)) + .shading(Shading::Unlit) + .blending(Blending::Translucent) + .two_sided(true) + .build(*this); + + Material::builder().name("blending4") + .color(glm::vec4(1.0f, 0.5f, 0.5f, 1.0f)) + .shading(Shading::Unlit) + .blending(Blending::Additive) + .two_sided(true) + .build(*this); + + Material::builder().name("blending5") + .color(glm::vec4(2.0f, 0.3f, 0.3f, 1.0f)) + .shading(Shading::Unlit) + .blending(Blending::Modulate) + .two_sided(true) + .build(*this); + + Material::builder().name("lava") + .diffuse( TextureLoader::load(*this, assets_dir / "textures/lava.png", { TextureLoaderFlags::Space::sRGB })) - .add(Property::EmissiveColor, glm::vec4(2.5f, 0.9f, 0.1f, 1.0f)) - .add(Property::Color, glm::vec4(2.5f, 0.9f, 0.1f, 1.0f)) - .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga"))) - .addUniform(std::make_unique("time")) - .setFragmentSnippet( + .emissive_color( glm::vec4(2.5f, 0.9f, 0.1f, 1.0f)) + .color(glm::vec4(2.5f, 0.9f, 0.1f, 1.0f)) + .custom("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga")) + .time() + .fragment( "vec2 panned = vec2(getVertexUV().x + time * 0.1, getVertexUV().y + time * 0.05);" "vec2 uv = getVertexUV() + texture(noise, panned).r;" "mctx.color.rgb = getMaterialDiffuse(uv).rgb;" "mctx.emissive_color *= texture(noise, panned).g;" ) - .setShading(Shading::Unlit) - .build(); + .shading(Shading::Unlit) + .build(*this); - builder .setName("ice") - .add(Property::EmissiveColor, glm::vec4(1.0f)) - .add(Property::Color, glm::vec4(1.0f)) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/ice.jpg", { + Material::builder().name("ice") + .emissive_color( glm::vec4(1.0f)) + .color(glm::vec4(1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/ice.jpg", { TextureLoaderFlags::Space::sRGB })) - .addUniform(std::make_unique("snow", TextureLoader::load(*this, assets_dir / "textures/snow.jpg"))) - .addUniform(std::make_unique("time")) - .setFragmentSnippet( + .custom("snow", TextureLoader::load(*this, assets_dir / "textures/snow.jpg")) + .time() + .fragment( "vec2 uv = getVertexUV() + time * 0.05;" "mctx.color.rgb += texture(snow, uv).rgb * abs(cos(time * 0.5));" "mctx.emissive_color *= texture(snow, uv).r;" ) - .setShading(Shading::Unlit) - .build(); + .shading(Shading::Unlit) + .build(*this); - builder .setName("poison") - .add(Property::EmissiveColor, glm::vec4(0.1f, 4.0f, 0.1f, 1.0f)) - .add(Property::Color, glm::vec4(0.1f, 4.0f, 0.1f, 1.0f)) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/poison.jpg", { + Material::builder().name("poison") + .emissive_color( glm::vec4(0.1f, 4.0f, 0.1f, 1.0f)) + .color(glm::vec4(0.1f, 4.0f, 0.1f, 1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/poison.jpg", { TextureLoaderFlags::Space::sRGB })) - .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga"))) - .addUniform(std::make_unique("time")) - .setFragmentSnippet( + .custom("noise", TextureLoader::load(*this, assets_dir / "textures/true_noise.tga")) + .time() + .fragment( "vec2 panned = vec2(getVertexUV().x + time * 0.05, getVertexUV().y);" "vec2 uv = vec2(getVertexUV().x, getVertexUV().y + texture(noise, panned).g);" "mctx.color.rgb = getMaterialDiffuse(uv).rgb;" "mctx.emissive_color *= getMaterialDiffuse(uv).g;" ) - .setShading(Shading::Unlit) - .build(); + .shading(Shading::Unlit) + .build(*this); - builder.setName("fireball") - .setVertexSnippet("vec2 uv_1 = vec2(uv.x + time * 0.05, uv.y + time * 0.0);\n" + Material::builder() + .name("fireball") + .vertex("vec2 uv_1 = vec2(uv.x + time * 0.05, uv.y + time * 0.0);\n" "vec2 uv_2 = vec2(uv.x - time * 0.05, uv.y - time * 0.0);\n" " \n" "float s = texture(fire_mask, uv_1).r;\n" "float t = texture(fire_mask, uv_2).r;\n" "\n" "vertex_position.xyz -= getVertexNormal() * texture(fire_mask, uv + vec2(s, t)).r * 0.6;") - .setFragmentSnippet("vec2 uv = getVertexUV();" + .fragment("vec2 uv = getVertexUV();" "vec2 uv_1 = vec2(uv.x + time * 0.05, uv.y + time * 0.0);\n" "vec2 uv_2 = vec2(uv.x - time * 0.05, uv.y - time * 0.0);\n" " \n" @@ -272,73 +274,73 @@ void DemoAssets::loadMaterialsScene() { "mctx.emissive_color = getMaterialDiffuse(uv + vec2(s, t)).rgb;\n" "\n" "if (mctx.emissive_color.r <= 0.2) discard;") - .addUniform(std::make_unique("time")) - .addUniform(std::make_unique("fire_mask", TextureLoader::load(*this, assets_dir / "textures/fireball_mask.png"))) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/rock_lava.png")) - .add(Property::Color, glm::vec4{15.0f, 5.0f, 0.0f, 1.0f}) - .add(Property::EmissiveColor, glm::vec4{1.0f}) - .setShading(Shading::Unlit) - .setBlending(Blending::Additive) - .setTwoSided(true) - .build(); - - builder .setName("bump_mapping") - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "textures/brickwork_metallic.png")) - .add(Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "textures/brickwork_roughness.png")) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/brickwork_albedo.png")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "textures/brickwork_normal.png")) - .add(Property::AmbientOcclusionTexture, TextureLoader::load(*this, assets_dir / "textures/brickwork_ao.png")) - .addUniform(std::make_unique("height", TextureLoader::load(*this, assets_dir / "textures/brickwork_height.png"))) - .setShading(Shading::Lit) - .setVertexSnippet( + .time() + .custom("fire_mask", TextureLoader::load(*this, assets_dir / "textures/fireball_mask.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/rock_lava.png")) + .color(glm::vec4{15.0f, 5.0f, 0.0f, 1.0f}) + .emissive_color( glm::vec4{1.0f}) + .shading(Shading::Unlit) + .blending(Blending::Additive) + .two_sided(true) + .build(*this); + + Material::builder().name("bump_mapping") + .metallic(TextureLoader::load(*this, assets_dir / "textures/brickwork_metallic.png")) + .roughness( TextureLoader::load(*this, assets_dir / "textures/brickwork_roughness.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/brickwork_albedo.png")) + .normal( TextureLoader::load(*this, assets_dir / "textures/brickwork_normal.png")) + .ao(TextureLoader::load(*this, assets_dir / "textures/brickwork_ao.png")) + .custom("height", TextureLoader::load(*this, assets_dir / "textures/brickwork_height.png")) + .shading(Shading::Lit) + .vertex( "vertex_position += getVertexNormal() * texture(height, getVertexUV()).xyz * 0.25;" ) - .build(); + .build(*this); - builder .setName("fresnel") - .add(::Property::EmissiveColor, glm::vec4(5.0, 0.7, 0.3, 1.0)) - .addUniform(std::make_unique("time")) - .setShading(Shading::Unlit) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/albedo.jpg", { + Material::builder().name("fresnel") + .emissive_color(glm::vec4(5.0, 0.7, 0.3, 1.0)) + .time() + .shading(Shading::Unlit) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/albedo.jpg", { TextureLoaderFlags::Space::sRGB })) - .setGlobalSnippet( + .global( "#include \"../functions/fresnel.glsl\"" ) - .setFragmentSnippet( + .fragment( "mctx.emissive_color *= fresnel(getVertexNormal(), getCameraPosition() - getVertexPosition(), 5.0);" ) - .build(); + .build(*this); - builder .setName("hue_shift") - .addUniform(std::make_unique("time")) - .setShading(Shading::Unlit) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/albedo.jpg", { + Material::builder().name("hue_shift") + .time() + .shading(Shading::Unlit) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/albedo.jpg", { TextureLoaderFlags::Space::sRGB })) - .add(Property::Color, glm::vec4(1.0)) - .setGlobalSnippet( + .color(glm::vec4(1.0)) + .global( "#include \"../functions/hue_shift.glsl\"" ) - .setFragmentSnippet( + .fragment( "mctx.color.rgb = hue_shift(mctx.color.rgb, time);" ) - .build(); + .build(*this); } void DemoAssets::loadEffectsScene() { { - MaterialBuilder builder {*this}; const fs::path assets_dir {ENGINE_ASSETS_DIR}; - builder .setName("blink") - .add(Property::Color, glm::vec4(1.0f)) - .addUniform(std::make_unique("mask", TextureLoader::load(*this, assets_dir / "textures/fireball_mask.png"))) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/blink.jpg")) - .setShading(Shading::Unlit) - .setBlending(Blending::Translucent) - .setTwoSided(true) - .setFragmentSnippet("vec2 uv = getVertexUV();" + Material::builder() + .name("blink") + .color(glm::vec4(1.0f)) + .custom("mask", TextureLoader::load(*this, assets_dir / "textures/fireball_mask.png")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/blink.jpg")) + .shading(Shading::Unlit) + .blending(Blending::Translucent) + .two_sided(true) + .fragment("vec2 uv = getVertexUV();" "float tile = getParticleProperties().z;\n" "float erode = getParticleProperties().y;\n" "float dist = getParticleProperties().x;\n" @@ -351,8 +353,8 @@ void DemoAssets::loadEffectsScene() { "\n" "mctx.color.a = mix(0.0, m_a, pow(r, erode));" ) - .addModelShader(InstanceType::Effect) - .build(); + .model(InstanceType::Effect) + .build(*this); } { @@ -393,27 +395,27 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; const fs::path assets_dir{ENGINE_ASSETS_DIR}; - builder .setName("shield") - .setShading(::Shading::Unlit) - .setBlending(::Blending::Additive) - .addModelShader(::InstanceType::Effect) - .add(Property::Color, glm::vec4(1.0f)) - .addUniform(std::make_unique("maintexture", TextureLoader::load(*this, assets_dir / "textures/shield_texture.jpg"))) - .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir / "textures/noise.png"))) - .addUniform(std::make_unique>("vertex_offset_freq", 2.0f)) - .addUniform(std::make_unique>("vertex_offset_dir", glm::vec3(0.2))) - .setFragmentSnippet("vec2 uv = getVertexUV();" + Material::builder() + .name("shield") + .shading(::Shading::Unlit) + .blending(::Blending::Additive) + .model(::InstanceType::Effect) + .color(glm::vec4(1.0f)) + .custom("maintexture", TextureLoader::load(*this, assets_dir / "textures/shield_texture.jpg")) + .custom("noise", TextureLoader::load(*this, assets_dir / "textures/noise.png")) + .custom("vertex_offset_freq", 2.0f) + .custom("vertex_offset_dir", glm::vec3(0.2)) + .fragment("vec2 uv = getVertexUV();" "float fres = fresnel(getVertexNormal(), getCameraPosition() - getVertexPosition(), 3.5);" "mctx.color.rgb *= 1.0 - texture(maintexture, uv).r;" "mctx.color.rgb *= fres * vec3(33.0 / 255.0 * 15.0f, 99.0 / 255.0 * 15.0f, 1000.0 / 255.0 * 25.0f);" ) - .setVertexSnippet( + .vertex( "vertex_position.xyz += sin(getParticleTime() * vertex_offset_freq) * getVertexNormal() * vertex_offset_dir *texture(noise, getParticleTime() + uv).r;") - .setGlobalSnippet("#include \"../functions/fresnel.glsl\"") - .build(); + .global("#include \"../functions/fresnel.glsl\"") + .build(*this); } { @@ -429,10 +431,10 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; const fs::path assets_dir {ENGINE_ASSETS_DIR}; - builder .setName("fireball_material") - .setFragmentSnippet("vec2 uv = getVertexUV();" + Material::builder() + .name("fireball_material") + .fragment("vec2 uv = getVertexUV();" "uv.y -= 0.1;\n" "vec2 panned = vec2(uv.x + getParticleTime() * 0.5 + getParticleProperties().x, " "uv.y + getParticleTime() * 0.8 + getParticleProperties().y);\n" @@ -449,26 +451,26 @@ void DemoAssets::loadEffectsScene() { "mctx.color.rgb = getMaterialDiffuse(uv).rgb;\n" "mctx.color.rgb *= clamp((1.0 - getParticleProperties().z) * r, 0, 1);" ) - .addUniform(std::make_unique("noise", TextureLoader::load(*this, assets_dir /"textures/true_noise.tga"))) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/true_fire.tga")) - .add(Property::Color, glm::vec4(1.0f)) - .setShading(Shading::Unlit) - .setBlending(Blending::Additive) - .setGlobalSnippet("#include \"../functions/tone_mapping.glsl\"") - .addModelShader(::InstanceType::Effect) - .build(); - - builder .setName("fireball_sparks") - .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7);" + .custom("noise", TextureLoader::load(*this, assets_dir /"textures/true_noise.tga")) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/true_fire.tga")) + .color(glm::vec4(1.0f)) + .shading(Shading::Unlit) + .blending(Blending::Additive) + .global("#include \"../functions/tone_mapping.glsl\"") + .model(::InstanceType::Effect) + .build(*this); + + Material::builder().name("fireball_sparks") + .fragment("mctx.emissive_color *= circle(getVertexUV(), 0.7);" "mctx.color.rgb *= circle(getVertexUV(), 0.7);") - .setGlobalSnippet("#include \"../functions/circle.glsl\"") - - .add(Property::EmissiveColor, glm::vec4{5.0f, 1.5f, 1.0f, 1.0f}) - .add(Property::Color, glm::vec4(1.0)) - .setShading(Shading::Unlit) - .setBlending(Blending::Additive) - .addModelShader(::InstanceType::Effect) - .build(); + .global("#include \"../functions/circle.glsl\"") + + .emissive_color( glm::vec4{5.0f, 1.5f, 1.0f, 1.0f}) + .color(glm::vec4(1.0)) + .shading(Shading::Unlit) + .blending(Blending::Additive) + .model(::InstanceType::Effect) + .build(*this); } { EffectBuilder builder {*this}; @@ -500,16 +502,16 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; - builder.setName("explosion") - .setBlending(Blending::Additive) - .add(::Property::EmissiveColor, glm::vec4(2.0, 1.0, 0.3, 1.0)) - .add(::Property::Color, glm::vec4(1.0, 1.0, 0.3, 1.0)) - .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" + Material::builder() + .name("explosion") + .blending(Blending::Additive) + .emissive_color(glm::vec4(2.0, 1.0, 0.3, 1.0)) + .color( glm::vec4(1.0, 1.0, 0.3, 1.0)) + .fragment("mctx.emissive_color *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" "mctx.color.rgb *= circle(getVertexUV(), 0.7);") - .setGlobalSnippet("#include \"../functions/circle.glsl\"") - .addModelShader(InstanceType::Effect) - .build(); + .global("#include \"../functions/circle.glsl\"") + .model(InstanceType::Effect) + .build(*this); } { @@ -532,16 +534,15 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; - builder .setName("hurricane") - .setBlending(Blending::Additive) - .add(::Property::EmissiveColor, glm::vec4(5.0, 0.0, 5.0, 1.0)) - .add(::Property::Color, glm::vec4(1.0, 0.0, 1.0, 1.0)) - .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.5);" + Material::builder().name("hurricane") + .blending(Blending::Additive) + .emissive_color(glm::vec4(5.0, 0.0, 5.0, 1.0)) + .color(glm::vec4(1.0, 0.0, 1.0, 1.0)) + .fragment("mctx.emissive_color *= circle(getVertexUV(), 0.5);" "mctx.color.rgb = vec3(0.0);") - .setGlobalSnippet("#include \"../functions/circle.glsl\"") - .addModelShader(InstanceType::Effect) - .build(); + .global("#include \"../functions/circle.glsl\"") + .model(InstanceType::Effect) + .build(*this); } { @@ -563,17 +564,17 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; - builder.setName("drop") - .add(Property::EmissiveColor, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) - .add(Property::Color, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) - .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" + Material::builder() + .name("drop") + .emissive_color( glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) + .color(glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) + .fragment("mctx.emissive_color *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;" "mctx.color.rgb *= circle(getVertexUV(), 0.7) * getParticleColor().rgb;") - .setShading(Shading::Unlit) - .setBlending(Blending::Additive) - .setGlobalSnippet("#include \"../functions/circle.glsl\"") - .addModelShader(InstanceType::Effect) - .build(); + .shading(Shading::Unlit) + .blending(Blending::Additive) + .global("#include \"../functions/circle.glsl\"") + .model(InstanceType::Effect) + .build(*this); } { @@ -593,14 +594,15 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; - builder.setName("beam_lightning") - .add(Property::EmissiveColor, glm::vec4(2.8f, 2.8f, 4.8f, 1.0f)) - .setFragmentSnippet("mctx.emissive_color *= getParticleColor().rgb;") - .setShading(Shading::Unlit) - .setBlending(Blending::Opaque) - .addModelShader(InstanceType::Effect) - .build(); + + Material::builder() + .name("beam_lightning") + .emissive_color( glm::vec4(2.8f, 2.8f, 4.8f, 1.0f)) + .fragment("mctx.emissive_color *= getParticleColor().rgb;") + .shading(Shading::Unlit) + .blending(Blending::Opaque) + .model(InstanceType::Effect) + .build(*this); } { @@ -625,17 +627,17 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; - builder.setName("skeleton4ik") - .add(Property::EmissiveColor, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) - .add(Property::Color, glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) - .setFragmentSnippet("mctx.emissive_color *= circle(getVertexUV(), 0.7);" + Material::builder() + .name("skeleton4ik") + .emissive_color( glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) + .color(glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) + .fragment("mctx.emissive_color *= circle(getVertexUV(), 0.7);" "mctx.color.rgb *= circle(getVertexUV(), 0.7);") - .setShading(Shading::Unlit) - .setBlending(Blending::Additive) - .setGlobalSnippet("#include \"../functions/circle.glsl\"") - .addModelShader(InstanceType::Effect) - .build(); + .shading(Shading::Unlit) + .blending(Blending::Additive) + .global("#include \"../functions/circle.glsl\"") + .model(InstanceType::Effect) + .build(*this); } { @@ -652,35 +654,35 @@ void DemoAssets::loadEffectsScene() { } { - MaterialBuilder builder {*this}; const fs::path assets_dir {ENGINE_ASSETS_DIR}; - builder .setName("aura") - .setShading(::Shading::Unlit) - .setBlending(::Blending::Additive) - .setTwoSided(true) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "textures/aura.png")) - .addModelShader(::InstanceType::Effect) - .build(); - - builder .setName("aura_sparks") - .setShading(::Shading::Unlit) - .setBlending(::Blending::Additive) - .setTwoSided(true) - .add(Property::BlendMask, TextureLoader::load(*this, assets_dir / "textures/pirate.jpg", { + Material::builder() + .name("aura") + .shading(::Shading::Unlit) + .blending(::Blending::Additive) + .two_sided(true) + .diffuse( TextureLoader::load(*this, assets_dir / "textures/aura.png")) + .model(::InstanceType::Effect) + .build(*this); + + Material::builder().name("aura_sparks") + .shading(::Shading::Unlit) + .blending(::Blending::Additive) + .two_sided(true) + .blend_mask(TextureLoader::load(*this, assets_dir / "textures/pirate.jpg", { TextureLoaderFlags::Origin::TopLeft, TextureLoaderFlags::Filter::Nearest })) - .add(Property::EmissiveColor, glm::vec4(3.5f, 0.0f, 0.0f, 1.0f)) - .addModelShader(::InstanceType::Effect) - .build(); - - builder .setName("aura_beam") - .setShading(::Shading::Unlit) - .setBlending(::Blending::Additive) - .setTwoSided(true) - .add(Property::EmissiveColor, glm::vec4(3.5f, 0.0f, 0.0f, 1.0f)) - .addModelShader(::InstanceType::Effect) - .build(); + .emissive_color( glm::vec4(3.5f, 0.0f, 0.0f, 1.0f)) + .model(::InstanceType::Effect) + .build(*this); + + Material::builder().name("aura_beam") + .shading(::Shading::Unlit) + .blending(::Blending::Additive) + .two_sided(true) + .emissive_color( glm::vec4(3.5f, 0.0f, 0.0f, 1.0f)) + .model(::InstanceType::Effect) + .build(*this); } { @@ -731,85 +733,87 @@ void DemoAssets::loadModelsScene() { auto& materials = thanos.getMaterials(); - MaterialBuilder builder{*this}; - auto yellowenv = builder.setName("yellowenv") - .add(Property::Color, glm::vec4(0.546171f, 0.532152f, 0.546140f, 1.0f)) - .add(Property::EmissiveColor, glm::vec4(0.546171f, 0.532152f, 0.546140f, 1.0f)) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/bodyyellow_m.tga")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) - .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / - "models/thanos/yellow_env.tga"))) - .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto grayenv = builder.setName("grayenv") - .add(Property::Color, glm::vec4(0.636099f, 0.753402f, 0.750975f, 1.0f)) - .add(Property::EmissiveColor, glm::vec4(0.636099f, 0.753402f, 0.750975f, 1.0f)) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/bodygray_m.tga")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) - .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/gray_env.tga"))) - .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto eyesenv = builder.setName("eyesenv") - .add(Property::Color, glm::vec4(0.539415f, 0.560208f, 0.510821f, 1.0f)) - .add(Property::EmissiveColor, glm::vec4(1.0f)) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) - .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / - "models/thanos/eye_env.tga"))) - .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto blueenv = builder.setName("blueenv") - .add(Property::Color, glm::vec4(0.576473f, 0.481502f, 0.448319f, 1.0f)) - .add(Property::EmissiveColor, glm::vec4(1.0f)) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/bodyblue_m.tga")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) - .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / - "models/thanos/blue_env.tga"))) - .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto eyes = builder.setName("eyes") - .add(Property::Color, glm::vec4(0.551182f, 0.681717f, 0.402268f, 1.0f)) - .add(Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) - .add(Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) - .add(Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "models/thanos/body_s.tga")) - .add(Property::Roughness, 0.2f) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto body = builder.setName("body") - .add(Property::Color, glm::vec4(0.566327f, 0.533939f, 0.783312f, 1.0f)) - .add(::Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) - .add(::Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) - .add(::Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "models/thanos/body_s.tga")) - .add(::Property::Roughness, 0.2f) - .add(::Property::AmbientOcclusionTexture, - TextureLoader::load(*this, assets_dir / "models/thanos/body_ao.tga")) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto skin = builder.setName("skin") - .add(::Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) - .add(::Property::Normal, TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) - .add(::Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "models/thanos/body_s.tga")) - .add(::Property::Roughness, 0.2f) - .add(::Property::AmbientOcclusionTexture, TextureLoader::load(*this, assets_dir / "models/thanos/skin_ao.tga")) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); + auto yellowenv = + Material::builder() + .name("yellowenv") + .color(glm::vec4(0.546171f, 0.532152f, 0.546140f, 1.0f)) + .emissive_color( glm::vec4(0.546171f, 0.532152f, 0.546140f, 1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "models/thanos/bodyyellow_m.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) + .custom("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/yellow_env.tga")) + .fragment("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto grayenv = Material::builder() + .name("grayenv") + .color(glm::vec4(0.636099f, 0.753402f, 0.750975f, 1.0f)) + .emissive_color( glm::vec4(0.636099f, 0.753402f, 0.750975f, 1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "models/thanos/bodygray_m.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) + .custom("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/gray_env.tga")) + .fragment("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto eyesenv = Material::builder().name("eyesenv") + .color(glm::vec4(0.539415f, 0.560208f, 0.510821f, 1.0f)) + .emissive_color( glm::vec4(1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) + .custom("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/eye_env.tga")) + .fragment("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto blueenv = Material::builder() + .name("blueenv") + .color(glm::vec4(0.576473f, 0.481502f, 0.448319f, 1.0f)) + .emissive_color( glm::vec4(1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "models/thanos/bodyblue_m.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) + .custom("emissive_map", TextureLoader::load(*this, assets_dir / "models/thanos/blue_env.tga")) + .fragment("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto eyes = Material::builder() + .name("eyes") + .color(glm::vec4(0.551182f, 0.681717f, 0.402268f, 1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) + .metallic(TextureLoader::load(*this, assets_dir / "models/thanos/body_s.tga")) + .roughness(0.2f) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto body = Material::builder() + .name("body") + .color(glm::vec4(0.566327f, 0.533939f, 0.783312f, 1.0f)) + .diffuse( TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) + .metallic( TextureLoader::load(*this, assets_dir / "models/thanos/body_s.tga")) + .roughness( 0.2f) + .ao(TextureLoader::load(*this, assets_dir / "models/thanos/body_ao.tga")) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto skin = Material::builder() + .name("skin") + .diffuse(TextureLoader::load(*this, assets_dir / "models/thanos/body_d.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/thanos/body_n.tga")) + .metallic( TextureLoader::load(*this, assets_dir / "models/thanos/body_s.tga")) + .roughness( 0.2f) + .ao( TextureLoader::load(*this, assets_dir / "models/thanos/skin_ao.tga")) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); materials[0] = skin; materials[1] = body; @@ -829,48 +833,39 @@ void DemoAssets::loadModelsScene() { auto& materials = daenerys.getMaterials(); - MaterialBuilder builder{*this}; - auto head = builder.setName("dae_head") - .add(::Property::Color, glm::vec4(0.657693f, 0.475201f, 0.647254f, 1.0f)) - .add(::Property::Diffuse, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_d.png")) - .add(::Property::Normal, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_n.png")) - .add(::Property::MetallicTexture, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_m.png")) - .add(::Property::Roughness, 0.2f) - .add(::Property::AmbientOcclusionTexture, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_L.png")) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto cloth = builder.setName("dae_cloth") - .add(::Property::Diffuse, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_d.png")) - .add(::Property::Normal, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_ns.png")) - .add(::Property::MetallicTexture, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_m.png")) - .add(::Property::Roughness, 0.2f) - .add(::Property::AmbientOcclusionTexture, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_L.png")) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto hair = builder.setName("dae_hair") - .add(::Property::Color, glm::vec4(0.657236f, 0.567879f, 0.703609f, 1.0f)) - .add(::Property::Diffuse, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_hair_d.png")) - .add(::Property::Normal, - TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_hair_n.png")) - .add(::Property::MetallicTexture, - TextureLoader::load(*this, assets_dir / "models/daenerys/jitter2.png")) - .add(::Property::Roughness, 0.2f) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); + auto head = Material::builder() + .name("dae_head") + .color( glm::vec4(0.657693f, 0.475201f, 0.647254f, 1.0f)) + .diffuse(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_d.png")) + .normal(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_n.png")) + .metallic(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_m.png")) + .roughness( 0.2f) + .ao(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_face_L.png")) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto cloth = Material::builder() + .name("dae_cloth") + .diffuse(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_d.png")) + .normal(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_ns.png")) + .metallic(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_m.png")) + .roughness( 0.2f) + .ao(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_cloth_L.png")) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto hair = Material::builder() + .name("dae_hair") + .color( glm::vec4(0.657236f, 0.567879f, 0.703609f, 1.0f)) + .diffuse(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_hair_d.png")) + .normal(TextureLoader::load(*this, assets_dir / "models/daenerys/tex_commander1_daenerys_hair_n.png")) + .metallic(TextureLoader::load(*this, assets_dir / "models/daenerys/jitter2.png")) + .roughness( 0.2f) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); materials[0] = hair; materials[1] = cloth; @@ -887,18 +882,18 @@ void DemoAssets::loadModelsScene() { auto& materials = dynamic_cast(*models.at("skeleton")).getMaterials(); materials.resize(1); - MaterialBuilder builder{*this}; - auto skin = builder.setName("skeleton") - .add(::Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body.png")) - .add(Property::AmbientOcclusionTexture, TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body_OcclusionRoughnessMetallic.png")) - .addUniform(std::make_unique("ao_r_m", TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body_OcclusionRoughnessMetallic.png"))) - .setFragmentSnippet("vec3 skin = texture(ao_r_m, getVertexUV()).rgb;" + auto skin = Material::builder() + .name("skeleton") + .diffuse(TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body.png")) + .ao(TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body_OcclusionRoughnessMetallic.png")) + .custom("ao_r_m", TextureLoader::load(*this, assets_dir / "models/skeleton/Skeleton_Body_OcclusionRoughnessMetallic.png")) + .fragment("vec3 skin = texture(ao_r_m, getVertexUV()).rgb;" "mctx.ao = skin.r;" "mctx.roughness = skin.g;" "mctx.metallic = skin.b;") - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); materials[0] = skin; } @@ -917,24 +912,25 @@ void DemoAssets::loadModelsScene() { auto& materials = k2.getMaterials(); - MaterialBuilder builder{*this}; - auto body = builder.setName("k2_body") - .add(::Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/k2/K2_D.tga")) - .add(::Property::Normal, TextureLoader::load(*this, assets_dir / "models/k2/K2_D.tga")) - .add(::Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "models/k2/K2_S.tga")) - .add(::Property::Roughness, 0.2f) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); - - auto head = builder.setName("k2_head") - .add(::Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/k2/K2_Head_D.tga")) - .add(::Property::Normal, TextureLoader::load(*this, assets_dir / "models/k2/K2_Head_N.tga")) - .add(::Property::MetallicTexture, TextureLoader::load(*this, assets_dir / "models/k2/K2_Head_S.tga")) - .add(::Property::Roughness, 0.2f) - .setShading(Shading::Lit) - .addModelShader(InstanceType::Skeletal) - .build(); + auto body = Material::builder() + .name("k2_body") + .diffuse( TextureLoader::load(*this, assets_dir / "models/k2/K2_D.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/k2/K2_D.tga")) + .metallic( TextureLoader::load(*this, assets_dir / "models/k2/K2_S.tga")) + .roughness( 0.2f) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); + + auto head = Material::builder() + .name("k2_head") + .diffuse( TextureLoader::load(*this, assets_dir / "models/k2/K2_Head_D.tga")) + .normal( TextureLoader::load(*this, assets_dir / "models/k2/K2_Head_N.tga")) + .metallic( TextureLoader::load(*this, assets_dir / "models/k2/K2_Head_S.tga")) + .roughness( 0.2f) + .shading(Shading::Lit) + .model(InstanceType::Skeletal) + .build(*this); materials[0] = head; materials[1] = body; @@ -949,17 +945,17 @@ void DemoAssets::loadModelsScene() { auto& materials = elemental.getMaterials(); - MaterialBuilder builder{*this}; - auto body = builder.setName("elemental_body") - .add(::Property::Diffuse, TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Albedo FireElemental.png")) - .add(::Property::EmissiveColor, glm::vec4(1.0f)) - .add(::Property::Normal, TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Normal FireElemental.png")) - .add(::Property::RoughnessTexture, TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Rougness FireElemental.png")) - .add(::Property::Metallic, 0.1f) - .addUniform(std::make_unique("emissive_map", TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Emission FireElemental.png"))) - .setFragmentSnippet("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") - .setShading(Shading::Lit) - .build(); + auto body = Material::builder() + .name("elemental_body") + .diffuse( TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Albedo FireElemental.png")) + .emissive_color(glm::vec4(1.0f)) + .normal( TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Normal FireElemental.png")) + .roughness(TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Rougness FireElemental.png")) + .metallic(0.1f) + .custom("emissive_map", TextureLoader::load(*this, assets_dir / "models/elemental/Textures/Emission FireElemental.png")) + .fragment("mctx.emissive_color = texture(emissive_map, getVertexUV()).rgb;") + .shading(Shading::Lit) + .build(*this); materials[0] = body; } @@ -974,19 +970,6 @@ void DemoAssets::loadModelsScene() { models.add("cyborg", ModelLoader::loadModel(*this, assets_dir / "models/cyborg/cyborg.obj")); models.add("drone", ModelLoader::loadModel(*this, assets_dir / "models/drone/model/BusterDrone.fbx")); } - - { - MaterialBuilder builder{*this}; - builder .setName("tesselation_sample") - .add(::Property::Color, glm::vec4(1.0f, 0.5f, 0.23f, 1.0f)) - .add(::Property::TessellationFactor, glm::vec2(128.0f)) - .add(::Property::Roughness, 0.75f) - .add(::Property::Metallic, 0.1f) - .setTwoSided(true) - .addModelShader(Limitless::InstanceType::Instanced) - .addModelShader(Limitless::InstanceType::Model) - .build(); - } } void DemoAssets::loadSponzaScene() { diff --git a/demo/materials_demoscene.cpp b/demo/materials_demoscene.cpp index 678f4007..13a017ea 100644 --- a/demo/materials_demoscene.cpp +++ b/demo/materials_demoscene.cpp @@ -101,10 +101,10 @@ void MaterialsScene::addModels(const Limitless::Assets& assets) { void MaterialsScene::update(Limitless::Context& context, const Limitless::Camera& camera) { Limitless::Scene::update(context, camera); - (*open)["plane_mesh"].getMaterial()[0].getEmissiveColor().setValue({ + (*open)["plane_mesh"].getMaterial()[0].getEmissiveColor() = { glm::abs(glm::cos(glfwGetTime() * 2.5)) * 2.5, 0.0f, glm::abs(glm::cos(glfwGetTime() * 2.5)) * 5.0, 1.0f - }); + }; } \ No newline at end of file diff --git a/demo/models_demoscene.cpp b/demo/models_demoscene.cpp index f0e23f08..2fce935b 100644 --- a/demo/models_demoscene.cpp +++ b/demo/models_demoscene.cpp @@ -72,8 +72,6 @@ void ModelsScene::addInstances(Limitless::Assets& assets) { .setScale(glm::vec3(0.5f)) .setRotation(glm::vec3{0.0f, -M_PI_2, 0.0f}); - add(assets.models.at("cube"), assets.materials.at("tesselation_sample"), glm::vec3(25.0f, 2.0f, 30.0f)); - { auto& drone = add(assets.models.at("drone"), glm::vec3(25.0f, 2.0f, 24.0f)) .setScale(glm::vec3(0.01f)) diff --git a/demo/sponza_demoscene.cpp b/demo/sponza_demoscene.cpp index 9722679f..d0df4aba 100644 --- a/demo/sponza_demoscene.cpp +++ b/demo/sponza_demoscene.cpp @@ -21,7 +21,7 @@ SponzaScene::SponzaScene(Limitless::Context& ctx, Limitless::Assets& assets) .setScale(glm::vec3(0.005f))); for (auto& [name, mesh] : sponza.getMeshes()) { - mesh.getMaterial()[0].getTwoSided() = true; +// mesh.getMaterial()[0].getTwoSided() = true; mesh.getMaterial()[0].getBlending() = Limitless::ms::Blending::Opaque; } } diff --git a/include/limitless/core/shader/shader_program.hpp b/include/limitless/core/shader/shader_program.hpp index 3b353b81..df795a92 100644 --- a/include/limitless/core/shader/shader_program.hpp +++ b/include/limitless/core/shader/shader_program.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -13,9 +14,7 @@ namespace Limitless::ms { namespace Limitless { template class UniformValue; class UniformSampler; - class Uniform; class Texture; - class ContextState; /** * ShadeProgram describes compiled shader program object that is used to render object diff --git a/include/limitless/fx/renderers/beam_emitter_renderer.hpp b/include/limitless/fx/renderers/beam_emitter_renderer.hpp index 5bf9fdfa..5dc886f4 100644 --- a/include/limitless/fx/renderers/beam_emitter_renderer.hpp +++ b/include/limitless/fx/renderers/beam_emitter_renderer.hpp @@ -34,7 +34,7 @@ namespace Limitless::fx { auto& shader = assets.shaders.get({unique_type, shader_type}); //TODO: move - setBlendingMode(ctx, material.getBlending()); + setBlendingMode(material.getBlending()); if (material.getTwoSided()) { ctx.disable(Capabilities::CullFace); } else { diff --git a/include/limitless/fx/renderers/mesh_emitter_renderer.hpp b/include/limitless/fx/renderers/mesh_emitter_renderer.hpp index ec91e527..34928c80 100644 --- a/include/limitless/fx/renderers/mesh_emitter_renderer.hpp +++ b/include/limitless/fx/renderers/mesh_emitter_renderer.hpp @@ -58,7 +58,7 @@ namespace Limitless::fx { auto& shader = assets.shaders.get({unique_type, pass}); - setBlendingMode(ctx, material.getBlending()); + setBlendingMode(material.getBlending()); if (material.getTwoSided()) { ctx.disable(Capabilities::CullFace); } else { diff --git a/include/limitless/fx/renderers/sprite_emitter_renderer.hpp b/include/limitless/fx/renderers/sprite_emitter_renderer.hpp index 3b99f33b..ba69f61b 100644 --- a/include/limitless/fx/renderers/sprite_emitter_renderer.hpp +++ b/include/limitless/fx/renderers/sprite_emitter_renderer.hpp @@ -39,7 +39,7 @@ namespace Limitless::fx { auto& shader = assets.shaders.get({unique_shader, pass}); //TODO: remove from here to somewhere - setBlendingMode(ctx, material.getBlending()); + setBlendingMode(material.getBlending()); if (material.getTwoSided()) { ctx.disable(Capabilities::CullFace); } else { diff --git a/include/limitless/ms/material.hpp b/include/limitless/ms/material.hpp index 14eb479c..081d9755 100644 --- a/include/limitless/ms/material.hpp +++ b/include/limitless/ms/material.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -10,11 +9,10 @@ #include #include #include -#include -#include namespace Limitless { class Buffer; + class Texture; } namespace Limitless::ms { @@ -44,24 +42,24 @@ namespace Limitless::ms { * * can be changed at run-time */ - Blending blending {}; + Blending blending; /** * Describes material shading model * * compile-time only */ - Shading shading {}; + Shading shading; /** * Describes whether material is two sided */ - bool two_sided {}; + bool two_sided; /** * Describes whether material is using refraction */ - bool refraction {}; + bool refraction; /** * Unique material name @@ -71,7 +69,7 @@ namespace Limitless::ms { /** * Describes which shader is compiled for this material */ - uint64_t shader_index {}; + uint64_t shader_index; /** * Describes for which ModelShader types this material is used and compiled @@ -103,10 +101,58 @@ namespace Limitless::ms { */ std::string shading_snippet; - friend void swap(Material&, Material&) noexcept; - Material() = default; + /** + * Material Buffer + */ + class Buffer final { + private: + /** + * Corresponding OpenGL buffer to store properties on GPU + */ + std::shared_ptr material_buffer; + + /** + * Property offsets in buffer + */ + std::unordered_map uniform_offsets; + + /** + * initializes material offsets in buffer + */ + void initialize(const Material& material); + + /** + * Adds uniform typed value at specific offset in block so it can be mapped to GPU + */ + template + void map(std::vector& block, const Uniform& uniform) const; + + /** + * Adds any uniform to block + */ + void map(std::vector& block, Uniform& uniform); + public: + explicit Buffer(const Material& material); + + Buffer(const Buffer& buffer); + Buffer& operator=(const Buffer& buffer); + + Buffer(Buffer&&) noexcept = default; + Buffer& operator=(Buffer&&) noexcept = default; + + const std::shared_ptr& getBuffer() const noexcept; + + /** + * Maps material to GPU uniform buffer + */ + void map(const Material& material); + }; + Buffer buffer; - friend class MaterialBuilder; + /** + * For copy and swap idiom + */ + friend void swap(Material&, Material&) noexcept; /** * Equality operators to determine whether two materials could be used by the same shader @@ -134,7 +180,7 @@ namespace Limitless::ms { Material& operator=(Material&&) noexcept = default; /** - * Maps material to uniform buffer + * Updates material */ void update(); @@ -142,73 +188,94 @@ namespace Limitless::ms { * Const-context property getters */ [[nodiscard]] const glm::vec4& getColor() const; - [[nodiscard]] const glm::vec4& getEmissiveColor() const; + [[nodiscard]] const glm::vec3& getEmissiveColor() const; [[nodiscard]] float getMetallic() const; [[nodiscard]] float getRoughness() const; [[nodiscard]] float getIoR() const; [[nodiscard]] float getAbsorption() const; - [[nodiscard]] const std::shared_ptr& getMetallicTexture() const; - [[nodiscard]] const std::shared_ptr& getRoughnessTexture() const; + [[nodiscard]] float getMicroThickness() const; + [[nodiscard]] float getThickness() const; + [[nodiscard]] float getReflectance() const; + [[nodiscard]] float getTransmission() const; [[nodiscard]] const std::shared_ptr& getDiffuseTexture() const; [[nodiscard]] const std::shared_ptr& getNormalTexture() const; [[nodiscard]] const std::shared_ptr& getEmissiveMaskTexture() const; [[nodiscard]] const std::shared_ptr& getBlendMaskTexture() const; + [[nodiscard]] const std::shared_ptr& getMetallicTexture() const; + [[nodiscard]] const std::shared_ptr& getRoughnessTexture() const; [[nodiscard]] const std::shared_ptr& getAmbientOcclusionTexture() const; [[nodiscard]] const std::shared_ptr& getORMTexture() const; /** - * Mutable property getters + * Mutable property getters for primitives */ glm::vec4& getColor(); glm::vec4& getEmissiveColor(); - glm::vec2& getTesselationFactor(); float& getMetallic(); float& getRoughness(); float& getIoR(); float& getAbsorption(); + float& getMicroThickness(); + float& getThickness(); + float& getReflectance(); + float& getTransmission(); + Blending& getBlending(); - [[nodiscard]] const auto& getModelShaders() const noexcept { return model_shaders; } - [[nodiscard]] auto getBlending() const noexcept { return blending; } - [[nodiscard]] auto getShading() const noexcept { return shading; } - [[nodiscard]] auto getTwoSided() const noexcept { return two_sided; } - [[nodiscard]] const auto& getName() const noexcept { return name; } - [[nodiscard]] auto getShaderIndex() const noexcept { return shader_index; } - [[nodiscard]] const auto& getVertexSnippet() const noexcept { return vertex_snippet; } - [[nodiscard]] const auto& getRefraction() const noexcept { return refraction; } - [[nodiscard]] const auto& getFragmentSnippet() const noexcept { return fragment_snippet; } - [[nodiscard]] const auto& getGlobalSnippet() const noexcept { return global_snippet; } - [[nodiscard]] const auto& getTessellationSnippet() const noexcept { return tessellation_snippet; } - [[nodiscard]] const auto& getMaterialBuffer() const noexcept { return material_buffer; } - [[nodiscard]] const auto& getProperties() const noexcept { return properties; } - [[nodiscard]] const auto& getUniforms() const noexcept { return uniforms; } - - auto& getBlending() noexcept { return blending; } - auto& getTwoSided() noexcept { return two_sided; } - - bool contains(Property property) const; - bool contains(const std::string& name) const; - - template - Uniform& getProperty(const std::string& uniform_name) { - try { - return static_cast(*uniforms.at(uniform_name)); - } catch (...) { - throw material_property_not_found(uniform_name); - } - } - - template - const Uniform& getProperty(const std::string& uniform_name) const { - try { - return static_cast(*uniforms.at(uniform_name)); - } catch (...) { - throw material_property_not_found(uniform_name); - } - } + /** + * Property setters + */ + void setColor(const glm::vec4& value); + void setEmissiveColor(const glm::vec3& value); + void setMetallic(float value); + void setRoughness(float value); + void setIoR(float value); + void setAbsorption(float value); + void setMicroThickness(float value); + void setThickness(float value); + void setReflectance(float value); + void setTransmission(float value); + void setDiffuseTexture(const std::shared_ptr& texture); + void setNormalTexture(const std::shared_ptr& texture); + void setEmissiveMaskTexture(const std::shared_ptr& texture); + void setBlendMaskTexture(const std::shared_ptr& texture); + void setMetallicTexture(const std::shared_ptr& texture); + void setRoughnessTexture(const std::shared_ptr& texture); + void setAmbientOcclusionTexture(const std::shared_ptr& texture); + void setORMTexture(const std::shared_ptr& texture); + void setBlending(Blending blending); + + [[nodiscard]] Blending getBlending() const noexcept; + [[nodiscard]] Shading getShading() const noexcept; + [[nodiscard]] bool getTwoSided() const noexcept; + [[nodiscard]] bool getRefraction() const noexcept; + [[nodiscard]] const std::string& getName() const noexcept; + [[nodiscard]] uint64_t getShaderIndex() const noexcept; + [[nodiscard]] const std::string& getVertexSnippet() const noexcept; + [[nodiscard]] const std::string& getFragmentSnippet() const noexcept; + [[nodiscard]] const std::string& getGlobalSnippet() const noexcept; + [[nodiscard]] const std::string& getShadingSnippet() const noexcept; + [[nodiscard]] const InstanceTypes& getModelShaders() const noexcept; + [[nodiscard]] const Buffer& getBuffer() const noexcept; + + + [[nodiscard]] const std::map>& getProperties() const noexcept; + [[nodiscard]] const std::map>& getUniforms() const noexcept; + /** + * Material Builder + */ class Builder; + /** + * Returns new instance of material builder + */ static Builder builder(); + + private: + /** + * Constructs material from builder + */ + explicit Material(Builder& builder); }; void swap(Material& lhs, Material& rhs) noexcept; diff --git a/include/limitless/ms/material_buffer.hpp b/include/limitless/ms/material_buffer.hpp index 99b34daf..0c6083da 100644 --- a/include/limitless/ms/material_buffer.hpp +++ b/include/limitless/ms/material_buffer.hpp @@ -13,32 +13,5 @@ namespace Limitless { namespace Limitless::ms { class Material; - class MaterialBuffer final { - private: - /** - * Corresponding OpenGL buffer to store properties on GPU - */ - std::shared_ptr material_buffer; - /** - * Property offsets in buffer - */ - std::unordered_map uniform_offsets; - - /** - * Adds uniform typed value at specific offset in block so it can be mapped to GPU - */ - template - void map(std::vector& block, const Uniform& uniform) const; - - /** - * Adds any uniform to block - */ - void map(std::vector& block, Uniform& uniform); - - /** - * Maps material to GPU uniform buffer - */ - void map(const Material& material); - }; } \ No newline at end of file diff --git a/include/limitless/ms/material_builder.hpp b/include/limitless/ms/material_builder.hpp index ff00d116..8085dc33 100644 --- a/include/limitless/ms/material_builder.hpp +++ b/include/limitless/ms/material_builder.hpp @@ -1,18 +1,15 @@ #pragma once #include -#include #include -#include #include -#include namespace Limitless { class Assets; } namespace Limitless::ms { - class material_builder_error : public std::runtime_error { + class material_builder_exception : public std::runtime_error { public: using std::runtime_error::runtime_error; }; @@ -23,91 +20,86 @@ namespace Limitless::ms { static inline uint64_t next_shader_index {}; static inline std::mutex mutex; - std::shared_ptr material; + std::map> properties; + std::map> uniforms; - Assets& assets; + Blending _blending {Blending::Opaque}; + Shading _shading {Shading::Lit}; + bool _two_sided {false}; + bool _refraction {false}; + std::string _name; + uint64_t shader_index {}; + InstanceTypes _model_shaders; - [[nodiscard]] UniqueMaterial getMaterialType() const noexcept; - void initializeMaterialBuffer(); + std::string vertex_snippet; + std::string fragment_snippet; + std::string global_snippet; + std::string shading_snippet; + + bool _skybox; + + UniqueMaterial getMaterialType() const noexcept; void checkRequirements(); void setMaterialIndex(); void setModelShaders(); - void createMaterial(); + + friend class Material; public: - explicit MaterialBuilder(Assets& assets); - virtual ~MaterialBuilder() = default; + Builder() noexcept = default; + virtual ~Builder() = default; - MaterialBuilder(const MaterialBuilder&) = delete; - MaterialBuilder& operator=(const MaterialBuilder&) = delete; + Builder(const Builder&) = delete; + Builder& operator=(const Builder&) = delete; - MaterialBuilder(MaterialBuilder&&) = delete; - MaterialBuilder& operator=(MaterialBuilder&&) = delete; + Builder(Builder&&) = delete; + Builder& operator=(Builder&&) = delete; Builder& color(const glm::vec4& color) noexcept; - Builder& emissive_color(const glm::vec4& color) noexcept; - Builder& diffuse(const glm::vec4& color) noexcept; - Builder& normal(const glm::vec4& color) noexcept; - Builder& emissive_mask(const glm::vec4& color) noexcept; - Builder& blend_mask(const glm::vec4& color) noexcept; - Builder& metallic(const glm::vec4& color) noexcept; - Builder& metallic(const glm::vec4& color) noexcept; - Builder& roughness(const glm::vec4& color) noexcept; - Builder& roughness(const glm::vec4& color) noexcept; - Builder& ao(const glm::vec4& color) noexcept; - Builder& orm(const glm::vec4& color) noexcept; - Builder& ior(const glm::vec4& color) noexcept; - Builder& absorption(const glm::vec4& color) noexcept; - Builder& microthickness(const glm::vec4& color) noexcept; - Builder& reflectance(const glm::vec4& color) noexcept; - Builder& transmission(const glm::vec4& color) noexcept; - - Builder& blending(const glm::vec4& color) noexcept; - Builder& shading(const glm::vec4& color) noexcept; - Builder& two_sided(const glm::vec4& color) noexcept; - Builder& refraction(const glm::vec4& color) noexcept; - Builder& name(const glm::vec4& color) noexcept; - - Builder& vertex(const glm::vec4& color) noexcept; - Builder& fragment(const glm::vec4& color) noexcept; - Builder& global(const glm::vec4& color) noexcept; - Builder& shading(const glm::vec4& color) noexcept; - Builder& model(const glm::vec4& color) noexcept; - Builder& models(const glm::vec4& color) noexcept; - - - - - - MaterialBuilder& add(Property type, std::shared_ptr texture); - MaterialBuilder& add(Property type, const glm::vec4& value); - MaterialBuilder& add(Property type, const glm::vec2& value); - MaterialBuilder& add(Property type, float value); - MaterialBuilder& remove(Property type); - - MaterialBuilder& setBlending(Blending blending) noexcept; - MaterialBuilder& setShading(Shading shading) noexcept; - MaterialBuilder& setTwoSided(bool two_sided) noexcept; - MaterialBuilder& setRefraction(bool refraction) noexcept; - MaterialBuilder& setName(std::string name) noexcept; - [[nodiscard]] const auto& getName() const noexcept { return material->name; } - - MaterialBuilder& setFragmentSnippet(std::string fs_code) noexcept; - MaterialBuilder& setVertexSnippet(std::string vs_code) noexcept; - MaterialBuilder& setTessellationSnippet(std::string tes_code) noexcept; - MaterialBuilder& setGlobalSnippet(std::string global_code) noexcept; - - MaterialBuilder& addUniform(std::unique_ptr uniform); - MaterialBuilder& removeUniform(const std::string& name); - - MaterialBuilder& setModelShaders(const InstanceTypes& shaders) noexcept; - MaterialBuilder& addModelShader(InstanceType model) noexcept; - - MaterialBuilder& set(decltype(material->properties)&& properties); - MaterialBuilder& set(decltype(material->uniforms)&& uniforms); - - void clear(); - void setTo(const std::shared_ptr& material); - std::shared_ptr build(); - std::shared_ptr buildSkybox(); + Builder& emissive_color(const glm::vec3& emissive_color) noexcept; + Builder& diffuse(const std::shared_ptr& texture) noexcept; + Builder& normal(const std::shared_ptr& texture) noexcept; + Builder& emissive_mask(const std::shared_ptr& texture) noexcept; + Builder& blend_mask(const std::shared_ptr& texture) noexcept; + Builder& metallic(float metallic) noexcept; + Builder& metallic(const std::shared_ptr& texture) noexcept; + Builder& roughness(float roughness) noexcept; + Builder& roughness(const std::shared_ptr& texture) noexcept; + Builder& ao(const std::shared_ptr& texture) noexcept; + Builder& orm(const std::shared_ptr& texture) noexcept; + Builder& ior(float ior) noexcept; + Builder& absorption(float absorption) noexcept; + Builder& microthickness(float microthickness) noexcept; + Builder& thickness(float thickness) noexcept; + Builder& reflectance(float reflectance) noexcept; + Builder& transmission(float transmission) noexcept; + + Builder& blending(Blending blending) noexcept; + Builder& shading(Shading shading) noexcept; + Builder& two_sided(bool two_sided) noexcept; + Builder& refraction(bool refraction) noexcept; + Builder& name(const std::string& name) noexcept; + + Builder& vertex(const std::string& snippet) noexcept; + Builder& fragment(const std::string& snippet) noexcept; + Builder& global(const std::string& snippet) noexcept; + Builder& shading(const std::string& snippet) noexcept; + + Builder& model(InstanceType model) noexcept; + Builder& models(const InstanceTypes& models) noexcept; + + Builder& skybox() noexcept; + + Builder& time() noexcept; + Builder& custom(const std::string& name, float value) noexcept; + Builder& custom(const std::string& name, int32_t value) noexcept; + Builder& custom(const std::string& name, uint32_t value) noexcept; + Builder& custom(const std::string& name, const glm::vec2& value) noexcept; + Builder& custom(const std::string& name, const glm::vec3& value) noexcept; + Builder& custom(const std::string& name, const glm::vec4& value) noexcept; + Builder& custom(const std::string& name, const glm::mat3& value) noexcept; + Builder& custom(const std::string& name, const glm::mat4& value) noexcept; + Builder& custom(const std::string& name, const std::shared_ptr& value) noexcept; + + std::shared_ptr build(Assets& assets); }; } \ No newline at end of file diff --git a/include/limitless/ms/material_shader_define_replacer.hpp b/include/limitless/ms/material_shader_define_replacer.hpp index 456f90e0..897620c7 100644 --- a/include/limitless/ms/material_shader_define_replacer.hpp +++ b/include/limitless/ms/material_shader_define_replacer.hpp @@ -69,7 +69,6 @@ namespace Limitless { { SnippetDefineType::Global, "ENGINE_MATERIAL_GLOBAL_DEFINITIONS" }, { SnippetDefineType::CustomScalar, "ENGINE_MATERIAL_CUSTOM_SCALARS" }, { SnippetDefineType::CustomSamplers, "ENGINE_MATERIAL_CUSTOM_SAMPLERS" }, - { SnippetDefineType::CustomShading, "ENGINE_MATERIAL_CUSTOM_SAMPLERS" }, { SnippetDefineType::CustomShading, "ENGINE_MATERIAL_SHADING_CUSTOM_SNIPPET" }, }; diff --git a/include/limitless/serialization/material_serializer.hpp b/include/limitless/serialization/material_serializer.hpp index e3093267..25d061e7 100644 --- a/include/limitless/serialization/material_serializer.hpp +++ b/include/limitless/serialization/material_serializer.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace Limitless { class Context; @@ -9,17 +10,12 @@ namespace Limitless { class ByteBuffer; } -namespace Limitless::ms { - class Material; - class MaterialBuilder; -} - namespace Limitless { class MaterialSerializer { private: - static constexpr uint8_t VERSION = 0x1; + static constexpr uint8_t VERSION = 0x2; - void deserialize(ByteBuffer& buffer, Assets& assets, ms::MaterialBuilder& builder); + void deserialize(ByteBuffer& buffer, Assets& assets, ms::Material::Builder& builder); public: ByteBuffer serialize(const ms::Material& material); std::shared_ptr deserialize(Assets& assets, ByteBuffer& buffer); diff --git a/shaders_ref/lighting/lighting.glsl b/shaders_ref/lighting/lighting.glsl index 2192c2eb..743f5e47 100644 --- a/shaders_ref/lighting/lighting.glsl +++ b/shaders_ref/lighting/lighting.glsl @@ -2,8 +2,6 @@ #include "../scene.glsl" #include "../shading/regular.glsl" -#include "../shading/cloth.glsl" -#include "../shading/subsurface.glsl" #include "../shading/custom.glsl" #include "./scene_lighting.glsl" @@ -17,17 +15,13 @@ vec3 computeLight(const ShadingContext sctx, const LightingContext lctx, const L return clothShading(sctx, lctx, light); #elif defined (ENGINE_MATERIAL_SHADING_SUBSURFACE_MODEL) return subsurfaceShading(sctx, lctx, light); -#elif defined (ENGINE_MATERIAL_SHADING_CUSTOM_LIT_MODEL) +#elif defined (ENGINE_MATERIAL_SHADING_CUSTOM_MODEL) return customShading(sctx, lctx, light); #else /* [deferred pipeline] */ switch (sctx.shading_model) { - case 1u: // Lit + case ENGINE_SHADING_LIT: // Lit return regularShading(sctx, lctx, light); - case 2u: // Cloth - return clothShading(sctx, lctx, light); - case 3u: // Subsurface - return subsurfaceShading(sctx, lctx, light); default: // deferred pipeline does not support custom shading // and unlit paths calculated before diff --git a/shaders_ref/material/material.glsl b/shaders_ref/material/material.glsl index 6a58c2ee..954f9830 100644 --- a/shaders_ref/material/material.glsl +++ b/shaders_ref/material/material.glsl @@ -120,8 +120,6 @@ layout (std140) uniform MATERIAL_BUFFER { ENGINE_MATERIAL_CUSTOM_SAMPLERS #endif -ENGINE_MATERIAL_GLOBAL_DEFINITIONS - /** * Public material access API * diff --git a/shaders_ref/material/material_context.glsl b/shaders_ref/material/material_context.glsl index 932b9e23..10867c72 100644 --- a/shaders_ref/material/material_context.glsl +++ b/shaders_ref/material/material_context.glsl @@ -124,6 +124,8 @@ MaterialContext computeDefaultMaterialContext() { return mctx; } +ENGINE_MATERIAL_GLOBAL_DEFINITIONS + void customMaterialContext(inout MaterialContext mctx) { ENGINE_MATERIAL_FRAGMENT_SNIPPET } diff --git a/shaders_ref/shading/cloth.glsl b/shaders_ref/shading/cloth.glsl deleted file mode 100644 index 137bd798..00000000 --- a/shaders_ref/shading/cloth.glsl +++ /dev/null @@ -1,16 +0,0 @@ -vec3 clothShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { -// vec3 Fd = DiffuseBRDF_Cloth(sctx, lctx); -// vec3 Fr = SpecularBRDF_Cloth(sctx, lctx); -// -//#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) -// Fd *= saturate(sctx.subsurfaceColor + lctx.NoL); -// vec3 color = Fd + Fr * NoL; -// color *= light.color.rgb * (light.color.a * lctx.attenuation * lctx.visibility); -//#else -// vec3 color = Fd + Fr; -// color *= light.color.rgb * (light.color.a * lctx.attenuation * lctx.NoL * lctx.visibility); -//#endif -// -// return color; - return vec3(0.0); -} \ No newline at end of file diff --git a/shaders_ref/shading/custom.glsl b/shaders_ref/shading/custom.glsl index ae200422..0317405a 100644 --- a/shaders_ref/shading/custom.glsl +++ b/shaders_ref/shading/custom.glsl @@ -1,3 +1,5 @@ -vec3 customShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { - ENGINE_MATERIAL_SHADING_CUSTOM_SNIPPET -} +#if defined (ENGINE_MATERIAL_SHADING_CUSTOM_MODEL) + vec3 customShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { + ENGINE_MATERIAL_SHADING_CUSTOM_SNIPPET + } +#endif diff --git a/shaders_ref/shading/shading_context.glsl b/shaders_ref/shading/shading_context.glsl index 626f0ec6..a43ddb4b 100644 --- a/shaders_ref/shading/shading_context.glsl +++ b/shaders_ref/shading/shading_context.glsl @@ -3,9 +3,7 @@ #define ENGINE_SHADING_UNLIT 0u #define ENGINE_SHADING_LIT 1u -#define ENGINE_SHADING_CLOTH 2u -#define ENGINE_SHADING_SUBSURFACE 3u -#define ENGINE_SHADING_CUSTOM 4u +#define ENGINE_SHADING_CUSTOM 3u struct ShadingContext { vec3 diffuseColor; diff --git a/shaders_ref/shading/subsurface.glsl b/shaders_ref/shading/subsurface.glsl deleted file mode 100644 index 5b3a7509..00000000 --- a/shaders_ref/shading/subsurface.glsl +++ /dev/null @@ -1,17 +0,0 @@ -vec3 subsurfaceShading(const ShadingContext sctx, const LightingContext lctx, const Light light) { -// vec3 Fd = DiffuseBRDF(sctx, lctx); -// vec3 Fr = vec3(0.0); -// if (lctx.NoL > 0.0) { -// Fr = SpecularBRDF(sctx, lctx) * sctx.energyCompensation; -// } -// -// vec3 color = (Fd + Fr) * (lctx.NoL * lctx.occlusion); -// float scatterVoH = saturate(dot(sctx.V, -lctx.L)); -// float forwardScatter = exp2(scatterVoH * pixel.subsurfacePower - pixel.subsurfacePower); -// float backScatter = saturate(lctx.NoL * sctx.thickness + (1.0 - sctx.thickness)) * 0.5; -// float subsurface = mix(backScatter, 1.0, forwardScatter) * (1.0 - sctx.thickness); -// color += sctx.subsurfaceColor * (subsurface * Fd_Lambert()); -// -// return (color * lctx.color.rgb) * (lctx.color.a * light.attenuation); - return vec3(0.0); -} \ No newline at end of file diff --git a/src/limitless/assets.cpp b/src/limitless/assets.cpp index 191319d3..c2438af2 100644 --- a/src/limitless/assets.cpp +++ b/src/limitless/assets.cpp @@ -29,18 +29,34 @@ Assets::Assets(fs::path _base_dir, fs::path _shader_dir) noexcept void Assets::load([[maybe_unused]] Context& context) { // builds default materials for every model type - ms::MaterialBuilder builder {*this}; - InstanceTypes model_types = {InstanceType::Model, InstanceType::Skeletal, InstanceType::Effect, InstanceType::Instanced }; - builder.setName("default") - .setShading(ms::Shading::Unlit) - .add(ms::Property::Color, {0.7f, 0.0f, 0.7f, 1.0f}) - .setModelShaders(model_types) - .setTwoSided(true) - .build(); - - builder.setName("red").add(ms::Property::Color, {1.0f, 0.0f, 0.0f, 1.0f}).setModelShaders(model_types).setTwoSided(true).build(); - builder.setName("blue").add(ms::Property::Color, {0.0f, 0.0f, 1.0f, 1.0f}).setModelShaders(model_types).setTwoSided(true).build(); - builder.setName("green").add(ms::Property::Color, {0.0f, 1.0f, 0.0f, 1.0f}).setModelShaders(model_types).setTwoSided(true).build(); + ms::Material::builder() + .name("default") + .shading(ms::Shading::Unlit) + .color({0.7f, 0.0f, 0.7f, 1.0f}) + .models({InstanceType::Model, InstanceType::Skeletal, InstanceType::Effect, InstanceType::Instanced }) + .two_sided(true) + .build(*this); + + ms::Material::builder() + .name("red") + .color({1.0f, 0.0f, 0.0f, 1.0f}) + .models({InstanceType::Model, InstanceType::Skeletal, InstanceType::Effect, InstanceType::Instanced }) + .two_sided(true) + .build(*this); + + ms::Material::builder() + .name("blue") + .color({0.0f, 0.0f, 1.0f, 1.0f}) + .models({InstanceType::Model, InstanceType::Skeletal, InstanceType::Effect, InstanceType::Instanced }) + .two_sided(true) + .build(*this); + + ms::Material::builder() + .name("green") + .color({0.0f, 1.0f, 0.0f, 1.0f}) + .models({InstanceType::Model, InstanceType::Skeletal, InstanceType::Effect, InstanceType::Instanced }) + .two_sided(true) + .build(*this); // used in render as point light model models.add("sphere", std::make_shared(glm::uvec2{32})); diff --git a/src/limitless/core/shader/shader_program.cpp b/src/limitless/core/shader/shader_program.cpp index 498bd319..d856ff23 100644 --- a/src/limitless/core/shader/shader_program.cpp +++ b/src/limitless/core/shader/shader_program.cpp @@ -130,7 +130,7 @@ ShaderProgram& ShaderProgram::setMaterial(const ms::Material& material) { // bind current material buffer to shader // these contain scalar values - material.getMaterialBuffer()->bindBase(found->bound_point); + material.getBuffer().getBuffer()->bindBase(found->bound_point); // and we need explicitly set samplers for (const auto& [type, uniform] : material.getProperties()) { diff --git a/src/limitless/fx/effect_builder.cpp b/src/limitless/fx/effect_builder.cpp index 76ed7090..50acbc32 100644 --- a/src/limitless/fx/effect_builder.cpp +++ b/src/limitless/fx/effect_builder.cpp @@ -78,9 +78,9 @@ EffectBuilder& EffectBuilder::setMaterial(std::shared_ptr material throw std::runtime_error{"Cannot set empty material for emitter!"}; } - if (material->contains("time")) { - throw std::runtime_error{"Uniform Time cannot be used in emitter material. Use TimeModule instead!"}; - } +// if (material->contains("time")) { +// throw std::runtime_error{"Uniform Time cannot be used in emitter material. Use TimeModule instead!"}; +// } switch (effect->emitters.at(last_emitter)->getType()) { case AbstractEmitter::Type::Sprite: diff --git a/src/limitless/fx/effect_shader_define_replacer.cpp b/src/limitless/fx/effect_shader_define_replacer.cpp index 861181f0..4e2ec6c0 100644 --- a/src/limitless/fx/effect_shader_define_replacer.cpp +++ b/src/limitless/fx/effect_shader_define_replacer.cpp @@ -102,9 +102,9 @@ void EffectShaderDefineReplacer::replaceMaterialDependentDefine(Shader& shader, shader.replaceKey(DEFINE_NAMES.at(Define::MaterialDependent), getMaterialDependentDefine(material, model_shader) + getEmitterDefines(emitter)); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Vertex], material.getVertexSnippet()); - shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Tesselation], material.getTessellationSnippet()); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Fragment], material.getFragmentSnippet()); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::Global], material.getGlobalSnippet()); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomScalar], getScalarUniformDefines(material)); shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomSamplers], getSamplerUniformDefines(material)); + shader.replaceKey(SNIPPET_DEFINE[SnippetDefineType::CustomShading], material.getShadingSnippet()); } diff --git a/src/limitless/instances/mesh_instance.cpp b/src/limitless/instances/mesh_instance.cpp index 69271df3..f0bb025a 100644 --- a/src/limitless/instances/mesh_instance.cpp +++ b/src/limitless/instances/mesh_instance.cpp @@ -54,13 +54,7 @@ void MeshInstance::draw(Context& ctx, shader.use(); - if (mat.contains(ms::Property::TessellationFactor)) { - //TODO: move to somewhere else - glPatchParameteri(GL_PATCH_VERTICES, 4); - mesh->draw(VertexStreamDraw::Patches); - } else { - mesh->draw(); - } + mesh->draw(); return; } @@ -85,12 +79,7 @@ void MeshInstance::draw(Context& ctx, shader.use(); - if (mat->contains(ms::Property::TessellationFactor)) { - glPatchParameteri(GL_PATCH_VERTICES, 4); - mesh->draw(VertexStreamDraw::Patches); - } else { - mesh->draw(); - } + mesh->draw(); } } @@ -127,12 +116,7 @@ void MeshInstance::draw_instanced(Context& ctx, shader.use(); - if (mat->contains(ms::Property::TessellationFactor)) { - glPatchParameteri(GL_PATCH_VERTICES, 4); - mesh->draw_instanced(VertexStreamDraw::Patches, count); - } else { - mesh->draw_instanced(count); - } + mesh->draw_instanced(count); } } diff --git a/src/limitless/loaders/model_loader.cpp b/src/limitless/loaders/model_loader.cpp index 9bd2654a..4eca9bab 100644 --- a/src/limitless/loaders/model_loader.cpp +++ b/src/limitless/loaders/model_loader.cpp @@ -185,44 +185,37 @@ std::shared_ptr ModelLoader::loadMaterial( return assets.materials.at(name); } - ms::MaterialBuilder builder {assets}; + ms::Material::Builder builder = ms::Material::builder(); - builder.setName(std::move(name)) - .setShading(ms::Shading::Lit); + builder.name(std::move(name)) + .shading(ms::Shading::Lit); if (auto diffuse_count = mat->GetTextureCount(aiTextureType_DIFFUSE); diffuse_count != 0) { aiString texture_name; mat->GetTexture(aiTextureType_DIFFUSE, 0, &texture_name); - builder.add(ms::Property::Diffuse, TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str(), {TextureLoaderFlags::Space::sRGB})); + builder.diffuse(TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str(), {TextureLoaderFlags::Space::sRGB})); } if (auto normal_count = mat->GetTextureCount(aiTextureType_HEIGHT); normal_count != 0) { aiString texture_name; mat->GetTexture(aiTextureType_HEIGHT, 0, &texture_name); - builder.add(ms::Property::Normal, TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str())); + builder.normal(TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str())); } -// if (auto specular_count = mat->GetTextureCount(aiTextureType_SPECULAR); specular_count != 0) { -// aiString texture_name; -// mat->GetTexture(aiTextureType_SPECULAR, 0, &texture_name); -// -// builder.add(ms::Property::Specular, TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str())); -// } - if (auto opacity_mask = mat->GetTextureCount(aiTextureType_OPACITY); opacity_mask != 0) { aiString texture_name; mat->GetTexture(aiTextureType_OPACITY, 0, &texture_name); - builder.add(ms::Property::BlendMask, TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str())); + builder.blend_mask(TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str())); } if (auto emissive_mask = mat->GetTextureCount(aiTextureType_EMISSIVE); emissive_mask != 0) { aiString texture_name; mat->GetTexture(aiTextureType_EMISSIVE, 0, &texture_name); - builder.add(ms::Property::EmissiveMask, TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str(), {TextureLoaderFlags::Space::sRGB})); + builder.emissive_mask(TextureLoader::load(assets, path_str + PATH_SEPARATOR + texture_name.C_Str(), {TextureLoaderFlags::Space::sRGB})); } { @@ -231,10 +224,10 @@ std::shared_ptr ModelLoader::loadMaterial( switch (blending) { case _aiBlendMode_Force32Bit: case aiBlendMode_Default: - builder.setBlending(ms::Blending::Opaque); + builder.blending(ms::Blending::Opaque); break; case aiBlendMode_Additive: - builder.setBlending(ms::Blending::Additive); + builder.blending(ms::Blending::Additive); break; } } @@ -244,7 +237,7 @@ std::shared_ptr ModelLoader::loadMaterial( mat->Get(AI_MATKEY_TWOSIDED, twosided); - builder.setTwoSided(twosided); + builder.two_sided(twosided); } { @@ -255,11 +248,11 @@ std::shared_ptr ModelLoader::loadMaterial( mat->Get(AI_MATKEY_OPACITY, opacity); if (opacity != 1.0f) { - builder.setBlending(ms::Blending::Translucent); + builder.blending(ms::Blending::Translucent); } if (color != aiColor3D{0.0f}) { - builder.add(ms::Property::Color, glm::vec4{color.r, color.g, color.b, opacity}); + builder.color({color.r, color.g, color.b, opacity}); } } @@ -268,13 +261,13 @@ std::shared_ptr ModelLoader::loadMaterial( mat->Get(AI_MATKEY_COLOR_EMISSIVE, color); if (color != aiColor3D{0.0f}) { - builder.add(ms::Property::EmissiveColor, glm::vec4{color.r, color.g, color.b, 1.0f}); - builder.setShading(ms::Shading::Unlit); + builder.emissive_color({color.r, color.g, color.b}); + builder.shading(ms::Shading::Unlit); } } - builder.setModelShaders(model_shaders); - return builder.build(); + builder.models(model_shaders); + return builder.build(assets); } std::vector ModelLoader::loadBoneWeights(aiMesh* mesh, std::vector& bones, std::unordered_map& bone_map) { diff --git a/src/limitless/ms/material.cpp b/src/limitless/ms/material.cpp index ea14b07e..7672e326 100644 --- a/src/limitless/ms/material.cpp +++ b/src/limitless/ms/material.cpp @@ -1,16 +1,153 @@ #include #include -#include + #include +#include +#include #include -#include +#include #include using namespace Limitless::ms; using namespace Limitless; +void Material::Buffer::initialize(const Material& material) { + // check the order in material.glsl + // std140 + // https://www.khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159 + + size_t offset = 0; + const auto offset_setter = [&] (const auto& container, const std::function& condition = {}) { + for (const auto& [key, uniform] : container) { + if (!ContextInitializer::isBindlessTextureSupported() && uniform->getType() == UniformType::Sampler) { + continue; + } + + if (condition && !condition(*uniform)) { + continue; + } + + const auto size = getUniformSize(*uniform); + const auto alignment = getUniformAlignment(*uniform); + + offset += offset % alignment ? alignment - offset % alignment : 0; + + uniform_offsets.emplace(uniform->getName(), offset); + offset += size; + } + }; + + offset_setter(material.getProperties()); + offset_setter(material.getUniforms(), [] (const Uniform& uniform) { return uniform.getType() == UniformType::Sampler; }); + offset_setter(material.getUniforms(), [] (const Uniform& uniform) { return uniform.getType() != UniformType::Sampler; }); + + // ShadingModel uint32_t + offset += sizeof(uint32_t); + + BufferBuilder builder; + material_buffer = builder + .setTarget(Limitless::Buffer::Type::Uniform) + .setUsage(Limitless::Buffer::Usage::DynamicDraw) + .setAccess(Limitless::Buffer::MutableAccess::WriteOrphaning) + .setDataSize(sizeof(std::byte) * offset) + .build(); +} + +template +void Material::Buffer::map(std::vector& block, const Uniform& uniform) const { + const auto& uni = static_cast&>(uniform); + const auto offset = uniform_offsets.at(uniform.getName()); + std::memcpy(block.data() + offset, &uni.getValue(), sizeof(V)); +} + +void Material::Buffer::map(std::vector& block, Uniform& uniform) { + switch (uniform.getType()) { + case UniformType::Value: + switch (uniform.getValueType()) { + case UniformValueType::Uint: + map(block, uniform); + break; + case UniformValueType::Int: + map(block, uniform); + break; + case UniformValueType::Float: + map(block, uniform); + break; + case UniformValueType::Vec2: + map(block, uniform); + break; + case UniformValueType::Vec3: + map(block, uniform); + break; + case UniformValueType::Vec4: + map(block, uniform); + break; + case UniformValueType::Mat4: + map(block, uniform); + break; + case UniformValueType::Mat3: + map(block, uniform); + break; + } + break; + case UniformType::Sampler: + if (ContextInitializer::isBindlessTextureSupported()) { + const auto& uni = static_cast(uniform); //NOLINT + const auto offset = uniform_offsets.at(uniform.getName()); + auto& bindless_texture = static_cast(uni.getSampler()->getExtensionTexture()); //NOLINT + bindless_texture.makeResident(); + std::memcpy(block.data() + offset, &bindless_texture.getHandle(), sizeof(uint64_t)); + } + break; + case UniformType::Time: { + auto& time = static_cast(uniform); //NOLINT + time.update(); + map(block, uniform); + break; + } + } +} + +Material::Buffer::Buffer(const Material &material) { + initialize(material); +} + +Material::Buffer::Buffer(const Buffer& buffer) + : material_buffer {buffer.material_buffer->clone()} + , uniform_offsets {buffer.uniform_offsets} { +} + +Material::Buffer& Material::Buffer::operator=(const Buffer& buf) { + auto copy = Buffer {buf}; + std::swap(material_buffer, copy.material_buffer); + std::swap(uniform_offsets, copy.uniform_offsets); + return *this; +} + +const std::shared_ptr& Material::Buffer::getBuffer() const noexcept { + return material_buffer; +} + +void Material::Buffer::map(const Material& material) { + std::vector block(material_buffer->getSize()); + + for (const auto& [_, uniform] : material.getProperties()) { + map(block, *uniform); + } + + for (const auto& [_, uniform] : material.getUniforms()) { + map(block, *uniform); + } + + // adding shading in the end + auto s = material.getShading(); + std::memcpy(block.data() + block.size() - sizeof(uint32_t), &s, sizeof(uint32_t)); + + material_buffer->mapData(block.data(), block.size()); +} + void Limitless::ms::swap(Material& lhs, Material& rhs) noexcept { using std::swap; @@ -22,13 +159,39 @@ void Limitless::ms::swap(Material& lhs, Material& rhs) noexcept { swap(lhs.name, rhs.name); swap(lhs.shader_index, rhs.shader_index); swap(lhs.model_shaders, rhs.model_shaders); - swap(lhs.material_buffer, rhs.material_buffer); - swap(lhs.uniform_offsets, rhs.uniform_offsets); swap(lhs.uniforms, rhs.uniforms); swap(lhs.vertex_snippet, rhs.vertex_snippet); swap(lhs.fragment_snippet, rhs.fragment_snippet); swap(lhs.global_snippet, rhs.global_snippet); swap(lhs.shading_snippet, rhs.shading_snippet); + swap(lhs.buffer, rhs.buffer); +} + +Material::Material(const Material& material) + : blending {material.blending} + , shading {material.shading} + , two_sided {material.two_sided} + , refraction {material.refraction} + , name {material.name} + , shader_index {material.shader_index} + , model_shaders {material.model_shaders} + , vertex_snippet {material.vertex_snippet} + , fragment_snippet {material.fragment_snippet} + , global_snippet {material.global_snippet} + , shading_snippet {material.shading_snippet} + , buffer {material.buffer} { + + // deep copy of properties + for (const auto& [type, property] : material.properties) { + properties.emplace(type, property->clone()); + } + + // deep copy of custom properties + for (const auto& [uniform_name, uniform] : material.uniforms) { + uniforms.emplace(uniform_name, uniform->clone()); + } + + update(); } Material& Material::operator=(Material material) { @@ -88,55 +251,7 @@ bool Limitless::ms::operator<(const Material& lhs, const Material& rhs) noexcept return std::tie(lhs.blending, lhs.two_sided, lhs.shader_index) < std::tie(rhs.blending, rhs.two_sided, rhs.shader_index); } -Material::Material(const Material& material) - : blending {material.blending} - , shading {material.shading} - , two_sided {material.two_sided} - , refraction {material.refraction} - , name {material.name} - , shader_index {material.shader_index} - , model_shaders {material.model_shaders} - , uniform_offsets {material.uniform_offsets} - , vertex_snippet {material.vertex_snippet} - , fragment_snippet {material.fragment_snippet} - , global_snippet {material.global_snippet} { - - // deep copy of properties - for (const auto& [type, property] : material.properties) { - properties.emplace(type, property->clone()); - } - - // deep copy of custom properties - for (const auto& [uniform_name, uniform] : material.uniforms) { - uniforms.emplace(uniform_name, uniform->clone()); - } - - material_buffer = std::shared_ptr(material.material_buffer->clone()); - - //TODO: what to do with copy? map here or in update? - // move to update mb - map(); -} - -void Material::map() { - std::vector block(material_buffer->getSize()); - - for (const auto& [_, uniform] : properties) { - map(block, *uniform); - } - - for (const auto& [_, uniform] : uniforms) { - map(block, *uniform); - } - - std::memcpy(block.data() + block.size() - 4, &shading, 4); - - material_buffer->mapData(block.data(), block.size()); -} - void Material::update() { - //TODO: not map the whole buffer if changed only 1 value? - // must do for time const auto properties_changed = std::any_of(properties.begin(), properties.end(), [] (auto& property) { return property.second->isChanged(); }); @@ -148,7 +263,7 @@ void Material::update() { return; } - map(); + buffer.map(*this); for (const auto& [_, uniform] : properties) { uniform->resetChanged(); @@ -167,9 +282,9 @@ const glm::vec4& Material::getColor() const { } } -const glm::vec4& Material::getEmissiveColor() const { +const glm::vec3& Material::getEmissiveColor() const { try { - return static_cast&>(*properties.at(Property::EmissiveColor)).getValue(); //NOLINT + return static_cast&>(*properties.at(Property::EmissiveColor)).getValue(); //NOLINT } catch (const std::out_of_range& e) { throw material_exception("Material property not found - Emissive Color"); } @@ -191,6 +306,54 @@ float Material::getRoughness() const { } } +float Material::getIoR() const { + try { + return static_cast&>(*properties.at(Property::IoR)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - IoR"); + } +} + +float Material::getAbsorption() const { + try { + return static_cast&>(*properties.at(Property::Absorption)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Absorption"); + } +} + +float Material::getMicroThickness() const { + try { + return static_cast&>(*properties.at(Property::MicroThickness)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - MicroThickness"); + } +} + +float Material::getThickness() const { + try { + return static_cast&>(*properties.at(Property::Thickness)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Thickness"); + } +} + +float Material::getReflectance() const { + try { + return static_cast&>(*properties.at(Property::Reflectance)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Reflectance"); + } +} + +float Material::getTransmission() const { + try { + return static_cast&>(*properties.at(Property::Transmission)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Transmission"); + } +} + const std::shared_ptr& Material::getDiffuseTexture() const { try { return static_cast(*properties.at(Property::Diffuse)).getSampler(); //NOLINT @@ -239,6 +402,22 @@ const std::shared_ptr& Material::getRoughnessTexture() const { } } +const std::shared_ptr& Material::getORMTexture() const { + try { + return static_cast(*properties.at(Property::ORM)).getSampler(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - ORM"); + } +} + +const std::shared_ptr& Material::getAmbientOcclusionTexture() const { + try { + return static_cast(*properties.at(Property::AmbientOcclusionTexture)).getSampler(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - AmbientOcclusionTexture"); + } +} + glm::vec4& Material::getColor() { try { return static_cast&>(*properties.at(Property::Color)).getValue(); //NOLINT @@ -271,6 +450,14 @@ float& Material::getRoughness() { } } +float& Material::getIoR() { + try { + return static_cast&>(*properties.at(Property::IoR)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - IoR"); + } +} + float& Material::getAbsorption() { try { return static_cast&>(*properties.at(Property::Absorption)).getValue(); //NOLINT @@ -279,66 +466,263 @@ float& Material::getAbsorption() { } } -bool Material::contains(Property property) const { - return properties.count(property); +float& Material::getMicroThickness() { + try { + return static_cast&>(*properties.at(Property::MicroThickness)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - MicroThickness"); + } } -bool Material::contains(const std::string& uniform_name) const { - return uniforms.count(uniform_name); +float& Material::getThickness() { + try { + return static_cast&>(*properties.at(Property::Thickness)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Thickness"); + } } -float& Material::getIoR() { +float& Material::getReflectance() { try { - return static_cast&>(*properties.at(Property::IoR)).getValue(); //NOLINT + return static_cast&>(*properties.at(Property::Reflectance)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Reflectance"); + } +} + +float& Material::getTransmission() { + try { + return static_cast&>(*properties.at(Property::Transmission)).getValue(); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Transmission"); + } +} + +Blending& Material::getBlending() { + return blending; +} + +void Material::setColor(const glm::vec4& value) { + try { + static_cast&>(*properties.at(Property::Color)).setValue(value); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Color"); + } +} + +void Material::setEmissiveColor(const glm::vec3& value) { + try { + static_cast&>(*properties.at(Property::EmissiveColor)).setValue(value); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - EmissiveColor"); + } +} + +void Material::setMetallic(float value) { + try { + static_cast&>(*properties.at(Property::Metallic)).setValue(value); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Metallic"); + } +} + +void Material::setRoughness(float value) { + try { + static_cast&>(*properties.at(Property::Roughness)).setValue(value); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Roughness"); + } +} + +void Material::setIoR(float value) { + try { + static_cast&>(*properties.at(Property::IoR)).setValue(value); //NOLINT } catch (const std::out_of_range& e) { throw material_exception("Material property not found - IoR"); } } -UniformValue& Material::getAbsorption() { +void Material::setAbsorption(float value) { try { - return static_cast&>(*properties.at(Property::Absorption)); //NOLINT + static_cast&>(*properties.at(Property::Absorption)).setValue(value); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No absorption in material."); + throw material_exception("Material property not found - Absorption"); } } -const UniformValue& Material::getIoR() const { +void Material::setMicroThickness(float value) { try { - return static_cast&>(*properties.at(Property::IoR)); //NOLINT + static_cast&>(*properties.at(Property::MicroThickness)).setValue(value); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No IoR in material."); + throw material_exception("Material property not found - MicroThickness"); } } -const UniformSampler &Material::getAmbientOcclusionTexture() const { +void Material::setThickness(float value) { try { - return static_cast(*properties.at(Property::AmbientOcclusionTexture)); //NOLINT + static_cast&>(*properties.at(Property::Thickness)).setValue(value); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No AmbientOcclusionTexture in material."); + throw material_exception("Material property not found - Thickness"); } } -UniformSampler &Material::getAmbientOcclusionTexture() { +void Material::setReflectance(float value) { try { - return static_cast(*properties.at(Property::AmbientOcclusionTexture)); //NOLINT + static_cast&>(*properties.at(Property::Reflectance)).setValue(value); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No AmbientOcclusionTexture in material."); + throw material_exception("Material property not found - Reflectance"); } } -const UniformSampler &Material::getORMTexture() const { +void Material::setTransmission(float value) { try { - return static_cast(*properties.at(Property::ORM)); //NOLINT + static_cast&>(*properties.at(Property::Transmission)).setValue(value); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No ORM in material."); + throw material_exception("Material property not found - Transmission"); } } -UniformSampler &Material::getORMTexture() { +void Material::setDiffuseTexture(const std::shared_ptr& texture) { try { - return static_cast(*properties.at(Property::ORM)); //NOLINT + static_cast(*properties.at(Property::Diffuse)).setSampler(texture); //NOLINT } catch (const std::out_of_range& e) { - throw material_property_not_found("No ORM in material."); + throw material_exception("Material property not found - Diffuse"); } } + +void Material::setNormalTexture(const std::shared_ptr& texture) { + try { + static_cast(*properties.at(Property::Normal)).setSampler(texture); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - Normal"); + } +} + +void Material::setEmissiveMaskTexture(const std::shared_ptr& texture) { + try { + static_cast(*properties.at(Property::EmissiveMask)).setSampler(texture); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - EmissiveMask"); + } +} + +void Material::setBlendMaskTexture(const std::shared_ptr& texture) { + try { + static_cast(*properties.at(Property::BlendMask)).setSampler(texture); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - BlendMask"); + } +} + +void Material::setMetallicTexture(const std::shared_ptr& texture) { + try { + static_cast(*properties.at(Property::MetallicTexture)).setSampler(texture); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - MetallicTexture"); + } +} + +void Material::setRoughnessTexture(const std::shared_ptr& texture) { + try { + static_cast(*properties.at(Property::RoughnessTexture)).setSampler(texture); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - RoughnessTexture"); + } +} + +void Material::setAmbientOcclusionTexture(const std::shared_ptr& texture) { + try { + static_cast(*properties.at(Property::AmbientOcclusionTexture)).setSampler(texture); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - AmbientOcclusionTexture"); + } +} + +void Material::setORMTexture(const std::shared_ptr& texture) { + try { + static_cast(*properties.at(Property::ORM)).setSampler(texture); //NOLINT + } catch (const std::out_of_range& e) { + throw material_exception("Material property not found - ORM"); + } +} + +void Material::setBlending(Blending _blending) { + blending = _blending; +} + +Blending Material::getBlending() const noexcept { + return blending; +} + +Shading Material::getShading() const noexcept { + return shading; +} + +bool Material::getTwoSided() const noexcept { + return two_sided; +} + +bool Material::getRefraction() const noexcept { + return refraction; +} + +const std::string& Material::getName() const noexcept { + return name; +} + +uint64_t Material::getShaderIndex() const noexcept { + return shader_index; +} + +const std::string& Material::getVertexSnippet() const noexcept { + return vertex_snippet; +} + +const std::string& Material::getFragmentSnippet() const noexcept { + return fragment_snippet; +} + +const std::string& Material::getGlobalSnippet() const noexcept { + return global_snippet; +} + +const std::string& Material::getShadingSnippet() const noexcept { + return shading_snippet; +} + +const InstanceTypes& Material::getModelShaders() const noexcept { + return model_shaders; +} + +const Material::Buffer &Material::getBuffer() const noexcept { + return buffer; +} + +const std::map>& Material::getProperties() const noexcept { + return properties; +} + +const std::map>& Material::getUniforms() const noexcept { + return uniforms; +} + +Material::Builder Material::builder() { + return {}; +} + +Material::Material(Material::Builder& builder) + : properties {std::move(builder.properties)} + , blending {builder._blending} + , shading {builder._shading} + , two_sided {builder._two_sided} + , refraction {builder._refraction} + , name {builder._name} + , shader_index {builder.shader_index} + , model_shaders {builder._model_shaders} + , uniforms {std::move(builder.uniforms)} + , vertex_snippet {builder.vertex_snippet} + , fragment_snippet {builder.fragment_snippet} + , global_snippet {builder.global_snippet} + , shading_snippet {builder.shading_snippet} + , buffer {*this} { +} \ No newline at end of file diff --git a/src/limitless/ms/material_buffer.cpp b/src/limitless/ms/material_buffer.cpp index 1029f56e..e69de29b 100644 --- a/src/limitless/ms/material_buffer.cpp +++ b/src/limitless/ms/material_buffer.cpp @@ -1,88 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace Limitless; -using namespace Limitless::ms; - -template -void MaterialBuffer::map(std::vector& block, const Uniform& uniform) const { - const auto& uni = static_cast&>(uniform); - const auto offset = uniform_offsets.at(uniform.getName()); - std::memcpy(block.data() + offset, &uni.getValue(), sizeof(V)); -} - -void MaterialBuffer::map(std::vector& block, Uniform& uniform) { - switch (uniform.getType()) { - case UniformType::Value: - switch (uniform.getValueType()) { - case UniformValueType::Uint: - map(block, uniform); - break; - case UniformValueType::Int: - map(block, uniform); - break; - case UniformValueType::Float: - map(block, uniform); - break; - case UniformValueType::Vec2: - map(block, uniform); - break; - case UniformValueType::Vec3: - map(block, uniform); - break; - case UniformValueType::Vec4: - map(block, uniform); - break; - case UniformValueType::Mat4: - map(block, uniform); - break; - case UniformValueType::Mat3: - map(block, uniform); - break; - } - break; - case UniformType::Sampler: - if (ContextInitializer::isBindlessTextureSupported()) { - const auto& uni = static_cast(uniform); //NOLINT - const auto offset = uniform_offsets.at(uniform.getName()); - auto& bindless_texture = static_cast(uni.getSampler()->getExtensionTexture()); //NOLINT - bindless_texture.makeResident(); - std::memcpy(block.data() + offset, &bindless_texture.getHandle(), sizeof(uint64_t)); - } - break; - case UniformType::Time: { - auto& time = static_cast(uniform); //NOLINT - time.update(); - map(block, uniform); - break; - } - } -} - -void MaterialBuffer::map(const Material& material) { - std::vector block(material_buffer->getSize()); - - for (const auto& [_, uniform] : material.getProperties()) { - map(block, *uniform); - } - - for (const auto& [_, uniform] : material.getUniforms()) { - map(block, *uniform); - } - - // adding shading in the end - auto shading = material.getShading(); - std::memcpy(block.data() + block.size() - sizeof(uint32_t), &shading, sizeof(uint32_t)); - - material_buffer->mapData(block.data(), block.size()); -} \ No newline at end of file diff --git a/src/limitless/ms/material_builder.cpp b/src/limitless/ms/material_builder.cpp index fa5e5fb9..00dd8973 100644 --- a/src/limitless/ms/material_builder.cpp +++ b/src/limitless/ms/material_builder.cpp @@ -5,383 +5,265 @@ #include "limitless/core/shader/shader_program.hpp" #include #include +#include +#include using namespace Limitless::ms; -void MaterialBuilder::createMaterial() { - // this is private ctor - material = std::shared_ptr(new Material()); +void Material::Builder::setMaterialIndex() { + std::unique_lock lock(mutex); + + //TODO: make snippets comparisons + if (!uniforms.empty() || !vertex_snippet.empty() || !fragment_snippet.empty() || !global_snippet.empty() || !shading_snippet.empty()) { + // it is custom material; makes index unique + shader_index = next_shader_index++; + } else { + const auto material_type = getMaterialType(); + if (auto found = unique_materials.find(material_type); found != unique_materials.end()) { + // already exists + shader_index = found->second; + } else { + // new one + shader_index = next_shader_index++; + unique_materials.emplace(material_type, shader_index); + } + } } -MaterialBuilder::MaterialBuilder(Assets& _assets) - : assets {_assets} { - createMaterial(); +void Material::Builder::checkRequirements() { + if (_name.empty()) { + throw material_builder_exception("Name cannot be empty!"); + } } -void MaterialBuilder::initializeMaterialBuffer() { - // check the order in material.glsl - // std140 - // https://www.khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159 +std::shared_ptr Material::Builder::build(Assets& assets) { + checkRequirements(); - size_t offset = 0; - const auto offset_setter = [&] (const auto& container, const std::function& condition = {}) { - for (const auto& [key, uniform] : container) { - if (!ContextInitializer::isExtensionSupported("GL_ARB_bindless_texture") && uniform->getType() == UniformType::Sampler) { - continue; - } + setMaterialIndex(); - if (condition && !condition(*uniform)) { - continue; - } + if (!_skybox) { + setModelShaders(); + } - const auto size = getUniformSize(*uniform); - const auto alignment = getUniformAlignment(*uniform); + auto material = std::shared_ptr(new Material(*this)); - offset += offset % alignment ? alignment - offset % alignment : 0; + assets.materials.add(material->name, material); - material->uniform_offsets.emplace(uniform->getName(), offset); - offset += size; - } - }; - - offset_setter(material->properties); - offset_setter(material->uniforms, [] (const Uniform& uniform) { return uniform.getType() == UniformType::Sampler; }); - offset_setter(material->uniforms, [] (const Uniform& uniform) { return uniform.getType() != UniformType::Sampler; }); - - // ShadingModel uint - offset += 4; - - BufferBuilder builder; - material->material_buffer = builder - .setTarget(Buffer::Type::Uniform) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(std::byte) * offset) - .build(); -} - -MaterialBuilder& MaterialBuilder::set(decltype(material->properties)&& properties) { - material->properties = std::move(properties); - return *this; -} - -MaterialBuilder& MaterialBuilder::set(decltype(material->uniforms)&& uniforms) { - material->uniforms = std::move(uniforms); - return *this; -} - -MaterialBuilder& MaterialBuilder::add(Property type, float value) { - switch (type) { - case Property::Absorption: - material->properties[type] = std::make_unique>("_material_absorption", value); - break; - case Property::IoR: - material->properties[type] = std::make_unique>("_material_ior", value); - break; - case Property::Metallic: - material->properties[type] = std::make_unique>("_material_metallic", value); - break; - case Property::Roughness: - material->properties[type] = std::make_unique>("_material_roughness", value); - break; - case Property::TessellationFactor: - case Property::Color: - case Property::EmissiveColor: - case Property::Normal: - case Property::Diffuse: - case Property::EmissiveMask: - case Property::MetallicTexture: - case Property::RoughnessTexture: - case Property::BlendMask: - case Property::AmbientOcclusionTexture: - case Property::ORM: - throw material_builder_error{"Wrong data for material property."}; - } - return *this; + return material; } -MaterialBuilder& MaterialBuilder::add(Property type, const glm::vec4& value) { - switch (type) { - case Property::Color: - material->properties[type] = std::make_unique>("_material_color", value); - break; - case Property::EmissiveColor: - material->properties[type] = std::make_unique>("_material_emissive_color", value); - break; - case Property::TessellationFactor: - case Property::IoR: - case Property::Absorption: - case Property::Normal: - case Property::Metallic: - case Property::Roughness: - case Property::Diffuse: - case Property::EmissiveMask: - case Property::MetallicTexture: - case Property::RoughnessTexture: - case Property::BlendMask: - case Property::AmbientOcclusionTexture: - case Property::ORM: - throw material_builder_error{"Wrong data for material property."}; - } - return *this; +UniqueMaterial Material::Builder::getMaterialType() const noexcept { + std::set props; + + std::for_each(properties.begin(), properties.end(), [&] (auto& prop) { + props.emplace(prop.first); + }); + + return { std::move(props), _shading }; } -MaterialBuilder& MaterialBuilder::add(Property type, std::shared_ptr texture) { - if (!texture) { - throw material_builder_error{"Bad texture specified."}; +void Material::Builder::setModelShaders() { + if (_model_shaders.empty()) { + _model_shaders.emplace(InstanceType::Model); } +} - switch (type) { - case Property::TessellationFactor: - case Property::Color: - case Property::Absorption: - case Property::IoR: - case Property::Metallic: - case Property::Roughness: - case Property::EmissiveColor: - throw material_builder_error{"Wrong data for material property."}; - case Property::Diffuse: - material->properties[type] = std::make_unique("_material_diffuse_texture", std::move(texture)); - break; - case Property::Normal: - material->properties[type] = std::make_unique("_material_normal_texture", std::move(texture)); - break; - case Property::EmissiveMask: - material->properties[type] = std::make_unique("_material_emissive_mask_texture", std::move(texture)); - break; - case Property::BlendMask: - material->properties[type] = std::make_unique("_material_blend_mask_texture", std::move(texture)); - break; - case Property::MetallicTexture: - material->properties[type] = std::make_unique("_material_metallic_texture", std::move(texture)); - break; - case Property::RoughnessTexture: - material->properties[type] = std::make_unique("_material_roughness_texture", std::move(texture)); - break; - case Property::AmbientOcclusionTexture: - material->properties[type] = std::make_unique("_material_ambient_occlusion_texture", std::move(texture)); - break; - case Property::ORM: - material->properties[type] = std::make_unique("_material_orm_texture", std::move(texture)); - break; - } +Material::Builder &Material::Builder::color(const glm::vec4& color) noexcept { + properties[Property::Color] = std::make_unique>("_material_color", color); return *this; } -MaterialBuilder& MaterialBuilder::add(Property type, const glm::vec2& value) { - switch (type) { - case Property::TessellationFactor: - material->properties[type] = std::make_unique>("_material_tessellation", value); - break; - case Property::Color: - case Property::IoR: - case Property::Absorption: - case Property::Metallic: - case Property::Roughness: - case Property::EmissiveColor: - case Property::Diffuse: - case Property::Normal: - case Property::EmissiveMask: - case Property::BlendMask: - case Property::MetallicTexture: - case Property::RoughnessTexture: - case Property::AmbientOcclusionTexture: - case Property::ORM: - throw material_builder_error{"Wrong data for material property."}; - } +Material::Builder &Material::Builder::emissive_color(const glm::vec3& emissive_color) noexcept { + properties[Property::EmissiveColor] = std::make_unique>("_material_emissive_color", emissive_color); return *this; } -MaterialBuilder& MaterialBuilder::remove(Property type) { - material->properties.erase(type); +Material::Builder& Material::Builder::diffuse(const std::shared_ptr& texture) noexcept { + properties[Property::Diffuse] = std::make_unique("_material_diffuse_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::setBlending(Blending blending) noexcept { - material->blending = blending; +Material::Builder &Material::Builder::normal(const std::shared_ptr& texture) noexcept { + properties[Property::Normal] = std::make_unique("_material_normal_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::setShading(Shading shading) noexcept { - material->shading = shading; +Material::Builder &Material::Builder::emissive_mask(const std::shared_ptr& texture) noexcept { + properties[Property::EmissiveMask] = std::make_unique("_material_emissive_mask_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::setTwoSided(bool two_sided) noexcept { - material->two_sided = two_sided; +Material::Builder &Material::Builder::blend_mask(const std::shared_ptr &texture) noexcept { + properties[Property::BlendMask] = std::make_unique("_material_blend_mask_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::setRefraction(bool refraction) noexcept { - material->refraction = refraction; +Material::Builder &Material::Builder::metallic(float metallic) noexcept { + properties[Property::Metallic] = std::make_unique>("_material_metallic", metallic); return *this; } -MaterialBuilder& MaterialBuilder::setName(std::string name) noexcept { - material->name = std::move(name); +Material::Builder &Material::Builder::metallic(const std::shared_ptr& texture) noexcept { + properties[Property::MetallicTexture] = std::make_unique("_material_metallic_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::setFragmentSnippet(std::string fs_code) noexcept { - material->fragment_snippet = std::move(fs_code); +Material::Builder &Material::Builder::roughness(float roughness) noexcept { + properties[Property::Roughness] = std::make_unique>("_material_roughness", roughness); return *this; } -MaterialBuilder& MaterialBuilder::setVertexSnippet(std::string vs_code) noexcept { - material->vertex_snippet = std::move(vs_code); +Material::Builder &Material::Builder::roughness(const std::shared_ptr& texture) noexcept { + properties[Property::RoughnessTexture] = std::make_unique("_material_roughness_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::setGlobalSnippet(std::string g_code) noexcept { - material->global_snippet = std::move(g_code); +Material::Builder &Material::Builder::ao(const std::shared_ptr& texture) noexcept { + properties[Property::AmbientOcclusionTexture] = std::make_unique("_material_ambient_occlusion_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::addUniform(std::unique_ptr uniform) { - material->uniforms[uniform->getName()] = std::move(uniform); +Material::Builder &Material::Builder::orm(const std::shared_ptr& texture) noexcept { + properties[Property::ORM] = std::make_unique("_material_orm_texture", texture); return *this; } -MaterialBuilder& MaterialBuilder::removeUniform(const std::string& name) { - material->uniforms.erase(name); +Material::Builder &Material::Builder::ior(float ior) noexcept { + properties[Property::IoR] = std::make_unique>("_material_ior", ior); return *this; } -void MaterialBuilder::setMaterialIndex() { - std::unique_lock lock(mutex); - - material->shader_index = next_shader_index++; - - if (!material->uniforms.empty() || !material->vertex_snippet.empty() || !material->fragment_snippet.empty() || !material->tessellation_snippet.empty() || !material->global_snippet.empty()) { - // it is custom material; makes index unique - material->shader_index = next_shader_index++; - } else { - const auto material_type = getMaterialType(); - if (auto found = unique_materials.find(material_type); found != unique_materials.end()) { - // already exist - material->shader_index = found->second; - } else { - // new one - material->shader_index = next_shader_index++; - unique_materials.emplace(material_type, material->shader_index); - } - } +Material::Builder &Material::Builder::absorption(float absorption) noexcept { + properties[Property::Absorption] = std::make_unique>("_material_absorption", absorption); + return *this; } -void MaterialBuilder::checkRequirements() { - if (material->properties.empty()) { - throw material_builder_error("Properties cannot be empty"); - } - - if (material->name.empty()) { - throw material_builder_error("Name cannot be empty"); - } - - if (!material->tessellation_snippet.empty() && !material->contains(Property::TessellationFactor)) { - throw material_builder_error("Tessellation snippet require TessellationFactor to be set"); - } +Material::Builder &Material::Builder::microthickness(float microthickness) noexcept { + properties[Property::MicroThickness] = std::make_unique>("_material_microthickness", microthickness); + return *this; } -void MaterialBuilder::clear() { - createMaterial(); +Material::Builder &Material::Builder::thickness(float thickness) noexcept { + properties[Property::Thickness] = std::make_unique>("_material_thickness", thickness); + return *this; } -std::shared_ptr MaterialBuilder::build() { - checkRequirements(); - - setMaterialIndex(); - setModelShaders(); - - initializeMaterialBuffer(); +Material::Builder &Material::Builder::reflectance(float reflectance) noexcept { + properties[Property::Reflectance] = std::make_unique>("_material_reflectance", reflectance); + return *this; +} - auto new_material = material; - assets.materials.add(material->name, material); +Material::Builder &Material::Builder::transmission(float transmission) noexcept { + properties[Property::Transmission] = std::make_unique>("_material_transmission", transmission); + return *this; +} - createMaterial(); +Material::Builder &Material::Builder::blending(Blending blending) noexcept { + _blending = blending; + return *this; +} - return new_material; +Material::Builder &Material::Builder::shading(Shading shading) noexcept { + _shading = shading; + return *this; } -UniqueMaterial MaterialBuilder::getMaterialType() const noexcept { - std::set props; +Material::Builder &Material::Builder::two_sided(bool two_sided) noexcept { + _two_sided = two_sided; + return *this; +} - std::for_each(material->properties.begin(), material->properties.end(), [&] (auto& prop) { - props.emplace(prop.first); - }); +Material::Builder &Material::Builder::name(const std::string& name) noexcept { + _name = name; + return *this; +} - return { std::move(props), material->shading }; +Material::Builder &Material::Builder::vertex(const std::string& snippet) noexcept { + vertex_snippet = snippet; + return *this; } -MaterialBuilder& MaterialBuilder::setModelShaders(const Limitless::InstanceTypes& shaders) noexcept { - material->model_shaders = shaders; +Material::Builder &Material::Builder::fragment(const std::string& snippet) noexcept { + fragment_snippet = snippet; return *this; } -MaterialBuilder& MaterialBuilder::addModelShader(InstanceType model) noexcept { - material->model_shaders.emplace(model); +Material::Builder &Material::Builder::global(const std::string& snippet) noexcept { + global_snippet = snippet; return *this; } -void MaterialBuilder::setModelShaders() { - if (material->model_shaders.empty()) { - material->model_shaders.emplace(InstanceType::Model); - } +Material::Builder &Material::Builder::shading(const std::string& snippet) noexcept { + shading_snippet = snippet; + return *this; } -MaterialBuilder& MaterialBuilder::setTessellationSnippet(std::string tes_code) noexcept { - material->tessellation_snippet = std::move(tes_code); +Material::Builder &Material::Builder::model(InstanceType model) noexcept { + _model_shaders = { model }; return *this; } -std::shared_ptr MaterialBuilder::buildSkybox() { - checkRequirements(); +Material::Builder& Material::Builder::models(const InstanceTypes& models) noexcept { + _model_shaders = models; + return *this; +} - // skybox allows only be unlit! - if (material->getShading() == Shading::Lit) { - throw material_builder_error("Does not make sense for skybox to be lit!"); - } +Material::Builder &Material::Builder::skybox() noexcept { + _skybox = true; + return *this; +} - setMaterialIndex(); +Material::Builder& Material::Builder::time() noexcept { + uniforms["time"] = std::make_unique("time"); + return *this; +} - initializeMaterialBuffer(); +Material::Builder &Material::Builder::custom(const std::string& name, float value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; +} - auto new_material = material; - assets.materials.add(material->name, material); +Material::Builder &Material::Builder::custom(const std::string &name, int32_t value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; +} - createMaterial(); +Material::Builder &Material::Builder::custom(const std::string &name, const glm::mat3 &value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; +} - return new_material; +Material::Builder &Material::Builder::custom(const std::string &name, const glm::mat4 &value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; } -void MaterialBuilder::setTo(const std::shared_ptr& mat) { - createMaterial(); +Material::Builder &Material::Builder::custom(const std::string &name, uint32_t value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; +} - setBlending(mat->getBlending()); - setShading(mat->getShading()); - setTwoSided(mat->getTwoSided()); - setRefraction(mat->getRefraction()); - setName(mat->getName()); +Material::Builder &Material::Builder::custom(const std::string &name, const glm::vec2 &value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; +} - setFragmentSnippet(mat->getFragmentSnippet()); - setVertexSnippet(mat->getVertexSnippet()); - setTessellationSnippet(mat->getTessellationSnippet()); - setGlobalSnippet(mat->getGlobalSnippet()); +Material::Builder &Material::Builder::custom(const std::string &name, const glm::vec3 &value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; +} - setModelShaders(mat->getModelShaders()); +Material::Builder &Material::Builder::custom(const std::string &name, const glm::vec4 &value) noexcept { + uniforms[name] = std::make_unique>(name, value); + return *this; +} - { - decltype(mat->properties) props; - for (const auto&[prop, uniform] : mat->getProperties()) { - props.emplace(prop, uniform->clone()); - } - set(std::move(props)); - } +Material::Builder &Material::Builder::custom(const std::string &name, const std::shared_ptr &value) noexcept { + uniforms[name] = std::make_unique(name, value); + return *this; +} - { - decltype(mat->uniforms) uniforms; - for (const auto& [name, uniform] : mat->uniforms) { - uniforms.emplace(name, uniform->clone()); - } - set(std::move(uniforms)); - } +Material::Builder &Material::Builder::refraction(bool refraction_) noexcept { + _refraction = refraction_; + return *this; } diff --git a/src/limitless/ms/material_instance.cpp b/src/limitless/ms/material_instance.cpp index eebd4c9a..783af843 100644 --- a/src/limitless/ms/material_instance.cpp +++ b/src/limitless/ms/material_instance.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include using namespace Limitless; using namespace Limitless::ms; @@ -58,10 +58,6 @@ void MaterialInstance::setMaterialState(Context& ctx, uint64_t id, ShaderType pa // checks for multiple opaque materials // that should be blended as sum color/N if (material->getBlending() == Blending::Opaque) { - const auto opaque_count = std::count_if(begin(), end(), [] (const auto& pair) { - return pair.second->getBlending() == Blending::Opaque; - }); - setBlendingMode(Blending::Opaque); } else { if (material->getRefraction()) { diff --git a/src/limitless/ms/material_shader_define_replacer.cpp b/src/limitless/ms/material_shader_define_replacer.cpp index 0dcdf671..c916c3cc 100644 --- a/src/limitless/ms/material_shader_define_replacer.cpp +++ b/src/limitless/ms/material_shader_define_replacer.cpp @@ -3,6 +3,7 @@ #include #include #include +#include using namespace Limitless::ms; diff --git a/src/limitless/pipeline/deferred/translucent_pass.cpp b/src/limitless/pipeline/deferred/translucent_pass.cpp index 4517d5d8..67c9841a 100644 --- a/src/limitless/pipeline/deferred/translucent_pass.cpp +++ b/src/limitless/pipeline/deferred/translucent_pass.cpp @@ -31,7 +31,6 @@ void TranslucentPass::sort(Instances& instances, const Camera& camera, ms::Blend case ms::Blending::Modulate: std::sort(instances.begin(), instances.end(), BackToFrontSorter{camera}); break; - case ms::Blending::MultipleOpaque: case ms::Blending::Text: throw std::logic_error("This type of blending cannot be used as ColorPass value"); } diff --git a/src/limitless/pipeline/forward/color_pass.cpp b/src/limitless/pipeline/forward/color_pass.cpp index 72bd8458..bd87bd21 100644 --- a/src/limitless/pipeline/forward/color_pass.cpp +++ b/src/limitless/pipeline/forward/color_pass.cpp @@ -24,7 +24,6 @@ void ColorPass::draw(Instances& instances, Context& ctx, const Assets& assets, c case ms::Blending::Modulate: std::sort(instances.begin(), instances.end(), BackToFrontSorter{camera}); break; - case ms::Blending::MultipleOpaque: case ms::Blending::Text: throw std::logic_error("This type of blending cannot be used as ColorPass value"); } diff --git a/src/limitless/serialization/material_serializer.cpp b/src/limitless/serialization/material_serializer.cpp index daaa4e7c..083993cb 100644 --- a/src/limitless/serialization/material_serializer.cpp +++ b/src/limitless/serialization/material_serializer.cpp @@ -5,11 +5,13 @@ #include #include #include +#include +#include using namespace Limitless::ms; using namespace Limitless; -void MaterialSerializer::deserialize(ByteBuffer& buffer, Assets& assets, MaterialBuilder& builder) { +void MaterialSerializer::deserialize(ByteBuffer& buffer, Assets& assets, Material::Builder& builder) { std::map> properties; std::map> uniforms; Blending blending{}; @@ -32,16 +34,111 @@ void MaterialSerializer::deserialize(ByteBuffer& buffer, Assets& assets, Materia >> global_code >> tes_code; - builder .setName(name) - .setShading(shading) - .setBlending(blending) - .setTwoSided(two_sided) - .set(std::move(properties)) - .set(std::move(uniforms)) - .setVertexSnippet(vertex_code) - .setFragmentSnippet(fragment_code) - .setGlobalSnippet(global_code) - .setTessellationSnippet(tes_code); + builder .name(name) + .shading(shading) + .blending(blending) + .two_sided(two_sided) + .vertex(vertex_code) + .fragment(fragment_code) + .global(global_code); + + for (auto& [property, uniform]: properties) { + switch (property) { + case Property::Color: + builder.color(static_cast&>(*uniform).getValue()); + break; + case Property::EmissiveColor: + builder.emissive_color(static_cast&>(*uniform).getValue()); + break; + case Property::Diffuse: + builder.diffuse(static_cast(*uniform).getSampler()); + break; + case Property::Normal: + builder.normal(static_cast(*uniform).getSampler()); + break; + case Property::EmissiveMask: + builder.emissive_mask(static_cast(*uniform).getSampler()); + break; + case Property::BlendMask: + builder.blend_mask(static_cast(*uniform).getSampler()); + break; + case Property::MetallicTexture: + builder.metallic(static_cast(*uniform).getSampler()); + break; + case Property::RoughnessTexture: + builder.roughness(static_cast(*uniform).getSampler()); + break; + case Property::AmbientOcclusionTexture: + builder.ao(static_cast(*uniform).getSampler()); + break; + case Property::ORM: + builder.orm(static_cast(*uniform).getSampler()); + break; + case Property::Metallic: + builder.metallic(static_cast&>(*uniform).getValue()); + break; + case Property::Roughness: + builder.roughness(static_cast&>(*uniform).getValue()); + break; + case Property::IoR: + builder.ior(static_cast&>(*uniform).getValue()); + break; + case Property::Absorption: + builder.absorption(static_cast&>(*uniform).getValue()); + break; + case Property::MicroThickness: + builder.microthickness(static_cast&>(*uniform).getValue()); + break; + case Property::Thickness: + builder.thickness(static_cast&>(*uniform).getValue()); + break; + case Property::Reflectance: + builder.reflectance(static_cast&>(*uniform).getValue()); + break; + case Property::Transmission: + builder.transmission(static_cast&>(*uniform).getValue()); + break; + } + } + + for (auto& [name, uniform]: uniforms) { + switch (uniform->getType()) { + case UniformType::Value: + switch (uniform->getValueType()) { + case UniformValueType::Float: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + case UniformValueType::Int: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + case UniformValueType::Uint: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + case UniformValueType::Vec2: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + case UniformValueType::Vec3: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + case UniformValueType::Vec4: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + case UniformValueType::Mat3: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + case UniformValueType::Mat4: + builder.custom(name, static_cast&>(*uniform).getValue()); + break; + } + break; + case UniformType::Sampler: + builder.custom(name, static_cast(*uniform).getSampler()); + break; + case UniformType::Time: + builder.time(); + break; + } + } } ByteBuffer MaterialSerializer::serialize(const Material& material) { @@ -58,7 +155,6 @@ ByteBuffer MaterialSerializer::serialize(const Material& material) { << material.getVertexSnippet() << material.getFragmentSnippet() << material.getGlobalSnippet() - << material.getTessellationSnippet() << material.getModelShaders(); return buffer; @@ -73,20 +169,20 @@ std::shared_ptr MaterialSerializer::deserialize(Assets& assets, ByteBu throw std::runtime_error("Wrong material serializer version! " + std::to_string(VERSION) + " vs " + std::to_string(version)); } - MaterialBuilder builder {assets}; + Material::Builder builder; deserialize(buffer, assets, builder); InstanceTypes compile_models; buffer >> compile_models; - builder.setModelShaders(compile_models); + builder.models(compile_models); - try { - return builder.build(); - } catch (const resource_container_error& ex) { - return assets.materials.at(builder.getName()); - } +// try { + return builder.build(assets); +// } catch (const resource_container_error& ex) { +// return assets.materials.at(builder.getName()); +// } } ByteBuffer& Limitless::operator<<(ByteBuffer& buffer, const Material& material) { diff --git a/src/limitless/skybox/skybox.cpp b/src/limitless/skybox/skybox.cpp index 6073eb2d..8d9a5034 100644 --- a/src/limitless/skybox/skybox.cpp +++ b/src/limitless/skybox/skybox.cpp @@ -17,16 +17,16 @@ Skybox::Skybox(const std::shared_ptr& material) Skybox::Skybox(Assets& assets, const fs::path& path, const TextureLoaderFlags& flags) { const auto& cube_map_texture = TextureLoader::loadCubemap(assets, path, flags); - MaterialBuilder material_builder {assets}; - material = material_builder - .setName(path.stem().string()) - .addUniform(std::make_unique("skybox", cube_map_texture)) - .setFragmentSnippet("mctx.color.rgb = texture(skybox, skybox_uv).rgb;\n") - .add(Property::Color, glm::vec4(1.0f)) - .setTwoSided(true) - .setShading(Shading::Unlit) - .setBlending(Blending::Opaque) - .buildSkybox(); + material = Material::builder() + .name(path.stem().string()) + .custom("skybox", cube_map_texture) + .fragment("mctx.color.rgb = texture(skybox, skybox_uv).rgb;\n") + .color(glm::vec4(1.0f)) + .two_sided(true) + .shading(Shading::Unlit) + .blending(Blending::Opaque) + .skybox() + .build(assets); } void Skybox::draw(Context& context, const Assets& assets) { diff --git a/test/limitless/ms/material_builder_test.cpp b/test/limitless/ms/material_builder_test.cpp index f7988443..acd7927a 100644 --- a/test/limitless/ms/material_builder_test.cpp +++ b/test/limitless/ms/material_builder_test.cpp @@ -16,7 +16,7 @@ TEST_CASE("MaterialBuilder throw on empty properties") { MaterialBuilder builder {assets}; - REQUIRE_THROWS_AS(builder.build(), material_builder_error); + REQUIRE_THROWS_AS(builder.build(), material_builder_exception); check_opengl_state(); } @@ -28,7 +28,7 @@ TEST_CASE("MaterialBuilder throw on empty name") { MaterialBuilder builder {assets}; builder.setName("material"); - REQUIRE_THROWS_AS(builder.build(), material_builder_error); + REQUIRE_THROWS_AS(builder.build(), material_builder_exception); check_opengl_state(); } @@ -41,7 +41,7 @@ TEST_CASE("MaterialBuilder throw on tesselation when factor is not set") { builder.setName("material"); builder.setTessellationSnippet("snippet"); - REQUIRE_THROWS_AS(builder.build(), material_builder_error); + REQUIRE_THROWS_AS(builder.build(), material_builder_exception); check_opengl_state(); } From f136653f23b4a549df39705b907db4f75ebda06d Mon Sep 17 00:00:00 2001 From: hotstreams Date: Sat, 25 Nov 2023 22:34:49 +0300 Subject: [PATCH 10/15] another ref --- CMakeLists.txt | 2 +- demo/materials_demoscene.cpp | 4 +- demo/models_demoscene.cpp | 6 - demo/sponza_demoscene.cpp | 8 +- include/limitless/core/buffer/buffer.hpp | 4 + .../limitless/core/buffer/buffer_builder.hpp | 26 +- include/limitless/core/indexed_stream.hpp | 20 +- include/limitless/core/skeletal_stream.hpp | 12 +- include/limitless/core/texture/texture.hpp | 13 +- .../core/texture/texture_builder.hpp | 48 ++-- include/limitless/core/vertex_stream.hpp | 20 +- .../limitless/fx/modules/mesh_location.hpp | 2 +- .../fx/renderers/mesh_emitter_renderer.hpp | 20 +- .../limitless/instances/abstract_instance.hpp | 11 +- .../instances/instance_attachment.hpp | 6 +- .../limitless/instances/instance_builder.hpp | 110 +++++++++ .../instances/instanced_instance.hpp | 12 +- .../limitless/instances/material_instance.hpp | 67 ----- include/limitless/instances/mesh_instance.hpp | 25 +- .../limitless/instances/model_instance.hpp | 79 +++++- .../limitless/instances/socket_attachment.hpp | 2 +- include/limitless/loaders/texture_loader.hpp | 4 +- include/limitless/scene.hpp | 26 +- src/limitless/core/buffer/buffer_builder.cpp | 60 ++--- src/limitless/core/framebuffer.cpp | 105 ++++---- src/limitless/core/texture/texture.cpp | 25 +- .../core/texture/texture_builder.cpp | 232 ++++++++---------- src/limitless/fx/effect_renderer.cpp | 2 +- .../instances/instance_attachment.cpp | 2 +- src/limitless/instances/instance_builder.cpp | 136 ++++++++++ src/limitless/instances/mesh_instance.cpp | 139 +++++------ src/limitless/instances/model_instance.cpp | 98 ++++++++ src/limitless/instances/skeletal_instance.cpp | 12 +- src/limitless/instances/socket_attachment.cpp | 2 +- src/limitless/lighting/cascade_shadows.cpp | 40 +-- src/limitless/lighting/light_container.cpp | 10 +- src/limitless/lighting/lighting.cpp | 10 +- src/limitless/loaders/dds_loader.cpp | 23 +- src/limitless/loaders/texture_loader.cpp | 59 +++-- src/limitless/models/text_model.cpp | 14 +- src/limitless/ms/material.cpp | 11 +- src/limitless/ms/material_instance.cpp | 95 ------- src/limitless/pipeline/common/dof_pass.cpp | 20 +- src/limitless/pipeline/common/scene_data.cpp | 12 +- .../deferred/deferred_framebuffer_pass.cpp | 10 +- .../pipeline/forward/framebuffer_pass.cpp | 39 +-- src/limitless/postprocessing/blur.cpp | 47 ++-- src/limitless/postprocessing/ssao.cpp | 86 +++---- src/limitless/postprocessing/ssr.cpp | 38 +-- src/limitless/scene.cpp | 4 +- src/limitless/text/font_atlas.cpp | 24 +- test/limitless/core/texture_builder_test.cpp | 72 +++--- .../instance/model_instance_test.cpp | 4 +- .../instance/skeletal_instance_test.cpp | 4 +- test/limitless/util/textures.hpp | 10 +- 55 files changed, 1098 insertions(+), 874 deletions(-) create mode 100644 include/limitless/instances/instance_builder.hpp delete mode 100644 include/limitless/instances/material_instance.hpp create mode 100644 src/limitless/instances/instance_builder.cpp delete mode 100644 src/limitless/ms/material_instance.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 638a74f4..0e401875 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,7 @@ set(ENGINE_INSTANCES src/limitless/instances/effect_instance.cpp src/limitless/instances/instance_attachment.cpp src/limitless/instances/socket_attachment.cpp + src/limitless/instances/instance_builder.cpp ) set(ENGINE_LIGHTING @@ -178,7 +179,6 @@ set(ENGINE_MS src/limitless/ms/unique_material.cpp src/limitless/ms/material_builder.cpp src/limitless/ms/material_compiler.cpp - src/limitless/ms/material_instance.cpp src/limitless/ms/material_buffer.cpp src/limitless/ms/material_shader_define_replacer.cpp ) diff --git a/demo/materials_demoscene.cpp b/demo/materials_demoscene.cpp index 13a017ea..b09f9684 100644 --- a/demo/materials_demoscene.cpp +++ b/demo/materials_demoscene.cpp @@ -88,8 +88,6 @@ void MaterialsScene::addModels(const Limitless::Assets& assets) { add(assets.models.at("sphere"), assets.materials.at("lava"), glm::vec3{14.0f, 1.0f, 1.0f }); add(assets.models.at("sphere"), assets.materials.at("ice"), glm::vec3{14.0f, 1.0f, 4.0f }); add(assets.models.at("sphere"), assets.materials.at("poison"), glm::vec3{14.0f, 1.0f, 7.0f }); - auto& m = add(assets.models.at("sphere"), assets.materials.at("ice"), glm::vec3{14.0f, 1.0f, 10.0f }); - m["sphere"].getMaterial().apply(assets.materials.at("poison")); add(assets.models.at("sphere"), assets.materials.at("bump_mapping"), glm::vec3{14.0f, 1.0f, 13.0f }); add(assets.models.at("sphere"), assets.materials.at("fresnel"), glm::vec3{14.0f, 1.0f, 17.0f }); @@ -101,7 +99,7 @@ void MaterialsScene::addModels(const Limitless::Assets& assets) { void MaterialsScene::update(Limitless::Context& context, const Limitless::Camera& camera) { Limitless::Scene::update(context, camera); - (*open)["plane_mesh"].getMaterial()[0].getEmissiveColor() = { + (*open)["plane_mesh"].getMaterial()->getEmissiveColor() = { glm::abs(glm::cos(glfwGetTime() * 2.5)) * 2.5, 0.0f, glm::abs(glm::cos(glfwGetTime() * 2.5)) * 5.0, diff --git a/demo/models_demoscene.cpp b/demo/models_demoscene.cpp index 2fce935b..c732f612 100644 --- a/demo/models_demoscene.cpp +++ b/demo/models_demoscene.cpp @@ -76,12 +76,6 @@ void ModelsScene::addInstances(Limitless::Assets& assets) { auto& drone = add(assets.models.at("drone"), glm::vec3(25.0f, 2.0f, 24.0f)) .setScale(glm::vec3(0.01f)) .setRotation(glm::vec3{M_PI, M_PI_2, 0.0f}); - - auto it = dynamic_cast(drone).getMeshes().begin(); - for (int i = 0; i < 21; ++i) { - ++it; - } - it->second.hide(); } add(assets.models.at("elemental"), glm::vec3(25.0f, 2.0f, 27.0f)) diff --git a/demo/sponza_demoscene.cpp b/demo/sponza_demoscene.cpp index d0df4aba..ff9077c8 100644 --- a/demo/sponza_demoscene.cpp +++ b/demo/sponza_demoscene.cpp @@ -20,10 +20,10 @@ SponzaScene::SponzaScene(Limitless::Context& ctx, Limitless::Assets& assets) auto& sponza = dynamic_cast(add(assets.models.at("sponza"), glm::vec3(17.0f, 8.0f, 15.0f)) .setScale(glm::vec3(0.005f))); - for (auto& [name, mesh] : sponza.getMeshes()) { -// mesh.getMaterial()[0].getTwoSided() = true; - mesh.getMaterial()[0].getBlending() = Limitless::ms::Blending::Opaque; - } +// for (auto& [name, mesh] : sponza.getMeshes()) { +//// mesh.getMaterial()[0].getTwoSided() = true; +// mesh.getMaterial()[0].getBlending() = Limitless::ms::Blending::Opaque; +// } } void SponzaScene::update(Limitless::Context& context, const Limitless::Camera& camera) { diff --git a/include/limitless/core/buffer/buffer.hpp b/include/limitless/core/buffer/buffer.hpp index c0ae5022..bd8f6c81 100644 --- a/include/limitless/core/buffer/buffer.hpp +++ b/include/limitless/core/buffer/buffer.hpp @@ -203,5 +203,9 @@ namespace Limitless { [[nodiscard]] virtual size_t getSize() const noexcept = 0; [[nodiscard]] virtual const std::variant& getUsageFlags() const noexcept = 0; [[nodiscard]] virtual const std::variant& getAccess() const noexcept = 0; + + class Builder; + + static Builder builder(); }; } diff --git a/include/limitless/core/buffer/buffer_builder.hpp b/include/limitless/core/buffer/buffer_builder.hpp index eae16894..562b2e14 100644 --- a/include/limitless/core/buffer/buffer_builder.hpp +++ b/include/limitless/core/buffer/buffer_builder.hpp @@ -6,21 +6,21 @@ namespace Limitless { class ContextState; - class BufferBuilder { + class Buffer::Builder { private: - Buffer::Type target; - std::variant usage; - std::variant access; - const void* data {}; - size_t size {}; + Buffer::Type target_; + std::variant usage_; + std::variant access_; + const void* data_ {}; + size_t size_ {}; public: - BufferBuilder& setTarget(Buffer::Type _target); - BufferBuilder& setUsage(Buffer::Usage _usage); - BufferBuilder& setUsage(Buffer::Storage _storage); - BufferBuilder& setAccess(Buffer::MutableAccess _access); - BufferBuilder& setAccess(Buffer::ImmutableAccess _access); - BufferBuilder& setData(const void* _data); - BufferBuilder& setDataSize(size_t _size); + Builder& target(Buffer::Type _target); + Builder& usage(Buffer::Usage _usage); + Builder& usage(Buffer::Storage _storage); + Builder& access(Buffer::MutableAccess _access); + Builder& access(Buffer::ImmutableAccess _access); + Builder& data(const void* _data); + Builder& size(size_t _size); std::unique_ptr build(); // builds indexed buffer for specified context diff --git a/include/limitless/core/indexed_stream.hpp b/include/limitless/core/indexed_stream.hpp index 4c66f0b6..b2925c32 100644 --- a/include/limitless/core/indexed_stream.hpp +++ b/include/limitless/core/indexed_stream.hpp @@ -11,24 +11,24 @@ namespace Limitless { std::shared_ptr indices_buffer; void initialize() { - BufferBuilder builder; - builder.setTarget(Buffer::Type::Element) - .setData(indices.data()) - .setDataSize(indices.size() * sizeof(index_type)); + Buffer::Builder builder = Buffer::builder(); + builder.target(Buffer::Type::Element) + .data(indices.data()) + .size(indices.size() * sizeof(index_type)); switch (this->usage) { case VertexStreamUsage::Static: - builder.setUsage(Buffer::Storage::Static) - .setAccess(Buffer::ImmutableAccess::None); + builder.usage(Buffer::Storage::Static) + .access(Buffer::ImmutableAccess::None); break; case VertexStreamUsage::Dynamic: - builder.setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning); + builder.usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning); break; case VertexStreamUsage::Stream: //TODO: should be x3 vertex array && x3 buffer - builder.setUsage(Buffer::Storage::DynamicCoherentWrite) - .setAccess(Buffer::ImmutableAccess::WriteCoherent); + builder.usage(Buffer::Storage::DynamicCoherentWrite) + .access(Buffer::ImmutableAccess::WriteCoherent); break; } diff --git a/include/limitless/core/skeletal_stream.hpp b/include/limitless/core/skeletal_stream.hpp index a60955f3..e942279a 100644 --- a/include/limitless/core/skeletal_stream.hpp +++ b/include/limitless/core/skeletal_stream.hpp @@ -11,12 +11,12 @@ namespace Limitless { std::shared_ptr bone_buffer; void initialize() { - BufferBuilder builder; - bone_buffer = builder.setTarget(Buffer::Type::Array) - .setUsage(Buffer::Storage::Static) - .setAccess(Buffer::ImmutableAccess::None) - .setData(bone_weights.data()) - .setDataSize(bone_weights.size() * sizeof(VertexBoneWeight)) + bone_buffer = Buffer::builder() + .target(Buffer::Type::Array) + .usage(Buffer::Storage::Static) + .access(Buffer::ImmutableAccess::None) + .data(bone_weights.data()) + .size(bone_weights.size() * sizeof(VertexBoneWeight)) .build(); this->vertex_array.template setAttribute(4, false, sizeof(VertexBoneWeight), (GLvoid*)offsetof(VertexBoneWeight, bone_index), bone_buffer); diff --git a/include/limitless/core/texture/texture.hpp b/include/limitless/core/texture/texture.hpp index f87a2414..b368f780 100644 --- a/include/limitless/core/texture/texture.hpp +++ b/include/limitless/core/texture/texture.hpp @@ -28,9 +28,6 @@ namespace Limitless { Depth32F = GL_DEPTH_COMPONENT32F, Depth24Stencil8 = GL_DEPTH24_STENCIL8, R = GL_RED, -// RG = GL_RG, -// RGB = GL_RGB, -// RGBA = GL_RGBA, R8 = GL_R8, RG8 = GL_RG8, RGB8 = GL_RGB8, @@ -119,7 +116,6 @@ namespace Limitless { private: std::unique_ptr texture; std::optional path {}; - glm::vec4 border_color {}; glm::uvec3 size {1}; InternalFormat internal_format {InternalFormat::RGB8}; DataType data_type {DataType::UnsignedByte}; @@ -133,12 +129,10 @@ namespace Limitless { uint32_t levels {1}; float anisotropic {1.0f}; bool mipmap {false}; - bool border {false}; bool compressed {false}; bool immutable {false}; protected: Texture() = default; - friend class TextureBuilder; public: virtual ~Texture() = default; @@ -149,7 +143,6 @@ namespace Limitless { Texture& operator=(Texture&&) noexcept = default; [[nodiscard]] const auto& getPath() const noexcept { return path; } - [[nodiscard]] const auto& getBorderColor() const noexcept { return border_color; } [[nodiscard]] auto getDataType() const noexcept { return data_type; } [[nodiscard]] auto getFormat() const noexcept { return format; } [[nodiscard]] auto getInternalFormat() const noexcept { return internal_format; } @@ -163,7 +156,6 @@ namespace Limitless { [[nodiscard]] auto getLevels() const noexcept { return levels; } [[nodiscard]] auto getAnisotropic() const noexcept { return anisotropic; } [[nodiscard]] auto hasMipmap() const noexcept { return mipmap; } - [[nodiscard]] auto hasBorder() const noexcept { return border; } [[nodiscard]] auto isCompressed() const noexcept { return compressed; } [[nodiscard]] bool isMutable() const noexcept; [[nodiscard]] bool isImmutable() const noexcept; @@ -177,7 +169,6 @@ namespace Limitless { Texture& setMagFilter(Filter filter); Texture& setAnisotropicFilter(float value); Texture& setAnisotropicFilterMax(); - Texture& setBorderColor(const glm::vec4& color); Texture& setWrapS(Wrap wrap); Texture& setWrapT(Wrap wrap); Texture& setWrapR(Wrap wrap); @@ -219,5 +210,9 @@ namespace Limitless { void resize(glm::uvec3 size); void accept(TextureVisitor& visitor); + + class Builder; + + static Builder builder(); }; } diff --git a/include/limitless/core/texture/texture_builder.hpp b/include/limitless/core/texture/texture_builder.hpp index 13c8fa0f..133c0a2b 100644 --- a/include/limitless/core/texture/texture_builder.hpp +++ b/include/limitless/core/texture/texture_builder.hpp @@ -11,7 +11,7 @@ namespace Limitless { * TextureBuilder is class that is used to build Textures * with different properties using different OpenGL extensions */ - class TextureBuilder { + class Texture::Builder final { private: [[nodiscard]] static bool isImmutable(); [[nodiscard]] bool isCompressed() const; @@ -20,34 +20,28 @@ namespace Limitless { std::unique_ptr texture; std::array cube_data {}; - const void* data {}; + const void* data_ {}; std::size_t byte_count {}; public: - TextureBuilder(); - ~TextureBuilder() = default; - - TextureBuilder(const TextureBuilder&) = delete; - TextureBuilder(TextureBuilder&&) = delete; - - TextureBuilder& setInternalFormat(Texture::InternalFormat internal); - TextureBuilder& setDataType(Texture::DataType data_type); - TextureBuilder& setFormat(Texture::Format format); - TextureBuilder& setTarget(Texture::Type target); - TextureBuilder& setData(const void* data); - TextureBuilder& setData(const std::array& data); - TextureBuilder& setCompressedData(const void* data, std::size_t bytes); - TextureBuilder& setLevels(uint32_t levels); - TextureBuilder& setPath(const fs::path& path); - TextureBuilder& setSize(glm::uvec2 size); - TextureBuilder& setSize(glm::uvec3 size); - TextureBuilder& setMipMap(bool mipmap); - TextureBuilder& setMinFilter(Texture::Filter filter); - TextureBuilder& setMagFilter(Texture::Filter filter); - TextureBuilder& setWrapS(Texture::Wrap wrap); - TextureBuilder& setWrapT(Texture::Wrap wrap); - TextureBuilder& setWrapR(Texture::Wrap wrap); - TextureBuilder& setBorder(bool border); - TextureBuilder& setBorderColor(const glm::vec4& color); + Builder(); + + Builder& internal_format(Texture::InternalFormat internal); + Builder& data_type(Texture::DataType data_type); + Builder& format(Texture::Format format); + Builder& target(Texture::Type target); + Builder& data(const void* data); + Builder& data(const std::array& data); + Builder& compressed_data(const void* data, std::size_t bytes); + Builder& levels(uint32_t levels); + Builder& path(const fs::path& path); + Builder& size(glm::uvec2 size); + Builder& size(glm::uvec3 size); + Builder& mipmap(bool mipmap); + Builder& min_filter(Texture::Filter filter); + Builder& mag_filter(Texture::Filter filter); + Builder& wrap_s(Texture::Wrap wrap); + Builder& wrap_t(Texture::Wrap wrap); + Builder& wrap_r(Texture::Wrap wrap); void useStateExtensionTexture(); void useNamedExtensionTexture(); diff --git a/include/limitless/core/vertex_stream.hpp b/include/limitless/core/vertex_stream.hpp index d61fae36..0ca780ff 100644 --- a/include/limitless/core/vertex_stream.hpp +++ b/include/limitless/core/vertex_stream.hpp @@ -15,24 +15,24 @@ namespace Limitless { VertexStreamDraw mode; void initialize(size_t count) { - BufferBuilder builder; - builder .setTarget(Buffer::Type::Array) - .setDataSize(count * sizeof(Vertex)) - .setData(stream.empty() ? nullptr : stream.data()); + Buffer::Builder builder = Buffer::builder(); + builder.target(Buffer::Type::Array) + .size(count * sizeof(Vertex)) + .data(stream.empty() ? nullptr : stream.data()); switch (usage) { case VertexStreamUsage::Static: - builder .setUsage(Buffer::Storage::Static) - .setAccess(Buffer::ImmutableAccess::None); + builder.usage(Buffer::Storage::Static) + .access(Buffer::ImmutableAccess::None); break; case VertexStreamUsage::Dynamic: - builder .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning); + builder.usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning); break; case VertexStreamUsage::Stream: //TODO: should be x3 vertex array && x3 buffer - builder .setUsage(Buffer::Storage::DynamicCoherentWrite) - .setAccess(Buffer::ImmutableAccess::WriteCoherent); + builder.usage(Buffer::Storage::DynamicCoherentWrite) + .access(Buffer::ImmutableAccess::WriteCoherent); break; } diff --git a/include/limitless/fx/modules/mesh_location.hpp b/include/limitless/fx/modules/mesh_location.hpp index 631dfecc..c71e83e7 100644 --- a/include/limitless/fx/modules/mesh_location.hpp +++ b/include/limitless/fx/modules/mesh_location.hpp @@ -46,7 +46,7 @@ namespace Limitless::fx { const auto v_index3 = indices[vertex_index + 2]; if (instance) { - if (instance->getShaderType() == InstanceType::Skeletal) { + if (instance->getInstanceType() == InstanceType::Skeletal) { const auto& skeletal_instance = static_cast(*instance); const auto pos1 = skeletal_instance.getSkinnedVertexPosition(_mesh, v_index1); const auto pos2 = skeletal_instance.getSkinnedVertexPosition(_mesh, v_index2); diff --git a/include/limitless/fx/renderers/mesh_emitter_renderer.hpp b/include/limitless/fx/renderers/mesh_emitter_renderer.hpp index 34928c80..70c4e552 100644 --- a/include/limitless/fx/renderers/mesh_emitter_renderer.hpp +++ b/include/limitless/fx/renderers/mesh_emitter_renderer.hpp @@ -16,11 +16,11 @@ namespace Limitless::fx { void checkStorageSize(uint64_t count) { if (count > max_particle_count) { max_particle_count = count; - BufferBuilder builder; - buffer = builder.setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(MeshParticle) * max_particle_count) + buffer = Buffer::builder() + .target(Buffer::Type::ShaderStorage) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .size(sizeof(MeshParticle) * max_particle_count) .build(); } } @@ -30,11 +30,11 @@ namespace Limitless::fx { explicit EmitterRenderer(const MeshEmitter& emitter) : max_particle_count {emitter.getSpawn().max_count * EMITTER_STORAGE_INSTANCE_COUNT} , unique_type {emitter.getUniqueShaderType()} { - BufferBuilder builder; - buffer = builder .setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(MeshParticle) * max_particle_count) + buffer = Buffer::builder() + .target(Buffer::Type::ShaderStorage) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .size(sizeof(MeshParticle) * max_particle_count) .build(); } diff --git a/include/limitless/instances/abstract_instance.hpp b/include/limitless/instances/abstract_instance.hpp index cb08347e..79f57344 100644 --- a/include/limitless/instances/abstract_instance.hpp +++ b/include/limitless/instances/abstract_instance.hpp @@ -94,7 +94,7 @@ namespace Limitless { bool hidden {}; /** - * Does instance should be removed from scene in next frame + * Whether instance should be removed from scene in the next update */ bool done {}; @@ -114,7 +114,7 @@ namespace Limitless { */ virtual std::unique_ptr clone() noexcept = 0; - [[nodiscard]] auto getShaderType() const noexcept { return shader_type; } + [[nodiscard]] auto getInstanceType() const noexcept { return shader_type; } [[nodiscard]] auto getId() const noexcept { return id; } [[nodiscard]] const auto& getPosition() const noexcept { return position; } @@ -207,5 +207,12 @@ namespace Limitless { void draw(Context& ctx, const Assets& assets, ShaderType shader_type, ms::Blending blending); virtual void draw(Context& ctx, const Assets& assets, ShaderType shader_type, ms::Blending blending, const UniformSetter& uniform_set) = 0; + + /** + * Instance builder + */ + class Builder; + + static Builder builder() noexcept; }; } diff --git a/include/limitless/instances/instance_attachment.hpp b/include/limitless/instances/instance_attachment.hpp index 7d7cc681..de3c3c85 100644 --- a/include/limitless/instances/instance_attachment.hpp +++ b/include/limitless/instances/instance_attachment.hpp @@ -22,7 +22,7 @@ namespace Limitless { * InstanceAttachment is base class for any instance that can have an attachments of another instances * * instances attached to this instance ARE OWNED BY this instance, - * it means they get deleted if this instance dies + * it means they become not managed if this instance dies */ class InstanceAttachment { public: @@ -44,7 +44,7 @@ namespace Limitless { bool operator<(const AttachmentID& rhs) const; }; private: - std::map> attachments; + std::map> attachments; protected: /** * Sets parent matrix to attachments @@ -68,7 +68,7 @@ namespace Limitless { /** * Attaches instance */ - void attach(std::unique_ptr attachment); + void attach(std::shared_ptr attachment); /** * Detaches instance with specified id diff --git a/include/limitless/instances/instance_builder.hpp b/include/limitless/instances/instance_builder.hpp new file mode 100644 index 00000000..b9393df0 --- /dev/null +++ b/include/limitless/instances/instance_builder.hpp @@ -0,0 +1,110 @@ +#pragma once + +#include +#include +#include + +namespace Limitless { + class instance_builder_exception : public std::runtime_error { + public: + using std::runtime_error::runtime_error; + }; + + class AbstractInstance::Builder { + private: + std::shared_ptr model_; + + glm::quat rotation_ {1.0f, 0.0f, 0.0f, 0.0f}; + glm::vec3 position_ {0.0f}; + glm::vec3 scale_ {1.0f}; + bool cast_shadow_ {true}; + + class MaterialChange { + public: + uint32_t index; + std::string name; + std::shared_ptr material; + }; + std::vector changed_materials; + + std::shared_ptr global_material; + + std::vector> attachments; + + class SocketAttachment { + public: + std::string bone_name; + std::shared_ptr attachment; + }; + std::vector bone_attachments; + + void initialize(const std::shared_ptr& instance); + public: + Builder() noexcept = default; + + /** + * Sets Model to building instance + */ + Builder& model(const std::shared_ptr& model); + + /** + * Sets position to building instance + */ + Builder& position(const glm::vec3& position); + + /** + * Sets rotation to building instance + */ + Builder& rotation(const glm::quat& rotation); + + /** + * Sets scale to building instance + */ + Builder& scale(const glm::vec3& scale); + + /** + * Sets whether instance should cast shadow + */ + Builder& cast_shadow(bool cast_shadow); + + /** + * Replaces default mesh material with specified one + */ + Builder& material(uint32_t mesh_index, const std::shared_ptr& material); + + /** + * Replaces default mesh material with specified one + */ + Builder& material(const std::string& mesh_name, const std::shared_ptr& material); + + /** + * Replaces all model materials with specified one + */ + Builder& material(const std::shared_ptr& material); + + /** + * Attaches specified instance to building one + */ + Builder& attach(const std::shared_ptr& instance); + + /** + * Attaches specified instance to bone + */ + Builder& attach(const std::string& bone_name, const std::shared_ptr& instance); + + /** + * + */ + std::shared_ptr build(); + + /** + * + */ + std::shared_ptr asModel(); + + /** + * + */ + std::shared_ptr asSkeletal(); + }; +} \ No newline at end of file diff --git a/include/limitless/instances/instanced_instance.hpp b/include/limitless/instances/instanced_instance.hpp index 99c6d47d..d2893ca3 100644 --- a/include/limitless/instances/instanced_instance.hpp +++ b/include/limitless/instances/instanced_instance.hpp @@ -20,12 +20,12 @@ namespace Limitless { std::shared_ptr buffer; void initializeBuffer(uint32_t count) { - BufferBuilder builder; - buffer = builder.setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setData(nullptr) - .setDataSize(sizeof(glm::mat4) * count) + buffer = Buffer::builder() + .target(Buffer::Type::ShaderStorage) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .data(nullptr) + .size(sizeof(glm::mat4) * count) .build("model_buffer", *ContextState::getState(glfwGetCurrentContext())); } diff --git a/include/limitless/instances/material_instance.hpp b/include/limitless/instances/material_instance.hpp deleted file mode 100644 index a467f184..00000000 --- a/include/limitless/instances/material_instance.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace Limitless::ms { - class Material; -} - -namespace Limitless { - class Context; - - class MaterialInstance final { - private: - uint64_t next_id {}; - std::shared_ptr base; - std::map> materials; - bool layered {true}; - public: - explicit MaterialInstance(const std::shared_ptr& material); - ~MaterialInstance() = default; - - MaterialInstance(const MaterialInstance&); - MaterialInstance(MaterialInstance&&) = default; - - // changes base material - void changeBaseMaterial(const std::shared_ptr& material) noexcept; - - // changes layer %0 material - void changeMaterial(const std::shared_ptr& material) noexcept; - - // resets base material to first initialized - void reset() noexcept; - - // clears all applied materials - void clear() noexcept; - - // applies material as a layer and returns its id - uint64_t apply(const std::shared_ptr& material) noexcept; - - // removes 'id' layer - void remove(uint64_t id); - - // sets context state for %id layer - void setMaterialState(Context& ctx, uint64_t id, ShaderType pass); - - void makeLayered() noexcept; - void makeNonLayered() noexcept; - bool isLayered() const noexcept; - - // gets material layer - ms::Material& operator[](uint64_t id) { return *materials.at(id); } - const ms::Material& operator[](uint64_t id) const { return *materials.at(id); } - - auto& get(uint64_t id) { return materials.at(id); } - - [[nodiscard]] auto count() const noexcept { return materials.size(); } - - [[nodiscard]] auto begin() const noexcept { return materials.cbegin(); } - [[nodiscard]] auto begin() noexcept { return materials.begin(); } - - [[nodiscard]] auto end() const noexcept { return materials.cend(); } - [[nodiscard]] auto end() noexcept { return materials.end(); } - }; -} \ No newline at end of file diff --git a/include/limitless/instances/mesh_instance.hpp b/include/limitless/instances/mesh_instance.hpp index 0be189d5..74d92475 100644 --- a/include/limitless/instances/mesh_instance.hpp +++ b/include/limitless/instances/mesh_instance.hpp @@ -1,9 +1,11 @@ #pragma once -#include #include #include +#include #include +#include +#include namespace Limitless { class Assets; @@ -15,23 +17,28 @@ namespace Limitless { class MeshInstance final { private: std::shared_ptr mesh; - MaterialInstance material; - bool hidden {}; + std::shared_ptr material; + std::shared_ptr base; public: MeshInstance(std::shared_ptr mesh, const std::shared_ptr& material) noexcept; ~MeshInstance() = default; - MeshInstance(const MeshInstance&) = default; - MeshInstance(MeshInstance&&) = default; + MeshInstance(const MeshInstance&); + MeshInstance(MeshInstance&&) noexcept = default; - void update(); + // changes current material + void changeMaterial(const std::shared_ptr& material) noexcept; + + // changes base material + void changeBaseMaterial(const std::shared_ptr& material) noexcept; + + // resets base material to base + void reset() noexcept; [[nodiscard]] const auto& getMaterial() const noexcept { return material; } [[nodiscard]] auto& getMaterial() noexcept { return material; } - [[nodiscard]] bool isHidden() const noexcept { return hidden; } - void hide() noexcept; - void reveal() noexcept; + void update(); void draw(Context& ctx, const Assets& assets, diff --git a/include/limitless/instances/model_instance.hpp b/include/limitless/instances/model_instance.hpp index 2f83da84..85494098 100644 --- a/include/limitless/instances/model_instance.hpp +++ b/include/limitless/instances/model_instance.hpp @@ -18,7 +18,6 @@ namespace Limitless { */ class ModelInstance : public AbstractInstance { protected: - //TODO: material applying interface to all meshes std::map meshes; std::shared_ptr model; @@ -28,12 +27,12 @@ namespace Limitless { /** * Creates static model with specified loaded Model */ - explicit ModelInstance(decltype(model) model, const glm::vec3& position = glm::vec3{0.0f}); + explicit ModelInstance(decltype(model) model, const glm::vec3& position); /** * Creates static model with specified elementary model and material */ - ModelInstance(decltype(model) model, std::shared_ptr material, const glm::vec3& position = glm::vec3{0.0f}); + ModelInstance(decltype(model) model, std::shared_ptr material, const glm::vec3& position); ~ModelInstance() override = default; @@ -53,7 +52,22 @@ namespace Limitless { /** * Gets used model */ - const auto& getAbstractModel() const noexcept { return *model; } + [[nodiscard]] const auto& getAbstractModel() const noexcept { return *model; } + + + /** + * Gets mesh instance with specified name + * + * throws no_such_mesh if not found + */ + MeshInstance& getMeshInstance(const std::string& mesh); + + /** + * Gets mesh instance with specified index + * + * throws no_such_mesh if not found + */ + MeshInstance& getMeshInstance(uint32_t index); /** * Gets mesh instance with specified name @@ -69,7 +83,62 @@ namespace Limitless { */ MeshInstance& operator[](uint32_t index); - const auto& getMeshes() const noexcept { return meshes; } + /** + * Gets material of specified mesh + */ + const std::shared_ptr& getMaterial(uint32_t mesh_index); + + /** + * Gets material of specified mesh + */ + const std::shared_ptr& getMaterial(const std::string& mesh_name); + + /** + * Changes current material of mesh + */ + void changeMaterial(uint32_t mesh_index, const std::shared_ptr& material); + + /** + * Changes current material of mesh + */ + void changeMaterial(const std::string& mesh_name, const std::shared_ptr& material); + + /** + * Changes current materials of all meshes to specified + */ + void changeMaterials(const std::shared_ptr& material); + + /** + * Changes base material of mesh + */ + void changeBaseMaterial(uint32_t mesh_index, const std::shared_ptr& material); + + /** + * Changes base material of mesh + */ + void changeBaseMaterial(const std::string& mesh_name, const std::shared_ptr& material); + + /** + * Changes base materials of all meshes to specified + */ + void changeBaseMaterials(const std::shared_ptr& material); + + /** + * Resets material to base of mesh + */ + void resetMaterial(uint32_t mesh_index); + + /** + * Resets material to base of mesh + */ + void resetMaterial(const std::string& mesh_name); + + /** + * Resets materials to base of all meshes + */ + void resetMaterials(); + + [[nodiscard]] const auto& getMeshes() const noexcept { return meshes; } auto& getMeshes() noexcept { return meshes; } using AbstractInstance::draw; diff --git a/include/limitless/instances/socket_attachment.hpp b/include/limitless/instances/socket_attachment.hpp index 00675096..aa65a6e1 100644 --- a/include/limitless/instances/socket_attachment.hpp +++ b/include/limitless/instances/socket_attachment.hpp @@ -64,7 +64,7 @@ namespace Limitless { * * throws no_such_bone if not found */ - void attachToBone(std::string bone_name, std::unique_ptr instance); + void attachToBone(std::string bone_name, std::shared_ptr instance); /** * Detaches instance from bone diff --git a/include/limitless/loaders/texture_loader.hpp b/include/limitless/loaders/texture_loader.hpp index f3e68757..565b5ac0 100644 --- a/include/limitless/loaders/texture_loader.hpp +++ b/include/limitless/loaders/texture_loader.hpp @@ -55,7 +55,7 @@ namespace Limitless { class TextureLoader final { private: - static void setFormat(TextureBuilder& builder, const TextureLoaderFlags& flags, int channels); + static void setFormat(Texture::Builder& builder, const TextureLoaderFlags& flags, int channels); static void setAnisotropicFilter(const std::shared_ptr& texture, const TextureLoaderFlags& flags); static void setDownScale(int& width, int& height, int channels, unsigned char*& data, const TextureLoaderFlags& flags); static bool isPowerOfTwo(int width, int height); @@ -63,7 +63,7 @@ namespace Limitless { TextureLoader() = delete; ~TextureLoader() = delete; - static void setTextureParameters(TextureBuilder& builder, const TextureLoaderFlags& flags); + static void setTextureParameters(Texture::Builder& builder, const TextureLoaderFlags& flags); static GLFWimage loadGLFWImage(Assets& assets, const fs::path& path, const TextureLoaderFlags& flags = {}); static std::shared_ptr load(Assets& assets, const fs::path& path, const TextureLoaderFlags& flags = {}); diff --git a/include/limitless/scene.hpp b/include/limitless/scene.hpp index 4870c08e..7a8fa885 100644 --- a/include/limitless/scene.hpp +++ b/include/limitless/scene.hpp @@ -12,11 +12,14 @@ namespace Limitless { using Instances = std::vector>; + /** + * + */ class Scene { public: Lighting lighting; private: - std::unordered_map> instances; + std::unordered_map> instances; std::shared_ptr skybox; void removeDeadInstances() noexcept; @@ -27,6 +30,11 @@ namespace Limitless { Scene(const Scene&) = delete; Scene(Scene&&) = delete; + /** + * Takes ownership of passed instance and manages it + */ + void add(AbstractInstance* instance); + template T& add(T* instance) noexcept { static_assert(std::is_base_of_v, "Typename type must be base of AbstractInstance"); @@ -67,21 +75,5 @@ namespace Limitless { Instances getWrappers() noexcept; auto size() const noexcept { return instances.size(); } - - #ifdef NDEBUG - template - T& get(uint64_t id) { - try { - return dynamic_cast(*instances[id]); - } catch (...) { - throw std::runtime_error("Scene wrong instance cast"); - } - } - #else - template - T& get(uint64_t id) noexcept { - return static_cast(*instances[id]); - } - #endif }; } \ No newline at end of file diff --git a/src/limitless/core/buffer/buffer_builder.cpp b/src/limitless/core/buffer/buffer_builder.cpp index 20df57e0..a7ee2e44 100644 --- a/src/limitless/core/buffer/buffer_builder.cpp +++ b/src/limitless/core/buffer/buffer_builder.cpp @@ -6,79 +6,83 @@ using namespace Limitless; -BufferBuilder& BufferBuilder::setTarget(Buffer::Type _target) { - target = _target; +Buffer::Builder Buffer::builder() { + return {}; +} + +Buffer::Builder& Buffer::Builder::target(Buffer::Type _target) { + target_ = _target; return *this; } -BufferBuilder& BufferBuilder::setUsage(Buffer::Usage _usage) { - usage = _usage; +Buffer::Builder& Buffer::Builder::usage(Buffer::Usage _usage) { + usage_ = _usage; return *this; } -BufferBuilder& BufferBuilder::setUsage(Buffer::Storage _storage) { - usage = _storage; +Buffer::Builder& Buffer::Builder::usage(Buffer::Storage _storage) { + usage_ = _storage; return *this; } -BufferBuilder& BufferBuilder::setAccess(Buffer::MutableAccess _access) { - access = _access; +Buffer::Builder& Buffer::Builder::access(Buffer::MutableAccess _access) { + access_ = _access; return *this; } -BufferBuilder& BufferBuilder::setAccess(Buffer::ImmutableAccess _access) { - access = _access; +Buffer::Builder& Buffer::Builder::access(Buffer::ImmutableAccess _access) { + access_ = _access; return *this; } -BufferBuilder& BufferBuilder::setData(const void* _data) { - data = _data; +Buffer::Builder& Buffer::Builder::data(const void* _data) { + data_ = _data; return *this; } -BufferBuilder& BufferBuilder::setDataSize(size_t _size) { - size = _size; +Buffer::Builder& Buffer::Builder::size(size_t _size) { + size_ = _size; return *this; } -std::unique_ptr BufferBuilder::build() { +std::unique_ptr Buffer::Builder::build() { if (ContextInitializer::isExtensionSupported("GL_ARB_direct_state_access")) { // building DSA buffer - if (std::holds_alternative(usage) && std::holds_alternative(access)) { + if (std::holds_alternative(usage_) && std::holds_alternative(access_)) { // building mutable buffer - return std::make_unique(target, size, data, std::get(usage), std::get(access)); + return std::make_unique(target_, size_, data_, std::get(usage_), std::get(access_)); } else { // building immutable buffer if (ContextInitializer::isExtensionSupported("GL_ARB_buffer_storage")) { - return std::make_unique(target, size, data, std::get(usage), std::get(access)); + return std::make_unique(target_, size_, data_, std::get(usage_), std::get(access_)); } else { // not supported, building mutable based on access - return std::get(access) == Buffer::ImmutableAccess::None ? - std::make_unique(target, size, data, Buffer::Usage::StaticDraw, Buffer::MutableAccess::None) : - std::make_unique(target, size, data, Buffer::Usage::DynamicDraw, Buffer::MutableAccess::WriteOrphaning); + return std::get(access_) == Buffer::ImmutableAccess::None ? + std::make_unique(target_, size_, data_, Buffer::Usage::StaticDraw, Buffer::MutableAccess::None) : + std::make_unique(target_, size_, data_, Buffer::Usage::DynamicDraw, Buffer::MutableAccess::WriteOrphaning); } } } else { // building state buffer - if (std::holds_alternative(usage) && std::holds_alternative(access)) { + if (std::holds_alternative(usage_) && std::holds_alternative(access_)) { // building mutable buffer - return std::make_unique(target, size, data, std::get(usage), std::get(access)); + return std::make_unique(target_, size_, data_, std::get(usage_), std::get(access_)); } else { // building immutable buffer if (ContextInitializer::isExtensionSupported("GL_ARB_buffer_storage")) { - return std::make_unique(target, size, data, std::get(usage), std::get(access)); + return std::make_unique(target_, size_, data_, std::get(usage_), std::get(access_)); } else { // not supported, building mutable based on access - return std::get(access) == Buffer::ImmutableAccess::None ? - std::make_unique(target, size, data, Buffer::Usage::StaticDraw, Buffer::MutableAccess::None) : - std::make_unique(target, size, data, Buffer::Usage::DynamicDraw, Buffer::MutableAccess::WriteOrphaning); + return std::get(access_) == Buffer::ImmutableAccess::None ? + std::make_unique(target_, size_, data_, Buffer::Usage::StaticDraw, Buffer::MutableAccess::None) : + std::make_unique(target_, size_, data_, Buffer::Usage::DynamicDraw, Buffer::MutableAccess::WriteOrphaning); } } } } // builds indexed buffer for specified context -std::shared_ptr BufferBuilder::build(std::string_view name, ContextState& ctx) { +std::shared_ptr Buffer::Builder::build(std::string_view name, ContextState& ctx) { std::shared_ptr buffer = build(); ctx.getIndexedBuffers().add(name, buffer); return buffer; diff --git a/src/limitless/core/framebuffer.cpp b/src/limitless/core/framebuffer.cpp index 2f645525..c57002fc 100644 --- a/src/limitless/core/framebuffer.cpp +++ b/src/limitless/core/framebuffer.cpp @@ -184,16 +184,16 @@ void Framebuffer::unbind() noexcept { Framebuffer Framebuffer::asRGB8LinearClampToEdge(glm::vec2 size) { Framebuffer framebuffer; - TextureBuilder builder; - auto color = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(size) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto color = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(size) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -207,16 +207,16 @@ Framebuffer Framebuffer::asRGB8LinearClampToEdge(glm::vec2 size) { Framebuffer Framebuffer::asRGB8LinearClampToEdgeWithDepth(glm::vec2 size, const std::shared_ptr& depth) { Framebuffer framebuffer; - TextureBuilder builder; - auto color = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(size) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto color = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(size) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -231,28 +231,29 @@ Framebuffer Framebuffer::asRGB8LinearClampToEdgeWithDepth(glm::vec2 size, const Framebuffer Framebuffer::asRGB8LinearClampToEdgeWithDepth(glm::vec2 size) { Framebuffer framebuffer; - TextureBuilder builder; - auto color = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(size) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto color = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(size) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); //TODO: 32F???? wtf? - auto depth = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::Depth32F) - .setSize(size) - .setFormat(Texture::Format::DepthComponent) - .setDataType(Texture::DataType::Float) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto depth = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::Depth32F) + .size(size) + .format(Texture::Format::DepthComponent) + .data_type(Texture::DataType::Float) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -267,16 +268,16 @@ Framebuffer Framebuffer::asRGB8LinearClampToEdgeWithDepth(glm::vec2 size) { Framebuffer Framebuffer::asRGB16FLinearClampToEdge(glm::vec2 size) { Framebuffer framebuffer; - TextureBuilder builder; - auto color = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB16F) - .setSize(size) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::Float) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto color = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB16F) + .size(size) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::Float) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -291,8 +292,7 @@ Framebuffer Framebuffer::asRGB16FLinearClampToEdge(glm::vec2 size) { Framebuffer Framebuffer::asRGB16FNearestClampToEdge(glm::uvec2 size) { Framebuffer framebuffer; - TextureBuilder builder; - auto color = TextureBuilder::asRGB16FNearestClampToEdge(size); + auto color = Texture::Builder::asRGB16FNearestClampToEdge(size); framebuffer.bind(); framebuffer << TextureAttachment{FramebufferAttachment::Color0, color}; @@ -306,8 +306,7 @@ Framebuffer Framebuffer::asRGB16FNearestClampToEdge(glm::uvec2 size) { Framebuffer Framebuffer::asRGB16FNearestClampToEdgeWithDepth(glm::uvec2 size, const std::shared_ptr& depth) { Framebuffer framebuffer; - TextureBuilder builder; - auto color = TextureBuilder::asRGB16FNearestClampToEdge(size); + auto color = Texture::Builder::asRGB16FNearestClampToEdge(size); framebuffer.bind(); framebuffer << TextureAttachment{FramebufferAttachment::Color0, color} diff --git a/src/limitless/core/texture/texture.cpp b/src/limitless/core/texture/texture.cpp index aec92bff..e9e97d3f 100644 --- a/src/limitless/core/texture/texture.cpp +++ b/src/limitless/core/texture/texture.cpp @@ -1,8 +1,8 @@ #include #include +#include #include -#include using namespace Limitless; @@ -65,7 +65,7 @@ void Texture::image(const std::array& data) { setParameters(); for (std::size_t i = 0; i < data.size(); ++i) { - texture->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, static_cast(internal_format), static_cast(format), static_cast(data_type), size, border, data[i]); + texture->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, static_cast(internal_format), static_cast(format), static_cast(data_type), size, false, data[i]); } if (mipmap) { @@ -75,12 +75,12 @@ void Texture::image(const std::array& data) { void Texture::image(uint32_t level, glm::uvec2 _size, const void* data) { setParameters(); - texture->texImage2D(static_cast(target), level, static_cast(internal_format), static_cast(format), static_cast(data_type), _size, border, data); + texture->texImage2D(static_cast(target), level, static_cast(internal_format), static_cast(format), static_cast(data_type), _size, false, data); } void Texture::image(uint32_t level, glm::uvec3 _size, const void* data) { setParameters(); - texture->texImage3D(static_cast(target), level, static_cast(internal_format), static_cast(format), static_cast(data_type), _size, border, data); + texture->texImage3D(static_cast(target), level, static_cast(internal_format), static_cast(format), static_cast(data_type), _size, false, data); } void Texture::compressedImage(const void* data, std::size_t byte_count) { @@ -92,12 +92,12 @@ void Texture::compressedImage(const void* data, std::size_t byte_count) { void Texture::compressedImage(uint32_t level, glm::uvec2 _size, const void* data, std::size_t byte_count) { setParameters(); - texture->compressedTexImage2D(static_cast(target), level, static_cast(internal_format), _size, border, data, byte_count); + texture->compressedTexImage2D(static_cast(target), level, static_cast(internal_format), _size, false, data, byte_count); } void Texture::compressedImage(uint32_t level, glm::uvec3 _size, const void* data, std::size_t byte_count) { setParameters(); - texture->compressedTexImage3D(static_cast(target), level, static_cast(internal_format), _size, border, data, byte_count); + texture->compressedTexImage3D(static_cast(target), level, static_cast(internal_format), _size, false, data, byte_count); } void Texture::subImage(uint32_t level, glm::uvec2 offset, glm::uvec2 _size, const void* data) { @@ -170,12 +170,6 @@ Texture& Texture::setAnisotropicFilterMax() { return *this; } -Texture& Texture::setBorderColor(const glm::vec4& color) { - border_color = color; - texture->setBorderColor(static_cast(target), &border_color[0]); - return *this; -} - Texture& Texture::setWrapS(Wrap wrap) { wrap_s = wrap; texture->setWrapS(static_cast(target), static_cast(wrap_s)); @@ -200,9 +194,6 @@ void Texture::setParameters() { setWrapS(wrap_s); setWrapT(wrap_t); setWrapR(wrap_r); - if (border) { - setBorderColor(border_color); - } if (anisotropic != 1.0f) { setAnisotropicFilter(anisotropic); @@ -219,4 +210,8 @@ bool Texture::isMutable() const noexcept { bool Texture::isImmutable() const noexcept { return immutable; +} + +Texture::Builder Texture::builder() { + return {}; } \ No newline at end of file diff --git a/src/limitless/core/texture/texture_builder.cpp b/src/limitless/core/texture/texture_builder.cpp index a12e095b..6ae9e671 100644 --- a/src/limitless/core/texture/texture_builder.cpp +++ b/src/limitless/core/texture/texture_builder.cpp @@ -8,130 +8,120 @@ using namespace Limitless; -void TextureBuilder::create() { +void Texture::Builder::create() { // uses protected ctor texture = std::unique_ptr(new Texture()); - data = {}; + data_ = {}; cube_data = {}; byte_count = {}; } -bool TextureBuilder::isCompressed() const { +bool Texture::Builder::isCompressed() const { return byte_count != 0; } -bool TextureBuilder::isCubeMap() const { +bool Texture::Builder::isCubeMap() const { return cube_data != std::array{}; } -bool TextureBuilder::isImmutable() { +bool Texture::Builder::isImmutable() { return ContextInitializer::isExtensionSupported("GL_ARB_texture_storage"); } -TextureBuilder::TextureBuilder() { +Texture::Builder::Builder() { create(); } -TextureBuilder& TextureBuilder::setInternalFormat(Texture::InternalFormat internal) { +Texture::Builder& Texture::Builder::internal_format(Texture::InternalFormat internal) { texture->internal_format = internal; return *this; } -TextureBuilder& TextureBuilder::setFormat(Texture::Format format) { +Texture::Builder& Texture::Builder::format(Texture::Format format) { texture->format = format; return *this; } -TextureBuilder& TextureBuilder::setTarget(Texture::Type target) { +Texture::Builder& Texture::Builder::target(Texture::Type target) { texture->target = target; return *this; } -TextureBuilder& TextureBuilder::setDataType(Texture::DataType type) { +Texture::Builder& Texture::Builder::data_type(Texture::DataType type) { texture->data_type = type; return *this; } -TextureBuilder& TextureBuilder::setData(const void* _data) { - data = _data; +Texture::Builder& Texture::Builder::data(const void* _data) { + data_ = _data; return *this; } -TextureBuilder& TextureBuilder::setData(const std::array& _data) { +Texture::Builder& Texture::Builder::data(const std::array& _data) { cube_data = _data; return *this; } -TextureBuilder& TextureBuilder::setSize(glm::uvec2 size) { +Texture::Builder& Texture::Builder::size(glm::uvec2 size) { texture->size = { size, 1 }; return *this; } -TextureBuilder& TextureBuilder::setSize(glm::uvec3 size) { +Texture::Builder& Texture::Builder::size(glm::uvec3 size) { texture->size = size; return *this; } -TextureBuilder& TextureBuilder::setLevels(uint32_t levels) { +Texture::Builder& Texture::Builder::levels(uint32_t levels) { texture->levels = levels; return *this; } -TextureBuilder& TextureBuilder::setPath(const fs::path& path) { +Texture::Builder& Texture::Builder::path(const fs::path& path) { texture->path = path; return *this; } -TextureBuilder& TextureBuilder::setMipMap(bool mipmap) { +Texture::Builder& Texture::Builder::mipmap(bool mipmap) { texture->mipmap = mipmap; return *this; } -TextureBuilder& TextureBuilder::setMinFilter(Texture::Filter filter) { +Texture::Builder& Texture::Builder::min_filter(Texture::Filter filter) { texture->min = filter; return *this; } -TextureBuilder& TextureBuilder::setMagFilter(Texture::Filter filter) { +Texture::Builder& Texture::Builder::mag_filter(Texture::Filter filter) { texture->mag = filter; return *this; } -TextureBuilder& TextureBuilder::setWrapS(Texture::Wrap wrap) { +Texture::Builder& Texture::Builder::wrap_s(Texture::Wrap wrap) { texture->wrap_s = wrap; return *this; } -TextureBuilder& TextureBuilder::setWrapT(Texture::Wrap wrap) { +Texture::Builder& Texture::Builder::wrap_t(Texture::Wrap wrap) { texture->wrap_t = wrap; return *this; } -TextureBuilder& TextureBuilder::setWrapR(Texture::Wrap wrap) { +Texture::Builder& Texture::Builder::wrap_r(Texture::Wrap wrap) { texture->wrap_r = wrap; return *this; } -TextureBuilder& TextureBuilder::setBorder(bool border) { - texture->border = border; - return *this; -} - -TextureBuilder& TextureBuilder::setBorderColor(const glm::vec4& color) { - texture->border_color = color; - return *this; -} - -std::shared_ptr TextureBuilder::buildMutable() { +std::shared_ptr Texture::Builder::buildMutable() { if (!texture->texture) { useBestSupportedExtensionTexture(); } if (isCompressed()) { - texture->compressedImage(data, byte_count); + texture->compressedImage(data_, byte_count); } else { - isCubeMap() ? texture->image(cube_data) : texture->image(data); + isCubeMap() ? texture->image(cube_data) : texture->image(data_); } auto tex = std::move(texture); @@ -139,7 +129,7 @@ std::shared_ptr TextureBuilder::buildMutable() { return tex; } -std::shared_ptr TextureBuilder::buildImmutable() { +std::shared_ptr Texture::Builder::buildImmutable() { if (!texture->texture) { useBestSupportedExtensionTexture(); } @@ -156,7 +146,7 @@ std::shared_ptr TextureBuilder::buildImmutable() { if (isCubeMap()) { texture->storage(cube_data); } else { - texture->storage(data); + texture->storage(data_); } } @@ -166,104 +156,94 @@ std::shared_ptr TextureBuilder::buildImmutable() { return tex; } -std::shared_ptr TextureBuilder::build() { +std::shared_ptr Texture::Builder::build() { return isImmutable() ? buildImmutable() : buildMutable(); } -TextureBuilder& TextureBuilder::setCompressedData(const void* _data, std::size_t count) { - data = _data; +Texture::Builder& Texture::Builder::compressed_data(const void* _data, std::size_t count) { + data_= _data; byte_count = count; return *this; } -std::shared_ptr TextureBuilder::asRGBA16NearestClampToEdge(glm::uvec2 size) { - TextureBuilder builder; - +std::shared_ptr Texture::Builder::asRGBA16NearestClampToEdge(glm::uvec2 size) { //TODO: change to RGB16 UNSIGNED SHORT? - builder .setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGBA16) - .setFormat(Texture::Format::RGBA) - .setDataType(Texture::DataType::UnsignedByte) - .setSize(size) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge); - - return builder.build(); -} - -std::shared_ptr TextureBuilder::asRGB16NearestClampToEdge(glm::uvec2 size) { - TextureBuilder builder; - - builder .setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB16) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte) - .setSize(size) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge); - - return builder.build(); -} - -std::shared_ptr TextureBuilder::asRGB16SNORMNearestClampToEdge(glm::uvec2 size) { - TextureBuilder builder; - - builder .setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB16_SNORM) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::Byte) - .setSize(size) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge); - - return builder.build(); -} - -std::shared_ptr TextureBuilder::asRGB16FNearestClampToEdge(glm::uvec2 size) { - TextureBuilder builder; - - builder .setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB16F) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::Float) - .setSize(size) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setMipMap(false); - - return builder.build(); -} - -std::shared_ptr TextureBuilder::asDepth32F(glm::uvec2 size) { - TextureBuilder builder; - - builder .setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::Depth32F) - .setFormat(Texture::Format::DepthComponent) - .setDataType(Texture::DataType::Float) - .setSize(size) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge); - - return builder.build(); -} - -void TextureBuilder::useStateExtensionTexture() { + return Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGBA16) + .format(Texture::Format::RGBA) + .data_type(Texture::DataType::UnsignedByte) + .size(size) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .build(); +} + +std::shared_ptr Texture::Builder::asRGB16NearestClampToEdge(glm::uvec2 size) { + return Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB16) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte) + .size(size) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .build(); +} + +std::shared_ptr Texture::Builder::asRGB16SNORMNearestClampToEdge(glm::uvec2 size) { + return Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB16_SNORM) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::Byte) + .size(size) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .build(); +} + +std::shared_ptr Texture::Builder::asRGB16FNearestClampToEdge(glm::uvec2 size) { + return Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB16F) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::Float) + .size(size) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .mipmap(false) + .build(); +} + +std::shared_ptr Texture::Builder::asDepth32F(glm::uvec2 size) { + return Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::Depth32F) + .format(Texture::Format::DepthComponent) + .data_type(Texture::DataType::Float) + .size(size) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .build(); +} + +void Texture::Builder::useStateExtensionTexture() { texture->texture = std::make_unique(); texture->texture->generateId(); } -void TextureBuilder::useNamedExtensionTexture() { +void Texture::Builder::useNamedExtensionTexture() { if (!ContextInitializer::isExtensionSupported("GL_ARB_direct_state_access")) { throw std::runtime_error{"NamedExtensionTexture is not supported!"}; } @@ -272,7 +252,7 @@ void TextureBuilder::useNamedExtensionTexture() { texture->texture->generateId(); } -void TextureBuilder::useBindlessExtensionTexture() { +void Texture::Builder::useBindlessExtensionTexture() { if (!ContextInitializer::isExtensionSupported("GL_ARB_bindless_texture")) { throw std::runtime_error{"BindlessTexture is not supported!"}; } @@ -284,7 +264,7 @@ void TextureBuilder::useBindlessExtensionTexture() { texture->texture = std::make_unique(texture->texture.release()); } -void TextureBuilder::useBestSupportedExtensionTexture() { +void Texture::Builder::useBestSupportedExtensionTexture() { ContextInitializer::isExtensionSupported("GL_ARB_direct_state_access") ? useNamedExtensionTexture() : useStateExtensionTexture(); if (ContextInitializer::isExtensionSupported("GL_ARB_bindless_texture")) { diff --git a/src/limitless/fx/effect_renderer.cpp b/src/limitless/fx/effect_renderer.cpp index 182f365e..0829a3d7 100644 --- a/src/limitless/fx/effect_renderer.cpp +++ b/src/limitless/fx/effect_renderer.cpp @@ -22,7 +22,7 @@ void EffectRenderer::visitEmitters(const Instances& instances, EmitterVisitor& e visitor(*attachment); } - if (instance.getShaderType() == InstanceType::Effect) { + if (instance.getInstanceType() == InstanceType::Effect) { effect_instance_visitor(static_cast(instance), emitter_visitor); } }; diff --git a/src/limitless/instances/instance_attachment.cpp b/src/limitless/instances/instance_attachment.cpp index bc34ff49..0d9c78f7 100644 --- a/src/limitless/instances/instance_attachment.cpp +++ b/src/limitless/instances/instance_attachment.cpp @@ -31,7 +31,7 @@ InstanceAttachment& InstanceAttachment::setAttachmentsParent(const glm::mat4& pa return *this; } -void InstanceAttachment::attach(std::unique_ptr attachment) { +void InstanceAttachment::attach(std::shared_ptr attachment) { attachments.emplace(AttachmentID {attachment->getId(), AttachmentType::Basic}, std::move(attachment)); } diff --git a/src/limitless/instances/instance_builder.cpp b/src/limitless/instances/instance_builder.cpp new file mode 100644 index 00000000..126f0912 --- /dev/null +++ b/src/limitless/instances/instance_builder.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include + +using namespace Limitless; + +void AbstractInstance::Builder::initialize(const std::shared_ptr& instance) { + // apply properties + instance->setPosition(position_); + instance->setRotation(rotation_); + instance->setScale(scale_); + if (cast_shadow_) { + instance->castShadow(); + } + + // add instance attachments + for (const auto &attachment: attachments) { + instance->attach(attachment); + } + + // add bone attachments + if (instance->getInstanceType() == InstanceType::Skeletal) { + auto &skeletal = static_cast(*instance); + + for (const auto &[bone, attachment]: bone_attachments) { + skeletal.attachToBone(bone, attachment); + } + } + + // change materials + if (global_material) { + instance->changeMaterials(global_material); + } + + for (const auto& [index, name, material] : changed_materials) { + if (!name.empty()) { + instance->changeMaterial(name, material); + } else { + instance->changeMaterial(index, material); + } + } +} + +AbstractInstance::Builder& AbstractInstance::Builder::model(const std::shared_ptr& model) { + model_ = model; + return *this; +} + +AbstractInstance::Builder &AbstractInstance::Builder::position(const glm::vec3& position) { + position_ = position; + return *this; +} + +AbstractInstance::Builder &AbstractInstance::Builder::rotation(const glm::quat& rotation) { + rotation_ = rotation; + return *this; +} + +AbstractInstance::Builder &AbstractInstance::Builder::scale(const glm::vec3& scale) { + scale_ = scale; + return *this; +} + +AbstractInstance::Builder &AbstractInstance::Builder::cast_shadow(bool cast_shadow) { + cast_shadow_ = cast_shadow; + return *this; +} + +std::shared_ptr AbstractInstance::Builder::asModel() { + if (dynamic_cast(model_.get())) { + auto instance = std::make_shared(model_, position_); + initialize(instance); + return instance; + } else { + throw instance_builder_exception {model_->getName() + " is not Model!"}; + } +} + +std::shared_ptr AbstractInstance::Builder::asSkeletal() { + if (dynamic_cast(model_.get())) { + auto instance = std::make_shared(model_, position_); + initialize(instance); + return instance; + } else { + throw instance_builder_exception {model_->getName() + " is not SkeletalModel!"}; + } +} + +std::shared_ptr AbstractInstance::Builder::build() { + if (dynamic_cast(model_.get())) { + return asSkeletal(); + } + + if (dynamic_cast(model_.get())) { + return asModel(); + } + + if (dynamic_cast(model_.get())) { + if (global_material) { + auto instance = std::make_shared(model_, global_material, position_); + initialize(instance); + return instance; + } else { + throw instance_builder_exception {"Material for Elementary model is not set!"}; + } + } + + throw instance_builder_exception {"Invalid parameters for instance builder!"}; +} + +AbstractInstance::Builder& AbstractInstance::Builder::material(uint32_t mesh_index, const std::shared_ptr& material) { + changed_materials.emplace_back(MaterialChange{mesh_index, {}, material}); + return *this; +} + +AbstractInstance::Builder& AbstractInstance::Builder::material(const std::string& mesh_name, const std::shared_ptr& material) { + changed_materials.emplace_back(MaterialChange{0, mesh_name, material}); + return *this; +} + + +AbstractInstance::Builder& AbstractInstance::Builder::material(const std::shared_ptr& material) { + global_material = material; + return *this; +} + +AbstractInstance::Builder& AbstractInstance::Builder::attach(const std::shared_ptr& instance) { + attachments.emplace_back(instance); + return *this; +} + +AbstractInstance::Builder& AbstractInstance::Builder::attach(const std::string& bone_name, const std::shared_ptr& instance) { + bone_attachments.emplace_back(SocketAttachment{bone_name, instance}); + return *this; +} diff --git a/src/limitless/instances/mesh_instance.cpp b/src/limitless/instances/mesh_instance.cpp index f0bb025a..b123f3d9 100644 --- a/src/limitless/instances/mesh_instance.cpp +++ b/src/limitless/instances/mesh_instance.cpp @@ -3,22 +3,34 @@ #include #include #include -#include "limitless/core/shader/shader_program.hpp" +#include #include using namespace Limitless; +using namespace Limitless::ms; -MeshInstance::MeshInstance(std::shared_ptr _mesh, const std::shared_ptr& _material) noexcept - : mesh {std::move(_mesh)} - , material {_material} { +MeshInstance::MeshInstance(std::shared_ptr mesh, const std::shared_ptr& material) noexcept + : mesh {std::move(mesh)} + , material {std::make_shared(*material)} { } -void MeshInstance::hide() noexcept { - hidden = true; +MeshInstance::MeshInstance(const MeshInstance& rhs) + : mesh {rhs.mesh} + , material {std::make_shared(*rhs.material)} + , base {std::make_shared(*rhs.base)} { } -void MeshInstance::reveal() noexcept { - hidden = false; +void MeshInstance::changeBaseMaterial(const std::shared_ptr& material_) noexcept { + base = std::make_shared(*material_); + material = std::make_shared(*material_); +} + +void MeshInstance::changeMaterial(const std::shared_ptr& material_) noexcept { + material = std::make_shared(*material_); +} + +void MeshInstance::reset() noexcept { + material = base; } void MeshInstance::draw(Context& ctx, @@ -28,59 +40,40 @@ void MeshInstance::draw(Context& ctx, const glm::mat4& model_matrix, ms::Blending blending, const UniformSetter& uniform_setter) { - if (hidden) { + + if (material->getBlending() != blending) { return; } - //TODO: refactor this shitty unreadable nonhuman orc code - if (!material.isLayered()) { - const auto& mat = material[0]; - if (mat.getBlending() != blending) { - return; - } + setBlendingMode(material->getBlending()); - // sets state for material - material.setMaterialState(ctx, 0, pass); + // sets culling based on two-sideness + if (material->getTwoSided()) { + ctx.disable(Capabilities::CullFace); + } else { + ctx.enable(Capabilities::CullFace); - // gets required shader from storage - auto& shader = assets.shaders.get(pass, model, mat.getShaderIndex()); - - // updates model/material uniforms - shader.setUniform("_model_transform", model_matrix) - .setMaterial(mat); - - // sets custom pass-dependent uniforms - uniform_setter(shader); - - shader.use(); - - mesh->draw(); - return; - } - - // iterates over material layers - for (const auto& [index, mat] : material) { - if (mat->getBlending() != blending) { - continue; + // front cullfacing for shadows helps prevent peter panning + if (pass == ShaderType::DirectionalShadow) { + ctx.setCullFace(CullFace::Front); + } else { + ctx.setCullFace(CullFace::Back); } + } - // sets state for material - material.setMaterialState(ctx, index, pass); - - // gets required shader from storage - auto& shader = assets.shaders.get(pass, model, mat->getShaderIndex()); + // gets required shader from storage + auto& shader = assets.shaders.get(pass, model, material->getShaderIndex()); - // updates model/material uniforms - shader.setUniform("_model_transform", model_matrix) - .setMaterial(*mat); + // updates model/material uniforms + shader.setUniform("_model_transform", model_matrix) + .setMaterial(*material); - // sets custom pass-dependent uniforms - uniform_setter(shader); + // sets custom pass-dependent uniforms + uniform_setter(shader); - shader.use(); + shader.use(); - mesh->draw(); - } + mesh->draw(); } void MeshInstance::draw_instanced(Context& ctx, @@ -91,37 +84,41 @@ void MeshInstance::draw_instanced(Context& ctx, ms::Blending blending, const UniformSetter& uniform_setter, uint32_t count) { - if (hidden) { + if (material->getBlending() != blending) { return; } - // iterates over material layers - for (const auto& [index, mat] : material) { - if (mat->getBlending() != blending) { - continue; - } + setBlendingMode(material->getBlending()); - // sets state for material - material.setMaterialState(ctx, index, pass); + // sets culling based on two-sideness + if (material->getTwoSided()) { + ctx.disable(Capabilities::CullFace); + } else { + ctx.enable(Capabilities::CullFace); - // gets required shader from storage - auto& shader = assets.shaders.get(pass, model, mat->getShaderIndex()); + // front cullfacing for shadows helps prevent peter panning + if (pass == ShaderType::DirectionalShadow) { + ctx.setCullFace(CullFace::Front); + } else { + ctx.setCullFace(CullFace::Back); + } + } - // updates model/material uniforms - shader.setUniform("_model_transform", model_matrix) - .setMaterial(*mat); + // gets required shader from storage + auto& shader = assets.shaders.get(pass, model, material->getShaderIndex()); - // sets custom pass-dependent uniforms - uniform_setter(shader); + // updates model/material uniforms + shader.setUniform("_model_transform", model_matrix) + .setMaterial(*material); - shader.use(); + // sets custom pass-dependent uniforms + uniform_setter(shader); - mesh->draw_instanced(count); - } + shader.use(); + + mesh->draw_instanced(count); } void MeshInstance::update() { - for (const auto& [_, mat] : material) { - mat->update(); - } + material->update(); } diff --git a/src/limitless/instances/model_instance.cpp b/src/limitless/instances/model_instance.cpp index ea0f86e3..779bdde0 100644 --- a/src/limitless/instances/model_instance.cpp +++ b/src/limitless/instances/model_instance.cpp @@ -81,3 +81,101 @@ void ModelInstance::update(Context& context, const Camera& camera) { mesh.update(); } } + +void ModelInstance::changeMaterial(uint32_t mesh_index, const std::shared_ptr &material) { + if (mesh_index >= meshes.size()) { + throw no_such_mesh("with index " + std::to_string(mesh_index)); + } + + std::next(meshes.begin(), mesh_index)->second.changeMaterial(material); +} + +void ModelInstance::changeMaterial(const std::string& mesh_name, const std::shared_ptr &material) { + try { + meshes.at(mesh_name).changeMaterial(material); + } catch (...) { + throw no_such_mesh("with name " + mesh_name); + } +} + +void ModelInstance::changeMaterials(const std::shared_ptr &material) { + for (auto& [_, mesh] : meshes) { + mesh.changeMaterial(material); + } +} + +void ModelInstance::changeBaseMaterial(uint32_t mesh_index, const std::shared_ptr &material) { + if (mesh_index >= meshes.size()) { + throw no_such_mesh("with index " + std::to_string(mesh_index)); + } + + std::next(meshes.begin(), mesh_index)->second.changeBaseMaterial(material); +} + +void ModelInstance::changeBaseMaterial(const std::string& mesh_name, const std::shared_ptr &material) { + try { + meshes.at(mesh_name).changeBaseMaterial(material); + } catch (...) { + throw no_such_mesh("with name " + mesh_name); + } +} + +void ModelInstance::changeBaseMaterials(const std::shared_ptr& material) { + for (auto& [_, mesh]: meshes) { + mesh.changeBaseMaterial(material); + } +} + +void ModelInstance::resetMaterial(uint32_t mesh_index) { + if (mesh_index >= meshes.size()) { + throw no_such_mesh("with index " + std::to_string(mesh_index)); + } + + std::next(meshes.begin(), mesh_index)->second.reset(); +} + +void ModelInstance::resetMaterial(const std::string& mesh_name) { + try { + meshes.at(mesh_name).reset(); + } catch (...) { + throw no_such_mesh("with name " + mesh_name); + } +} + +void ModelInstance::resetMaterials() { + for (auto& [_, mesh] : meshes) { + mesh.reset(); + } +} + +MeshInstance& ModelInstance::getMeshInstance(const std::string &mesh) { + try { + return meshes.at(mesh); + } catch (...) { + throw no_such_mesh("with name " + mesh); + } +} + +MeshInstance& ModelInstance::getMeshInstance(uint32_t index) { + if (index >= meshes.size()) { + throw no_such_mesh("with index " + std::to_string(index)); + } + + return std::next(meshes.begin(), index)->second; +} + +const std::shared_ptr &ModelInstance::getMaterial(uint32_t mesh_index) { + if (mesh_index >= meshes.size()) { + throw no_such_mesh("with index " + std::to_string(mesh_index)); + } + + return std::next(meshes.begin(), mesh_index)->second.getMaterial(); +} + +const std::shared_ptr &ModelInstance::getMaterial(const std::string& mesh_name) { + try { + return meshes.at(mesh_name).getMaterial(); + } catch (...) { + throw no_such_mesh("with name " + mesh_name); + } +} diff --git a/src/limitless/instances/skeletal_instance.cpp b/src/limitless/instances/skeletal_instance.cpp index a9b1cfdd..89cb82ea 100644 --- a/src/limitless/instances/skeletal_instance.cpp +++ b/src/limitless/instances/skeletal_instance.cpp @@ -15,12 +15,12 @@ using namespace Limitless; constexpr auto SKELETAL_BUFFER_NAME = "bone_buffer"; void SkeletalInstance::initializeBuffer() { - BufferBuilder builder; - bone_buffer = builder.setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setData(bone_transform.data()) - .setDataSize(bone_transform.size() * sizeof(glm::mat4)) + bone_buffer = Buffer::builder() + .target(Buffer::Type::ShaderStorage) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .data(bone_transform.data()) + .size(bone_transform.size() * sizeof(glm::mat4)) .build(); } diff --git a/src/limitless/instances/socket_attachment.cpp b/src/limitless/instances/socket_attachment.cpp index 9cd30376..66319e34 100644 --- a/src/limitless/instances/socket_attachment.cpp +++ b/src/limitless/instances/socket_attachment.cpp @@ -44,7 +44,7 @@ void SocketAttachment::updateSocketAttachments() { } } -void SocketAttachment::attachToBone(std::string bone_name, std::unique_ptr instance) { +void SocketAttachment::attachToBone(std::string bone_name, std::shared_ptr instance) { auto& skeletal_instance = static_cast(*this); //NOLINT const auto& skeletal = static_cast(skeletal_instance.getAbstractModel()); //NOLINT const auto& bone_map = skeletal.getBoneMap(); diff --git a/src/limitless/lighting/cascade_shadows.cpp b/src/limitless/lighting/cascade_shadows.cpp index b084cd68..7f5e773e 100644 --- a/src/limitless/lighting/cascade_shadows.cpp +++ b/src/limitless/lighting/cascade_shadows.cpp @@ -23,20 +23,20 @@ namespace { } void CascadeShadows::initBuffers(Context& context) { - TextureBuilder builder; - auto depth = builder.setTarget(Texture::Type::Tex2DArray) - .setInternalFormat(Texture::InternalFormat::Depth16) - .setSize(glm::uvec3{shadow_resolution, split_count}) - .setFormat(Texture::Format::DepthComponent) - .setDataType(Texture::DataType::Float) - .setMipMap(false) - .setLevels(1) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setWrapR(Texture::Wrap::ClampToEdge) - .build(); + auto depth = Texture::builder() + .target(Texture::Type::Tex2DArray) + .internal_format(Texture::InternalFormat::Depth16) + .size(glm::uvec3{shadow_resolution, split_count}) + .format(Texture::Format::DepthComponent) + .data_type(Texture::DataType::Float) + .mipmap(false) + .levels(1) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .wrap_r(Texture::Wrap::ClampToEdge) + .build(); framebuffer = std::make_unique(); framebuffer->bind(); @@ -48,12 +48,12 @@ void CascadeShadows::initBuffers(Context& context) { framebuffer->unbind(); - BufferBuilder buffer_builder; - light_buffer = buffer_builder .setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(glm::mat4) * split_count) - .build(DIRECTIONAL_CSM_BUFFER_NAME, context); + light_buffer = Buffer::builder() + .target(Buffer::Type::ShaderStorage) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .size(sizeof(glm::mat4) * split_count) + .build(DIRECTIONAL_CSM_BUFFER_NAME, context); } CascadeShadows::CascadeShadows(Context& context, const RenderSettings& settings) diff --git a/src/limitless/lighting/light_container.cpp b/src/limitless/lighting/light_container.cpp index 4631488f..50262f87 100644 --- a/src/limitless/lighting/light_container.cpp +++ b/src/limitless/lighting/light_container.cpp @@ -56,11 +56,11 @@ void LightContainer::InternalLight::update(const Light& light) noexcept { } LightContainer::LightContainer() { - BufferBuilder builder; - buffer = builder.setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(InternalLight) * 1024) + buffer = Buffer::builder() + .target(Buffer::Type::ShaderStorage) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .size(sizeof(InternalLight) * 1024) .build(SHADER_STORAGE_NAME, *ContextState::getState(glfwGetCurrentContext())); } diff --git a/src/limitless/lighting/lighting.cpp b/src/limitless/lighting/lighting.cpp index 0332d99a..9ff033d2 100644 --- a/src/limitless/lighting/lighting.cpp +++ b/src/limitless/lighting/lighting.cpp @@ -8,11 +8,11 @@ using namespace Limitless; constexpr auto SCENE_LIGHTING_BUFFER_NAME = "scene_lighting"; void Lighting::createLightBuffer() { - BufferBuilder builder; - buffer = builder.setTarget(Buffer::Type::ShaderStorage) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(SceneLighting)) + buffer = Buffer::builder() + .target(Buffer::Type::ShaderStorage) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .size(sizeof(SceneLighting)) .build(SCENE_LIGHTING_BUFFER_NAME, context); } diff --git a/src/limitless/loaders/dds_loader.cpp b/src/limitless/loaders/dds_loader.cpp index 0dfeed57..a4f13cad 100644 --- a/src/limitless/loaders/dds_loader.cpp +++ b/src/limitless/loaders/dds_loader.cpp @@ -85,25 +85,30 @@ std::shared_ptr DDSLoader::load(Assets& assets, const fs::path& _path, DDSHEADER header {}; fs.read(reinterpret_cast(&header), sizeof(DDSHEADER)); - TextureBuilder builder; - builder .setTarget(Texture::Type::Tex2D); + Texture::Builder& builder = Texture::builder().target(Texture::Type::Tex2D); uint32_t channels {}; switch (header.ddspf.dwFourCC) { case DXT1_CODE: - flags.space == TextureLoaderFlags::Space::Linear ? builder.setInternalFormat(Texture::InternalFormat::RGBA_DXT1) : builder.setInternalFormat(Texture::InternalFormat::sRGBA_DXT1); + flags.space == TextureLoaderFlags::Space::Linear ? builder.internal_format( + Texture::InternalFormat::RGBA_DXT1) : builder.internal_format( + Texture::InternalFormat::sRGBA_DXT1); channels = 3; break; case DXT3_CODE: - flags.space == TextureLoaderFlags::Space::Linear ? builder.setInternalFormat(Texture::InternalFormat::RGBA_DXT3) : builder.setInternalFormat(Texture::InternalFormat::sRGBA_DXT3); + flags.space == TextureLoaderFlags::Space::Linear ? builder.internal_format( + Texture::InternalFormat::RGBA_DXT3) : builder.internal_format( + Texture::InternalFormat::sRGBA_DXT3); channels = 4; break; case DXT5_CODE: - flags.space == TextureLoaderFlags::Space::Linear ? builder.setInternalFormat(Texture::InternalFormat::RGBA_DXT5) : builder.setInternalFormat(Texture::InternalFormat::sRGBA_DXT5); + flags.space == TextureLoaderFlags::Space::Linear ? builder.internal_format( + Texture::InternalFormat::RGBA_DXT5) : builder.internal_format( + Texture::InternalFormat::sRGBA_DXT5); channels = 4; break; case BC5u_CODE: - builder.setInternalFormat(Texture::InternalFormat::RG_RGTC); + builder.internal_format(Texture::InternalFormat::RG_RGTC); channels = 4; break; default: @@ -126,13 +131,13 @@ std::shared_ptr DDSLoader::load(Assets& assets, const fs::path& _path, } fs.seekg(byte_count, std::ios_base::cur); } - builder.setSize(size); + builder.size(size); const auto byte_count = getDXTByteCount(size, channels == 3 ? DXT1_BLOCK_SIZE : DXT5_BLOCK_SIZE); auto* data = new uint8_t[byte_count]; fs.read(reinterpret_cast(data), byte_count); - builder.setCompressedData(data, byte_count); + builder.compressed_data(data, byte_count); TextureLoader::setTextureParameters(builder, flags); - builder.setPath(path); + builder.path(path); auto texture = builder.buildMutable(); delete[] data; diff --git a/src/limitless/loaders/texture_loader.cpp b/src/limitless/loaders/texture_loader.cpp index b0cb1a69..a388f5f6 100644 --- a/src/limitless/loaders/texture_loader.cpp +++ b/src/limitless/loaders/texture_loader.cpp @@ -23,7 +23,7 @@ namespace { constexpr auto RGTC_EXTENSION = "GL_ARB_texture_compression_rgtc"; } -void TextureLoader::setFormat(TextureBuilder& builder, const TextureLoaderFlags& flags, int channels) { +void TextureLoader::setFormat(Texture::Builder& builder, const TextureLoaderFlags& flags, int channels) { Texture::InternalFormat internal {}; switch (flags.compression) { @@ -120,8 +120,8 @@ void TextureLoader::setFormat(TextureBuilder& builder, const TextureLoaderFlags& default: throw texture_loader_exception("Bad channels count!"); } - builder.setInternalFormat(internal) - .setFormat(format); + builder.internal_format(internal) + .format(format); } void TextureLoader::setAnisotropicFilter(const std::shared_ptr& texture, const TextureLoaderFlags& flags) { @@ -162,14 +162,14 @@ std::shared_ptr TextureLoader::load(Assets& assets, const fs::path& _pa setDownScale(width, height, channels, data, flags); - TextureBuilder builder; + Texture::Builder builder = Texture::builder(); - builder.setTarget(Texture::Type::Tex2D) - .setLevels(glm::floor(glm::log2(static_cast(glm::max(width, height)))) + 1) - .setSize({ width, height }) - .setDataType(Texture::DataType::UnsignedByte) - .setData(data) - .setPath(path); + builder.target(Texture::Type::Tex2D) + .levels(glm::floor(glm::log2(static_cast(glm::max(width, height)))) + 1) + .size({width, height}) + .data_type(Texture::DataType::UnsignedByte) + .data(data) + .path(path); setFormat(builder, flags, channels); setTextureParameters(builder, flags); @@ -206,20 +206,21 @@ std::shared_ptr TextureLoader::loadCubemap([[maybe_unused]] Assets& ass } } - TextureBuilder builder; - builder .setTarget(Texture::Type::CubeMap) - .setSize(glm::uvec2{ width, height }) - .setDataType(Texture::DataType::UnsignedByte) - .setData(data); + Texture::Builder builder = Texture::builder(); + + builder.target(Texture::Type::CubeMap) + .size(glm::uvec2{width, height}) + .data_type(Texture::DataType::UnsignedByte) + .data(data); setFormat(builder, flags, channels); setTextureParameters(builder, flags); - builder.setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setWrapR(Texture::Wrap::ClampToEdge); + builder.wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .wrap_r(Texture::Wrap::ClampToEdge); - builder.setPath(path); + builder.path(path); auto texture = builder.buildMutable(); setAnisotropicFilter(texture, flags); @@ -268,25 +269,23 @@ void TextureLoader::setDownScale(int& width, int& height, int channels, unsigned data = resized_data; } -void TextureLoader::setTextureParameters(TextureBuilder& builder, const TextureLoaderFlags& flags) { - builder.setMipMap(flags.mipmap) - .setBorder(flags.border) - .setBorderColor(flags.border_color) - .setWrapS(flags.wrapping) - .setWrapT(flags.wrapping) - .setWrapR(flags.wrapping); +void TextureLoader::setTextureParameters(Texture::Builder& builder, const TextureLoaderFlags& flags) { + builder.mipmap(flags.mipmap) + .wrap_s(flags.wrapping) + .wrap_t(flags.wrapping) + .wrap_r(flags.wrapping); switch (flags.filter) { case TextureLoaderFlags::Filter::Linear: - builder.setMagFilter(Texture::Filter::Linear); + builder.mag_filter(Texture::Filter::Linear); if (flags.mipmap) { - builder.setMinFilter(Texture::Filter::LinearMipmapLinear); + builder.min_filter(Texture::Filter::LinearMipmapLinear); } break; case TextureLoaderFlags::Filter::Nearest: - builder.setMagFilter(Texture::Filter::Nearest); + builder.mag_filter(Texture::Filter::Nearest); if (flags.mipmap) { - builder.setMinFilter(Texture::Filter::NearestMipmapNearest); + builder.min_filter(Texture::Filter::NearestMipmapNearest); } break; } diff --git a/src/limitless/models/text_model.cpp b/src/limitless/models/text_model.cpp index b174c0ef..fcfe2af1 100644 --- a/src/limitless/models/text_model.cpp +++ b/src/limitless/models/text_model.cpp @@ -15,13 +15,13 @@ TextModel::TextModel(size_t count) } void TextModel::initialize(size_t count) { - BufferBuilder builder; - buffer = builder .setTarget(Buffer::Type::Array) - .setData(vertices.empty() ? nullptr : vertices.data()) - .setDataSize(count * sizeof(TextVertex)) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .build(); + buffer = Buffer::builder() + .target(Buffer::Type::Array) + .data(vertices.empty() ? nullptr : vertices.data()) + .size(count * sizeof(TextVertex)) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .build(); vertex_array << std::pair&>(TextVertex{}, buffer); } diff --git a/src/limitless/ms/material.cpp b/src/limitless/ms/material.cpp index 7672e326..702af137 100644 --- a/src/limitless/ms/material.cpp +++ b/src/limitless/ms/material.cpp @@ -46,12 +46,11 @@ void Material::Buffer::initialize(const Material& material) { // ShadingModel uint32_t offset += sizeof(uint32_t); - BufferBuilder builder; - material_buffer = builder - .setTarget(Limitless::Buffer::Type::Uniform) - .setUsage(Limitless::Buffer::Usage::DynamicDraw) - .setAccess(Limitless::Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(std::byte) * offset) + material_buffer = ::Buffer::builder() + .target(::Buffer::Type::Uniform) + .usage(::Buffer::Usage::DynamicDraw) + .access(::Buffer::MutableAccess::WriteOrphaning) + .size(sizeof(std::byte) * offset) .build(); } diff --git a/src/limitless/ms/material_instance.cpp b/src/limitless/ms/material_instance.cpp deleted file mode 100644 index 783af843..00000000 --- a/src/limitless/ms/material_instance.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include - -#include -#include -#include -#include - -using namespace Limitless; -using namespace Limitless::ms; - -MaterialInstance::MaterialInstance(const std::shared_ptr& material) - : base {std::make_shared(*material)} { - materials.emplace(next_id++, base); -} - -MaterialInstance::MaterialInstance(const MaterialInstance& instance) - : next_id {instance.next_id} - , base {std::make_shared(*instance.base)} { - // deep map copy - for (const auto& [id, material] : instance.materials) { - materials.emplace(id, std::make_shared(*material)); - } -} - -void MaterialInstance::changeBaseMaterial(const std::shared_ptr& material) noexcept { - base = std::make_shared(*material); - changeMaterial(base); -} - -void MaterialInstance::changeMaterial(const std::shared_ptr& material) noexcept { - materials[0] = std::make_shared(*material); -} - -void MaterialInstance::reset() noexcept { - materials[0] = base; -} - -void MaterialInstance::clear() noexcept { - materials.erase(++materials.begin(), materials.end()); -} - -uint64_t MaterialInstance::apply(const std::shared_ptr& material) noexcept { - materials.emplace(next_id, std::make_shared(*material)); - return next_id++; -} - -void MaterialInstance::remove(uint64_t id) { - if (id == 0) { - throw std::runtime_error("Attempt to remove base material layer."); - } - - materials.erase(id); -} - -void MaterialInstance::setMaterialState(Context& ctx, uint64_t id, ShaderType pass) { - const auto& material = materials.at(id); - - // checks for multiple opaque materials - // that should be blended as sum color/N - if (material->getBlending() == Blending::Opaque) { - setBlendingMode(Blending::Opaque); - } else { - if (material->getRefraction()) { - setBlendingMode(Blending::Opaque); //TODO: ???? wtf? - } else { - setBlendingMode(material->getBlending()); - } - } - - // sets culling based on two-sideness - if (material->getTwoSided()) { - ctx.disable(Capabilities::CullFace); - } else { - ctx.enable(Capabilities::CullFace); - - // front cullfacing for shadows helps prevent peter panning - if (pass == ShaderType::DirectionalShadow) { - ctx.setCullFace(CullFace::Front); - } else { - ctx.setCullFace(CullFace::Back); - } - } -} - -void MaterialInstance::makeLayered() noexcept { - layered = true; -} - -void MaterialInstance::makeNonLayered() noexcept { - layered = false; -} - -bool MaterialInstance::isLayered() const noexcept { - return layered; -} diff --git a/src/limitless/pipeline/common/dof_pass.cpp b/src/limitless/pipeline/common/dof_pass.cpp index b6502ed9..53d4e82c 100644 --- a/src/limitless/pipeline/common/dof_pass.cpp +++ b/src/limitless/pipeline/common/dof_pass.cpp @@ -22,16 +22,16 @@ DoFPass::DoFPass(Pipeline& pipeline, ContextEventObserver& ctx) } void DoFPass::initialize(Context& ctx) { - TextureBuilder builder; - auto result = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(ctx.getSize()) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto result = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(ctx.getSize()) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); diff --git a/src/limitless/pipeline/common/scene_data.cpp b/src/limitless/pipeline/common/scene_data.cpp index 0bb5f773..85398df3 100644 --- a/src/limitless/pipeline/common/scene_data.cpp +++ b/src/limitless/pipeline/common/scene_data.cpp @@ -8,12 +8,12 @@ using namespace Limitless; SceneDataStorage::SceneDataStorage(Context& ctx) { - BufferBuilder builder; - buffer = builder.setTarget(Buffer::Type::Uniform) - .setUsage(Buffer::Usage::DynamicDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) - .setDataSize(sizeof(SceneData)) - .build(PipelineShaderBuffers::SCENE_DATA_BUFFER_NAME, ctx); + buffer = Buffer::builder() + .target(Buffer::Type::Uniform) + .usage(Buffer::Usage::DynamicDraw) + .access(Buffer::MutableAccess::WriteOrphaning) + .size(sizeof(SceneData)) + .build(PipelineShaderBuffers::SCENE_DATA_BUFFER_NAME, ctx); } SceneDataStorage::~SceneDataStorage() { diff --git a/src/limitless/pipeline/deferred/deferred_framebuffer_pass.cpp b/src/limitless/pipeline/deferred/deferred_framebuffer_pass.cpp index 9cfd27f3..e3f9659c 100644 --- a/src/limitless/pipeline/deferred/deferred_framebuffer_pass.cpp +++ b/src/limitless/pipeline/deferred/deferred_framebuffer_pass.cpp @@ -7,11 +7,11 @@ using namespace Limitless; DeferredFramebufferPass::DeferredFramebufferPass(Pipeline& pipeline, glm::uvec2 frame_size) : PipelinePass(pipeline) , framebuffer {} { - auto albedo = TextureBuilder::asRGBA16NearestClampToEdge(frame_size); - auto normal = TextureBuilder::asRGB16SNORMNearestClampToEdge(frame_size); - auto props = TextureBuilder::asRGB16NearestClampToEdge(frame_size); - auto emissive = TextureBuilder::asRGB16FNearestClampToEdge(frame_size); - auto depth = TextureBuilder::asDepth32F(frame_size); + auto albedo = Texture::Builder::asRGBA16NearestClampToEdge(frame_size); + auto normal = Texture::Builder::asRGB16SNORMNearestClampToEdge(frame_size); + auto props = Texture::Builder::asRGB16NearestClampToEdge(frame_size); + auto emissive = Texture::Builder::asRGB16FNearestClampToEdge(frame_size); + auto depth = Texture::Builder::asDepth32F(frame_size); framebuffer.bind(); framebuffer << TextureAttachment{FramebufferAttachment::Color0, albedo} diff --git a/src/limitless/pipeline/forward/framebuffer_pass.cpp b/src/limitless/pipeline/forward/framebuffer_pass.cpp index 8f81435e..ca388be5 100644 --- a/src/limitless/pipeline/forward/framebuffer_pass.cpp +++ b/src/limitless/pipeline/forward/framebuffer_pass.cpp @@ -13,27 +13,28 @@ FramebufferPass::FramebufferPass(Pipeline& pipeline, ContextEventObserver& ctx) : PipelinePass(pipeline) , target {framebuffer} { - TextureBuilder builder; - auto color = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGBA16F) - .setSize(ctx.getSize()) - .setFormat(Texture::Format::RGBA) - .setDataType(Texture::DataType::Float) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto color = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGBA16F) + .size(ctx.getSize()) + .format(Texture::Format::RGBA) + .data_type(Texture::DataType::Float) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); - auto depth = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::Depth32F) - .setSize(ctx.getSize()) - .setFormat(Texture::Format::DepthComponent) - .setDataType(Texture::DataType::Float) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto depth = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::Depth32F) + .size(ctx.getSize()) + .format(Texture::Format::DepthComponent) + .data_type(Texture::DataType::Float) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); diff --git a/src/limitless/postprocessing/blur.cpp b/src/limitless/postprocessing/blur.cpp index a1c1f2a0..8e5c2cb1 100644 --- a/src/limitless/postprocessing/blur.cpp +++ b/src/limitless/postprocessing/blur.cpp @@ -12,31 +12,32 @@ void Blur::build(glm::uvec2 frame_size) { ITERATION_COUNT = glm::min(BASE_ITERATION_COUNT, max_levels); - TextureBuilder builder; - stage = builder.setTarget(Texture::Type::Tex2D) - .setFormat(Texture::Format::RGB) - .setInternalFormat(Texture::InternalFormat::RGB16F) - .setDataType(Texture::DataType::Float) - .setSize(frame_size) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setMinFilter(Texture::Filter::LinearMipmapLinear) - .setMagFilter(Texture::Filter::Linear) - .setLevels(ITERATION_COUNT) - .setMipMap(true) + stage = Texture::builder() + .target(Texture::Type::Tex2D) + .format(Texture::Format::RGB) + .internal_format(Texture::InternalFormat::RGB16F) + .data_type(Texture::DataType::Float) + .size(frame_size) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .min_filter(Texture::Filter::LinearMipmapLinear) + .mag_filter(Texture::Filter::Linear) + .levels(ITERATION_COUNT) + .mipmap(true) .build(); - out = builder.setTarget(Texture::Type::Tex2D) - .setFormat(Texture::Format::RGB) - .setInternalFormat(Texture::InternalFormat::RGB16F) - .setDataType(Texture::DataType::Float) - .setSize(frame_size) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setMinFilter(Texture::Filter::LinearMipmapLinear) - .setMagFilter(Texture::Filter::Linear) - .setLevels(ITERATION_COUNT) - .setMipMap(true) + out = Texture::builder() + .target(Texture::Type::Tex2D) + .format(Texture::Format::RGB) + .internal_format(Texture::InternalFormat::RGB16F) + .data_type(Texture::DataType::Float) + .size(frame_size) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .min_filter(Texture::Filter::LinearMipmapLinear) + .mag_filter(Texture::Filter::Linear) + .levels(ITERATION_COUNT) + .mipmap(true) .build(); outRT.clear(); diff --git a/src/limitless/postprocessing/ssao.cpp b/src/limitless/postprocessing/ssao.cpp index f81bea97..8c7cf343 100644 --- a/src/limitless/postprocessing/ssao.cpp +++ b/src/limitless/postprocessing/ssao.cpp @@ -12,23 +12,24 @@ namespace { } SSAO::SSAO(ContextEventObserver& ctx) { - TextureBuilder builder; - auto ssao = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(ctx.getSize()) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto ssao = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(ctx.getSize()) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); - auto blurred = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(ctx.getSize()) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto blurred = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(ctx.getSize()) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -37,33 +38,34 @@ SSAO::SSAO(ContextEventObserver& ctx) { framebuffer.checkStatus(); framebuffer.unbind(); - BufferBuilder buffer_builder; - buffer = buffer_builder.setTarget(Buffer::Type::Uniform) - .setData(&settings) - .setDataSize(sizeof(Settings)) - .setUsage(Buffer::Usage::StaticDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) + buffer = Buffer::builder() + .target(Buffer::Type::Uniform) + .data(&settings) + .size(sizeof(Settings)) + .usage(Buffer::Usage::StaticDraw) + .access(Buffer::MutableAccess::WriteOrphaning) .build(SSAO_BUFFER_NAME, ctx); } SSAO::SSAO(ContextEventObserver &ctx, glm::uvec2 frame_size) { - TextureBuilder builder; - auto ssao = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(frame_size) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto ssao = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(frame_size) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); - auto blurred = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setSize(frame_size) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto blurred = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB8) + .size(frame_size) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -72,12 +74,12 @@ SSAO::SSAO(ContextEventObserver &ctx, glm::uvec2 frame_size) { framebuffer.checkStatus(); framebuffer.unbind(); - BufferBuilder buffer_builder; - buffer = buffer_builder.setTarget(Buffer::Type::Uniform) - .setData(&settings) - .setDataSize(sizeof(Settings)) - .setUsage(Buffer::Usage::StaticDraw) - .setAccess(Buffer::MutableAccess::WriteOrphaning) + buffer = Buffer::builder() + .target(Buffer::Type::Uniform) + .data(&settings) + .size(sizeof(Settings)) + .usage(Buffer::Usage::StaticDraw) + .access(Buffer::MutableAccess::WriteOrphaning) .build(SSAO_BUFFER_NAME, ctx); } diff --git a/src/limitless/postprocessing/ssr.cpp b/src/limitless/postprocessing/ssr.cpp index daf052dc..9c409319 100644 --- a/src/limitless/postprocessing/ssr.cpp +++ b/src/limitless/postprocessing/ssr.cpp @@ -11,15 +11,15 @@ using namespace Limitless; SSR::SSR(ContextEventObserver& ctx) : blur {ctx.getSize()} { - TextureBuilder builder; - auto ssr = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB16F) - .setDataType(Texture::DataType::Float) - .setSize(ctx.getSize()) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto ssr = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB16F) + .data_type(Texture::DataType::Float) + .size(ctx.getSize()) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -30,15 +30,15 @@ SSR::SSR(ContextEventObserver& ctx) SSR::SSR(ContextEventObserver &ctx, glm::uvec2 frame_size) : blur {frame_size} { - TextureBuilder builder; - auto ssr = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::RGB16F) - .setDataType(Texture::DataType::Float) - .setSize(ctx.getSize()) - .setMinFilter(Texture::Filter::Nearest) - .setMagFilter(Texture::Filter::Nearest) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) + auto ssr = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::RGB16F) + .data_type(Texture::DataType::Float) + .size(ctx.getSize()) + .min_filter(Texture::Filter::Nearest) + .mag_filter(Texture::Filter::Nearest) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) .build(); framebuffer.bind(); @@ -111,4 +111,4 @@ void SSR::addSetter(UniformSetter& setter) { setter.add([&](ShaderProgram& shader) { shader.setUniform("_ssr_strength", settings.reflection_strength); }); -} +} \ No newline at end of file diff --git a/src/limitless/scene.cpp b/src/limitless/scene.cpp index cb0f7847..332c515b 100644 --- a/src/limitless/scene.cpp +++ b/src/limitless/scene.cpp @@ -24,13 +24,13 @@ void Scene::update(Context& context, const Camera& camera) { //TODO: why is here two updates? for (auto& [_, instance] : instances) { - if (instance->getShaderType() != InstanceType::Effect) { + if (instance->getInstanceType() != InstanceType::Effect) { instance->update(context, camera); } } for (auto& [_, instance] : instances) { - if (instance->getShaderType() == InstanceType::Effect) { + if (instance->getInstanceType() == InstanceType::Effect) { instance->update(context, camera); } } diff --git a/src/limitless/text/font_atlas.cpp b/src/limitless/text/font_atlas.cpp index 618956ce..5d6da147 100644 --- a/src/limitless/text/font_atlas.cpp +++ b/src/limitless/text/font_atlas.cpp @@ -82,18 +82,18 @@ FontAtlas::FontAtlas(const fs::path& path, uint32_t size) chars.at('\t').advance *= TAB_WIDTH_IN_SPACES; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - TextureBuilder builder; - texture = builder.setTarget(Texture::Type::Tex2D) - .setInternalFormat(Texture::InternalFormat::R) - .setSize(side_size) - .setFormat(Texture::Format::Red) - .setDataType(Texture::DataType::UnsignedByte) - .setData(data.data()) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setMipMap(false) + texture = Texture::builder() + .target(Texture::Type::Tex2D) + .internal_format(Texture::InternalFormat::R) + .size(side_size) + .format(Texture::Format::Red) + .data_type(Texture::DataType::UnsignedByte) + .data(data.data()) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .mipmap(false) .buildMutable(); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); } diff --git a/test/limitless/core/texture_builder_test.cpp b/test/limitless/core/texture_builder_test.cpp index 4aafce41..56cf7022 100644 --- a/test/limitless/core/texture_builder_test.cpp +++ b/test/limitless/core/texture_builder_test.cpp @@ -138,25 +138,25 @@ void test_with_type_and_extension_texture(Texture::Type type, ExtensionTextureTy { TextureBuilder builder {}; - builder.setTarget(type) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setMipMap(false) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte); + builder.target(type) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .mipmap(false) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .internal_format(Texture::InternalFormat::RGB8) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte); switch(type) { case Texture::Type::Tex2D: - builder.setSize({512, 512}); + builder.size({512, 512}); break; case Texture::Type::Tex3D: - builder.setSize({512, 512, 512}); + builder.size({512, 512, 512}); break; case Texture::Type::Tex2DArray: - builder.setSize({512, 512, 512}); + builder.size({512, 512, 512}); break; default: throw std::runtime_error("not testable"); @@ -197,25 +197,25 @@ void test_with_type_and_extension_texture(Texture::Type type, ExtensionTextureTy { TextureBuilder builder {}; - builder.setTarget(type) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setMipMap(true) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte); + builder.target(type) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .mipmap(true) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .internal_format(Texture::InternalFormat::RGB8) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte); switch(type) { case Texture::Type::Tex2D: - builder.setSize({512, 512}); + builder.size({512, 512}); break; case Texture::Type::Tex3D: - builder.setSize({512, 512, 512}); + builder.size({512, 512, 512}); break; case Texture::Type::Tex2DArray: - builder.setSize({512, 512, 512}); + builder.size({512, 512, 512}); break; default: throw std::runtime_error("not testable"); @@ -256,25 +256,25 @@ void test_with_type_and_extension_texture(Texture::Type type, ExtensionTextureTy { TextureBuilder builder {}; - builder.setTarget(type) - .setWrapS(Texture::Wrap::ClampToEdge) - .setWrapT(Texture::Wrap::ClampToEdge) - .setMipMap(true) - .setMinFilter(Texture::Filter::Linear) - .setMagFilter(Texture::Filter::Linear) - .setInternalFormat(Texture::InternalFormat::RGB8) - .setFormat(Texture::Format::RGB) - .setDataType(Texture::DataType::UnsignedByte); + builder.target(type) + .wrap_s(Texture::Wrap::ClampToEdge) + .wrap_t(Texture::Wrap::ClampToEdge) + .mipmap(true) + .min_filter(Texture::Filter::Linear) + .mag_filter(Texture::Filter::Linear) + .internal_format(Texture::InternalFormat::RGB8) + .format(Texture::Format::RGB) + .data_type(Texture::DataType::UnsignedByte); switch(type) { case Texture::Type::Tex2D: - builder.setSize({512, 512}); + builder.size({512, 512}); break; case Texture::Type::Tex3D: - builder.setSize({512, 512, 512}); + builder.size({512, 512, 512}); break; case Texture::Type::Tex2DArray: - builder.setSize({512, 512, 512}); + builder.size({512, 512, 512}); break; default: throw std::runtime_error("not testable"); diff --git a/test/limitless/instance/model_instance_test.cpp b/test/limitless/instance/model_instance_test.cpp index e3c0f288..460d1240 100644 --- a/test/limitless/instance/model_instance_test.cpp +++ b/test/limitless/instance/model_instance_test.cpp @@ -93,7 +93,7 @@ TEST_CASE("ModelInstance model copy constructor") { REQUIRE(instance.getFinalMatrix() == copy.getFinalMatrix()); REQUIRE(instance.getModelMatrix() == copy.getModelMatrix()); REQUIRE(instance.getTransformationMatrix() == copy.getTransformationMatrix()); - REQUIRE(instance.getShaderType() == copy.getShaderType()); + REQUIRE(instance.getInstanceType() == copy.getInstanceType()); REQUIRE(instance.getPosition() == copy.getPosition()); REQUIRE(instance.getRotation() == copy.getRotation()); REQUIRE(instance.getScale() == copy.getScale()); @@ -128,7 +128,7 @@ TEST_CASE("ModelInstance clone") { REQUIRE(instance.getFinalMatrix() == copy->getFinalMatrix()); REQUIRE(instance.getModelMatrix() == copy->getModelMatrix()); REQUIRE(instance.getTransformationMatrix() == copy->getTransformationMatrix()); - REQUIRE(instance.getShaderType() == copy->getShaderType()); + REQUIRE(instance.getInstanceType() == copy->getInstanceType()); REQUIRE(instance.getPosition() == copy->getPosition()); REQUIRE(instance.getRotation() == copy->getRotation()); REQUIRE(instance.getScale() == copy->getScale()); diff --git a/test/limitless/instance/skeletal_instance_test.cpp b/test/limitless/instance/skeletal_instance_test.cpp index c748f737..c4b478c1 100644 --- a/test/limitless/instance/skeletal_instance_test.cpp +++ b/test/limitless/instance/skeletal_instance_test.cpp @@ -51,7 +51,7 @@ TEST_CASE("SkeletalInstance copy constructor") { REQUIRE(instance.getFinalMatrix() == copy.getFinalMatrix()); REQUIRE(instance.getModelMatrix() == copy.getModelMatrix()); REQUIRE(instance.getTransformationMatrix() == copy.getTransformationMatrix()); - REQUIRE(instance.getShaderType() == copy.getShaderType()); + REQUIRE(instance.getInstanceType() == copy.getInstanceType()); REQUIRE(instance.getPosition() == copy.getPosition()); REQUIRE(instance.getRotation() == copy.getRotation()); REQUIRE(instance.getScale() == copy.getScale()); @@ -86,7 +86,7 @@ TEST_CASE("SkeletalInstance clone") { REQUIRE(instance.getFinalMatrix() == copy->getFinalMatrix()); REQUIRE(instance.getModelMatrix() == copy->getModelMatrix()); REQUIRE(instance.getTransformationMatrix() == copy->getTransformationMatrix()); - REQUIRE(instance.getShaderType() == copy->getShaderType()); + REQUIRE(instance.getInstanceType() == copy->getInstanceType()); REQUIRE(instance.getPosition() == copy->getPosition()); REQUIRE(instance.getRotation() == copy->getRotation()); REQUIRE(instance.getScale() == copy->getScale()); diff --git a/test/limitless/util/textures.hpp b/test/limitless/util/textures.hpp index 64046149..8cfe5eaa 100644 --- a/test/limitless/util/textures.hpp +++ b/test/limitless/util/textures.hpp @@ -10,11 +10,11 @@ namespace LimitlessTest { static inline std::shared_ptr fake() { TextureBuilder builder {}; - return builder.setTarget(Texture::Type::Tex2D) - .setMipMap(false) - .setInternalFormat(Texture::InternalFormat::R8) - .setFormat(Texture::Format::Red) - .setDataType(Texture::DataType::UnsignedByte) + return builder.target(Texture::Type::Tex2D) + .mipmap(false) + .internal_format(Texture::InternalFormat::R8) + .format(Texture::Format::Red) + .data_type(Texture::DataType::UnsignedByte) .build(); } }; From 2108969ecee0e772a80d64ee10f149277db941b7 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Tue, 28 Nov 2023 20:00:16 +0300 Subject: [PATCH 11/15] another ref --- CMakeLists.txt | 3 +- demo/assets.cpp | 10 +- demo/demo.cpp | 25 +- demo/effects_demoscene.cpp | 98 +++++-- demo/effects_demoscene.hpp | 10 +- demo/lighting_demoscene.cpp | 52 ++-- demo/lighting_demoscene.hpp | 11 +- demo/materials_demoscene.cpp | 235 +++++++++++++--- demo/materials_demoscene.hpp | 10 +- demo/models_demoscene.cpp | 135 ++++++---- demo/models_demoscene.hpp | 8 +- demo/scene.hpp | 59 ++-- demo/sponza_demoscene.cpp | 31 --- demo/sponza_demoscene.hpp | 17 -- include/limitless/core/uniform/uniform.hpp | 3 + .../limitless/core/uniform/uniform_value.hpp | 2 + include/limitless/fx/effect_renderer.hpp | 4 +- .../limitless/instances/effect_instance.hpp | 13 +- .../{abstract_instance.hpp => instance.hpp} | 24 +- .../instances/instance_attachment.hpp | 10 +- .../limitless/instances/instance_builder.hpp | 30 ++- .../instances/instanced_instance.hpp | 14 +- .../limitless/instances/light_instance.hpp | 2 +- .../limitless/instances/model_instance.hpp | 8 +- .../limitless/instances/skeletal_instance.hpp | 4 +- .../limitless/instances/socket_attachment.hpp | 4 +- .../limitless/lighting/cascade_shadows.hpp | 4 +- include/limitless/lighting/lighting.hpp | 10 - include/limitless/pipeline/pipeline_pass.hpp | 4 +- .../limitless/renderer/render_settings.hpp | 2 +- include/limitless/scene.hpp | 76 ++---- include/limitless/util/color_picker.hpp | 2 +- include/limitless/util/sorter.hpp | 6 +- shaders/functions/circle.glsl | 4 - shaders/functions/fresnel.glsl | 3 - shaders/functions/hue_shift.glsl | 5 - shaders/functions/linearize_depth.glsl | 10 - shaders/functions/reconstruct_position.glsl | 23 -- shaders/functions/tone_mapping.glsl | 3 - shaders/pipeline/deferred/composite.frag | 21 -- shaders/pipeline/deferred/composite.vert | 12 - shaders/pipeline/deferred/deferred.frag | 49 ---- shaders/pipeline/deferred/deferred.vert | 12 - shaders/pipeline/deferred/depth.frag | 15 -- shaders/pipeline/deferred/depth.vert | 38 --- shaders/pipeline/deferred/gbuffer.frag | 29 -- shaders/pipeline/deferred/gbuffer.vert | 38 --- shaders/pipeline/deferred/gbuffer_input.glsl | 17 -- shaders/pipeline/deferred/gbuffer_output.glsl | 16 -- shaders/pipeline/deferred/skybox.frag | 30 --- shaders/pipeline/deferred/skybox.vert | 32 --- shaders/pipeline/forward/forward.frag | 20 -- shaders/pipeline/forward/forward.vert | 38 --- shaders/pipeline/instance/instance.glsl | 40 --- shaders/pipeline/instance/instanced.glsl | 7 - shaders/pipeline/instance/model.glsl | 6 - shaders/pipeline/instance/skeletal.glsl | 15 -- .../pipeline/interface_block/effect_fs.glsl | 177 ------------ .../pipeline/interface_block/effect_vs.glsl | 60 ----- .../pipeline/interface_block/fragment.glsl | 5 - shaders/pipeline/interface_block/mesh_fs.glsl | 28 -- shaders/pipeline/interface_block/mesh_vs.glsl | 10 - .../interface_block/pass_through.glsl | 75 ------ .../interface_block/tess_control_input.glsl | 196 -------------- .../interface_block/tess_control_output.glsl | 74 ----- .../interface_block/tess_control_pass.glsl | 69 ----- shaders/pipeline/interface_block/vertex.glsl | 5 - shaders/pipeline/lighting/ambient.glsl | 4 - .../pipeline/lighting/directional_csm.glsl | 65 ----- .../pipeline/lighting/directional_light.glsl | 30 --- .../lighting/directional_shadows.frag | 14 - .../lighting/directional_shadows.vert | 40 --- .../pipeline/lighting/lighting_context.glsl | 41 --- shaders/pipeline/lighting/point_light.glsl | 43 --- shaders/pipeline/lighting/scene_lighting.glsl | 32 --- shaders/pipeline/lighting/spot_light.glsl | 48 ---- shaders/pipeline/material/buffer.glsl | 255 ------------------ .../pipeline/material/custom_fragment.glsl | 3 - shaders/pipeline/material/material.glsl | 2 - shaders/pipeline/material/shading.glsl | 12 - shaders/pipeline/quad.frag | 12 - shaders/pipeline/quad.vert | 12 - shaders/pipeline/shading/brdf.glsl | 107 -------- shaders/pipeline/shading/common.glsl | 34 --- shaders/pipeline/shading/depth_discarder.glsl | 14 - shaders/pipeline/shading/fragment.glsl | 115 -------- shaders/pipeline/shading/fragment_data.glsl | 47 ---- .../shading/fragment_data_initializer.glsl | 83 ------ shaders/pipeline/shading/lit.glsl | 24 -- shaders/pipeline/shading/refraction.glsl | 43 --- shaders/pipeline/shading/shading.glsl | 14 - shaders/pipeline/shading/unlit.glsl | 3 - shaders/pipeline/util/color_picker.frag | 23 -- shaders/pipeline/util/color_picker.vert | 38 --- .../pipeline/vertex_streams/beam_emitter.glsl | 88 ------ .../pipeline/vertex_streams/mesh_emitter.glsl | 61 ----- .../pipeline/vertex_streams/model_mesh.glsl | 38 --- .../vertex_streams/sprite_emitter.glsl | 65 ----- .../vertex_streams/vertex_stream.glsl | 15 -- .../postprocessing/bloom/blur_downsample.frag | 62 ----- .../postprocessing/bloom/blur_downsample.vert | 12 - .../postprocessing/bloom/blur_upsample.frag | 26 -- .../postprocessing/bloom/blur_upsample.vert | 12 - shaders/postprocessing/bloom/brightness.frag | 14 - shaders/postprocessing/bloom/brightness.vert | 12 - shaders/postprocessing/dof.frag | 33 --- shaders/postprocessing/dof.vert | 13 - shaders/postprocessing/fxaa.frag | 14 - shaders/postprocessing/fxaa.vert | 12 - shaders/postprocessing/postprocess.frag | 81 ------ shaders/postprocessing/postprocess.vert | 13 - shaders/postprocessing/ssao/ssao.frag | 139 ---------- shaders/postprocessing/ssao/ssao.vert | 12 - shaders/postprocessing/ssao/ssao_blur.frag | 69 ----- shaders/postprocessing/ssao/ssao_blur.vert | 12 - shaders/postprocessing/ssr/ssr.frag | 172 ------------ shaders/postprocessing/ssr/ssr.vert | 13 - shaders/tesselation/tesselation.tesc | 29 -- shaders/tesselation/tesselation.tese | 144 ---------- shaders/text/text.frag | 13 - shaders/text/text.vert | 17 -- shaders/text/text_selection.frag | 11 - shaders/text/text_selection.vert | 13 - shaders_ref/functions/brdf.glsl | 36 +-- shaders_ref/functions/brdf_ctx.glsl | 32 +++ .../functions/cheap_contrast.glsl | 0 .../functions/elipse.glsl | 0 {shaders => shaders_ref}/functions/fxaa.glsl | 0 .../functions/gamma_correction.glsl | 0 {shaders => shaders_ref}/functions/math.glsl | 0 .../functions/polar_coordinates.glsl | 0 .../functions/radial_shear.glsl | 0 .../functions/random.glsl | 0 .../functions/reconstruct_normal.glsl | 0 .../functions/reconstruct_position.glsl | 2 +- .../functions/rectangle.glsl | 0 .../functions/rotate_uv.glsl | 0 .../functions/scale_uv_by_center.glsl | 0 .../functions/sphere_mask.glsl | 0 .../functions/spherize_uv.glsl | 0 .../functions/tiling_offset.glsl | 0 .../functions/trace_ray.glsl | 4 +- {shaders => shaders_ref}/functions/twirl.glsl | 0 shaders_ref/lighting/directional_shadows.vert | 2 +- shaders_ref/lighting/lighting.glsl | 6 +- shaders_ref/lighting/ssao.glsl | 7 + shaders_ref/lighting/ssr.glsl | 8 + shaders_ref/pipeline/color_picker.vert | 2 +- shaders_ref/pipeline/deferred.frag | 27 +- shaders_ref/pipeline/depth.vert | 2 +- shaders_ref/pipeline/forward.vert | 2 +- shaders_ref/pipeline/gbuffer.frag | 2 +- shaders_ref/pipeline/gbuffer.vert | 2 +- {shaders => shaders_ref}/pipeline/scene.glsl | 0 shaders_ref/pipeline/skybox.vert | 2 +- shaders_ref/postprocessing/ssao/ssao.frag | 5 +- shaders_ref/postprocessing/ssao/ssao.vert | 3 +- .../postprocessing/ssao/ssao_blur.frag | 3 +- .../postprocessing/ssao/ssao_blur.vert | 3 +- shaders_ref/postprocessing/ssr/ssr.frag | 19 +- shaders_ref/postprocessing/ssr/ssr.vert | 3 +- shaders_ref/scene.glsl | 67 ----- shaders_ref/shading/regular.glsl | 1 + shaders_ref/shading/shading_context.glsl | 10 +- .../shading/shading_context_from_gctx.glsl | 18 +- .../shading/shading_context_from_mctx.glsl | 3 +- src/limitless/core/uniform/uniform.cpp | 8 + src/limitless/fx/effect_renderer.cpp | 2 +- src/limitless/instances/effect_instance.cpp | 10 +- .../{abstract_instance.cpp => instance.cpp} | 57 ++-- .../instances/instance_attachment.cpp | 8 +- src/limitless/instances/instance_builder.cpp | 97 +++++-- src/limitless/instances/model_instance.cpp | 8 +- src/limitless/instances/skeletal_instance.cpp | 2 +- src/limitless/instances/socket_attachment.cpp | 2 +- src/limitless/lighting/cascade_shadows.cpp | 2 +- .../pipeline/common/render_debug_pass.cpp | 2 +- .../pipeline/common/sceneupdate_pass.cpp | 2 +- src/limitless/pipeline/common/shadow_pass.cpp | 2 +- src/limitless/pipeline/common/ssao_pass.cpp | 4 +- src/limitless/pipeline/common/ssr_pass.cpp | 5 +- .../pipeline/deferred/depth_pass.cpp | 2 +- .../pipeline/deferred/gbuffer_pass.cpp | 2 +- .../pipeline/deferred/translucent_pass.cpp | 2 +- src/limitless/pipeline/forward/color_pass.cpp | 2 +- .../render_settings_shader_definer.cpp | 62 ++--- src/limitless/scene.cpp | 123 +++++++-- src/limitless/shader_storage.cpp | 19 +- src/limitless/util/color_picker.cpp | 2 +- src/limitless/util/sorter.cpp | 6 +- .../instance/instance_attachment_test.cpp | 4 +- .../instance/model_instance_test.cpp | 2 +- .../instance/skeletal_instance_test.cpp | 2 +- .../instance/socket_attachment_test.cpp | 6 +- 194 files changed, 945 insertions(+), 4252 deletions(-) delete mode 100644 demo/sponza_demoscene.cpp delete mode 100644 demo/sponza_demoscene.hpp rename include/limitless/instances/{abstract_instance.hpp => instance.hpp} (85%) delete mode 100644 shaders/functions/circle.glsl delete mode 100644 shaders/functions/fresnel.glsl delete mode 100644 shaders/functions/hue_shift.glsl delete mode 100644 shaders/functions/linearize_depth.glsl delete mode 100644 shaders/functions/reconstruct_position.glsl delete mode 100644 shaders/functions/tone_mapping.glsl delete mode 100644 shaders/pipeline/deferred/composite.frag delete mode 100644 shaders/pipeline/deferred/composite.vert delete mode 100644 shaders/pipeline/deferred/deferred.frag delete mode 100644 shaders/pipeline/deferred/deferred.vert delete mode 100644 shaders/pipeline/deferred/depth.frag delete mode 100644 shaders/pipeline/deferred/depth.vert delete mode 100644 shaders/pipeline/deferred/gbuffer.frag delete mode 100644 shaders/pipeline/deferred/gbuffer.vert delete mode 100644 shaders/pipeline/deferred/gbuffer_input.glsl delete mode 100644 shaders/pipeline/deferred/gbuffer_output.glsl delete mode 100644 shaders/pipeline/deferred/skybox.frag delete mode 100644 shaders/pipeline/deferred/skybox.vert delete mode 100644 shaders/pipeline/forward/forward.frag delete mode 100644 shaders/pipeline/forward/forward.vert delete mode 100644 shaders/pipeline/instance/instance.glsl delete mode 100644 shaders/pipeline/instance/instanced.glsl delete mode 100644 shaders/pipeline/instance/model.glsl delete mode 100644 shaders/pipeline/instance/skeletal.glsl delete mode 100644 shaders/pipeline/interface_block/effect_fs.glsl delete mode 100644 shaders/pipeline/interface_block/effect_vs.glsl delete mode 100644 shaders/pipeline/interface_block/fragment.glsl delete mode 100644 shaders/pipeline/interface_block/mesh_fs.glsl delete mode 100644 shaders/pipeline/interface_block/mesh_vs.glsl delete mode 100644 shaders/pipeline/interface_block/pass_through.glsl delete mode 100644 shaders/pipeline/interface_block/tess_control_input.glsl delete mode 100644 shaders/pipeline/interface_block/tess_control_output.glsl delete mode 100644 shaders/pipeline/interface_block/tess_control_pass.glsl delete mode 100644 shaders/pipeline/interface_block/vertex.glsl delete mode 100644 shaders/pipeline/lighting/ambient.glsl delete mode 100644 shaders/pipeline/lighting/directional_csm.glsl delete mode 100644 shaders/pipeline/lighting/directional_light.glsl delete mode 100644 shaders/pipeline/lighting/directional_shadows.frag delete mode 100644 shaders/pipeline/lighting/directional_shadows.vert delete mode 100644 shaders/pipeline/lighting/lighting_context.glsl delete mode 100644 shaders/pipeline/lighting/point_light.glsl delete mode 100644 shaders/pipeline/lighting/scene_lighting.glsl delete mode 100644 shaders/pipeline/lighting/spot_light.glsl delete mode 100644 shaders/pipeline/material/buffer.glsl delete mode 100644 shaders/pipeline/material/custom_fragment.glsl delete mode 100644 shaders/pipeline/material/material.glsl delete mode 100644 shaders/pipeline/material/shading.glsl delete mode 100644 shaders/pipeline/quad.frag delete mode 100644 shaders/pipeline/quad.vert delete mode 100644 shaders/pipeline/shading/brdf.glsl delete mode 100644 shaders/pipeline/shading/common.glsl delete mode 100644 shaders/pipeline/shading/depth_discarder.glsl delete mode 100644 shaders/pipeline/shading/fragment.glsl delete mode 100644 shaders/pipeline/shading/fragment_data.glsl delete mode 100644 shaders/pipeline/shading/fragment_data_initializer.glsl delete mode 100644 shaders/pipeline/shading/lit.glsl delete mode 100644 shaders/pipeline/shading/refraction.glsl delete mode 100644 shaders/pipeline/shading/shading.glsl delete mode 100644 shaders/pipeline/shading/unlit.glsl delete mode 100644 shaders/pipeline/util/color_picker.frag delete mode 100644 shaders/pipeline/util/color_picker.vert delete mode 100644 shaders/pipeline/vertex_streams/beam_emitter.glsl delete mode 100644 shaders/pipeline/vertex_streams/mesh_emitter.glsl delete mode 100644 shaders/pipeline/vertex_streams/model_mesh.glsl delete mode 100644 shaders/pipeline/vertex_streams/sprite_emitter.glsl delete mode 100644 shaders/pipeline/vertex_streams/vertex_stream.glsl delete mode 100644 shaders/postprocessing/bloom/blur_downsample.frag delete mode 100644 shaders/postprocessing/bloom/blur_downsample.vert delete mode 100644 shaders/postprocessing/bloom/blur_upsample.frag delete mode 100644 shaders/postprocessing/bloom/blur_upsample.vert delete mode 100644 shaders/postprocessing/bloom/brightness.frag delete mode 100644 shaders/postprocessing/bloom/brightness.vert delete mode 100644 shaders/postprocessing/dof.frag delete mode 100644 shaders/postprocessing/dof.vert delete mode 100644 shaders/postprocessing/fxaa.frag delete mode 100644 shaders/postprocessing/fxaa.vert delete mode 100644 shaders/postprocessing/postprocess.frag delete mode 100644 shaders/postprocessing/postprocess.vert delete mode 100644 shaders/postprocessing/ssao/ssao.frag delete mode 100644 shaders/postprocessing/ssao/ssao.vert delete mode 100644 shaders/postprocessing/ssao/ssao_blur.frag delete mode 100644 shaders/postprocessing/ssao/ssao_blur.vert delete mode 100644 shaders/postprocessing/ssr/ssr.frag delete mode 100644 shaders/postprocessing/ssr/ssr.vert delete mode 100644 shaders/tesselation/tesselation.tesc delete mode 100644 shaders/tesselation/tesselation.tese delete mode 100644 shaders/text/text.frag delete mode 100644 shaders/text/text.vert delete mode 100644 shaders/text/text_selection.frag delete mode 100644 shaders/text/text_selection.vert create mode 100644 shaders_ref/functions/brdf_ctx.glsl rename {shaders => shaders_ref}/functions/cheap_contrast.glsl (100%) rename {shaders => shaders_ref}/functions/elipse.glsl (100%) rename {shaders => shaders_ref}/functions/fxaa.glsl (100%) rename {shaders => shaders_ref}/functions/gamma_correction.glsl (100%) rename {shaders => shaders_ref}/functions/math.glsl (100%) rename {shaders => shaders_ref}/functions/polar_coordinates.glsl (100%) rename {shaders => shaders_ref}/functions/radial_shear.glsl (100%) rename {shaders => shaders_ref}/functions/random.glsl (100%) rename {shaders => shaders_ref}/functions/reconstruct_normal.glsl (100%) rename {shaders => shaders_ref}/functions/rectangle.glsl (100%) rename {shaders => shaders_ref}/functions/rotate_uv.glsl (100%) rename {shaders => shaders_ref}/functions/scale_uv_by_center.glsl (100%) rename {shaders => shaders_ref}/functions/sphere_mask.glsl (100%) rename {shaders => shaders_ref}/functions/spherize_uv.glsl (100%) rename {shaders => shaders_ref}/functions/tiling_offset.glsl (100%) rename {shaders => shaders_ref}/functions/trace_ray.glsl (99%) rename {shaders => shaders_ref}/functions/twirl.glsl (100%) create mode 100644 shaders_ref/lighting/ssao.glsl create mode 100644 shaders_ref/lighting/ssr.glsl rename {shaders => shaders_ref}/pipeline/scene.glsl (100%) delete mode 100644 shaders_ref/scene.glsl rename src/limitless/instances/{abstract_instance.cpp => instance.cpp} (59%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e401875..aff81013 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,7 +114,7 @@ set(ENGINE_CORE ) set(ENGINE_INSTANCES - src/limitless/instances/abstract_instance.cpp + src/limitless/instances/instance.cpp src/limitless/instances/skeletal_instance.cpp src/limitless/instances/mesh_instance.cpp src/limitless/instances/model_instance.cpp @@ -349,7 +349,6 @@ add_executable(limitless_demo demo/lighting_demoscene.cpp demo/effects_demoscene.cpp demo/models_demoscene.cpp - demo/sponza_demoscene.cpp demo/assets.cpp ) diff --git a/demo/assets.cpp b/demo/assets.cpp index 21f6dc2b..a945e84c 100644 --- a/demo/assets.cpp +++ b/demo/assets.cpp @@ -504,6 +504,7 @@ void DemoAssets::loadEffectsScene() { { Material::builder() .name("explosion") + .shading(Shading::Unlit) .blending(Blending::Additive) .emissive_color(glm::vec4(2.0, 1.0, 0.3, 1.0)) .color( glm::vec4(1.0, 1.0, 0.3, 1.0)) @@ -542,6 +543,7 @@ void DemoAssets::loadEffectsScene() { "mctx.color.rgb = vec3(0.0);") .global("#include \"../functions/circle.glsl\"") .model(InstanceType::Effect) + .shading(Shading::Unlit) .build(*this); } @@ -632,7 +634,7 @@ void DemoAssets::loadEffectsScene() { .emissive_color( glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) .color(glm::vec4(0.3f, 1.5f, 0.5f, 1.0f)) .fragment("mctx.emissive_color *= circle(getVertexUV(), 0.7);" - "mctx.color.rgb *= circle(getVertexUV(), 0.7);") + "mctx.color.rgb *= circle(getVertexUV(), 0.7);") .shading(Shading::Unlit) .blending(Blending::Additive) .global("#include \"../functions/circle.glsl\"") @@ -973,8 +975,8 @@ void DemoAssets::loadModelsScene() { } void DemoAssets::loadSponzaScene() { - const fs::path assets_dir {getAssetsDir()}; - models.add("sponza", ModelLoader::loadModel(*this, assets_dir / "models/sponza/sponza.obj")); +// const fs::path assets_dir {getAssetsDir()}; +// models.add("sponza", ModelLoader::loadModel(*this, assets_dir / "models/sponza/sponza.obj")); } void DemoAssets::loadAssets() { @@ -982,7 +984,7 @@ void DemoAssets::loadAssets() { loadModelsScene(); loadLightingScene(); loadEffectsScene(); - loadSponzaScene(); +// loadSponzaScene(); { const fs::path assets_dir{getAssetsDir()}; diff --git a/demo/demo.cpp b/demo/demo.cpp index 0ee79702..1c367528 100644 --- a/demo/demo.cpp +++ b/demo/demo.cpp @@ -152,29 +152,6 @@ class Game : public MouseMoveObserver, public KeyObserver, public FramebufferObs } } - void drawText() { - if (hidden_text) { - return; - } - - auto start = glm::vec2 {0.0f, window_size.y - 20}; - for (auto it = scene.getScenes().begin(); it != scene.getScenes().end(); ++it) { - TextInstance list {it->first, start, assets.fonts.at("nunito")}; - list.setColor((it == scene.getCurrent()) ? glm::vec4(1.0f, 0.0f, 0.0f, 1.0f) : glm::vec4(1.0f)); - list.setSize(glm::vec2{0.3f}); - list.draw(context, assets); - start.y -= 20.0f; - } - - TextInstance helper {"Use 'WASD' & 'mouse' to look around.\n" - "Press 'TAB' to switch scene.\n" - "Hold 'SPACE' to boost camera speed.\n" - "Press '~' to hide this text.\n" - "Press 'ESC' to quit.", start, assets.fonts.at("nunito")}; - helper.setSize(glm::vec2{0.3f}); - helper.draw(context, assets); - } - void gameLoop() { using namespace std::chrono; while (!context.shouldClose() && !done) { @@ -183,8 +160,8 @@ class Game : public MouseMoveObserver, public KeyObserver, public FramebufferObs auto delta_time = duration_cast>(current_time - last_time).count(); last_time = current_time; + scene.update(context, camera); render.draw(context, assets, scene.getCurrentScene(), camera); - drawText(); context.swapBuffers(); context.pollEvents(); diff --git a/demo/effects_demoscene.cpp b/demo/effects_demoscene.cpp index da430669..faa6450f 100644 --- a/demo/effects_demoscene.cpp +++ b/demo/effects_demoscene.cpp @@ -19,46 +19,93 @@ using namespace Limitless::ms; using namespace Limitless::fx; void EffectsScene::addInstances(Limitless::Assets& assets) { - add(assets.effects.at("blink"), glm::vec3 {29.0f, 1.0f, 1.0f}); - add(assets.effects.at("shield"), glm::vec3{29.0f, 1.0f, 4.0f}); - add(assets.effects.at("fireball"), glm::vec3{29.0f, 1.0f, 7.0f}); - add(assets.effects.at("explosion"), glm::vec3{29.0f, 1.0f, 10.0f}); - hurricane = &add(assets.effects.at("hurricane"), glm::vec3{29.0f, 1.0f, 13.0f}); - add(assets.effects.at("lightning"), glm::vec3{29.0f, 1.0f, 16.0f}); - - auto& bob = add(assets.models.at("bob"), glm::vec3(29.0f, 1.0f, 19.0f)) - .play("") - .setScale(glm::vec3(0.025f)) - .setRotation(glm::vec3{0.0f, -M_PI_2, M_PI}); - - const auto& module = add(assets.effects.at("modeldrop"), glm::vec3{0.0f}) - .get("sparks") + scene.add(Instance::builder() + .effect(assets.effects.at("blink")) + .position({29.0f, 1.0f, 1.0f}) + .build() + ); + + scene.add(Instance::builder() + .effect(assets.effects.at("shield")) + .position({29.0f, 1.0f, 4.0f}) + .build() + ); + + scene.add(Instance::builder() + .effect(assets.effects.at("fireball")) + .position({29.0f, 1.0f, 7.0f}) + .build() + ); + + scene.add(Instance::builder() + .effect(assets.effects.at("explosion")) + .position({29.0f, 1.0f, 10.0f}) + .build() + ); + + hurricane = Instance::builder() + .effect(assets.effects.at("hurricane")) + .position({29.0f, 1.0f, 13.0f}) + .asEffect(); + scene.add(hurricane); + + scene.add(Instance::builder() + .effect(assets.effects.at("lightning")) + .position({29.0f, 1.0f, 16.0f}) + .build() + ); + + auto bob = Instance::builder() + .model(assets.models.at("bob")) + .position({29.0f, 1.0f, 19.0f}) + .rotation(glm::vec3{0.0f, -M_PI_2, M_PI}) + .scale(glm::vec3(0.025f)) + .asSkeletal(); + bob->play(""); + scene.add(bob); + + auto mod = Instance::builder() + .effect(assets.effects.at("modeldrop")) + .position({0.0f, 0.0f, 0.0f}) + .asEffect(); + + const auto& module = mod->get("sparks") .getModule(fx::ModuleType::InitialMeshLocation); dynamic_cast&>(*module) - .attachModelInstance(dynamic_cast(&bob)); + .attachModelInstance(bob.get()); + scene.add(mod); + + scene.add(Instance::builder() + .effect(assets.effects.at("skeleton")) + .position({23.0f, 1.0f, 1.0f}) + .build() + ); - add(assets.effects.at("skeleton"), glm::vec3{23.0f, 1.0f, 1.0f}); - add(assets.effects.at("aura"), glm::vec3{23.0f, 1.0f, 4.0f}); + scene.add(Instance::builder() + .effect(assets.effects.at("aura")) + .position({23.0f, 1.0f, 4.0f}) + .build() + ); } EffectsScene::EffectsScene(Limitless::Context& ctx, Limitless::Assets& assets) - : Limitless::Scene(ctx) { + : scene(ctx) { addInstances(assets); - setSkybox(assets.skyboxes.at("skybox")); + scene.setSkybox(assets.skyboxes.at("skybox")); - lighting.getAmbientColor().a *= 0.5; + scene.getLighting().getAmbientColor().a *= 0.5; - lighting.add(Light::builder() - .color({2.0, -2.0, 1.5, 1.0f}) + scene.add(Light::builder() + .color({0.6, 1.0, 0.3, 1.0f}) .direction(glm::vec3{-1.0f}) .build() ); - auto& floor = add>(glm::vec3{0.0f}); + auto floor = std::make_shared>(glm::vec3{0.0f}); for (int i = 0; i < 30; ++i) { for (int j = 0; j < 30; ++j) { - floor.addInstance( + floor->addInstance( std::make_unique( assets.models.at("plane"), assets.materials.at("basic4"), @@ -67,10 +114,11 @@ EffectsScene::EffectsScene(Limitless::Context& ctx, Limitless::Assets& assets) ); } } + scene.add(floor); } void EffectsScene::update(Context& context, const Camera& camera) { - Scene::update(context, camera); + scene.update(context, camera); hurricane->rotateBy(glm::vec3(0.0f, 0.3f, 0.0f)); } diff --git a/demo/effects_demoscene.hpp b/demo/effects_demoscene.hpp index e70de52e..551e70a3 100644 --- a/demo/effects_demoscene.hpp +++ b/demo/effects_demoscene.hpp @@ -2,15 +2,17 @@ #include namespace LimitlessDemo { - class EffectsScene : public Limitless::Scene { + class EffectsScene { private: - Limitless::EffectInstance* hurricane {}; + Limitless::Scene scene; + std::shared_ptr hurricane {}; void addInstances(Limitless::Assets& assets); public: EffectsScene(Limitless::Context& ctx, Limitless::Assets& assets); - ~EffectsScene() override = default; - void update(Limitless::Context& context, const Limitless::Camera& camera) override; + auto& getScene() { return scene; } + + void update(Limitless::Context& context, const Limitless::Camera& camera); }; } \ No newline at end of file diff --git a/demo/lighting_demoscene.cpp b/demo/lighting_demoscene.cpp index 9566e84f..c284910d 100644 --- a/demo/lighting_demoscene.cpp +++ b/demo/lighting_demoscene.cpp @@ -10,34 +10,36 @@ using namespace Limitless; void LightingScene::addFloor(const Limitless::Assets& assets) { using namespace Limitless; - auto& floor = add>(glm::vec3{0.0f}); + auto floor = std::make_shared>(glm::vec3{0.0f}); for (int i = 0; i < FLOOR_INSTANCE_COUNT / 2; ++i) { for (int j = 0; j < FLOOR_INSTANCE_COUNT / 2; ++j) { - floor.addInstance( - std::make_unique( - assets.models.at("plane"), - assets.materials.at("floor"), - glm::vec3{i, 0.0f, j} - ) + floor->addInstance( + std::make_unique( + assets.models.at("plane"), + assets.materials.at("floor"), + glm::vec3{i, 0.0f, j} + ) ); } } + scene.add(floor); } void LightingScene::addSpheres(const Limitless::Assets& assets) { using namespace Limitless; - auto& floor = add>(glm::vec3{0.0f}); + auto spheres = std::make_shared>(glm::vec3{0.0f}); for (int i = 0; i < FLOOR_INSTANCE_COUNT / 4; ++i) { for (int j = 0; j < FLOOR_INSTANCE_COUNT / 4; ++j) { - floor.addInstance( + spheres->addInstance( std::make_unique( assets.models.at("sphere"), assets.materials.at("PBR"), - glm::vec3{i * 2.0, 0.0f, j * 2.0} + glm::vec3{i * 2.0, 1.0f, j * 2.0} ) ); } } + scene.add(spheres); } bool LightingScene::isInsideFloor(const glm::vec3& position) { @@ -54,7 +56,7 @@ bool LightingScene::isInsideFloor(const glm::vec3& position) { void LightingScene::addLights() { for (int i = 0; i < LIGHT_COUNT; ++i) { - lighting.add(Light::builder() + scene.add(Light::builder() .position({FLOOR_INSTANCE_COUNT / 4.0f, 1.0f, FLOOR_INSTANCE_COUNT / 4.0f}) .color({1.0f, 1.0f, 1.0f, 1.0f}) .radius(2.0f) @@ -64,31 +66,21 @@ void LightingScene::addLights() { } LightingScene::LightingScene(Limitless::Context& ctx, const Limitless::Assets& assets) - : Limitless::Scene(ctx) { + : scene {ctx} { addFloor(assets); addSpheres(assets); addLights(); - setSkybox(assets.skyboxes.at("skybox")); - - lighting.getAmbientColor().a = 0.5f; - - lighting.add(Light::builder() - .color(glm::vec4(1.0, 1.0, 0.5, 1.0f)) - .direction(glm::vec3{1.0f}) - .build() - ); - - lighting.add(Light::builder() - .color({1.0, -1.0, 0.5, 1.0f}) - .direction(glm::vec3{-1.0f}) - .build() + scene.setSkybox(assets.skyboxes.at("skybox")); + scene.getLighting().getAmbientColor().a = 0.7f; + scene.add(Light::builder() + .color(glm::vec4(1.0, 1.0, 0.5, 1.0f)) + .direction(glm::vec3{1.0f}) + .build() ); } void LightingScene::update(Limitless::Context& context, const Limitless::Camera& camera) { - Limitless::Scene::update(context, camera); - using namespace std::chrono; auto current_time = steady_clock::now(); static auto last_time = steady_clock::now(); @@ -101,7 +93,7 @@ void LightingScene::update(Limitless::Context& context, const Limitless::Camera& std::uniform_real_distribution<> dis_color(0.0, 1.0); uint32_t i = 0; - for (auto& [_, light]: lighting.getLights()) { + for (auto& [_, light]: scene.getLighting().getLights()) { auto& light_data = data[i++]; light.getPosition() += glm::vec3(light_data.direction) * delta_time * 10.0f; @@ -119,4 +111,6 @@ void LightingScene::update(Limitless::Context& context, const Limitless::Camera& light_data.direction *= -0.3f; } } + + scene.update(context, camera); } diff --git a/demo/lighting_demoscene.hpp b/demo/lighting_demoscene.hpp index 27858ec6..fc5cccaa 100644 --- a/demo/lighting_demoscene.hpp +++ b/demo/lighting_demoscene.hpp @@ -6,8 +6,10 @@ #include namespace LimitlessDemo { - class LightingScene : public Limitless::Scene { + class LightingScene { private: + Limitless::Scene scene; + static constexpr auto FLOOR_INSTANCE_COUNT = 64; static constexpr auto LIGHT_COUNT = 512; @@ -19,12 +21,13 @@ namespace LimitlessDemo { void addFloor(const Limitless::Assets& assets); void addSpheres(const Limitless::Assets& assets); - bool isInsideFloor(const glm::vec3& position); + static bool isInsideFloor(const glm::vec3& position); void addLights(); public: LightingScene(Limitless::Context& ctx, const Limitless::Assets& assets); - ~LightingScene() override = default; - void update(Limitless::Context& context, const Limitless::Camera& camera) override; + auto& getScene() { return scene; } + + void update(Limitless::Context& context, const Limitless::Camera& camera); }; } \ No newline at end of file diff --git a/demo/materials_demoscene.cpp b/demo/materials_demoscene.cpp index b09f9684..c7ae4310 100644 --- a/demo/materials_demoscene.cpp +++ b/demo/materials_demoscene.cpp @@ -9,31 +9,32 @@ using namespace LimitlessDemo; using namespace Limitless; MaterialsScene::MaterialsScene(Limitless::Context& ctx, Limitless::Assets& assets) - : Limitless::Scene(ctx) { + : scene(ctx) { addModels(assets); - setSkybox(assets.skyboxes.at("skybox")); - lighting.add(Light::builder() - .color(glm::vec4(1.0, 1.0, 0.5, 1.0f)) + scene.setSkybox(assets.skyboxes.at("skybox")); + + scene.add(Light::builder() + .color(glm::vec4(1.0, 1.0, 1.0, 1.0f)) .direction(glm::vec3{-1.0f}) .build() ); - lighting.add(Light::builder() + scene.add(Light::builder() .position({0.0f, 0.5f, 0.0f}) .color({1.0f, 0.0f, 0.0f, 2.0f}) .radius(2.0f) .build() ); - lighting.add(Light::builder() + scene.add(Light::builder() .position({5.0f, 0.5f, 0.0f}) .color({0.0f, 1.0f, 0.0f, 2.0f}) .radius(2.0f) .build() ); - lighting.add(Light::builder() + scene.add(Light::builder() .position({0.0f, 0.5f, 5.0f}) .color({0.0f, 0.0f, 1.0f, 2.0f}) .radius(2.0f) @@ -44,28 +45,104 @@ MaterialsScene::MaterialsScene(Limitless::Context& ctx, Limitless::Assets& asset void MaterialsScene::addModels(const Limitless::Assets& assets) { using namespace Limitless; - add(assets.models.at("sphere"), assets.materials.at("color"), glm::vec3{29.0f, 1.0f, 1.0f}); - add(assets.models.at("sphere"), assets.materials.at("albedo"), glm::vec3{29.0f, 1.0f, 4.0f }); - add(assets.models.at("sphere"), assets.materials.at("emissive_color"), glm::vec3{29.0f, 1.0f, 7.0f }); - open = &add(assets.models.at("plane"), assets.materials.at("emissive_mask"), glm::vec3{29.0f, 1.0f, 10.0f}); - open->setRotation(glm::vec3(M_PI_2, M_PI_2 * 3, 0.0f)); - add(assets.models.at("plane"), assets.materials.at("blend_mask"), glm::vec3{29.0f, 1.0f, 13.0f }) - .setRotation(glm::vec3(M_PI_2, M_PI_2 * 3, 0.0f)); - add(assets.models.at("sphere"), assets.materials.at("refraction"), glm::vec3{29.0f, 1.0f, 16.0f }); - - add(assets.models.at("sphere"), assets.materials.at("basic1"), glm::vec3{24.0f, 1.0f, 1.0f }); - add(assets.models.at("sphere"), assets.materials.at("basic2"), glm::vec3{24.0f, 1.0f, 4.0f }); - add(assets.models.at("sphere"), assets.materials.at("basic3"), glm::vec3{24.0f, 1.0f, 7.0f }); - add(assets.models.at("plane"), assets.materials.at("basic5"), glm::vec3{24.0f, 1.0f, 10.0f }) - .setRotation(glm::vec3(M_PI_2, M_PI_2 * 3, 0.0f)); - add(assets.models.at("sphere"), assets.materials.at("basic6"), glm::vec3{24.0f, 1.0f, 13.0f }); - add(assets.models.at("sphere"), assets.materials.at("basic7"), glm::vec3{24.0f, 1.0f, 16.0f }); - add(assets.models.at("sphere"), assets.materials.at("basic8"), glm::vec3{24.0f, 1.0f, 19.0f }); - - auto& floor = add>(glm::vec3{0.0f}); + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("color")) + .position({29.0f, 1.0f, 1.0f}) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("albedo")) + .position({29.0f, 1.0f, 4.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("emissive_color")) + .position({29.0f, 1.0f, 7.0f }) + .build() + ); + + open = Instance::builder() + .model(assets.models.at("plane")) + .material(assets.materials.at("emissive_mask")) + .position({29.0f, 1.0f, 10.0f}) + .rotation(glm::vec3{M_PI_2, M_PI_2 * 3, 0.0f}) + .asModel(); + scene.add(open); + + scene.add(Instance::builder() + .model(assets.models.at("plane")) + .material(assets.materials.at("blend_mask")) + .position({29.0f, 1.0f, 13.0f }) + .rotation(glm::vec3(M_PI_2, M_PI_2 * 3, 0.0f)) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("refraction")) + .position({29.0f, 1.0f, 16.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("basic1")) + .position({24.0f, 1.0f, 1.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("basic2")) + .position({24.0f, 1.0f, 4.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("basic3")) + .position({24.0f, 1.0f, 7.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("basic5")) + .position({24.0f, 1.0f, 10.0f }) + .rotation(glm::vec3(M_PI_2, M_PI_2 * 3, 0.0f)) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("basic6")) + .position({24.0f, 1.0f, 13.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("basic7")) + .position({24.0f, 1.0f, 16.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("basic8")) + .position({24.0f, 1.0f, 19.0f }) + .build() + ); + + auto floor = std::make_shared>(glm::vec3{0.0f}); for (int i = 0; i < 30; ++i) { for (int j = 0; j < 30; ++j) { - floor.addInstance( + floor->addInstance( std::make_unique( assets.models.at("plane"), assets.materials.at("basic4"), @@ -74,32 +151,102 @@ void MaterialsScene::addModels(const Limitless::Assets& assets) { ); } } + scene.add(floor); + + scene.add(Instance::builder() + .model(assets.models.at("plane")) + .material(assets.materials.at("blending1")) + .position({19.0f, 1.0f, 1.0f }) + .rotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)) + .build() + ); - add(assets.models.at("plane"), assets.materials.at("blending1"), glm::vec3{19.0f, 1.0f, 1.0f }) - .setRotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)); - add(assets.models.at("plane"), assets.materials.at("blending2"), glm::vec3{19.0f, 1.0f, 4.0f }) - .setRotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)); - add(assets.models.at("plane"), assets.materials.at("blending3"), glm::vec3{19.0f, 1.0f, 7.0f }) - .setRotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)); + scene.add(Instance::builder() + .model(assets.models.at("plane")) + .material(assets.materials.at("blending2")) + .position({19.0f, 1.0f, 4.0f }) + .rotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)) + .build() + ); - add(assets.models.at("cube"), assets.materials.at("blending4"), glm::vec3{19.0f, 1.0f, 10.0f }); - add(assets.models.at("cube"), assets.materials.at("blending5"), glm::vec3{19.0f, 1.0f, 13.0f }); + scene.add(Instance::builder() + .model(assets.models.at("plane")) + .material(assets.materials.at("blending3")) + .position({19.0f, 1.0f, 7.0f }) + .rotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)) + .build() + ); - add(assets.models.at("sphere"), assets.materials.at("lava"), glm::vec3{14.0f, 1.0f, 1.0f }); - add(assets.models.at("sphere"), assets.materials.at("ice"), glm::vec3{14.0f, 1.0f, 4.0f }); - add(assets.models.at("sphere"), assets.materials.at("poison"), glm::vec3{14.0f, 1.0f, 7.0f }); + scene.add(Instance::builder() + .model(assets.models.at("cube")) + .material(assets.materials.at("blending4")) + .position({19.0f, 1.0f, 10.0f }) + .rotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)) + .build() + ); - add(assets.models.at("sphere"), assets.materials.at("bump_mapping"), glm::vec3{14.0f, 1.0f, 13.0f }); - add(assets.models.at("sphere"), assets.materials.at("fresnel"), glm::vec3{14.0f, 1.0f, 17.0f }); + scene.add(Instance::builder() + .model(assets.models.at("cube")) + .material(assets.materials.at("blending5")) + .position({19.0f, 1.0f, 13.0f }) + .rotation(glm::vec3(M_PI_2, M_PI_2 * 2, 0.0f)) + .build() + ); - add(assets.models.at("sphere"), assets.materials.at("hue_shift"), glm::vec3{14.0f, 1.0f, 20.0f }); - add(assets.models.at("sphere"), assets.materials.at("fireball"), glm::vec3{14.0f, 1.0f, 23.0f }); + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("lava")) + .position({14.0f, 1.0f, 1.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("ice")) + .position({14.0f, 1.0f, 4.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("poison")) + .position({14.0f, 1.0f, 7.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("bump_mapping")) + .position({14.0f, 1.0f, 13.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("fresnel")) + .position({14.0f, 1.0f, 17.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("hue_shift")) + .position({14.0f, 1.0f, 20.0f }) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("sphere")) + .material(assets.materials.at("fireball")) + .position({14.0f, 1.0f, 23.0f }) + .build() + ); } void MaterialsScene::update(Limitless::Context& context, const Limitless::Camera& camera) { - Limitless::Scene::update(context, camera); + scene.update(context, camera); - (*open)["plane_mesh"].getMaterial()->getEmissiveColor() = { + open->getMaterial("plane_mesh")->getEmissiveColor() = { glm::abs(glm::cos(glfwGetTime() * 2.5)) * 2.5, 0.0f, glm::abs(glm::cos(glfwGetTime() * 2.5)) * 5.0, diff --git a/demo/materials_demoscene.hpp b/demo/materials_demoscene.hpp index 4bd1c28a..d46e3bd3 100644 --- a/demo/materials_demoscene.hpp +++ b/demo/materials_demoscene.hpp @@ -5,14 +5,16 @@ #include namespace LimitlessDemo { - class MaterialsScene : public Limitless::Scene { + class MaterialsScene { private: - Limitless::ModelInstance* open; + Limitless::Scene scene; + std::shared_ptr open; void addModels(const Limitless::Assets& assets); public: MaterialsScene(Limitless::Context& ctx, Limitless::Assets& assets); - ~MaterialsScene() override = default; - void update(Limitless::Context& context, const Limitless::Camera& camera) override; + auto& getScene() { return scene; } + + void update(Limitless::Context& context, const Limitless::Camera& camera); }; } \ No newline at end of file diff --git a/demo/models_demoscene.cpp b/demo/models_demoscene.cpp index c732f612..37405712 100644 --- a/demo/models_demoscene.cpp +++ b/demo/models_demoscene.cpp @@ -13,12 +13,12 @@ using namespace LimitlessDemo; using namespace Limitless; ModelsScene::ModelsScene(Limitless::Context& ctx, Limitless::Assets& assets) - : Limitless::Scene(ctx) { - setSkybox(assets.skyboxes.at("skybox")); + : scene{ctx} { + scene.setSkybox(assets.skyboxes.at("skybox")); - lighting.add(Light::builder() - .color({1.0, -1.0, 1.5, 1.0f}) - .direction({-1.0f, -1.0f, -1.0f}) + scene.add(Light::builder() + .color({1.0, 1.0, 1.0, 1.0f}) + .direction({0.5f, -1.0f, 0.0f}) .build() ); @@ -28,10 +28,10 @@ ModelsScene::ModelsScene(Limitless::Context& ctx, Limitless::Assets& assets) void ModelsScene::addInstances(Limitless::Assets& assets) { using namespace Limitless; - auto& floor = add>(glm::vec3{0.0f}); + auto floor = std::make_shared>(glm::vec3{0.0f}); for (int i = 0; i < 30; ++i) { for (int j = 0; j < 30; ++j) { - floor.addInstance( + floor->addInstance( std::make_unique( assets.models.at("plane"), assets.materials.at("basic4"), @@ -40,49 +40,86 @@ void ModelsScene::addInstances(Limitless::Assets& assets) { ); } } - - add(assets.models.at("thanos"), glm::vec3(25.0f, 1.0f, 1.0f)) - .setRotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}); - - add(assets.models.at("daenerys"), glm::vec3(25.0f, 1.0f, 4.0f)) - .setScale(glm::vec3(1.1f)) - .setRotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}); - - add(assets.models.at("taskmaster"), glm::vec3(25.0f, 1.0f, 7.0f)) - .setScale(glm::vec3(0.03f)) - .setRotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}); - - add(assets.models.at("k2"), glm::vec3(25.0f, 1.0f, 10.0f)) - .setRotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}); - - add(assets.models.at("skeleton"), glm::vec3(25.0f, 1.0f, 13.0f)) - .setScale(glm::vec3(0.03f)) - .setRotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}); - - add(assets.models.at("bob"), glm::vec3(25.0f, 1.0f, 16.0f)) - .play("") - .setScale(glm::vec3(0.03f)) - .setRotation(glm::vec3{M_PI, -M_PI_2, 0.0f}); - - add(assets.models.at("backpack"), glm::vec3(25.0f, 1.5f, 19.0f)) - .setScale(glm::vec3(0.5f)) - .setRotation(glm::vec3{0.0f, -M_PI_2, 0.0f}); - - add(assets.models.at("cyborg"), glm::vec3(25.0f, 1.0f, 21.0f)) - .setScale(glm::vec3(0.5f)) - .setRotation(glm::vec3{0.0f, -M_PI_2, 0.0f}); - - { - auto& drone = add(assets.models.at("drone"), glm::vec3(25.0f, 2.0f, 24.0f)) - .setScale(glm::vec3(0.01f)) - .setRotation(glm::vec3{M_PI, M_PI_2, 0.0f}); - } - - add(assets.models.at("elemental"), glm::vec3(25.0f, 2.0f, 27.0f)) - .setScale(glm::vec3(10.0f)) - .setRotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}); + scene.add(floor); + + scene.add(Instance::builder() + .model(assets.models.at("thanos")) + .position(glm::vec3(25.0f, 1.0f, 1.0f)) + .rotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("daenerys")) + .position(glm::vec3(25.0f, 1.0f, 4.0f)) + .rotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("taskmaster")) + .position(glm::vec3(25.0f, 1.0f, 7.0f)) + .rotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}) + .scale(glm::vec3(0.03f)) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("k2")) + .position(glm::vec3(25.0f, 1.0f, 10.0f)) + .rotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("skeleton")) + .position(glm::vec3(25.0f, 1.0f, 13.0f)) + .rotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}) + .scale(glm::vec3(0.03f)) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("bob")) + .position(glm::vec3(25.0f, 1.0f, 16.0f)) + .rotation(glm::vec3{0.0f, -M_PI_2, 0.0f}) + .scale(glm::vec3(0.03f)) + .build() + ); + + scene.add(Instance::builder() + .model(assets.models.at("backpack")) + .position(glm::vec3(25.0f, 1.5f, 19.0f)) + .rotation(glm::vec3{0.0f, -M_PI_2, 0.0f}) + .scale(glm::vec3(0.5f)) + .asModel() + ); + + scene.add(Instance::builder() + .model(assets.models.at("cyborg")) + .position(glm::vec3(25.0f, 1.0f, 21.0f)) + .rotation(glm::vec3{0.0f, -M_PI_2, 0.0f}) + .scale(glm::vec3(0.5f)) + .asModel() + ); + + scene.add(Instance::builder() + .model(assets.models.at("drone")) + .position(glm::vec3(25.0f, 2.0f, 24.0f)) + .rotation(glm::vec3{M_PI, M_PI_2, 0.0f}) + .scale(glm::vec3(0.01f)) + .asModel() + ); + + scene.add(Instance::builder() + .model(assets.models.at("elemental")) + .position(glm::vec3(25.0f, 2.0f, 27.0f)) + .rotation(glm::vec3{-M_PI_2, -M_PI_2, 0.0f}) + .scale(glm::vec3(10.0f)) + .asModel() + ); } void ModelsScene::update(Limitless::Context& context, const Limitless::Camera& camera) { - Limitless::Scene::update(context, camera); + scene.update(context, camera); } \ No newline at end of file diff --git a/demo/models_demoscene.hpp b/demo/models_demoscene.hpp index 54b2ff3b..45ee3f0c 100644 --- a/demo/models_demoscene.hpp +++ b/demo/models_demoscene.hpp @@ -6,13 +6,15 @@ #include namespace LimitlessDemo { - class ModelsScene : public Limitless::Scene { + class ModelsScene { private: + Limitless::Scene scene; void addInstances(Limitless::Assets& assets); public: ModelsScene(Limitless::Context& ctx, Limitless::Assets& assets); - ~ModelsScene() override = default; - void update(Limitless::Context& context, const Limitless::Camera& camera) override; + auto& getScene() { return scene; } + + void update(Limitless::Context& context, const Limitless::Camera& camera); }; } \ No newline at end of file diff --git a/demo/scene.hpp b/demo/scene.hpp index 5d7a4f49..0bae69cf 100644 --- a/demo/scene.hpp +++ b/demo/scene.hpp @@ -5,28 +5,25 @@ #include "materials_demoscene.hpp" #include "effects_demoscene.hpp" #include "models_demoscene.hpp" -#include "sponza_demoscene.hpp" using namespace Limitless; namespace LimitlessDemo { class DemoScene { private: - std::map> scenes; - decltype(scenes)::iterator current; + LightingScene lightingScene; + MaterialsScene materialsScene; + EffectsScene effectsScene; + ModelsScene modelsScene; + uint32_t current {0}; public: - DemoScene(Context& ctx, Assets& assets) { - scenes.emplace("1. lighting demo", new LightingScene(ctx, assets)); - scenes.emplace("2. materials demo", new MaterialsScene(ctx, assets)); - scenes.emplace("3. effects demo", new EffectsScene(ctx, assets)); - scenes.emplace("4. models demo", new ModelsScene(ctx, assets)); - scenes.emplace("5. sponza demo", new SponzaScene(ctx, assets)); - - current = scenes.begin(); + DemoScene(Context& ctx, Assets& assets) + : lightingScene {ctx, assets} + , materialsScene {ctx, assets} + , effectsScene {ctx, assets} + , modelsScene {ctx, assets} { } - ~DemoScene() = default; - static void setCameraDefault(Camera& camera) { camera.setPosition({15.0f, 10.0f, 15.0f}); } @@ -34,15 +31,41 @@ namespace LimitlessDemo { void next(Camera& camera) { ++current; - if (current == scenes.end()) { - current = scenes.begin(); + if (current > 4 - 1) { + current = 0; } setCameraDefault(camera); } - auto getCurrent() noexcept { return current; } - auto& getCurrentScene() noexcept { return *current->second; } - [[nodiscard]] const auto& getScenes() const noexcept { return scenes; } + void update(Context& ctx, Camera& camera) { + switch (current) { + case 0: + lightingScene.update(ctx, camera); + case 1: + materialsScene.update(ctx, camera); + case 2: + effectsScene.update(ctx, camera); + case 3: + modelsScene.update(ctx, camera); + default: + lightingScene.update(ctx, camera); + } + } + + Limitless::Scene& getCurrentScene() noexcept { + switch (current) { + case 0: + return lightingScene.getScene(); + case 1: + return materialsScene.getScene(); + case 2: + return effectsScene.getScene(); + case 3: + return modelsScene.getScene(); + default: + return lightingScene.getScene(); + } + } }; } diff --git a/demo/sponza_demoscene.cpp b/demo/sponza_demoscene.cpp deleted file mode 100644 index ff9077c8..00000000 --- a/demo/sponza_demoscene.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "sponza_demoscene.hpp" - -#include -#include - -using namespace LimitlessDemo; -using namespace Limitless; - -SponzaScene::SponzaScene(Limitless::Context& ctx, Limitless::Assets& assets) - : Limitless::Scene(ctx) { - - setSkybox(assets.skyboxes.at("skybox")); - - lighting.add(Light::builder() - .color(glm::vec4(0.0, -1.0, 0.25, 1.0f)) - .direction(glm::vec3(0.5f, -1.1f, 1.0f)) - .build() - ); - - auto& sponza = dynamic_cast(add(assets.models.at("sponza"), glm::vec3(17.0f, 8.0f, 15.0f)) - .setScale(glm::vec3(0.005f))); - -// for (auto& [name, mesh] : sponza.getMeshes()) { -//// mesh.getMaterial()[0].getTwoSided() = true; -// mesh.getMaterial()[0].getBlending() = Limitless::ms::Blending::Opaque; -// } -} - -void SponzaScene::update(Limitless::Context& context, const Limitless::Camera& camera) { - Limitless::Scene::update(context, camera); -} \ No newline at end of file diff --git a/demo/sponza_demoscene.hpp b/demo/sponza_demoscene.hpp deleted file mode 100644 index 9032416a..00000000 --- a/demo/sponza_demoscene.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace LimitlessDemo { - class SponzaScene : public Limitless::Scene { - private: - public: - SponzaScene(Limitless::Context& ctx, Limitless::Assets& assets); - ~SponzaScene() override = default; - - void update(Limitless::Context& context, const Limitless::Camera& camera) override; - }; -} \ No newline at end of file diff --git a/include/limitless/core/uniform/uniform.hpp b/include/limitless/core/uniform/uniform.hpp index f4a5dd2d..d68efc43 100644 --- a/include/limitless/core/uniform/uniform.hpp +++ b/include/limitless/core/uniform/uniform.hpp @@ -46,6 +46,9 @@ namespace Limitless { Uniform(std::string name, UniformType type, UniformValueType value_type) noexcept; virtual ~Uniform() = default; + Uniform(const Uniform&) noexcept; + Uniform(Uniform&&) noexcept = default; + /* * Makes uniform deep copy */ diff --git a/include/limitless/core/uniform/uniform_value.hpp b/include/limitless/core/uniform/uniform_value.hpp index ad9f258e..69beba01 100644 --- a/include/limitless/core/uniform/uniform_value.hpp +++ b/include/limitless/core/uniform/uniform_value.hpp @@ -30,6 +30,8 @@ namespace Limitless { UniformValue(std::string name, const T& value) noexcept; ~UniformValue() override = default; + + [[nodiscard]] std::unique_ptr clone() noexcept override; void set() override; diff --git a/include/limitless/fx/effect_renderer.hpp b/include/limitless/fx/effect_renderer.hpp index 64bab9cc..af1ed621 100644 --- a/include/limitless/fx/effect_renderer.hpp +++ b/include/limitless/fx/effect_renderer.hpp @@ -7,12 +7,12 @@ #include namespace Limitless { - class AbstractInstance; + class Instance; class UniformSetter; class Context; class Assets; - using Instances = std::vector>; + using Instances = std::vector>; namespace ms { enum class Blending; diff --git a/include/limitless/instances/effect_instance.hpp b/include/limitless/instances/effect_instance.hpp index d826546f..ddef882c 100644 --- a/include/limitless/instances/effect_instance.hpp +++ b/include/limitless/instances/effect_instance.hpp @@ -1,12 +1,13 @@ #pragma once +#include +#include + +#include +#include #include #include #include -#include -#include -#include -#include namespace Limitless { namespace fx { @@ -26,7 +27,7 @@ namespace Limitless { /** * EffectInstance is a class that contains emitters describing some effect */ - class EffectInstance : public AbstractInstance { + class EffectInstance : public Instance { private: /** * Contains [emitter_name, emitter] @@ -65,7 +66,7 @@ namespace Limitless { /** * Makes a copy */ - std::unique_ptr clone() noexcept override; + std::unique_ptr clone() noexcept override; /** * Updates instance and then emitters diff --git a/include/limitless/instances/abstract_instance.hpp b/include/limitless/instances/instance.hpp similarity index 85% rename from include/limitless/instances/abstract_instance.hpp rename to include/limitless/instances/instance.hpp index 79f57344..bf29782a 100644 --- a/include/limitless/instances/abstract_instance.hpp +++ b/include/limitless/instances/instance.hpp @@ -22,7 +22,7 @@ namespace Limitless { /** * AbstractInstance is a base class that provides basic functionality for rendering objects */ - class AbstractInstance : public InstanceAttachment { + class Instance : public InstanceAttachment { private: static inline uint64_t next_id {1}; /** @@ -102,17 +102,17 @@ namespace Limitless { void updateModelMatrix() noexcept; void updateFinalMatrix() noexcept; - AbstractInstance(InstanceType shader_type, const glm::vec3& position) noexcept; + Instance(InstanceType shader_type, const glm::vec3& position) noexcept; public: - ~AbstractInstance() override = default; + ~Instance() override = default; - AbstractInstance(const AbstractInstance&); - AbstractInstance(AbstractInstance&&) = default; + Instance(const Instance&); + Instance(Instance&&) = default; /** * Makes instance copy */ - virtual std::unique_ptr clone() noexcept = 0; + virtual std::unique_ptr clone() noexcept = 0; [[nodiscard]] auto getInstanceType() const noexcept { return shader_type; } [[nodiscard]] auto getId() const noexcept { return id; } @@ -169,34 +169,34 @@ namespace Limitless { /** * Sets instance absolute position */ - virtual AbstractInstance& setPosition(const glm::vec3& position) noexcept; + virtual Instance& setPosition(const glm::vec3& position) noexcept; /** * Sets instance absolute rotation */ - virtual AbstractInstance& setRotation(const glm::quat& rotation) noexcept; + virtual Instance& setRotation(const glm::quat& rotation) noexcept; /** * Rotates instance with specified amount */ - virtual AbstractInstance& rotateBy(const glm::quat& rotation) noexcept; + virtual Instance& rotateBy(const glm::quat& rotation) noexcept; /** * Sets instance absolute scale */ - virtual AbstractInstance& setScale(const glm::vec3& scale) noexcept; + virtual Instance& setScale(const glm::vec3& scale) noexcept; /** * Sets current instance transformation matrix * * This is skeletal-transformation matrix used in bone attachments */ - virtual AbstractInstance& setTransformation(const glm::mat4& transformation); + virtual Instance& setTransformation(const glm::mat4& transformation); /** * Sets current instance parent matrix */ - virtual AbstractInstance& setParent(const glm::mat4& parent) noexcept; + virtual Instance& setParent(const glm::mat4& parent) noexcept; /** * Updates instance diff --git a/include/limitless/instances/instance_attachment.hpp b/include/limitless/instances/instance_attachment.hpp index de3c3c85..65c9c90b 100644 --- a/include/limitless/instances/instance_attachment.hpp +++ b/include/limitless/instances/instance_attachment.hpp @@ -7,7 +7,7 @@ #include namespace Limitless { - class AbstractInstance; + class Instance; class Context; class Camera; @@ -44,7 +44,7 @@ namespace Limitless { bool operator<(const AttachmentID& rhs) const; }; private: - std::map> attachments; + std::map> attachments; protected: /** * Sets parent matrix to attachments @@ -68,7 +68,7 @@ namespace Limitless { /** * Attaches instance */ - void attach(std::shared_ptr attachment); + void attach(std::shared_ptr attachment); /** * Detaches instance with specified id @@ -82,8 +82,8 @@ namespace Limitless { * * throws no_such_attachment if not found */ - [[nodiscard]] const AbstractInstance& getAttachment(uint64_t id) const; - AbstractInstance& getAttachment(uint64_t id); + [[nodiscard]] const Instance& getAttachment(uint64_t id) const; + Instance& getAttachment(uint64_t id); auto& getAttachments() noexcept { return attachments; } [[nodiscard]] const auto& getAttachments() const noexcept { return attachments; } diff --git a/include/limitless/instances/instance_builder.hpp b/include/limitless/instances/instance_builder.hpp index b9393df0..830c192e 100644 --- a/include/limitless/instances/instance_builder.hpp +++ b/include/limitless/instances/instance_builder.hpp @@ -1,7 +1,8 @@ #pragma once -#include +#include #include +#include #include namespace Limitless { @@ -10,9 +11,10 @@ namespace Limitless { using std::runtime_error::runtime_error; }; - class AbstractInstance::Builder { + class Instance::Builder { private: - std::shared_ptr model_; + std::shared_ptr model_; + std::shared_ptr effect_; glm::quat rotation_ {1.0f, 0.0f, 0.0f, 0.0f}; glm::vec3 position_ {0.0f}; @@ -29,12 +31,12 @@ namespace Limitless { std::shared_ptr global_material; - std::vector> attachments; + std::vector> attachments; class SocketAttachment { public: std::string bone_name; - std::shared_ptr attachment; + std::shared_ptr attachment; }; std::vector bone_attachments; @@ -45,7 +47,12 @@ namespace Limitless { /** * Sets Model to building instance */ - Builder& model(const std::shared_ptr& model); + Builder& model(const std::shared_ptr& model); + + /** + * Sets Model to effect instance + */ + Builder& effect(const std::shared_ptr& effect); /** * Sets position to building instance @@ -85,17 +92,17 @@ namespace Limitless { /** * Attaches specified instance to building one */ - Builder& attach(const std::shared_ptr& instance); + Builder& attach(const std::shared_ptr& instance); /** * Attaches specified instance to bone */ - Builder& attach(const std::string& bone_name, const std::shared_ptr& instance); + Builder& attach(const std::string& bone_name, const std::shared_ptr& instance); /** * */ - std::shared_ptr build(); + std::shared_ptr build(); /** * @@ -106,5 +113,10 @@ namespace Limitless { * */ std::shared_ptr asSkeletal(); + + /** + * + */ + std::shared_ptr asEffect(); }; } \ No newline at end of file diff --git a/include/limitless/instances/instanced_instance.hpp b/include/limitless/instances/instanced_instance.hpp index d2893ca3..dd6fd067 100644 --- a/include/limitless/instances/instanced_instance.hpp +++ b/include/limitless/instances/instanced_instance.hpp @@ -6,12 +6,12 @@ namespace Limitless { template - class InstancedInstance : public AbstractInstance { + class InstancedInstance : public Instance { static_assert(std::is_same_v, "InstancedInstance for this typename is unimplemented!"); }; template<> - class InstancedInstance : public AbstractInstance { + class InstancedInstance : public Instance { protected: // contains instanced models std::vector> instances; @@ -60,19 +60,19 @@ namespace Limitless { } explicit InstancedInstance(InstanceType shader, const glm::vec3& position, uint32_t count) - : AbstractInstance(shader, position) { + : Instance(shader, position) { initializeBuffer(count); } public: explicit InstancedInstance(const glm::vec3& position, uint32_t count = 4) - : AbstractInstance(InstanceType::Instanced, position) { + : Instance(InstanceType::Instanced, position) { initializeBuffer(count); } ~InstancedInstance() override = default; InstancedInstance(const InstancedInstance& rhs) - : AbstractInstance(rhs.shader_type, rhs.position) { + : Instance(rhs.shader_type, rhs.position) { initializeBuffer(rhs.instances.size()); for (const auto& instance : rhs.instances) { instances.emplace_back((ModelInstance*)instance->clone().release()); @@ -80,7 +80,7 @@ namespace Limitless { } InstancedInstance(InstancedInstance&&) noexcept = default; - std::unique_ptr clone() noexcept override { + std::unique_ptr clone() noexcept override { return std::make_unique(*this); } @@ -106,7 +106,7 @@ namespace Limitless { return; } - AbstractInstance::update(context, camera); + Instance::update(context, camera); updateBuffer(context, camera); } diff --git a/include/limitless/instances/light_instance.hpp b/include/limitless/instances/light_instance.hpp index fbfa48a6..4c3682e2 100644 --- a/include/limitless/instances/light_instance.hpp +++ b/include/limitless/instances/light_instance.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/include/limitless/instances/model_instance.hpp b/include/limitless/instances/model_instance.hpp index 85494098..8512f0ad 100644 --- a/include/limitless/instances/model_instance.hpp +++ b/include/limitless/instances/model_instance.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include namespace Limitless { @@ -16,7 +16,7 @@ namespace Limitless { /** * ModelInstance is an instance that contains static model */ - class ModelInstance : public AbstractInstance { + class ModelInstance : public Instance { protected: std::map meshes; std::shared_ptr model; @@ -47,7 +47,7 @@ namespace Limitless { /** * Makes copy */ - std::unique_ptr clone() noexcept override; + std::unique_ptr clone() noexcept override; /** * Gets used model @@ -141,7 +141,7 @@ namespace Limitless { [[nodiscard]] const auto& getMeshes() const noexcept { return meshes; } auto& getMeshes() noexcept { return meshes; } - using AbstractInstance::draw; + using Instance::draw; void draw(Context& ctx, const Assets& assets, ShaderType shader_type, ms::Blending blending, const UniformSetter& uniform_setter) override; }; } \ No newline at end of file diff --git a/include/limitless/instances/skeletal_instance.hpp b/include/limitless/instances/skeletal_instance.hpp index 5eaf1ce8..49588fb5 100644 --- a/include/limitless/instances/skeletal_instance.hpp +++ b/include/limitless/instances/skeletal_instance.hpp @@ -70,7 +70,7 @@ namespace Limitless { /** * Makes instance copy */ - std::unique_ptr clone() noexcept override; + std::unique_ptr clone() noexcept override; /** * Updates current animation, socket attachments data and instance itself @@ -110,7 +110,7 @@ namespace Limitless { const auto& getBoneTransform() const noexcept { return bone_transform; } - using AbstractInstance::draw; + using Instance::draw; void draw(Context& ctx, const Assets& assets, ShaderType shader_type, ms::Blending blending, const UniformSetter& uniform_setter) override; }; } diff --git a/include/limitless/instances/socket_attachment.hpp b/include/limitless/instances/socket_attachment.hpp index aa65a6e1..0e2cd0f7 100644 --- a/include/limitless/instances/socket_attachment.hpp +++ b/include/limitless/instances/socket_attachment.hpp @@ -14,7 +14,7 @@ namespace Limitless { } namespace Limitless { - class AbstractInstance; + class Instance; /** * SocketAttachment is a class that allows you to attach instance to specific bones of SkeletalInstance */ @@ -64,7 +64,7 @@ namespace Limitless { * * throws no_such_bone if not found */ - void attachToBone(std::string bone_name, std::shared_ptr instance); + void attachToBone(std::string bone_name, std::shared_ptr instance); /** * Detaches instance from bone diff --git a/include/limitless/lighting/cascade_shadows.hpp b/include/limitless/lighting/cascade_shadows.hpp index d49738a0..bcfaec7a 100644 --- a/include/limitless/lighting/cascade_shadows.hpp +++ b/include/limitless/lighting/cascade_shadows.hpp @@ -9,7 +9,7 @@ namespace Limitless::fx { namespace Limitless { class Light; - class AbstractInstance; + class Instance; class ShaderProgram; class Renderer; class Camera; @@ -26,7 +26,7 @@ namespace Limitless { float ratio {}; }; - using Instances = std::vector>; + using Instances = std::vector>; class CascadeShadows final { private: diff --git a/include/limitless/lighting/lighting.hpp b/include/limitless/lighting/lighting.hpp index 167fbc02..15bb82a4 100644 --- a/include/limitless/lighting/lighting.hpp +++ b/include/limitless/lighting/lighting.hpp @@ -6,16 +6,6 @@ namespace Limitless { class Context; - /** - * light = Light::builder() - * .pos(p) - * .col(l) - * .build() - * - * Light& l = scene.add(light) - * Light* l = &scene.add(light) - */ - class Lighting final { private: /** diff --git a/include/limitless/pipeline/pipeline_pass.hpp b/include/limitless/pipeline/pipeline_pass.hpp index e455e41b..2afbe680 100644 --- a/include/limitless/pipeline/pipeline_pass.hpp +++ b/include/limitless/pipeline/pipeline_pass.hpp @@ -6,8 +6,8 @@ #include namespace Limitless { - class AbstractInstance; - using Instances = std::vector>; + class Instance; + using Instances = std::vector>; class RenderTarget; class UniformSetter; class Context; diff --git a/include/limitless/renderer/render_settings.hpp b/include/limitless/renderer/render_settings.hpp index 266f1b01..bbdd1099 100644 --- a/include/limitless/renderer/render_settings.hpp +++ b/include/limitless/renderer/render_settings.hpp @@ -32,7 +32,7 @@ namespace Limitless { /** * Screen Space Reflections */ - bool screen_space_reflections {false}; + bool screen_space_reflections {true}; SSR::Settings screen_space_reflections_settings; /** diff --git a/include/limitless/scene.hpp b/include/limitless/scene.hpp index 7a8fa885..8b936df8 100644 --- a/include/limitless/scene.hpp +++ b/include/limitless/scene.hpp @@ -1,79 +1,61 @@ #pragma once #include +#include +#include +#include +#include +#include #include #include #include namespace Limitless { - class AbstractInstance; - class Camera; - class Skybox; + class scene_exception : public std::runtime_error { + public: + using std::runtime_error::runtime_error; + }; - using Instances = std::vector>; + using Instances = std::vector>; /** * */ - class Scene { - public: - Lighting lighting; + class Scene final { private: - std::unordered_map> instances; + Lighting lighting; + std::unordered_map> instances; std::shared_ptr skybox; void removeDeadInstances() noexcept; public: explicit Scene(Context& context); - virtual ~Scene() = default; Scene(const Scene&) = delete; Scene(Scene&&) = delete; - /** - * Takes ownership of passed instance and manages it - */ - void add(AbstractInstance* instance); - - template - T& add(T* instance) noexcept { - static_assert(std::is_base_of_v, "Typename type must be base of AbstractInstance"); - - instances.emplace(instance->getId(), instance); - return *instance; - } - - template - T& add(Args&&... args) { - static_assert(std::is_base_of_v, "Typename type must be base of AbstractInstance"); - - T* instance = new T(std::forward(args)...); - instances.emplace(instance->getId(), instance); - return *instance; - } - + void add(const std::shared_ptr& instance); + void remove(const std::shared_ptr& instance); void remove(uint64_t id); + void removeAll(); - void clear(); - - AbstractInstance& operator[](uint64_t id) noexcept; - AbstractInstance& at(uint64_t id); - - auto& getSkybox() noexcept { return skybox; } - const auto& getSkybox() const noexcept { return skybox; } - void setSkybox(std::shared_ptr skybox); + std::shared_ptr getInstance(uint64_t id); + std::shared_ptr getModelInstance(uint64_t id); + std::shared_ptr getSkeletalInstance(uint64_t id); + std::shared_ptr getEffectInstance(uint64_t id); - virtual void update(Context& context, const Camera& camera); + const Lighting& getLighting() const noexcept; + Lighting& getLighting() noexcept; - auto begin() noexcept { return instances.begin(); } - auto begin() const noexcept { return instances.begin(); } + Light& add(Light&& light); + Light& add(const Light& light); - auto end() noexcept { return instances.end(); } - auto end() const noexcept { return instances.end(); } + const std::shared_ptr& getSkybox() const noexcept; + std::shared_ptr& getSkybox() noexcept; + void setSkybox(const std::shared_ptr& skybox); - auto& getInstances() noexcept { return instances; } - Instances getWrappers() noexcept; + Instances getInstances() const noexcept; - auto size() const noexcept { return instances.size(); } + void update(Context& context, const Camera& camera); }; } \ No newline at end of file diff --git a/include/limitless/util/color_picker.hpp b/include/limitless/util/color_picker.hpp index c2947a64..fd11d9cc 100644 --- a/include/limitless/util/color_picker.hpp +++ b/include/limitless/util/color_picker.hpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "limitless/core/uniform/uniform_setter.hpp" #include "limitless/core/shader/shader_program.hpp" #include diff --git a/include/limitless/util/sorter.hpp b/include/limitless/util/sorter.hpp index b3c472d4..bf8caf46 100644 --- a/include/limitless/util/sorter.hpp +++ b/include/limitless/util/sorter.hpp @@ -3,16 +3,16 @@ #include namespace Limitless { - class AbstractInstance; + class Instance; class Camera; struct FrontToBackSorter { const Camera& camera; - bool operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept; + bool operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept; }; struct BackToFrontSorter { const Camera& camera; - bool operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept; + bool operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept; }; } \ No newline at end of file diff --git a/shaders/functions/circle.glsl b/shaders/functions/circle.glsl deleted file mode 100644 index 089e61cd..00000000 --- a/shaders/functions/circle.glsl +++ /dev/null @@ -1,4 +0,0 @@ -float circle(in vec2 uv, in float r){ - vec2 dist = uv - vec2(0.5); - return 1.0 - smoothstep(r - (r * 0.3), r + (r * 0.3), dot(dist, dist) * 4.0); -} \ No newline at end of file diff --git a/shaders/functions/fresnel.glsl b/shaders/functions/fresnel.glsl deleted file mode 100644 index c2592bcc..00000000 --- a/shaders/functions/fresnel.glsl +++ /dev/null @@ -1,3 +0,0 @@ -float fresnel(vec3 normal, vec3 view, float power) { - return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0)), power); -} \ No newline at end of file diff --git a/shaders/functions/hue_shift.glsl b/shaders/functions/hue_shift.glsl deleted file mode 100644 index f452297c..00000000 --- a/shaders/functions/hue_shift.glsl +++ /dev/null @@ -1,5 +0,0 @@ -vec3 hue_shift(vec3 color, float hue) { - const vec3 k = vec3(0.57735, 0.57735, 0.57735); - float cosAngle = cos(hue); - return vec3(color * cosAngle + cross(k, color) * sin(hue) + k * dot(k, color) * (1.0 - cosAngle)); -} \ No newline at end of file diff --git a/shaders/functions/linearize_depth.glsl b/shaders/functions/linearize_depth.glsl deleted file mode 100644 index 02e60a2b..00000000 --- a/shaders/functions/linearize_depth.glsl +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Depth value in depth texture stored in [0, 1] range - * - * Normalized Device Coordinates for OpenGL in range [-1, 1] - * - */ -float linearize_depth(float depth, float near, float far) { - float z_n = 2.0 * depth - 1.0; - return 2.0 * near * far / (far + near - z_n * (far - near)); -} diff --git a/shaders/functions/reconstruct_position.glsl b/shaders/functions/reconstruct_position.glsl deleted file mode 100644 index b8fc8f0e..00000000 --- a/shaders/functions/reconstruct_position.glsl +++ /dev/null @@ -1,23 +0,0 @@ -#include "./linearize_depth.glsl" - -vec3 reconstructPosition(vec2 uv, float depth) { - vec4 p = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); - p = getViewProjectionInverse() * p; - return p.xyz / p.w; -} - -/** - * Reconstructs world position from depth - - * uv - normalized coordinates [0, 1] - * depth - normalized depth [0, 1] - * fov_scale2 - {2.0 * tan(getProjectionInverse()[0][0] / 2.0), - * 2.0 * tan(getProjectionInverse()[1][1] / 2.0)} - */ -vec3 reconstructViewSpacePosition(vec2 uv, float depth) { - vec2 fov_scale2 = 2.0 * vec2(tan(getProjectionInverse()[0][0] / 2.0), tan(getProjectionInverse()[1][1] / 2.0)); - - float z = linearize_depth(depth, getCameraNearPlane(), getCameraFarPlane()); - vec2 half_ndc = vec2(0.5) - uv; // multiplication * 2.0 done in fov_scale2 - return vec3(half_ndc * fov_scale2 * -z, -z); -} diff --git a/shaders/functions/tone_mapping.glsl b/shaders/functions/tone_mapping.glsl deleted file mode 100644 index 0f9b08c9..00000000 --- a/shaders/functions/tone_mapping.glsl +++ /dev/null @@ -1,3 +0,0 @@ -vec3 toneMapping(vec3 color, float exposure) { - return vec3(1.0) - exp(-color * exposure); -} diff --git a/shaders/pipeline/deferred/composite.frag b/shaders/pipeline/deferred/composite.frag deleted file mode 100644 index 6f8fc119..00000000 --- a/shaders/pipeline/deferred/composite.frag +++ /dev/null @@ -1,21 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings - -#include "../../functions/tone_mapping.glsl" - -in vec2 uv; - -out vec3 color; - -uniform sampler2D lightened; - -uniform sampler2D bloom; -uniform float bloom_strength; - -void main() { - vec3 bloom_color = texture(bloom, uv).rgb * bloom_strength; - color = texture(lightened, uv).rgb + bloom_color; - - color = toneMapping(color, 1.0); -} \ No newline at end of file diff --git a/shaders/pipeline/deferred/composite.vert b/shaders/pipeline/deferred/composite.vert deleted file mode 100644 index 719e0736..00000000 --- a/shaders/pipeline/deferred/composite.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout (location = 0) in vec3 vertex_position; -layout (location = 1) in vec2 vertex_uv; - -out vec2 uv; - -void main() { - uv = vertex_uv; - gl_Position = vec4(vertex_position, 1.0); -} \ No newline at end of file diff --git a/shaders/pipeline/deferred/deferred.frag b/shaders/pipeline/deferred/deferred.frag deleted file mode 100644 index 05d689cd..00000000 --- a/shaders/pipeline/deferred/deferred.frag +++ /dev/null @@ -1,49 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings - -#include "../scene.glsl" -#include "../shading/shading.glsl" -#include "../../functions/reconstruct_position.glsl" -#include "../../functions/gamma_correction.glsl" - -#include "./gbuffer_input.glsl" - -in vec2 uv; - -out vec3 color; - -#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) - uniform sampler2D ssao_texture; -#endif - -//TODO: refactor - separate responsibilities - -#ifdef SCREEN_SPACE_REFLECTIONS - uniform sampler2D ssr_texture; - uniform float _ssr_strength; -#endif - -void main() { - // sample parameters from textures - vec3 P = reconstructPosition(uv, texture(depth_texture, uv).r); - vec3 normal = texture(normal_texture, uv).rgb; - vec4 base = texture(base_texture, uv).rgba; - vec3 props = texture(props_texture, uv).rgb; - float roughness = props.r; - float metallic = props.g; - uint shading_model = uint(props.b * 255.0); - -#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) - base.a *= texture(ssao_texture, uv).r; -#endif - - color = getFragmentColor(base.rgb, base.a, normal, P, metallic, roughness, shading_model); - color += texture(emissive_texture, uv).rgb; - // just add for now for test - -#ifdef SCREEN_SPACE_REFLECTIONS - // TODO: move to indirect lighting - color += texture(ssr_texture, uv).rgb *_ssr_strength; -#endif -} diff --git a/shaders/pipeline/deferred/deferred.vert b/shaders/pipeline/deferred/deferred.vert deleted file mode 100644 index 006f91b9..00000000 --- a/shaders/pipeline/deferred/deferred.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout (location = 0) in vec3 vertex_position; -layout (location = 1) in vec2 vertex_uv; - -out vec2 uv; - -void main() { - uv = vertex_uv; - gl_Position = vec4(vertex_position, 1.0); -} diff --git a/shaders/pipeline/deferred/depth.frag b/shaders/pipeline/deferred/depth.frag deleted file mode 100644 index 404cb620..00000000 --- a/shaders/pipeline/deferred/depth.frag +++ /dev/null @@ -1,15 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../interface_block/fragment.glsl" - -#include "../scene.glsl" -#include "../shading/depth_discarder.glsl" - -void main() { - discardForDepth(); -} diff --git a/shaders/pipeline/deferred/depth.vert b/shaders/pipeline/deferred/depth.vert deleted file mode 100644 index d7dd5a05..00000000 --- a/shaders/pipeline/deferred/depth.vert +++ /dev/null @@ -1,38 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../vertex_streams/vertex_stream.glsl" -#include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" -#include "../scene.glsl" -#include "../instance/instance.glsl" -#include "../material/material.glsl" -#include "../interface_block/pass_through.glsl" - -void main() { - #if !defined (SpriteEmitter) - vec2 uv = getVertexUV(); - #else - vec2 uv = vec2(0.0); - #endif - - vec3 vertex_position = getVertexPosition(); - - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET - - mat4 model_transform = getModelTransform(); - - vec4 world_position = model_transform * vec4(vertex_position, 1.0); - - #if !defined (MATERIAL_TESSELATION_FACTOR) - gl_Position = getViewProjection() * world_position; - #endif - - InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); -} diff --git a/shaders/pipeline/deferred/gbuffer.frag b/shaders/pipeline/deferred/gbuffer.frag deleted file mode 100644 index 2606c8fb..00000000 --- a/shaders/pipeline/deferred/gbuffer.frag +++ /dev/null @@ -1,29 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../interface_block/fragment.glsl" -#include "../scene.glsl" -#include "../shading/fragment.glsl" - -#include "./gbuffer_output.glsl" - -void main() { - FragmentData data = initializeFragmentData(); - - customFragment(data); - - g_base.rgb = getFragmentBaseColor(data).rgb; - g_base.a = getFragmentAO(data); - - g_normal = getFragmentNormal(data); - - g_props.r = data.roughness; - g_props.g = data.metallic; - g_props.b = float(data.shading_model) / 255.0; - - g_emissive = getFragmentEmissive(data); -} diff --git a/shaders/pipeline/deferred/gbuffer.vert b/shaders/pipeline/deferred/gbuffer.vert deleted file mode 100644 index d7dd5a05..00000000 --- a/shaders/pipeline/deferred/gbuffer.vert +++ /dev/null @@ -1,38 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../vertex_streams/vertex_stream.glsl" -#include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" -#include "../scene.glsl" -#include "../instance/instance.glsl" -#include "../material/material.glsl" -#include "../interface_block/pass_through.glsl" - -void main() { - #if !defined (SpriteEmitter) - vec2 uv = getVertexUV(); - #else - vec2 uv = vec2(0.0); - #endif - - vec3 vertex_position = getVertexPosition(); - - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET - - mat4 model_transform = getModelTransform(); - - vec4 world_position = model_transform * vec4(vertex_position, 1.0); - - #if !defined (MATERIAL_TESSELATION_FACTOR) - gl_Position = getViewProjection() * world_position; - #endif - - InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); -} diff --git a/shaders/pipeline/deferred/gbuffer_input.glsl b/shaders/pipeline/deferred/gbuffer_input.glsl deleted file mode 100644 index e4f956de..00000000 --- a/shaders/pipeline/deferred/gbuffer_input.glsl +++ /dev/null @@ -1,17 +0,0 @@ -// UNSIGNED NORMALIZED [0; 1] -// RGBA8 - RGB - base color, A - ao - -// SIGNED NORMALIZED [-1; 1] -// RGB - normal - -// UNSIGNED NORMALIZED [0; 1] -// R - roughness, G - metallic, B - shading model (uint) - -// FLOATING POINT -// RGB - emissive - -uniform sampler2D base_texture; -uniform sampler2D normal_texture; -uniform sampler2D props_texture; -uniform sampler2D depth_texture; -uniform sampler2D emissive_texture; \ No newline at end of file diff --git a/shaders/pipeline/deferred/gbuffer_output.glsl b/shaders/pipeline/deferred/gbuffer_output.glsl deleted file mode 100644 index e76004f6..00000000 --- a/shaders/pipeline/deferred/gbuffer_output.glsl +++ /dev/null @@ -1,16 +0,0 @@ -// UNSIGNED NORMALIZED [0; 1] -// RGBA8 - RGB - base color, A - ao - -// SIGNED NORMALIZED [-1; 1] -// RGB - normal - -// UNSIGNED NORMALIZED [0; 1] -// R - roughness, G - metallic, B - shading model (uint) - -// FLOATING POINT -// RGB - emissive - -layout (location = 0) out vec4 g_base; -layout (location = 1) out vec3 g_normal; -layout (location = 2) out vec3 g_props; -layout (location = 3) out vec3 g_emissive; diff --git a/shaders/pipeline/deferred/skybox.frag b/shaders/pipeline/deferred/skybox.frag deleted file mode 100644 index def05296..00000000 --- a/shaders/pipeline/deferred/skybox.frag +++ /dev/null @@ -1,30 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType - -in vec3 skybox_uv; - -#include "../interface_block/fragment.glsl" -#include "../scene.glsl" -#include "../shading/fragment.glsl" - -#include "./gbuffer_output.glsl" - -void main() { - FragmentData data = initializeFragmentData(); - - customFragment(data); - - g_base.rgb = getFragmentBaseColor(data).rgb; - g_base.a = getFragmentAO(data); - - g_normal = getFragmentNormal(data); - - g_props.r = data.roughness; - g_props.g = data.metallic; - g_props.b = float(data.shading_model) / 255.0; - - g_emissive = getFragmentEmissive(data); -} diff --git a/shaders/pipeline/deferred/skybox.vert b/shaders/pipeline/deferred/skybox.vert deleted file mode 100644 index 914dfea5..00000000 --- a/shaders/pipeline/deferred/skybox.vert +++ /dev/null @@ -1,32 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType - -#include "../vertex_streams/vertex_stream.glsl" -#include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" -#include "../scene.glsl" -#include "../instance/instance.glsl" -#include "../material/material.glsl" -#include "../interface_block/pass_through.glsl" - -out vec3 skybox_uv; - -void main() { - vec2 uv = vec2(0.0); - - vec3 vertex_position = getVertexPosition(); - - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET - - skybox_uv = getVertexPosition(); - - vec4 pos = getProjection() * mat4(mat3(getView())) * vec4(vertex_position, 1.0); - gl_Position = pos.xyww; - - InterfaceBlockPassThrough(pos.xyw, uv, getModelTransform()); -} \ No newline at end of file diff --git a/shaders/pipeline/forward/forward.frag b/shaders/pipeline/forward/forward.frag deleted file mode 100644 index 6c632a1e..00000000 --- a/shaders/pipeline/forward/forward.frag +++ /dev/null @@ -1,20 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../interface_block/fragment.glsl" -#include "../scene.glsl" -#include "../shading/fragment.glsl" - -out vec4 color; - -void main() { - FragmentData data = initializeFragmentData(); - - customFragment(data); - - color = computeFragment(data); -} \ No newline at end of file diff --git a/shaders/pipeline/forward/forward.vert b/shaders/pipeline/forward/forward.vert deleted file mode 100644 index d7dd5a05..00000000 --- a/shaders/pipeline/forward/forward.vert +++ /dev/null @@ -1,38 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../vertex_streams/vertex_stream.glsl" -#include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" -#include "../scene.glsl" -#include "../instance/instance.glsl" -#include "../material/material.glsl" -#include "../interface_block/pass_through.glsl" - -void main() { - #if !defined (SpriteEmitter) - vec2 uv = getVertexUV(); - #else - vec2 uv = vec2(0.0); - #endif - - vec3 vertex_position = getVertexPosition(); - - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET - - mat4 model_transform = getModelTransform(); - - vec4 world_position = model_transform * vec4(vertex_position, 1.0); - - #if !defined (MATERIAL_TESSELATION_FACTOR) - gl_Position = getViewProjection() * world_position; - #endif - - InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); -} diff --git a/shaders/pipeline/instance/instance.glsl b/shaders/pipeline/instance/instance.glsl deleted file mode 100644 index c3f1deae..00000000 --- a/shaders/pipeline/instance/instance.glsl +++ /dev/null @@ -1,40 +0,0 @@ -#if defined (SIMPLE_MODEL) || defined (SKELETAL_MODEL) - #include "./model.glsl" -#endif - -#if defined (SKELETAL_MODEL) - #include "./skeletal.glsl" -#endif - -#if defined (INSTANCED_MODEL) - #include "./instanced.glsl" -#endif - -#if defined (EFFECT_MODEL) && !defined (MeshEmitter) - mat4 getModelMatrix() { - return mat4(1.0); - } -#endif - -mat4 getModelTransform() { - #if defined (SKELETAL_MODEL) - return getModelMatrix() * getBoneMatrix(); - #else - return getModelMatrix(); - #endif -} - -// TBN matrix only for meshes -#if (defined (MeshEmitter) || defined (SIMPLE_MODEL) || defined (SKELETAL_MODEL) || defined (INSTANCED_MODEL)) && defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 getModelTBN(mat4 model_transform) { - //TODO: pass through uniform instance buffer ? bone transform ? - mat3 normal_matrix = transpose(inverse(mat3(model_transform))); - - vec3 T = normalize(normal_matrix * getVertexTangent()); - vec3 N = normalize(normal_matrix * getVertexNormal()); - T = normalize(T - dot(T, N) * N); - vec3 B = cross(N, T); - - return mat3(T, B, N); - } -#endif diff --git a/shaders/pipeline/instance/instanced.glsl b/shaders/pipeline/instance/instanced.glsl deleted file mode 100644 index ad6bd91c..00000000 --- a/shaders/pipeline/instance/instanced.glsl +++ /dev/null @@ -1,7 +0,0 @@ -layout (std430) buffer model_buffer { - mat4 _models[]; -}; - -mat4 getModelMatrix() { - return _models[gl_InstanceID]; -} diff --git a/shaders/pipeline/instance/model.glsl b/shaders/pipeline/instance/model.glsl deleted file mode 100644 index 3c00a9c4..00000000 --- a/shaders/pipeline/instance/model.glsl +++ /dev/null @@ -1,6 +0,0 @@ -//TODO: model buffer + bounds + more info -uniform mat4 _model_transform; - -mat4 getModelMatrix() { - return _model_transform; -} diff --git a/shaders/pipeline/instance/skeletal.glsl b/shaders/pipeline/instance/skeletal.glsl deleted file mode 100644 index be517592..00000000 --- a/shaders/pipeline/instance/skeletal.glsl +++ /dev/null @@ -1,15 +0,0 @@ -layout (std430) buffer bone_buffer { - mat4 _bones[]; -}; - -mat4 getBoneMatrix() { - ivec4 bone_id = getVertexBoneID(); - vec4 bone_weight = getVertexBoneWeight(); - - mat4 bone_transform = _bones[bone_id[0]] * bone_weight[0]; - bone_transform += _bones[bone_id[1]] * bone_weight[1]; - bone_transform += _bones[bone_id[2]] * bone_weight[2]; - bone_transform += _bones[bone_id[3]] * bone_weight[3]; - - return bone_transform; -} diff --git a/shaders/pipeline/interface_block/effect_fs.glsl b/shaders/pipeline/interface_block/effect_fs.glsl deleted file mode 100644 index df4651ea..00000000 --- a/shaders/pipeline/interface_block/effect_fs.glsl +++ /dev/null @@ -1,177 +0,0 @@ -in _vertex_data { - #if defined (InitialColor_MODULE) - vec4 color; - #endif - - #if defined (SubUV_MODULE) - vec4 subUV; - #endif - - #if defined (CustomMaterial_MODULE) - vec4 properties; - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - vec3 acceleration; - float lifetime; - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - #endif - - vec3 world_position; - - #if defined (SpriteEmitter) - float size; - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) - vec3 rotation; - float time; - #endif - - #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) - vec3 velocity; - #endif - - #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) - vec3 velocity; - float size; - #endif - - #if defined (MeshEmitter) - vec3 size; - #endif - - #if defined (BeamEmitter) || defined (MeshEmitter) - vec2 uv; - #endif - - #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - vec3 start; - vec3 end; - float length; - #endif -} _in_data; - -#if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - float getParticleLength() { - return _in_data.length; - } - - vec3 getParticleStart() { - return _in_data.start; - } - - vec3 getParticleEnd() { - return _in_data.end; - } -#endif - -#if defined (InitialColor_MODULE) - vec4 getParticleColor() { - return _in_data.color; - } -#endif - -#if defined (SubUV_MODULE) - vec4 getParticleSubUV() { - return _in_data.subUV; - } -#endif - -#if defined (CustomMaterial_MODULE) - vec4 getParticleProperties() { - return _in_data.properties; - } -#endif - -#if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - vec3 getParticleAcceleration() { - return _in_data.acceleration; - } - - float getParticleLifetime() { - return _in_data.lifetime; - } -#endif - -vec3 getVertexPosition() { - return _in_data.world_position; -} - -#if defined (SpriteEmitter) - float getParticleSize() { - return _in_data.size; - } -#endif - -#if defined (InitialRotation_MODULE) || defined (Time_MODULE) - vec3 getParticleRotation() { - return _in_data.rotation; - } - - float getParticleTime() { - return _in_data.time; - } -#endif - -#if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) - vec3 getParticleVelocity() { - return _in_data.velocity; - } -#endif - -#if defined (BeamEmitter) && defined (InitialVelocity_MODULE) - vec3 getParticleVelocity() { - return _in_data.velocity; - } - - float getParticleSize() { - return _in_data.size; - } -#endif - -#if defined (BeamEmitter) || defined (MeshEmitter) - vec2 getVertexUV() { - return _in_data.uv; - } -#endif - -#if defined (SpriteEmitter) - vec2 getVertexUV() { - vec2 uv = gl_PointCoord; - - #if defined (InitialRotation_MODULE) - vec2 center = vec2(0.5, 0.5); - vec2 translated = uv - center; - mat2 rotation = mat2(cos(getParticleRotation().x), sin(getParticleRotation().x), -sin(getParticleRotation().x), cos(getParticleRotation().x)); - translated = rotation * translated; - translated = translated + center; - uv = clamp(translated, 0.0, 1.0); - #endif - - #if defined (SubUV_MODULE) - uv = uv * getParticleSubUV().xy + getParticleSubUV().zw; - #endif - - return uv; - } -#endif - -#if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 getVertexTBN() { - return _in_data.TBN; - } - #else - vec3 getVertexNormal() { - return _in_data.normal; - } - #endif -#endif diff --git a/shaders/pipeline/interface_block/effect_vs.glsl b/shaders/pipeline/interface_block/effect_vs.glsl deleted file mode 100644 index 84e1c873..00000000 --- a/shaders/pipeline/interface_block/effect_vs.glsl +++ /dev/null @@ -1,60 +0,0 @@ -out _vertex_data { - #if defined (InitialColor_MODULE) - vec4 color; - #endif - - #if defined (SubUV_MODULE) - vec4 subUV; - #endif - - #if defined (CustomMaterial_MODULE) - vec4 properties; - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - vec3 acceleration; - float lifetime; - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - #endif - - vec3 world_position; - - #if defined (SpriteEmitter) - float size; - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) - vec3 rotation; - float time; - #endif - - #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) - vec3 velocity; - #endif - - #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) - vec3 velocity; - float size; - #endif - - #if defined (MeshEmitter) - vec3 size; - #endif - - #if defined (BeamEmitter) || defined (MeshEmitter) - vec2 uv; - #endif - - #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - vec3 start; - vec3 end; - float length; - #endif -} _out_data; diff --git a/shaders/pipeline/interface_block/fragment.glsl b/shaders/pipeline/interface_block/fragment.glsl deleted file mode 100644 index 2b95b1e0..00000000 --- a/shaders/pipeline/interface_block/fragment.glsl +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (EFFECT_MODEL) - #include "./effect_fs.glsl" -#else - #include "./mesh_fs.glsl" -#endif diff --git a/shaders/pipeline/interface_block/mesh_fs.glsl b/shaders/pipeline/interface_block/mesh_fs.glsl deleted file mode 100644 index 04f2f425..00000000 --- a/shaders/pipeline/interface_block/mesh_fs.glsl +++ /dev/null @@ -1,28 +0,0 @@ -in _vertex_data { - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - - vec3 world_position; - vec2 uv; -} _in_data; - -vec3 getVertexPosition() { - return _in_data.world_position; -} - -vec2 getVertexUV() { - return _in_data.uv; -} - -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 getVertexTBN() { - return _in_data.TBN; - } -#else - vec3 getVertexNormal() { - return _in_data.normal; - } -#endif diff --git a/shaders/pipeline/interface_block/mesh_vs.glsl b/shaders/pipeline/interface_block/mesh_vs.glsl deleted file mode 100644 index 4c088471..00000000 --- a/shaders/pipeline/interface_block/mesh_vs.glsl +++ /dev/null @@ -1,10 +0,0 @@ -out _vertex_data { - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - - vec3 world_position; - vec2 uv; -} _out_data; diff --git a/shaders/pipeline/interface_block/pass_through.glsl b/shaders/pipeline/interface_block/pass_through.glsl deleted file mode 100644 index 40b7edb2..00000000 --- a/shaders/pipeline/interface_block/pass_through.glsl +++ /dev/null @@ -1,75 +0,0 @@ -void InterfaceBlockPassThrough(vec3 world_position, vec2 uv, mat4 model_transform) { - #if defined (EFFECT_MODEL) - _out_data.world_position = world_position; - - #if !defined (SpriteEmitter) - _out_data.uv = uv; - #endif - - #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - _out_data.start = getParticleStart(); - _out_data.end = getParticleEnd(); - _out_data.length = getParticleLength(); - #endif - - #if defined (SpriteEmitter) - #if defined (InitialSize_MODULE) - gl_PointSize = getProjection()[1][1] * getParticleSize() / gl_Position.w; - #else - gl_PointSize = getProjection()[1][1] * 16.0 / gl_Position.w; - #endif - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - _out_data.TBN = getModelTBN(model_transform); - #else - _out_data.normal = transpose(inverse(mat3(model_transform))) * getVertexNormal(); - #endif - #endif - - #if defined (InitialColor_MODULE) - _out_data.color = getParticleColor(); - #endif - - #if defined (SubUV_MODULE) - _out_data.subUV = getParticleSubUV(); - #endif - - #if defined (CustomMaterial_MODULE) - _out_data.properties = getParticleProperties(); - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) - _out_data.rotation = getParticleRotation(); - _out_data.time = getParticleTime(); - #endif - - #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) - _out_data.velocity = getParticleVelocity(); - #endif - - #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_Module)) - _out_data.velocity = getParticleVelocity(); - _out_data.size = getParticleSize(); - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - _out_data.acceleration = getParticleAcceleration(); - _out_data.lifetime = getParticleLifetime(); - #endif - - #if defined (SpriteEmitter) - _out_data.size = getParticleSize(); - #endif - #else - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - _out_data.TBN = getModelTBN(model_transform); - #else - _out_data.normal = transpose(inverse(mat3(model_transform))) * getVertexNormal(); - #endif - - _out_data.world_position = world_position; - _out_data.uv = uv; - #endif -} diff --git a/shaders/pipeline/interface_block/tess_control_input.glsl b/shaders/pipeline/interface_block/tess_control_input.glsl deleted file mode 100644 index 837c09f9..00000000 --- a/shaders/pipeline/interface_block/tess_control_input.glsl +++ /dev/null @@ -1,196 +0,0 @@ -#if defined (EFFECT_MODEL) -in _vertex_data { -#if defined (InitialColor_MODULE) - vec4 color; - #endif - - #if defined (SubUV_MODULE) - vec4 subUV; - #endif - - #if defined (CustomMaterial_MODULE) - vec4 properties; - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - vec3 acceleration; - float lifetime; - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - #endif - - vec3 world_position; - - #if defined (SpriteEmitter) - float size; - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) - vec3 rotation; - float time; - #endif - - #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) - vec3 velocity; - #endif - - #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) - vec3 velocity; - float size; - #endif - - #if defined (MeshEmitter) - vec3 size; - #endif - - #if defined (BeamEmitter) || defined (MeshEmitter) - vec2 uv; - #endif - - #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - vec3 start; - vec3 end; - float length; - #endif -} _in_data[]; - -#if defined (BeamEmitter) && defined (BeamSpeed_MODULE) -float getParticleLength(uint id) { - return _in_data[id].length; -} - -vec3 getParticleStart(uint id) { - return _in_data[id].start; -} - -vec3 getParticleEnd(uint id) { - return _in_data[id].end; -} - #endif - - #if defined (InitialColor_MODULE) -vec4 getParticleColor(uint id) { - return _in_data[id].color; -} - #endif - - #if defined (SubUV_MODULE) -vec4 getParticleSubUV(uint id) { - return _in_data[id].subUV; -} - #endif - - #if defined (CustomMaterial_MODULE) -vec4 getParticleProperties(uint id) { - return _in_data[id].properties; -} - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) -vec3 getParticleAcceleration(uint id) { - return _in_data[id].acceleration; -} - -float getParticleLifetime(uint id) { - return _in_data[id].lifetime; -} - #endif - -vec3 getVertexPosition(uint id) { - return _in_data[id].world_position; -} - - #if defined (SpriteEmitter) -float getParticleSize(uint id) { - return _in_data[id].size; -} - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) -vec3 getParticleRotation(uint id) { - return _in_data[id].rotation; -} - -float getParticleTime(uint id) { - return _in_data[id].time; -} - #endif - - #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) -vec3 getParticleVelocity(uint id) { - return _in_data[id].velocity; -} - #endif - - #if defined (BeamEmitter) && defined (InitialVelocity_MODULE) -vec3 getParticleVelocity(uint id) { - return _in_data[id].velocity; -} - -float getParticleSize(uint id) { - return _in_data[id].size; -} - #endif - - #if defined (BeamEmitter) || defined (MeshEmitter) -vec2 getVertexUV(uint id) { - return _in_data[id].uv; -} - #endif - - #if defined (SpriteEmitter) -vec2 getVertexUV() { - vec2 uv = gl_PointCoord; - - return uv; -} - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) -mat3 getVertexTBN(uint id) { - return _in_data[id].TBN; -} - #else -vec3 getVertexNormal(uint id) { - return _in_data[id].normal; -} - #endif - #endif - - #else -in _vertex_data { -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - - vec3 world_position; - vec2 uv; -} _in_data[]; - -vec3 getVertexPosition(uint id) { - return _in_data[id].world_position; -} - -vec2 getVertexUV(uint id) { - return _in_data[id].uv; -} - - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) -mat3 getVertexTBN(uint id) { - return _in_data[id].TBN; -} - #else -vec3 getVertexNormal(uint id) { - return _in_data[id].normal; -} - #endif - #endif \ No newline at end of file diff --git a/shaders/pipeline/interface_block/tess_control_output.glsl b/shaders/pipeline/interface_block/tess_control_output.glsl deleted file mode 100644 index 17180000..00000000 --- a/shaders/pipeline/interface_block/tess_control_output.glsl +++ /dev/null @@ -1,74 +0,0 @@ -#if defined (EFFECT_MODEL) - out _vertex_data { - #if defined (InitialColor_MODULE) - vec4 color; - #endif - - #if defined (SubUV_MODULE) - vec4 subUV; - #endif - - #if defined (CustomMaterial_MODULE) - vec4 properties; - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - vec3 acceleration; - float lifetime; - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - #endif - - vec3 world_position; - - #if defined (SpriteEmitter) - float size; - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) - vec3 rotation; - float time; - #endif - - #if (defined (SpriteEmitter) || defined (MeshEmitter)) && defined (InitialVelocity_MODULE) - vec3 velocity; - #endif - - #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_MODULE)) - vec3 velocity; - float size; - #endif - - #if defined (MeshEmitter) - vec3 size; - #endif - - #if defined (BeamEmitter) || defined (MeshEmitter) - vec2 uv; - #endif - - #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - vec3 start; - vec3 end; - float length; - #endif - } _out_data[]; - -#else - out _vertex_data { - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - mat3 TBN; - #else - vec3 normal; - #endif - - vec3 world_position; - vec2 uv; - } _out_data[]; -#endif \ No newline at end of file diff --git a/shaders/pipeline/interface_block/tess_control_pass.glsl b/shaders/pipeline/interface_block/tess_control_pass.glsl deleted file mode 100644 index 07a8d7d1..00000000 --- a/shaders/pipeline/interface_block/tess_control_pass.glsl +++ /dev/null @@ -1,69 +0,0 @@ -void InterfaceBlockPassThrough() { - uint index = uint(gl_InvocationID); - -#if defined (EFFECT_MODEL) - _out_data[gl_InvocationID].world_position = getVertexPosition(index); - - #if !defined (SpriteEmitter) - _out_data[gl_InvocationID].uv = getVertexUV(index); - #endif - - #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - _out_data[gl_InvocationID].start = getParticleStart(index); - _out_data[gl_InvocationID].end = getParticleEnd(index); - _out_data[gl_InvocationID].length = getParticleLength(index); - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - _out_data[gl_InvocationID].TBN = getVertexTBN(index); - #else - _out_data[gl_InvocationID].normal = getVertexNormal(index); - #endif - #endif - - #if defined (InitialColor_MODULE) - _out_data[gl_InvocationID].color = getParticleColor(index); - #endif - - #if defined (SubUV_MODULE) - _out_data[gl_InvocationID].subUV = getParticleSubUV(index); - #endif - - #if defined (CustomMaterial_MODULE) - _out_data[gl_InvocationID].properties = getParticleProperties(index); - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) - _out_data[gl_InvocationID].rotation = getParticleRotation(index); - _out_data[gl_InvocationID].time = getParticleTime(index); - #endif - - #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) - _out_data[gl_InvocationID].velocity = getParticleVelocity(index); - #endif - - #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_Module)) - _out_data[gl_InvocationID].velocity = getParticleVelocity(index); - _out_data[gl_InvocationID].size = getParticleSize(index); - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - _out_data[gl_InvocationID].acceleration = getParticleAcceleration(index); - _out_data[gl_InvocationID].lifetime = getParticleLifetime(index); - #endif - - #if defined (SpriteEmitter) - _out_data[gl_InvocationID].size = getParticleSize(index); - #endif -#else - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - _out_data[gl_InvocationID].TBN = getVertexTBN(index); - #else - _out_data[gl_InvocationID].normal = getVertexNormal(index); - #endif - - _out_data[gl_InvocationID].world_position = getVertexPosition(index); - _out_data[gl_InvocationID].uv = getVertexUV(index); -#endif -} diff --git a/shaders/pipeline/interface_block/vertex.glsl b/shaders/pipeline/interface_block/vertex.glsl deleted file mode 100644 index fd16e727..00000000 --- a/shaders/pipeline/interface_block/vertex.glsl +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (EFFECT_MODEL) - #include "./effect_vs.glsl" -#else - #include "./mesh_vs.glsl" -#endif diff --git a/shaders/pipeline/lighting/ambient.glsl b/shaders/pipeline/lighting/ambient.glsl deleted file mode 100644 index e2a60780..00000000 --- a/shaders/pipeline/lighting/ambient.glsl +++ /dev/null @@ -1,4 +0,0 @@ -vec3 getAmbientLighting(vec3 albedo, float ao) { - vec4 ambient = getAmbientColor(); - return (ambient.rgb * albedo) * (ambient.a * ao); -} \ No newline at end of file diff --git a/shaders/pipeline/lighting/directional_csm.glsl b/shaders/pipeline/lighting/directional_csm.glsl deleted file mode 100644 index 273d40e6..00000000 --- a/shaders/pipeline/lighting/directional_csm.glsl +++ /dev/null @@ -1,65 +0,0 @@ -#if defined (DIRECTIONAL_CSM) - layout (std140) buffer directional_shadows { - mat4 _dir_light_space[]; - }; - - uniform sampler2DArray _dir_shadows; - uniform vec4 _far_bounds; - - int getShadowFrustumIndex(vec3 position) { - vec4 p = getViewProjection() * vec4(position, 1.0); - p.xyz /= p.w; - - float z = p.z * 0.5 + 0.5; - - int index = DIRECTIONAL_SPLIT_COUNT; - for (int i = 0; i < DIRECTIONAL_SPLIT_COUNT; ++i) { - if (z < _far_bounds[i]) { - index = i; - break; - } - } - - return index; - } - - float getDirectionalShadow(vec3 normal, vec3 world_pos) { - DirectionalLight light = getDirectionalLight(); - - int index = getShadowFrustumIndex(world_pos); - - mat4 light_space = _dir_light_space[index]; - - // transforming from global space to ndc light space - vec4 light_pos_space = light_space * vec4(world_pos, 1.0); -// vec3 ndc = light_pos_space.xyz / light_pos_space.w; ?????????/ - vec3 ndc = light_pos_space.xyz; - ndc = ndc * 0.5 + 0.5; - - if (ndc.z > 1.0) { - return 0.0; - } - - float closestDepth = texture(_dir_shadows, vec3(ndc.xy, index)).r; - float currentDepth = ndc.z; - - float shadow = 0.0; - const float MIN_BIAS = 0.0005; - float bias = max(0.05 * (1.0 - dot(normal, vec3(-light.direction.xyz))), MIN_BIAS); - - #if defined (DIRECTIONAL_PFC) - vec2 texelSize = 1.0 / textureSize(_dir_shadows, 0).xy; - for (int x = -1; x <= 1; ++x) { - for (int y = -1; y <= 1; ++y) { - float pcfDepth = texture(_dir_shadows, vec3(ndc.xy + vec2(x, y) * texelSize, index)).r; - shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; - } - } - shadow /= 9.0; - #else - shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0; - #endif - - return shadow; - } -#endif diff --git a/shaders/pipeline/lighting/directional_light.glsl b/shaders/pipeline/lighting/directional_light.glsl deleted file mode 100644 index 51f667a2..00000000 --- a/shaders/pipeline/lighting/directional_light.glsl +++ /dev/null @@ -1,30 +0,0 @@ -#include "./directional_csm.glsl" - -vec3 computeDirectionalLight(const LightingContext context) { - DirectionalLight light = getDirectionalLight(); - - vec3 L = normalize(-light.direction.xyz); - vec3 H = normalize(context.V + L); - - float NoL = saturate(dot(context.N, L)); - float NoH = saturate(dot(context.N, H)); - float LoH = saturate(dot(L, H)); - - vec3 Fd = DiffuseBRDF(context.diffuseColor, context.roughness, context.NoV, NoL, LoH); - vec3 Fr = SpecularBRDF(context.roughness, NoH, context.NoV, NoL, LoH, H, context.F0, context.a2); - - vec3 color = Fd + Fr; - - float visibility = 1.0; - - #if defined (DIRECTIONAL_CSM) - float shadow = getDirectionalShadow(context.N, context.worldPos); - visibility *= (1.0 - shadow); - #endif - - #if defined (MICRO_SHADOWING) - visibility *= computeMicroShadowing(NoL, context.ambientOcclusion); - #endif - - return (color * light.color.rgb) * (light.color.a * NoL * visibility); -} diff --git a/shaders/pipeline/lighting/directional_shadows.frag b/shaders/pipeline/lighting/directional_shadows.frag deleted file mode 100644 index 55be82c0..00000000 --- a/shaders/pipeline/lighting/directional_shadows.frag +++ /dev/null @@ -1,14 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../interface_block/fragment.glsl" -#include "../scene.glsl" -#include "../shading/depth_discarder.glsl" - -void main() { - discardForDepth(); -} diff --git a/shaders/pipeline/lighting/directional_shadows.vert b/shaders/pipeline/lighting/directional_shadows.vert deleted file mode 100644 index 63ffd878..00000000 --- a/shaders/pipeline/lighting/directional_shadows.vert +++ /dev/null @@ -1,40 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../vertex_streams/vertex_stream.glsl" -#include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" -#include "../scene.glsl" -#include "../instance/instance.glsl" -#include "../material/material.glsl" -#include "../interface_block/pass_through.glsl" - -uniform mat4 light_space; - -void main() { - #if !defined (SpriteEmitter) - vec2 uv = getVertexUV(); - #else - vec2 uv = vec2(0.0); - #endif - - vec3 vertex_position = getVertexPosition(); - - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET - - mat4 model_transform = getModelTransform(); - - vec4 world_position = model_transform * vec4(vertex_position, 1.0); - - #if !defined (MATERIAL_TESSELATION_FACTOR) - gl_Position = light_space * world_position; - #endif - - InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); -} diff --git a/shaders/pipeline/lighting/lighting_context.glsl b/shaders/pipeline/lighting/lighting_context.glsl deleted file mode 100644 index 1b94d19b..00000000 --- a/shaders/pipeline/lighting/lighting_context.glsl +++ /dev/null @@ -1,41 +0,0 @@ -struct LightingContext { - vec3 diffuseColor; - float metallic; - - vec3 worldPos; - float roughness; - - vec3 N; - float a2; - - vec3 V; - float NoV; - - vec3 F0; - float ambientOcclusion; -}; - -LightingContext computeLightingContext(const vec3 baseColor, float metallic, - const vec3 worldPos, float roughness, - const vec3 N, float ambientOcclusion) { - LightingContext context; - - context.metallic = saturate(metallic); - context.diffuseColor = computeDiffuseColor(baseColor, context.metallic); - - context.worldPos = worldPos; - - float perceptualRoughness = clamp(roughness, MIN_PERCEPTUAL_ROUGHNESS, 1.0); - context.roughness = perceptualRoughness * perceptualRoughness; - - context.N = N; - context.a2 = context.roughness * context.roughness; - - context.V = normalize(getCameraPosition() - context.worldPos); - context.NoV = computeNoV(context.N, context.V); - - context.F0 = computeF0(baseColor, context.metallic, 1.0); - context.ambientOcclusion = ambientOcclusion; - - return context; -} diff --git a/shaders/pipeline/lighting/point_light.glsl b/shaders/pipeline/lighting/point_light.glsl deleted file mode 100644 index d0fae26b..00000000 --- a/shaders/pipeline/lighting/point_light.glsl +++ /dev/null @@ -1,43 +0,0 @@ -struct PointLight { - vec4 position; - vec4 color; - float constant; - float linear; - float quadratic; - float radius; -}; - -layout (std140) buffer POINT_LIGHTS_BUFFER { - PointLight _point_lights[]; -}; - -vec3 computePointLight(const LightingContext context, const PointLight light) { - vec3 L = normalize(light.position.xyz - context.worldPos); - vec3 H = normalize(context.V + L); - - float NoL = saturate(dot(context.N, L)); - float NoH = saturate(dot(context.N, H)); - float LoH = saturate(dot(L, H)); - - vec3 Fd = DiffuseBRDF(context.diffuseColor, context.roughness, context.NoV, NoL, LoH); - vec3 Fr = SpecularBRDF(context.roughness, NoH, context.NoV, NoL, LoH, H, context.F0, context.a2); - - vec3 color = Fd + Fr; - - float distance = length(light.position.xyz - context.worldPos); - float attenuation = 1.0 / (distance * distance * light.quadratic); - - float visibility = 1.0; - return (color * light.color.rgb) * (light.color.a * NoL * visibility * attenuation); -} - -vec3 computePointLight(const LightingContext context) { - vec3 pointLight = vec3(0.0); - for (uint i = 0u; i < getPointLightsCount(); ++i) { - float l = length(_point_lights[i].position.xyz - context.worldPos); - if (l <= _point_lights[i].radius) { - pointLight += computePointLight(context, _point_lights[i]); - } - } - return pointLight; -} diff --git a/shaders/pipeline/lighting/scene_lighting.glsl b/shaders/pipeline/lighting/scene_lighting.glsl deleted file mode 100644 index 1d2e56e6..00000000 --- a/shaders/pipeline/lighting/scene_lighting.glsl +++ /dev/null @@ -1,32 +0,0 @@ -struct DirectionalLight { - vec4 direction; - vec4 color; -}; - -layout (std140) buffer scene_lighting { - DirectionalLight _dir_light; - vec4 _ambient_color; - uint _point_lights_count; - uint _dir_lights_count; - uint _spot_lights_count; -}; - -DirectionalLight getDirectionalLight() { - return _dir_light; -} - -vec4 getAmbientColor() { - return _ambient_color; -} - -uint getPointLightsCount() { - return _point_lights_count; -} - -uint getDirectionalLightsCount() { - return _dir_lights_count; -} - -uint getSpotLightsCount() { - return _spot_lights_count; -} diff --git a/shaders/pipeline/lighting/spot_light.glsl b/shaders/pipeline/lighting/spot_light.glsl deleted file mode 100644 index 6e9445ae..00000000 --- a/shaders/pipeline/lighting/spot_light.glsl +++ /dev/null @@ -1,48 +0,0 @@ -struct SpotLight { - vec4 position; - vec4 direction; - vec4 color; - float cutoff; - float radius; -}; - -layout (std140) buffer SPOT_LIGHTS_BUFFER { - SpotLight _spot_lights[]; -}; - -vec3 computeSpotLight(const LightingContext context, const SpotLight light) { - vec3 L = normalize(light.position.xyz - context.worldPos); - float factor = dot(L, -light.direction.xyz); - - vec3 lighting = vec3(0.0); - if (factor > light.cutoff) { - vec3 H = normalize(context.V + L); - - float NoL = saturate(dot(context.N, L)); - float NoH = saturate(dot(context.N, H)); - float LoH = saturate(dot(L, H)); - - vec3 Fd = DiffuseBRDF(context.diffuseColor, context.roughness, context.NoV, NoL, LoH); - vec3 Fr = SpecularBRDF(context.roughness, NoH, context.NoV, NoL, LoH, H, context.F0, context.a2); - - vec3 color = Fd + Fr; - - float distance = length(light.position.xyz - context.worldPos); - float attenuation = 1.0 / (distance * distance); - - lighting = (color * light.color.rgb) * (light.color.a * attenuation * NoL * factor); - } - - return lighting; -} - -vec3 computeSpotLight(const LightingContext context) { - vec3 direct_light = vec3(0.0); - for (uint i = 0u; i < getSpotLightsCount(); ++i) { - float l = length(_spot_lights[i].position.xyz - context.worldPos); - if (l <= _spot_lights[i].radius) { - direct_light += computeSpotLight(context, _spot_lights[i]); - } - } - return direct_light; -} diff --git a/shaders/pipeline/material/buffer.glsl b/shaders/pipeline/material/buffer.glsl deleted file mode 100644 index 58614756..00000000 --- a/shaders/pipeline/material/buffer.glsl +++ /dev/null @@ -1,255 +0,0 @@ -/* - !!!order of buffer variables should match Limitless::ms::Property!!! - - functions to get material properties - - uint getMaterialShadingModel(); - - vec4 getMaterialColor(); - vec3 getMaterialEmissive(); - - vec4 getMaterialDiffuse(vec2 uv); - vec3 getMaterialNormal(vec2 uv); - vec3 getMaterialDisplacement(vec2 uv); - - vec2 getMaterialTesselationFactor(); - - vec3 getMaterialEmissiveMask(vec2 uv); - float getMaterialBlendMask(vec2 uv); - float getMaterialMetallic(vec2 uv); - float getMaterialRoughness(vec2 uv); - - float getMaterialMetallic(); - float getMaterialRoughness(); - float getMaterialIoR(); - float getMaterialAbsorption(); - -*/ - -layout (std140) uniform material_buffer { - #if defined (MATERIAL_COLOR) - vec4 _material_color; - #endif - - #if defined (MATERIAL_EMISSIVE_COLOR) - vec4 _material_emissive; - #endif - - #if defined (BINDLESS_TEXTURE) - #if defined (MATERIAL_DIFFUSE) - sampler2D material_diffuse; - #endif - - #if defined (MATERIAL_NORMAL) - sampler2D material_normal; - #endif - - #if defined (MATERIAL_EMISSIVEMASK) - sampler2D material_emissive_mask; - #endif - - #if defined (MATERIAL_BLENDMASK) - sampler2D material_blend_mask; - #endif - - #if defined (MATERIAL_METALLIC_TEXTURE) - sampler2D material_metallic_texture; - #endif - - #if defined (MATERIAL_ROUGHNESS_TEXTURE) - sampler2D material_roughness_texture; - #endif - - #if defined (MATERIAL_AMBIENT_OCCLUSION_TEXTURE) - sampler2D material_ambient_occlusion_texture; - #endif - - #if defined (MATERIAL_ORM_TEXTURE) - sampler2D material_orm_texture; - #endif - - #if defined (MATERIAL_DISPLACEMENT) - sampler2D material_displacement; - #endif - #endif - - #if defined (MATERIAL_TESSELLATION_FACTOR) - vec2 _material_tessellation_factor; - #endif - - #if defined (MATERIAL_METALLIC) - float _material_metallic; - #endif - - #if defined (MATERIAL_ROUGHNESS) - float _material_roughness; - #endif - - #if defined (MATERIAL_REFRACTION) - #if defined (MATERIAL_IOR) - float _material_ior; - #endif - - #if defined (MATERIAL_ABSORPTION) - float _material_absorption; - #endif - #endif - - #if defined (BINDLESS_TEXTURE) - _MATERIAL_SAMPLER_UNIFORMS - #endif - - _MATERIAL_SCALAR_UNIFORMS - - uint _material_shading_model; -}; - -#if !defined (BINDLESS_TEXTURE) - #if defined (MATERIAL_DIFFUSE) - uniform sampler2D material_diffuse; - #endif - - #if defined (MATERIAL_NORMAL) - uniform sampler2D material_normal; - #endif - - #if defined (MATERIAL_DISPLACEMENT) - uniform sampler2D material_displacement; - #endif - - #if defined (MATERIAL_EMISSIVEMASK) - uniform sampler2D material_emissive_mask; - #endif - - #if defined (MATERIAL_BLENDMASK) - uniform sampler2D material_blend_mask; - #endif - - #if defined (MATERIAL_METALLIC_TEXTURE) - uniform sampler2D material_metallic_texture; - #endif - - #if defined (MATERIAL_ROUGHNESS_TEXTURE) - uniform sampler2D material_roughness_texture; - #endif - - #if defined (MATERIAL_AMBIENT_OCCLUSION_TEXTURE) - uniform sampler2D material_ambient_occlusion_texture; - #endif - - #if defined (MATERIAL_ORM_TEXTURE) - uniform sampler2D material_orm_texture; - #endif - - _MATERIAL_SAMPLER_UNIFORMS -#endif - -_MATERIAL_GLOBAL_DEFINITIONS - -uint getMaterialShadingModel() { - return _material_shading_model; -} - -#if defined (MATERIAL_COLOR) - vec4 getMaterialColor() { - return _material_color; - } -#endif - -#if defined (MATERIAL_EMISSIVE_COLOR) - vec3 getMaterialEmissive() { - return _material_emissive.rgb; - } -#endif - -#if defined (MATERIAL_TESSELLATION_FACTOR) - vec2 getMaterialTesselationFactor() { - return _material_tessellation_factor; - } -#endif - -#if defined (MATERIAL_SHININESS) - float getMaterialShininess() { - return _material_shininess; - } -#endif - -#if defined (MATERIAL_METALLIC) -float getMaterialMetallic() { - return _material_metallic; -} -#endif - -#if defined (MATERIAL_ROUGHNESS) -float getMaterialRoughness() { - return _material_roughness; -} -#endif - -#if defined (MATERIAL_AMBIENT_OCCLUSION_TEXTURE) - float getMaterialAmbientOcclusion(vec2 uv) { - return texture(material_ambient_occlusion_texture, uv).r; - } -#endif - -#if defined (MATERIAL_ORM_TEXTURE) - vec3 getMaterialORM(vec2 uv) { - return texture(material_orm_texture, uv).rgb; - } -#endif - -#if defined (MATERIAL_REFRACTION) - #if defined (MATERIAL_IOR) - float getMaterialIOR() { - return _material_ior; - } - #endif - - #if defined (MATERIAL_ABSORPTION) - float getMaterialAbsorption() { - return _material_absorption; - } - #endif -#endif - -#if defined (MATERIAL_DIFFUSE) - vec4 getMaterialDiffuse(vec2 uv) { - return texture(material_diffuse, uv); - } -#endif - -#if defined (MATERIAL_NORMAL) - vec3 getMaterialNormal(vec2 uv) { - return texture(material_normal, uv).xyz; - } -#endif - -#if defined (MATERIAL_DISPLACEMENT) - vec3 getMaterialDisplacement(vec2 uv) { - return texture(material_displacement, uv).rgb; - } -#endif - -#if defined (MATERIAL_EMISSIVEMASK) - vec3 getMaterialEmissiveMask(vec2 uv) { - return texture(material_emissive_mask, uv).rgb; - } -#endif - -#if defined (MATERIAL_BLENDMASK) - float getMaterialBlendMask(vec2 uv) { - return texture(material_blend_mask, uv).r; - } -#endif - -#if defined (MATERIAL_METALLIC_TEXTURE) - float getMaterialMetallic(vec2 uv) { - return texture(material_metallic_texture, uv).r; - } -#endif - -#if defined (MATERIAL_ROUGHNESS_TEXTURE) - float getMaterialRoughness(vec2 uv) { - return texture(material_roughness_texture, uv).r; - } -#endif diff --git a/shaders/pipeline/material/custom_fragment.glsl b/shaders/pipeline/material/custom_fragment.glsl deleted file mode 100644 index a5be0415..00000000 --- a/shaders/pipeline/material/custom_fragment.glsl +++ /dev/null @@ -1,3 +0,0 @@ -void customFragment(inout FragmentData data) { - _MATERIAL_FRAGMENT_SNIPPET -} diff --git a/shaders/pipeline/material/material.glsl b/shaders/pipeline/material/material.glsl deleted file mode 100644 index d484ef0c..00000000 --- a/shaders/pipeline/material/material.glsl +++ /dev/null @@ -1,2 +0,0 @@ -#include "./buffer.glsl" -#include "./shading.glsl" diff --git a/shaders/pipeline/material/shading.glsl b/shaders/pipeline/material/shading.glsl deleted file mode 100644 index 826689e7..00000000 --- a/shaders/pipeline/material/shading.glsl +++ /dev/null @@ -1,12 +0,0 @@ -/* - should match Limitless::ms::Shading -*/ - -#define LIT_SHADING 0u -#define UNLIT_SHADING 1u - -#define SHADING_LIT_REGULAR -#define SHADING_LIT_CLOTH -#define SHADING_LIT_SUBSURFACE -#define SHADING_UNLIT -#define SHADING_CUSTOM diff --git a/shaders/pipeline/quad.frag b/shaders/pipeline/quad.frag deleted file mode 100644 index cd9a884b..00000000 --- a/shaders/pipeline/quad.frag +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -in vec2 uv; - -out vec3 color; - -uniform sampler2D screen_texture; - -void main() { - color = texture(screen_texture, uv).rgb; -} \ No newline at end of file diff --git a/shaders/pipeline/quad.vert b/shaders/pipeline/quad.vert deleted file mode 100644 index 719e0736..00000000 --- a/shaders/pipeline/quad.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout (location = 0) in vec3 vertex_position; -layout (location = 1) in vec2 vertex_uv; - -out vec2 uv; - -void main() { - uv = vertex_uv; - gl_Position = vec4(vertex_position, 1.0); -} \ No newline at end of file diff --git a/shaders/pipeline/shading/brdf.glsl b/shaders/pipeline/shading/brdf.glsl deleted file mode 100644 index 6e4b4f25..00000000 --- a/shaders/pipeline/shading/brdf.glsl +++ /dev/null @@ -1,107 +0,0 @@ -// "An Inexpensive BRDF Model for Physically-Based Rendering", Schlick 1994 -vec3 F_Schlick(const vec3 F0, float F90, float VoH) { - return F0 + (F90 - F0) * pow5(1.0 - VoH); -} - -vec3 F_Schlick(const vec3 F0, float VoH) { - return F0 + (vec3(1.0) - F0) * pow5(1.0 - VoH); -} - -float F_Schlick(float F0, float f90, float VoH) { - return F0 + (f90 - F0) * pow5(1.0 - VoH); -} - -// "Microfacet Models for Refraction through Rough Surfaces", Walter et al. 2007 -float D_GGX(float roughness, float NoH) { - float oneMinusNoHSquared = 1.0 - NoH * NoH; - float a = NoH * roughness; - float k = roughness / (oneMinusNoHSquared + a * a); - float d = k * k * (1.0 / PI); - return d; -} - -// "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", Heitz 2014 -float V_SmithGGXCorrelated(float NoV, float NoL, float a2, float lambdaV) { - float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2); - return 0.5 / (lambdaV + lambdaL); -} - -// Hammon 2017, "PBR Diffuse Lighting for GGX+Smith Microsurfaces" -float V_SmithGGXCorrelatedFast(float roughness, float NoV, float NoL) { - float v = 0.5 / mix(2.0 * NoL * NoV, NoL + NoV, roughness); - return v; -} - -vec3 SpecularF(const vec3 F0, float LoH) { -#if defined (ENGINE_MATERIAL_QUALITY_LOW) - return F_Schlick(F0, LoH); -#else - float F90 = saturate(dot(F0, vec3(50.0 * 0.33))); - return F_Schlick(F0, F90, LoH); -#endif -} - -// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF" -float D_Charlie(float roughness, float NoH) { - float invAlpha = 1.0 / roughness; - float cos2h = NoH * NoH; - float sin2h = max(1.0 - cos2h, 0.0078125); // 2^(-14/2), so sin2h^2 > 0 in fp16 - return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI); -} - -// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886" -float V_Neubelt(float NoV, float NoL) { - return 1.0 / (4.0 * (NoL + NoV - NoL * NoV)); -} - -// "Physically-Based Shading at Disney", Burley 2012 -float Fd_Burley(float roughness, float NoV, float NoL, float LoH) { - float F90 = 0.5 + 2.0 * roughness * LoH * LoH; - float lightScatter = F_Schlick(1.0, F90, NoL); - float viewScatter = F_Schlick(1.0, F90, NoV); - return lightScatter * viewScatter * (1.0 / PI); -} - -float Fd_Lambert() { - return 1.0 / PI; -} - -// Energy conserving wrap diffuse term, does *not* include the divide by pi -float Fd_Wrap(float NoL, float w) { - float w1 = 1.0 + w; - float x = w1 * w1; - return (NoL + w) / x; -} - -vec3 DiffuseBRDF(const ShadingContext sctx, const LightingContext lctx) { -#if defined (ENGINE_MATERIAL_DIFFUSE_BURLEY) - return sctx.diffuseColor * Fd_Burley(sctx.roughness, sctx.NoV, lctx.NoL, lctx.LoH); -#elif defined (ENGINE_MATERIAL_DIFFUSE_LAMBERT) - return sctx.diffuseColor * Fd_Lambert(); -#endif -} - -vec3 SpecularBRDF(const ShadingContext sctx, const LightingContext lctx) { - float D = D_GGX(sctx.roughness, lctx.NoH); -#if defined (ENGINE_MATERIAL_SPECULAR_GGX) - float V = V_SmithGGXCorrelated(sctx.NoV, lctx.NoL, sctx.a2, lctxlambdaV); -#elif defined (ENGINE_MATERIAL_SPECULAR_GGX_FAST) - float V = V_SmithGGXCorrelatedFast(sctx.roughness, sctx.NoV, lctx.NoL); -#endif - vec3 F = SpecularF(sctx.F0, lctx.LoH); - return (D * V) * F; -} - -vec3 DiffuseBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { - vec3 diffuse = DiffuseBRDF(sctx, lctx); -#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) - diffuse *= Fd_Wrap(lsctx.NoL, 0.5); -#endif - return diffuse; -} - -vec3 SpecularBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { - float D = D_Charlie(sctx.roughness, lctx.NoH); - float V = V_Neubelt(sctx.NoV, lctx.NoL); - return (D * V) * sctx.F0; -} diff --git a/shaders/pipeline/shading/common.glsl b/shaders/pipeline/shading/common.glsl deleted file mode 100644 index 2d6ba6da..00000000 --- a/shaders/pipeline/shading/common.glsl +++ /dev/null @@ -1,34 +0,0 @@ -#define PI 3.14159265359 -#define MIN_ROUGHNESS 0.002025 -#define MIN_PERCEPTUAL_ROUGHNESS 0.045 - -#define MIN_NoV 1e-4 - -float pow5(float x) { - float x2 = x * x; - return x2 * x2 * x; -} - -float saturate(float val) { - return clamp(val, 0.0, 1.0); -} - -vec3 computeDiffuseColor(const vec3 baseColor, float metallic) { - return baseColor * (1.0 - metallic); -} - -vec3 computeF0(const vec3 baseColor, float metallic, float reflectance) { - return baseColor * metallic + (reflectance * (1.0 - metallic)); -} - -float computeNoV(const vec3 N, const vec3 V) { - float NoV = saturate(dot(N, V)); - return max(MIN_NoV, NoV); -} - -// "Material Advances in Call of Duty: WWII", Chan 2018 -float computeMicroShadowing(float NoL, float visibility) { - float aperture = inversesqrt(1.0 - visibility); - float microShadow = saturate(NoL * aperture); - return microShadow * microShadow; -} diff --git a/shaders/pipeline/shading/depth_discarder.glsl b/shaders/pipeline/shading/depth_discarder.glsl deleted file mode 100644 index 45e81f78..00000000 --- a/shaders/pipeline/shading/depth_discarder.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#include "./fragment.glsl" - -/* - this function is used when - fragment shader outputs only depth values - but material can discard some fragments based on properties - so we invoke this code -*/ - -void discardForDepth() { - FragmentData data = initializeFragmentData(); - customFragment(data); - getFragmentBaseColor(data); -} diff --git a/shaders/pipeline/shading/fragment.glsl b/shaders/pipeline/shading/fragment.glsl deleted file mode 100644 index 4db38e6f..00000000 --- a/shaders/pipeline/shading/fragment.glsl +++ /dev/null @@ -1,115 +0,0 @@ -#include "../material/material.glsl" -#include "./fragment_data.glsl" -#include "./fragment_data_initializer.glsl" - -vec4 getFragmentBaseColor(const FragmentData data) { - vec4 baseColor = vec4(1.0); - -#if defined (MATERIAL_COLOR) - baseColor *= data.color; -#endif - -#if defined (MATERIAL_DIFFUSE) - baseColor *= data.baseColor; -#endif - -#if defined (MATERIAL_BLENDMASK) - if (getMaterialBlendMask(getVertexUV()) == 0.0) { - discard; - } -#endif - -#if defined (EFFECT_MODEL) && defined (BeamEmitter) && defined (BeamSpeed_MODULE) - if (distance(getVertexPosition(), getParticleStart()) / distance(getParticleStart(), getParticleEnd()) >= getParticleLength()) { - discard; - } -#endif - -#if defined (EFFECT_MODEL) && defined (InitialColor_MODULE) - baseColor *= getParticleColor(); -#endif - - return baseColor; -} - -vec3 getFragmentNormal(const FragmentData data) { -#if defined (SpriteEmitter) || defined (BeamEmitter) - return getCameraPosition() - getVertexPosition(); -#else - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - vec3 normal = data.normal; - normal = normalize(normal * 2.0 - 1.0); - normal = normalize(getVertexTBN() * normal); - #else - vec3 normal = normalize(getVertexNormal()); - #endif - - return normal; -#endif -} - -/* - * It is for forward pipeline?? - */ -//#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) -// uniform sampler2D ssao_texture; -//#endif - -float getFragmentAO(const FragmentData data) { - float ao = 1.0; - -#if defined (MATERIAL_AMBIENT_OCCLUSION_TEXTURE) - ao = data.ao; -#endif - -//#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) -// ao = min(ao, texture(ssao_texture, getVertexUV()).r); -//#endif - - return ao; -} - -vec3 getFragmentEmissive(const FragmentData data) { -#if !defined (MATERIAL_EMISSIVE_COLOR) && !defined (MATERIAL_EMISSIVEMASK) - return vec3(0.0); -#else - vec3 emissive = vec3(1.0); - - #if defined (MATERIAL_EMISSIVE_COLOR) - emissive *= data.emissive; - #endif - - #if defined (MATERIAL_EMISSIVEMASK) - emissive *= data.emissive_mask; - #endif - - return emissive; -#endif -} - -#include "./shading.glsl" - -#if defined (MATERIAL_REFRACTION) - #include "./refraction.glsl" -#endif - -vec4 computeFragment(const FragmentData data) { - vec4 baseColor = getFragmentBaseColor(data); - vec3 normal = getFragmentNormal(data); - vec3 emissive = getFragmentEmissive(data); - float ao = getFragmentAO(data); - - vec4 color; - color.rgb = getFragmentColor(baseColor.rgb, ao, normal, getVertexPosition(), data.metallic, data.roughness, data.shading_model); - color.a = baseColor.a; - - #if defined (MATERIAL_REFRACTION) - color.rgb += computeRefraction(normal, data.metallic, baseColor.rgb, data.IoR, data.absorption); - #endif - - color.rgb += getFragmentEmissive(data); - - return color; -} - -#include "../material/custom_fragment.glsl" \ No newline at end of file diff --git a/shaders/pipeline/shading/fragment_data.glsl b/shaders/pipeline/shading/fragment_data.glsl deleted file mode 100644 index 74a67783..00000000 --- a/shaders/pipeline/shading/fragment_data.glsl +++ /dev/null @@ -1,47 +0,0 @@ -struct FragmentData { -#if defined (MATERIAL_COLOR) - vec4 color; -#endif - -#if defined (MATERIAL_EMISSIVE_COLOR) - vec3 emissive; -#endif - -#if defined (MATERIAL_DIFFUSE) - vec4 baseColor; -#endif - -#if defined (MATERIAL_NORMAL) - vec3 normal; -#endif - -#if defined (MATERIAL_EMISSIVEMASK) - vec3 emissive_mask; -#endif - -#if defined (MATERIAL_BLENDMASK) - float blend_mask; -#endif - - float metallic; - float roughness; - -#if defined (MATERIAL_AMBIENT_OCCLUSION_TEXTURE) || defined (MATERIAL_ORM_TEXTURE) - float ao; -#endif - -#if defined (MATERIAL_DISPLACEMENT) - vec3 displacement; -#endif - -#if defined (MATERIAL_TESSELLATION_FACTOR) - vec2 tessellation_factor; -#endif - -#if defined (MATERIAL_REFRACTION) - float IoR; - float absorption; -#endif - - uint shading_model; -}; diff --git a/shaders/pipeline/shading/fragment_data_initializer.glsl b/shaders/pipeline/shading/fragment_data_initializer.glsl deleted file mode 100644 index 553047d3..00000000 --- a/shaders/pipeline/shading/fragment_data_initializer.glsl +++ /dev/null @@ -1,83 +0,0 @@ -FragmentData initializeFragmentData() { - FragmentData data; - -#if defined (MATERIAL_COLOR) - data.color = getMaterialColor(); -#endif - -#if defined (MATERIAL_EMISSIVE_COLOR) - data.emissive = getMaterialEmissive(); -#endif - -#if defined (MATERIAL_DIFFUSE) - data.baseColor = getMaterialDiffuse(getVertexUV()); -#endif - -#if defined (MATERIAL_NORMAL) - data.normal = getMaterialNormal(getVertexUV()); -#endif - -#if defined (MATERIAL_EMISSIVEMASK) - data.emissive_mask = getMaterialEmissiveMask(getVertexUV()); -#endif - -#if defined (MATERIAL_BLENDMASK) - data.blend_mask = getMaterialBlendMask(getVertexUV()); -#endif - -#if defined (MATERIAL_ORM_TEXTURE) - vec3 _orm = getMaterialORM(getVertexUV()); -#endif - -#if defined (MATERIAL_ORM_TEXTURE) - data.metallic = _orm.b; -#elif defined (MATERIAL_METALLIC_TEXTURE) - data.metallic = getMaterialMetallic(getVertexUV()); -#elif defined (MATERIAL_METALLIC) - data.metallic = getMaterialMetallic(); -#else - data.metallic = 0.1; -#endif - -#if defined (MATERIAL_ORM_TEXTURE) - data.roughness = _orm.g; -#elif defined (MATERIAL_ROUGHNESS_TEXTURE) - data.roughness = getMaterialRoughness(getVertexUV()); -#elif defined (MATERIAL_ROUGHNESS) - data.roughness = getMaterialRoughness(); -#else - data.roughness = 0.8; -#endif - -#if defined (MATERIAL_ORM_TEXTURE) - data.ao = _orm.r; -#elif defined (MATERIAL_AMBIENT_OCCLUSION_TEXTURE) - data.ao = getMaterialAmbientOcclusion(getVertexUV()); -#endif - -#if defined (MATERIAL_DISPLACEMENT) - data.displacement = getMaterialDisplacement(getVertexUV()); -#endif - -#if defined (MATERIAL_TESSELLATION_FACTOR) - data.tessellation_factor = getMaterialTesselationFactor(); -#endif - -#if defined (MATERIAL_REFRACTION) - #if defined (MATERIAL_IOR) - data.IoR = getMaterialIOR(); - #else - data.IoR = 1.0; - #endif - - #if defined (MATERIAL_ABSORPTION) - data.absorption = getMaterialAbsorption(); - #else - data.absorption = 0.0; - #endif -#endif - - data.shading_model = getMaterialShadingModel(); - - return data; -} diff --git a/shaders/pipeline/shading/lit.glsl b/shaders/pipeline/shading/lit.glsl deleted file mode 100644 index a8224660..00000000 --- a/shaders/pipeline/shading/lit.glsl +++ /dev/null @@ -1,24 +0,0 @@ -#include "./common.glsl" -#include "./brdf.glsl" - -#include "../lighting/lighting_context.glsl" -#include "../lighting/scene_lighting.glsl" - -#include "../lighting/ambient.glsl" -#include "../lighting/directional_light.glsl" -#include "../lighting/point_light.glsl" -#include "../lighting/spot_light.glsl" - -vec3 litShading(const vec3 baseColor, float ao, const vec3 N, const vec3 P, float metallic, float roughness) { - LightingContext context = computeLightingContext(baseColor, metallic, P, roughness, N, ao); - - vec3 color = getAmbientLighting(baseColor, ao); - - color += computeDirectionalLight(context); - - color += computePointLight(context); - - color += computeSpotLight(context); - - return color; -} \ No newline at end of file diff --git a/shaders/pipeline/shading/refraction.glsl b/shaders/pipeline/shading/refraction.glsl deleted file mode 100644 index 1342cdab..00000000 --- a/shaders/pipeline/shading/refraction.glsl +++ /dev/null @@ -1,43 +0,0 @@ -uniform sampler2D refraction_texture; - -float f0ToIor(float f0) { - float r = sqrt(f0); - return (1.0 + r) / (1.0 - r); -} - -vec3 refractionSolidSphere(const vec3 N, vec3 r, float etaIR, float etaRI) { - float thickness = 0.5; - r = refract(r, N, etaIR); - float NoR = dot(N, r); - float d = thickness * -NoR; - vec3 position = vec3(getVertexPosition() + r * d); - return position; -} - -vec3 computeRefraction(const vec3 N, float metallic, const vec3 baseColor, float IoR, float absorption) { - #if !defined (MATERIAL_IOR) - vec3 F0 = computeF0(baseColor, metallic, 1.0); - IoR = f0ToIor(F0.g); - #endif - - const float airIor = 1.0; - - float etaIR = airIor / IoR; - float etaRI = IoR / airIor; - - vec3 p = refractionSolidSphere(N, -normalize(getCameraPosition() - getVertexPosition()), etaIR, etaRI); - vec4 p_cs = getViewProjection() * vec4(p, 1.0); - p_cs.xy = p_cs.xy * (0.5 / p_cs.w) + 0.5; - - vec3 Ft = texture(refraction_texture, p_cs.xy).rgb; - - #if !defined (MATERIAL_IOR) - Ft *= baseColor; - #endif - - #if defined (MATERIAL_ABSORPTION) - Ft *= 1.0 - absorption; - #endif - - return Ft; -} diff --git a/shaders/pipeline/shading/shading.glsl b/shaders/pipeline/shading/shading.glsl deleted file mode 100644 index 40a64a11..00000000 --- a/shaders/pipeline/shading/shading.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#include "../material/shading.glsl" -#include "./lit.glsl" -#include "./unlit.glsl" - -vec3 getFragmentColor(vec3 albedo, float ao, vec3 N, vec3 P, float metallic, float roughness, uint shading_model) { - switch (shading_model) { - case LIT_SHADING: - return litShading(albedo, ao, N, P, metallic, roughness); - case UNLIT_SHADING: - return unlitShading(albedo, ao); - default: - return vec3(0.0); - } -} \ No newline at end of file diff --git a/shaders/pipeline/shading/unlit.glsl b/shaders/pipeline/shading/unlit.glsl deleted file mode 100644 index 54fb60be..00000000 --- a/shaders/pipeline/shading/unlit.glsl +++ /dev/null @@ -1,3 +0,0 @@ -vec3 unlitShading(vec3 albedo, float ao) { - return getAmbientLighting(albedo, ao); -} \ No newline at end of file diff --git a/shaders/pipeline/util/color_picker.frag b/shaders/pipeline/util/color_picker.frag deleted file mode 100644 index ba19a61d..00000000 --- a/shaders/pipeline/util/color_picker.frag +++ /dev/null @@ -1,23 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../interface_block/fragment.glsl" -#include "../scene.glsl" -#include "../shading/depth_discarder.glsl" - -out vec3 color; - -uniform vec3 color_id; - -void main() { - discardForDepth(); - - color = color_id; -} - - - diff --git a/shaders/pipeline/util/color_picker.vert b/shaders/pipeline/util/color_picker.vert deleted file mode 100644 index d7dd5a05..00000000 --- a/shaders/pipeline/util/color_picker.vert +++ /dev/null @@ -1,38 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../vertex_streams/vertex_stream.glsl" -#include "../interface_block/vertex.glsl" -#include "../shading/common.glsl" -#include "../scene.glsl" -#include "../instance/instance.glsl" -#include "../material/material.glsl" -#include "../interface_block/pass_through.glsl" - -void main() { - #if !defined (SpriteEmitter) - vec2 uv = getVertexUV(); - #else - vec2 uv = vec2(0.0); - #endif - - vec3 vertex_position = getVertexPosition(); - - // %uv - // %vertex_position - _MATERIAL_VERTEX_SNIPPET - - mat4 model_transform = getModelTransform(); - - vec4 world_position = model_transform * vec4(vertex_position, 1.0); - - #if !defined (MATERIAL_TESSELATION_FACTOR) - gl_Position = getViewProjection() * world_position; - #endif - - InterfaceBlockPassThrough(world_position.xyz, uv, model_transform); -} diff --git a/shaders/pipeline/vertex_streams/beam_emitter.glsl b/shaders/pipeline/vertex_streams/beam_emitter.glsl deleted file mode 100644 index 834db8a6..00000000 --- a/shaders/pipeline/vertex_streams/beam_emitter.glsl +++ /dev/null @@ -1,88 +0,0 @@ -layout (location = 0) in vec4 vertex_position; - -vec3 getVertexPosition() { - return vertex_position.xyz; -} - -#if defined(InitialColor_MODULE) - layout (location = 1) in vec4 vertex_color; - - vec4 getParticleColor() { - return vertex_color; - } -#endif - -#if defined(SubUV_MODULE) - layout(location = 2) in vec4 vertex_subUV; - - vec4 getParticleSubUV() { - return vertex_subUV; - } -#endif - -#if defined(CustomMaterial_MODULE) - layout(location = 3) in vec4 vertex_properties; - - vec4 getParticleProperties() { - return vertex_properties; - } -#endif - -#if defined(Lifetime_MODULE) || defined(Acceleration_MODULE) - layout(location = 4) in vec4 vertex_acceleration_lifetime; - - vec3 getParticleAcceleration() { - return vertex_acceleration_lifetime.xyz; - } - - float getParticleLifetime() { - return vertex_acceleration_lifetime.w; - } -#endif - -#if defined(InitialRotation_MODULE) || defined(Time_MODULE) - layout(location = 5) in vec4 vertex_rotation_time; - - vec3 getParticleRotation() { - return vertex_rotation_time.xyz; - } - - float getParticleTime() { - return vertex_rotation_time.w; - } -#endif - -#if defined(InitialVelocity_MODULE) || defined(InitialSize_MODULE) - layout(location = 6) in vec4 vertex_velocity_size; - - vec3 getParticleVelocity() { - return vertex_velocity_size.xyz; - } - - float getParticleSize() { - return vertex_velocity_size.w; - } -#endif - -layout (location = 7) in vec4 vertex_uv_length; - -vec2 getVertexUV() { - return vertex_uv_length.xy; -} - -float getParticleLength() { - return vertex_uv_length.z; -} - -#if defined(BeamSpeed_MODULE) - layout (location = 8) in vec3 vertex_start; - layout (location = 9) in vec3 vertex_end; - - vec3 getParticleStart() { - return vertex_start; - } - - vec3 getParticleEnd() { - return vertex_end; - } -#endif diff --git a/shaders/pipeline/vertex_streams/mesh_emitter.glsl b/shaders/pipeline/vertex_streams/mesh_emitter.glsl deleted file mode 100644 index 3e3e51de..00000000 --- a/shaders/pipeline/vertex_streams/mesh_emitter.glsl +++ /dev/null @@ -1,61 +0,0 @@ -#include "./model_mesh.glsl" - -struct MeshParticle { - mat4 model; - vec4 color; - vec4 subUV; - vec4 properties; - vec4 acceleration_lifetime; - vec4 position; - vec4 rotation_time; - vec4 velocity; - vec4 size; -}; - -layout (std430) buffer mesh_emitter_particles { - MeshParticle _particles[]; -}; - -mat4 getModelMatrix() { - return _particles[gl_InstanceID].model; -} - -vec4 getParticleColor() { - return _particles[gl_InstanceID].color; -} - -vec4 getParticleSubUV() { - return _particles[gl_InstanceID].subUV; -} - -vec4 getParticleProperties() { - return _particles[gl_InstanceID].properties; -} - -vec3 getParticleAcceleration() { - return _particles[gl_InstanceID].acceleration_lifetime.xyz; -} - -float getParticleLifetime() { - return _particles[gl_InstanceID].acceleration_lifetime.w; -} - -vec3 getParticlePosition() { - return _particles[gl_InstanceID].position.xyz; -} - -vec3 getParticleSize() { - return _particles[gl_InstanceID].size.xyz; -} - -vec3 getParticleRotation() { - return _particles[gl_InstanceID].rotation_time.xyz; -} - -float getParticleTime() { - return _particles[gl_InstanceID].rotation_time.w; -} - -vec3 getParticleVelocity() { - return _particles[gl_InstanceID].velocity.xyz; -} diff --git a/shaders/pipeline/vertex_streams/model_mesh.glsl b/shaders/pipeline/vertex_streams/model_mesh.glsl deleted file mode 100644 index 1bc0aea0..00000000 --- a/shaders/pipeline/vertex_streams/model_mesh.glsl +++ /dev/null @@ -1,38 +0,0 @@ -layout (location = 0) in vec3 _vertex_position; -layout (location = 1) in vec3 _vertex_normal; -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - layout (location = 2) in vec3 _vertex_tangent; -#endif -layout (location = 3) in vec2 _vertex_uv; -#if defined (SKELETAL_MODEL) - layout (location = 4) in ivec4 _vertex_bone_id; - layout (location = 5) in vec4 _vertex_bone_weight; -#endif - -vec3 getVertexPosition() { - return _vertex_position; -} - -vec3 getVertexNormal() { - return _vertex_normal; -} - -vec2 getVertexUV() { - return _vertex_uv; -} - -#if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - vec3 getVertexTangent() { - return _vertex_tangent; - } -#endif - -#if defined (SKELETAL_MODEL) - ivec4 getVertexBoneID() { - return _vertex_bone_id; - } - - vec4 getVertexBoneWeight() { - return _vertex_bone_weight; - } -#endif diff --git a/shaders/pipeline/vertex_streams/sprite_emitter.glsl b/shaders/pipeline/vertex_streams/sprite_emitter.glsl deleted file mode 100644 index b48641fb..00000000 --- a/shaders/pipeline/vertex_streams/sprite_emitter.glsl +++ /dev/null @@ -1,65 +0,0 @@ -#if defined(InitialColor_MODULE) - layout(location = 0) in vec4 vertex_color; - - vec4 getParticleColor() { - return vertex_color; - } -#endif - -#if defined(SubUV_MODULE) - layout(location = 1) in vec4 vertex_subUV; - - vec4 getParticleSubUV() { - return vertex_subUV; - } -#endif - -#if defined(CustomMaterial_MODULE) - layout(location = 2) in vec4 vertex_properties; - - vec4 getParticleProperties() { - return vertex_properties; - } -#endif - -#if defined(Lifetime_MODULE) || defined(Acceleration_MODULE) - layout(location = 3) in vec4 vertex_acceleration_lifetime; - - vec3 getParticleAcceleration() { - return vertex_acceleration_lifetime.xyz; - } - - float getParticleLifetime() { - return vertex_acceleration_lifetime.w; - } -#endif - -layout (location = 4) in vec4 vertex_position_size; - -vec3 getVertexPosition() { - return vertex_position_size.xyz; -} - -float getParticleSize() { - return vertex_position_size.w; -} - -#if defined (InitialRotation_MODULE) || defined (Time_MODULE) - layout(location = 5) in vec4 vertex_rotation_time; - - vec3 getParticleRotation() { - return vertex_rotation_time.xyz; - } - - float getParticleTime() { - return vertex_rotation_time.w; - } -#endif - -#if defined(InitialVelocity_MODULE) - layout(location = 6) in vec4 vertex_velocity; - - vec3 getParticleVelocity() { - return vertex_velocity.xyz; - } -#endif diff --git a/shaders/pipeline/vertex_streams/vertex_stream.glsl b/shaders/pipeline/vertex_streams/vertex_stream.glsl deleted file mode 100644 index c0b8913b..00000000 --- a/shaders/pipeline/vertex_streams/vertex_stream.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#if defined (EFFECT_MODEL) - #if defined (SpriteEmitter) - #include "./sprite_emitter.glsl" - #endif - - #if defined (BeamEmitter) - #include "./beam_emitter.glsl" - #endif - - #if defined (MeshEmitter) - #include "./mesh_emitter.glsl" - #endif -#else - #include "./model_mesh.glsl" -#endif diff --git a/shaders/postprocessing/bloom/blur_downsample.frag b/shaders/postprocessing/bloom/blur_downsample.frag deleted file mode 100644 index b0e033b4..00000000 --- a/shaders/postprocessing/bloom/blur_downsample.frag +++ /dev/null @@ -1,62 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -in vec2 uv; - -out vec3 color; - -uniform sampler2D source; -uniform float level; - -float max3(const vec3 v) { - return max(v.x, max(v.y, v.z)); -} - -vec3 box4x4(vec3 s0, vec3 s1, vec3 s2, vec3 s3) { - return (s0 + s1 + s2 + s3) * 0.25; -} - -vec3 box4x4Reinhard(vec3 s0, vec3 s1, vec3 s2, vec3 s3) { - float w0 = 1.0 / (1.0 + max3(s0)); - float w1 = 1.0 / (1.0 + max3(s1)); - float w2 = 1.0 / (1.0 + max3(s2)); - float w3 = 1.0 / (1.0 + max3(s3)); - return (s0 * w0 + s1 * w1 + s2 * w2 + s3 * w3) * (1.0 / (w0 + w1 + w2 + w3)); -} - -void main() { - vec3 c = textureLod(source, uv, level).rgb; - - vec3 lt = textureLodOffset(source, uv, level, ivec2(-1, -1)).rgb; - vec3 rt = textureLodOffset(source, uv, level, ivec2( 1, -1)).rgb; - vec3 rb = textureLodOffset(source, uv, level, ivec2( 1, 1)).rgb; - vec3 lb = textureLodOffset(source, uv, level, ivec2(-1, 1)).rgb; - - vec3 lt2 = textureLodOffset(source, uv, level, ivec2(-2, -2)).rgb; - vec3 rt2 = textureLodOffset(source, uv, level, ivec2( 2, -2)).rgb; - vec3 rb2 = textureLodOffset(source, uv, level, ivec2( 2, 2)).rgb; - vec3 lb2 = textureLodOffset(source, uv, level, ivec2(-2, 2)).rgb; - - vec3 l = textureLodOffset(source, uv, level, ivec2(-2, 0)).rgb; - vec3 t = textureLodOffset(source, uv, level, ivec2( 0, -2)).rgb; - vec3 r = textureLodOffset(source, uv, level, ivec2( 2, 0)).rgb; - vec3 b = textureLodOffset(source, uv, level, ivec2( 0, 2)).rgb; - - vec3 c0, c1; - - if (level <= 0.5) { - c0 = box4x4Reinhard(lt, rt, rb, lb); - c1 = box4x4Reinhard(c, l, t, lt2); - c1 += box4x4Reinhard(c, r, t, rt2); - c1 += box4x4Reinhard(c, r, b, rb2); - c1 += box4x4Reinhard(c, l, b, lb2); - } else { - c0 = box4x4(lt, rt, rb, lb); - c1 = box4x4(c, l, t, lt2); - c1 += box4x4(c, r, t, rt2); - c1 += box4x4(c, r, b, rb2); - c1 += box4x4(c, l, b, lb2); - } - - color = c0 * 0.5 + c1 * 0.125; -} diff --git a/shaders/postprocessing/bloom/blur_downsample.vert b/shaders/postprocessing/bloom/blur_downsample.vert deleted file mode 100644 index b5d09096..00000000 --- a/shaders/postprocessing/bloom/blur_downsample.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout (location = 0) in vec3 v_position; -layout (location = 1) in vec2 v_uv; - -out vec2 uv; - -void main() { - uv = v_uv; - gl_Position = vec4(v_position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/bloom/blur_upsample.frag b/shaders/postprocessing/bloom/blur_upsample.frag deleted file mode 100644 index e4348d69..00000000 --- a/shaders/postprocessing/bloom/blur_upsample.frag +++ /dev/null @@ -1,26 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -in vec2 uv; - -out vec3 color; - -uniform sampler2D source; -uniform float level; -uniform vec4 resolution; - -void main() { - const float radius = 1.0; - vec4 d = vec4(resolution.zw, -resolution.zw) * radius; - vec3 c0, c1; - c0 = textureLod(source, uv + d.zw, level).rgb; - c0 += textureLod(source, uv + d.xw, level).rgb; - c0 += textureLod(source, uv + d.xy, level).rgb; - c0 += textureLod(source, uv + d.zy, level).rgb; - c0 += 4.0 * textureLod(source, uv, level).rgb; - c1 = textureLod(source, uv + vec2(d.z, 0.0), level).rgb; - c1 += textureLod(source, uv + vec2(0.0, d.w), level).rgb; - c1 += textureLod(source, uv + vec2(d.x, 0.0), level).rgb; - c1 += textureLod(source, uv + vec2( 0.0, d.y), level).rgb; - color = (c0 + 2.0 * c1) * (1.0 / 16.0); -} diff --git a/shaders/postprocessing/bloom/blur_upsample.vert b/shaders/postprocessing/bloom/blur_upsample.vert deleted file mode 100644 index b5d09096..00000000 --- a/shaders/postprocessing/bloom/blur_upsample.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout (location = 0) in vec3 v_position; -layout (location = 1) in vec2 v_uv; - -out vec2 uv; - -void main() { - uv = v_uv; - gl_Position = vec4(v_position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/bloom/brightness.frag b/shaders/postprocessing/bloom/brightness.frag deleted file mode 100644 index 7e09760d..00000000 --- a/shaders/postprocessing/bloom/brightness.frag +++ /dev/null @@ -1,14 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -out vec3 color; - -in vec2 fs_uv; - -uniform sampler2D image; -uniform float threshold; - -void main() { - vec3 source = texture(image, fs_uv).rgb; - color = max(vec3(0.0), source - vec3(threshold)); -} \ No newline at end of file diff --git a/shaders/postprocessing/bloom/brightness.vert b/shaders/postprocessing/bloom/brightness.vert deleted file mode 100644 index 7a044439..00000000 --- a/shaders/postprocessing/bloom/brightness.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout(location = 0) in vec3 position; -layout(location = 1) in vec2 uv; - -out vec2 fs_uv; - -void main() { - fs_uv = uv; - gl_Position = vec4(position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/dof.frag b/shaders/postprocessing/dof.frag deleted file mode 100644 index c0dcc370..00000000 --- a/shaders/postprocessing/dof.frag +++ /dev/null @@ -1,33 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -#include "../pipeline/scene.glsl" -#include "../functions/reconstruct_position.glsl" - -in vec2 fs_uv; - -out vec3 color; - -uniform sampler2D depth_texture; -uniform sampler2D focus_texture; -uniform sampler2D unfocus_texture; - -uniform vec2 uv_focus; -uniform vec2 distance; - -void main() { - vec2 uv = fs_uv; - - float far = getCameraFarPlane(); - - vec3 position = reconstructPosition(uv, texture(depth_texture, uv).r); - - vec3 focus_position = reconstructPosition(uv_focus, texture(depth_texture, uv_focus).r); - - vec3 uf = texture(unfocus_texture, uv).rgb; - vec3 f = texture(focus_texture, uv).rgb; - - float blur = smoothstep(distance.x, distance.y, length(position - focus_position)); - - color = mix(f, uf, blur); -} \ No newline at end of file diff --git a/shaders/postprocessing/dof.vert b/shaders/postprocessing/dof.vert deleted file mode 100644 index abb57776..00000000 --- a/shaders/postprocessing/dof.vert +++ /dev/null @@ -1,13 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout(location = 0) in vec3 position; -layout(location = 1) in vec2 uv; - -out vec2 fs_uv; - -void main() -{ - fs_uv = uv; - gl_Position = vec4(position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/fxaa.frag b/shaders/postprocessing/fxaa.frag deleted file mode 100644 index eb82b167..00000000 --- a/shaders/postprocessing/fxaa.frag +++ /dev/null @@ -1,14 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -in vec2 uv; - -out vec3 color; - -uniform sampler2D scene; - -#include "../functions/fxaa.glsl" - -void main() { - color = fxaaProcess(scene, uv); -} \ No newline at end of file diff --git a/shaders/postprocessing/fxaa.vert b/shaders/postprocessing/fxaa.vert deleted file mode 100644 index ba2e8301..00000000 --- a/shaders/postprocessing/fxaa.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout(location = 0) in vec3 vertex_position; -layout(location = 1) in vec2 vertex_uv; - -out vec2 uv; - -void main() { - uv = vertex_uv; - gl_Position = vec4(vertex_position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/postprocess.frag b/shaders/postprocessing/postprocess.frag deleted file mode 100644 index 85eaa9ff..00000000 --- a/shaders/postprocessing/postprocess.frag +++ /dev/null @@ -1,81 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -in vec2 fs_uv; - -out vec4 color; - -uniform sampler2D image; -uniform sampler2D image_depth; - -uniform bool bloom; -uniform sampler2D bloom_image; - -uniform bool gamma_correction; -uniform float gamma; - -uniform bool tone_mapping; -uniform float exposure; - -uniform bool vignette; -uniform float vignette_radius; -uniform float vignette_softness; - -uniform bool tone_shading; -uniform float number_of_colors; -uniform float line_texel_offset; -uniform float line_multiplier; -uniform float line_bias; - -uniform bool fxaa; - -#include "../glsl/fxaa.glsl" - -void main() -{ - vec3 scene_color = texture(image, fs_uv).rgb; - float scene_depth = texture(image_depth, fs_uv).r; - vec2 resolution = textureSize(image, 0); - - if (fxaa) { - scene_color = fxaaProcess(image, fs_uv); - } - - if (bloom) { - scene_color += texture(bloom_image, fs_uv).rgb; - } - - if (tone_mapping) { - scene_color = vec3(1.0) - exp(-scene_color * exposure); - } - - if (gamma_correction) { - scene_color = pow(scene_color, vec3(1.0 / gamma)); - } - - if (tone_shading) { - scene_color = scene_color * vec3(0.666) + floor(scene_color * number_of_colors) / number_of_colors; - vec2 inv_resolution = 1.0 / resolution; - - float right = texture(image_depth, inv_resolution * vec2(1.0 * line_texel_offset, 0.0) + fs_uv).r; - float left = texture(image_depth, inv_resolution * vec2(-1.0 * line_texel_offset, 0.0) + fs_uv).r; - - float top = texture(image_depth, inv_resolution * vec2(0.0, -1.0 * line_texel_offset) + fs_uv).r; - float down = texture(image_depth, inv_resolution * vec2(0.0, 1.0 * line_texel_offset) + fs_uv).r; - - float lines = 4.0 * scene_depth - right - left - top - down; - lines *= line_multiplier; - lines = pow(lines, line_bias); - lines = clamp(lines, 0.0, 1.0); - - scene_color = mix(scene_color, vec3(0.0), lines); - } - - if (vignette) { - float len = length(gl_FragCoord.xy / resolution - vec2(0.5)); - float vig = smoothstep(vignette_radius, vignette_softness, len); - scene_color = mix(scene_color, scene_color * vig, 0.5); - } - - color = vec4(scene_color, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/postprocess.vert b/shaders/postprocessing/postprocess.vert deleted file mode 100644 index abb57776..00000000 --- a/shaders/postprocessing/postprocess.vert +++ /dev/null @@ -1,13 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout(location = 0) in vec3 position; -layout(location = 1) in vec2 uv; - -out vec2 fs_uv; - -void main() -{ - fs_uv = uv; - gl_Position = vec4(position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/ssao/ssao.frag b/shaders/postprocessing/ssao/ssao.frag deleted file mode 100644 index 35dfb698..00000000 --- a/shaders/postprocessing/ssao/ssao.frag +++ /dev/null @@ -1,139 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -in vec2 uv; - -#include "../../pipeline/scene.glsl" -#include "../../functions/reconstruct_position.glsl" -#include "../../functions/reconstruct_normal.glsl" -#include "../../functions/random.glsl" -#include "../../pipeline/shading/common.glsl" - -layout (std140) uniform SSAO_BUFFER { - vec2 sample_count; - vec2 angle_inc_cos_sin; - float projection_scale_radius; - float intensity; - float spiral_turns; - float inv_radius_squared; - float min_horizon_angle_sine_squared; - float bias; - float peak2; - float power; - uint max_level; -}; - -uniform sampler2D depth_texture; - -out vec3 color; - -vec3 tapLocation(float i, const float noise) { - float offset = ((2.0 * PI) * 2.4) * noise; - float angle = ((i * sample_count.y) * spiral_turns) * (2.0 * PI) + offset; - float radius = (i + noise + 0.5) * sample_count.y; - return vec3(cos(angle), sin(angle), radius * radius); -} - -highp vec2 startPosition(const float noise) { - float angle = ((2.0 * PI) * 2.4) * noise; - return vec2(cos(angle), sin(angle)); -} - -highp mat2 tapAngleStep() { - vec2 t = angle_inc_cos_sin; - return mat2(t.x, t.y, -t.y, t.x); -} - -vec3 tapLocationFast(float i, vec2 p, const float noise) { - float radius = (i + noise + 0.5) * sample_count.y; - return vec3(p, radius * radius); -} - -void computeAmbientOcclusionSAO(inout float occlusion, inout vec3 bentNormal, - float i, float ssDiskRadius, - const highp vec2 uv, const highp vec3 origin, const vec3 normal, - const vec2 tapPosition, const float noise) { - - vec3 tap = tapLocationFast(i, tapPosition, noise); - float ssRadius = max(1.0, tap.z * ssDiskRadius); - - vec2 uvSamplePos = uv + vec2(ssRadius * tap.xy) * 1.0 / getResolution(); - - float level = clamp(floor(log2(ssRadius)) - 3.0, 0.0, float(max_level)); - //TODO: make mipmap depth - float occlusionDepth = texture(depth_texture, uvSamplePos).r; - - vec3 p = reconstructViewSpacePosition(uvSamplePos, occlusionDepth); - - // now we have the sample, compute AO - highp vec3 v = p - origin; // sample vector - float vv = dot(v, v); // squared distance - float vn = dot(v, normal); // distance * cos(v, normal) - - // discard samples that are outside of the radius, preventing distant geometry to - // cast shadows -- there are many functions that work and choosing one is an artistic - // decision. - float s = max(0.0, 1.0 - vv * inv_radius_squared); - float w = s * s; - - // discard samples that are too close to the horizon to reduce shadows cast by geometry - // not sufficently tessellated. The goal is to discard samples that form an angle 'beta' - // smaller than 'epsilon' with the horizon. We already have dot(v,n) which is equal to the - // sin(beta) * |v|. So the test simplifies to vn^2 < vv * sin(epsilon)^2. - w *= step(vv * min_horizon_angle_sine_squared, vn * vn); - - float sampleOcclusion = max(0.0, vn + (origin.z * bias)) / (vv + peak2); - occlusion += w * sampleOcclusion; -} - -/* - * https://research.nvidia.com/sites/default/files/pubs/2012-06_Scalable-Ambient-Obscurance/McGuire12SAO.pdf - */ -void scalableAmbientObscurance(out float obscurance, out vec3 bentNormal, vec2 uv, vec3 origin, vec3 normal) { - float noise = getRandom(gl_FragCoord.xy); - highp vec2 tapPosition = startPosition(noise); - highp mat2 angleStep = tapAngleStep(); - - // Choose the screen-space sample radius - // proportional to the projected area of the sphere - float ssDiskRadius = -(projection_scale_radius / origin.z); - - obscurance = 0.0; - bentNormal = normal; - for (float i = 0.0; i < sample_count.x; i += 1.0) { - computeAmbientOcclusionSAO(obscurance, bentNormal, i, ssDiskRadius, uv, origin, normal, tapPosition, noise); - tapPosition = angleStep * tapPosition; - } - obscurance = sqrt(obscurance * intensity); -} - -vec2 pack(highp float normalizedDepth) { - // we need 16-bits of precision - highp float z = clamp(normalizedDepth, 0.0, 1.0); - highp float t = floor(256.0 * z); - mediump float hi = t * (1.0 / 256.0); // we only need 8-bits of precision - mediump float lo = (256.0 * z) - t; // we only need 8-bits of precision - return vec2(hi, lo); -} - -highp float unpack(highp vec2 depth) { - // depth here only has 8-bits of precision, but the unpacked depth is highp - // this is equivalent to (x8 * 256 + y8) / 65535, which gives a value between 0 and 1 - return (depth.x * (256.0 / 257.0) + depth.y * (1.0 / 257.0)); -} - -void main() { - float depth = texture(depth_texture, uv).r; - float z = linearize_depth(depth, getCameraNearPlane(), getCameraFarPlane()); - - vec3 position = reconstructViewSpacePosition(uv, depth); - vec3 normal = reconstructViewSpaceNormal(depth_texture, uv, depth, position, vec2(1.0) / getResolution()); - - float occlusion = 0.0; - vec3 bentNormal; // will be discarded - scalableAmbientObscurance(occlusion, bentNormal, uv, position, normal); - - float aoVisibility = pow(saturate(1.0 - occlusion), power); - - color = vec3(aoVisibility, pack(position.z * 1.0 / getCameraFarPlane())); -} diff --git a/shaders/postprocessing/ssao/ssao.vert b/shaders/postprocessing/ssao/ssao.vert deleted file mode 100644 index ba2e8301..00000000 --- a/shaders/postprocessing/ssao/ssao.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout(location = 0) in vec3 vertex_position; -layout(location = 1) in vec2 vertex_uv; - -out vec2 uv; - -void main() { - uv = vertex_uv; - gl_Position = vec4(vertex_position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/ssao/ssao_blur.frag b/shaders/postprocessing/ssao/ssao_blur.frag deleted file mode 100644 index b983ada1..00000000 --- a/shaders/postprocessing/ssao/ssao_blur.frag +++ /dev/null @@ -1,69 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -#include "../../pipeline/scene.glsl" -#include "../../functions/random.glsl" - -in vec2 uv; - -uniform sampler2D ssao; - -uniform float kernel[16]; -uniform vec2 axis; -uniform uint sample_count; -uniform float far_plane_over_edge_distance; - -out float color; - -float unpack(vec2 depth) { - // depth here only has 8-bits of precision, but the unpacked depth is highp - // this is equivalent to (x8 * 256 + y8) / 65535, which gives a value between 0 and 1 - return (depth.x * (256.0 / 257.0) + depth.y * (1.0 / 257.0)); -} - -float bilateralWeight(in highp float depth, in highp float sampleDepth) { - float diff = (sampleDepth - depth) * far_plane_over_edge_distance; - return max(0.0, 1.0 - diff * diff); -} - -void tap(inout float sum, inout float totalWeight, float weight, float depth, vec2 position) { - // ambient occlusion sample - vec3 data = texture(ssao, position).rgb; - - // bilateral sample - float bilateral = weight * bilateralWeight(depth, unpack(data.gb)); - sum += data.r * bilateral; - totalWeight += bilateral; -} - -void main() { - vec3 data = texture(ssao, uv).rgb; - - // This is the skybox, skip - if (data.g * data.b == 1.0) { - color= data.r; - return; - } - - float depth = unpack(data.gb); - float totalWeight = kernel[0]; - float sum = data.r * totalWeight; - - vec2 texel_size = axis / getResolution(); - - vec2 offset = texel_size; - for (int i = 1; i < int(sample_count); i++) { - float weight = kernel[i]; - tap(sum, totalWeight, weight, depth, uv + offset); - tap(sum, totalWeight, weight, depth, uv - offset); - offset += texel_size; - } - - float ao = sum * (1.0 / totalWeight); - - // simple dithering helps a lot (assumes 8 bits target) - // this is most useful with high quality/large blurs - ao += ((getRandom(uv) - 0.5) / 255.0); - - color = ao; -} \ No newline at end of file diff --git a/shaders/postprocessing/ssao/ssao_blur.vert b/shaders/postprocessing/ssao/ssao_blur.vert deleted file mode 100644 index ba2e8301..00000000 --- a/shaders/postprocessing/ssao/ssao_blur.vert +++ /dev/null @@ -1,12 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout(location = 0) in vec3 vertex_position; -layout(location = 1) in vec2 vertex_uv; - -out vec2 uv; - -void main() { - uv = vertex_uv; - gl_Position = vec4(vertex_position, 1.0); -} \ No newline at end of file diff --git a/shaders/postprocessing/ssr/ssr.frag b/shaders/postprocessing/ssr/ssr.frag deleted file mode 100644 index 55223616..00000000 --- a/shaders/postprocessing/ssr/ssr.frag +++ /dev/null @@ -1,172 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -#include "../../pipeline/scene.glsl" - -#include "../../functions/reconstruct_position.glsl" -#include "../../functions/random.glsl" -#include "../../functions/math.glsl" -#include "../../functions/trace_ray.glsl" -#include "../../pipeline/shading/common.glsl" -#include "../../pipeline/shading/brdf.glsl" - -// input normalized uv -in vec2 uv; - -// output vec3 reflected_color color -out vec3 color; - -// GBUFFER textures -uniform sampler2D normal_texture; -uniform sampler2D depth_texture; -uniform sampler2D props_texture; - -uniform sampler2D base_color_texture; - -// SSR settings -uniform float vs_thickness = 0.5; -uniform float stride = 2.0; -uniform float vs_max_distance = 1000.0; -uniform float bias = 0.1; -uniform float max_steps = 1000.0; - -uniform float reflection_threshold = 0.0; -uniform float roughness_factor = 0.1; - -uniform float camera_attenuation_lower_edge = 0.2; -uniform float camera_attenuation_upper_edge = 0.55; - -uniform float reflection_strength = 5.0; -uniform float reflection_falloff_exp = 1.0; - -float compute_attenuation(ivec2 hitPixel, vec2 hitUV, vec3 vsRayOrigin, vec3 vsHitPoint, float maxRayDistance, float numIterations) { - float attenuation = 1.0; - -#ifdef SCREEN_SPACE_REFLECTIONS_BORDERS_ATTENUATION - // Attenuation against the border of the screen - vec2 dCoords = smoothstep(0.2, 0.6, abs(vec2(0.5) - hitUV.xy)); - - attenuation *= clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0); -#endif - -#ifdef SCREEN_SPACE_REFLECTIONS_INTERSECTION_DISTANCE_ATTENUATION - // Attenuation based on the distance between the origin of the reflection ray and the intersection point - attenuation *= 1.0 - clamp(distance(vsRayOrigin, vsHitPoint) / maxRayDistance, 0.0, 1.0); -#endif - -#ifdef SCREEN_SPACE_REFLECTIONS_ITERATION_COUNT_ATTENUATION - // Attenuation based on the number of iterations performed to find the intersection - attenuation *= 1.0 - (numIterations / max_steps); -#endif - - return attenuation; -} - -void main() { - vec2 props = texture(props_texture, uv).rg; - float roughness = props.r; - float metallic = props.g; - - if (metallic < reflection_threshold) { - return; - } - - // normalized depth - float depth = texture(depth_texture, uv).r; - - // skip if skybox - if (abs(depth - 1.0) < 0.000001) { - return; - } - - // world space position - vec3 ws_position = reconstructPosition(uv, depth); - - // world space view direction - vec3 ws_view_dir = normalize(ws_position - getCameraPosition()); - - // world space normal (already normalized) - vec3 ws_normal = texture(normal_texture, uv).xyz; - - // world space reflected_color vector from current position - vec3 ws_reflected = reflect(ws_view_dir, ws_normal); - - // world space ray direction - vec3 ws_ray_direction = normalize(ws_reflected); - - // world space ray origin - vec3 ws_origin = ws_position + bias * ws_ray_direction; - - // view space ray origin - vec3 vs_origin = mul_mat4_vec3(getView(), ws_origin).xyz; - - // view space ray direction (independent of camera position) - vec3 vs_ray_direction = mul_mat3_vec3(getView(), ws_ray_direction); - - float attenuation = 1.0; -#ifdef SCREEN_SPACE_REFLECTIONS_CAMERA_FACING_ATTENUATION -// This will check the direction of the reflection vector with the view direction, -// and if they are pointing in the same direction, it will drown out those reflections -// since we are limited to pixels visible on screen. Attenuate reflections for angles between -// 60 degrees and 75 degrees, and drop all contribution beyond the (-60,60) degree range - attenuation *= 1.0 - smoothstep(camera_attenuation_lower_edge, camera_attenuation_upper_edge, dot(-ws_view_dir, ws_reflected)); - if (attenuation <= 0) { - return; - } -#endif - - vec3 jitt = vec3(0.0); -#ifndef SCREEN_SPACE_REFLECTIONS_BLUR - jitt = mix(vec3(0.0), hash(vs_origin) - vec3(0.5), roughness) * roughness_factor; // jittering of the reflection direction to simulate roughness -#endif - - vec2 uv2 = uv * getResolution(); - float c = (uv2.x + uv2.y) * 0.25; - float jitter = mod(c, 1.0); // jittering to hide artefacts when stepSize is > 1 - - // Outputs from the traceScreenSpaceRay function. - vec2 hitPixel; // not currently used - vec3 hitPoint; - float numIterations; - - vec3 reflected_color = vec3(0.0); - if (traceScreenSpaceRay( - vs_origin, - normalize(vs_ray_direction + jitt), - getViewToScreen(), - depth_texture, - getResolution(), - vs_thickness, - getCameraNearPlane(), - stride, - jitter, - max_steps, - vs_max_distance, - 0, - hitPixel, - hitPoint, - numIterations)) - { - vec3 base_color = texelFetch(base_color_texture, ivec2(hitPixel), 0).rgb; - - attenuation *= compute_attenuation(ivec2(hitPixel), - hitPixel / getResolution(), - vs_origin, - hitPoint, - vs_max_distance, - numIterations); - -#ifdef SCREEN_SPACE_REFLECTIONS_FRESNEL_ATTENUATION - vec3 F0 = computeF0(base_color, metallic, 1.0); - vec3 scatter = F_Schlick(F0, 1.0, max(dot(ws_normal, -ws_view_dir), 0.0)); - - vec3 reflection_attenuation = clamp(pow(scatter * reflection_strength, vec3(reflection_falloff_exp)), 0.0, 1.0); - reflected_color = base_color * (1.0 - reflection_attenuation) + base_color * attenuation * reflection_attenuation; -#else - float reflection_attenuation = clamp(pow(metallic * reflection_strength, reflection_falloff_exp), 0.0, 1.0); - reflected_color = base_color * (1.0 - reflection_attenuation) + base_color * attenuation * reflection_attenuation; -#endif - } - - color = reflected_color; -} \ No newline at end of file diff --git a/shaders/postprocessing/ssr/ssr.vert b/shaders/postprocessing/ssr/ssr.vert deleted file mode 100644 index cc36e2df..00000000 --- a/shaders/postprocessing/ssr/ssr.vert +++ /dev/null @@ -1,13 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout(location = 0) in vec3 position; -layout(location = 1) in vec2 v_uv; - -out vec2 uv; - -void main() -{ - uv = v_uv; - gl_Position = vec4(position, 1.0); -} \ No newline at end of file diff --git a/shaders/tesselation/tesselation.tesc b/shaders/tesselation/tesselation.tesc deleted file mode 100644 index 103eb737..00000000 --- a/shaders/tesselation/tesselation.tesc +++ /dev/null @@ -1,29 +0,0 @@ -Limitless::GLSL_VERSION - -#extension GL_ARB_tessellation_shader : enable -Limitless::Extensions - -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -#include "../pipeline/material/material.glsl" - -layout (vertices = 4) out; - -#include "../pipeline/interface_block/tess_control_input.glsl" -#include "../pipeline/interface_block/tess_control_output.glsl" -#include "../pipeline/interface_block/tess_control_pass.glsl" - -void main() { - InterfaceBlockPassThrough(); - - vec2 factor = getMaterialTesselationFactor(); - gl_TessLevelOuter[0] = factor.x; - gl_TessLevelOuter[1] = factor.x; - gl_TessLevelOuter[2] = factor.x; - gl_TessLevelOuter[3] = factor.x; - gl_TessLevelInner[0] = factor.y; - gl_TessLevelInner[1] = factor.y; -} \ No newline at end of file diff --git a/shaders/tesselation/tesselation.tese b/shaders/tesselation/tesselation.tese deleted file mode 100644 index c3dfcfec..00000000 --- a/shaders/tesselation/tesselation.tese +++ /dev/null @@ -1,144 +0,0 @@ -Limitless::GLSL_VERSION -#extension GL_ARB_tessellation_shader : enable -Limitless::Extensions -Limitless::Settings -Limitless::MaterialType -Limitless::ModelType -Limitless::EmitterType - -layout(quads, equal_spacing, ccw) in; - -#include "../pipeline/scene.glsl" -#include "../pipeline/material/material.glsl" - -#include "../pipeline/interface_block/tess_control_input.glsl" -#include "../pipeline/interface_block/vertex.glsl" - -float interpolate1D(float v0, float v1, float v2) { - return gl_TessCoord.x * v0 + gl_TessCoord.y * v1 + gl_TessCoord.z * v2; -} - -vec2 interpolate2D(vec2 v0, vec2 v1, vec2 v2) { - return gl_TessCoord.x * v0 + gl_TessCoord.y * v1 + gl_TessCoord.z * v2; -} - -vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2) { - return gl_TessCoord.x * v0 + gl_TessCoord.y * v1 + gl_TessCoord.z * v2; -} - -mat3 interpolateMat3(mat3 v0, mat3 v1, mat3 v2) { - return gl_TessCoord.x * v0 + gl_TessCoord.y * v1 + gl_TessCoord.z * v2; -} - -float interpolate1D(float v0, float v1, float v2, float v3) { - float u = mix(v0, v1, gl_TessCoord.x); - float v = mix(v2, v3, gl_TessCoord.x); - return mix(u, v, gl_TessCoord.y); -} - -vec2 interpolate2D(vec2 v0, vec2 v1, vec2 v2, vec2 v3) { - vec2 u = mix(v0, v1, gl_TessCoord.x); - vec2 v = mix(v2, v3, gl_TessCoord.x); - return mix(u, v, gl_TessCoord.y); -} - -vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2, vec3 v3) { - vec3 u = mix(v0, v1, gl_TessCoord.x); - vec3 v = mix(v2, v3, gl_TessCoord.x); - return mix(u, v, gl_TessCoord.y); -} - -mat3 interpolateMat3(mat3 v0, mat3 v1, mat3 v2, mat3 v3) { - mat3 u; - u[0] = mix(v0[0], v1[0], gl_TessCoord.x); - u[1] = mix(v0[1], v1[1], gl_TessCoord.x); - u[2] = mix(v0[2], v1[2], gl_TessCoord.x); - - mat3 v; - v[0] = mix(v2[0], v3[0], gl_TessCoord.x); - v[1] = mix(v2[1], v3[1], gl_TessCoord.x); - v[2] = mix(v2[2], v3[2], gl_TessCoord.x); - - mat3 r; - r[0] = mix(u[0], v[0], gl_TessCoord.y); - r[1] = mix(u[1], v[1], gl_TessCoord.y); - r[2] = mix(u[2], v[2], gl_TessCoord.y); - - return r; -} - -void main() { - #if defined (EFFECT_MODEL) - _out_data.world_position = interpolate3D(getVertexPosition(0u), getVertexPosition(1u), getVertexPosition(2u), getVertexPosition(3u)); - - #if !defined (SpriteEmitter) - _out_data.uv = interpolate2D(getVertexUV(0u), getVertexUV(1u), getVertexUV(2u), getVertexUV(3u)); - #endif - - #if defined (BeamEmitter) && defined (BeamSpeed_MODULE) - _out_data.start = interpolate3D(getParticleStart(0u), getParticleStart(1u), getParticleStart(2u), getParticleStart(3u)); - _out_data.end = interpolate3D(getParticleEnd(0u), getParticleEnd(1u), getParticleEnd(2u), getParticleEnd(3u)); - _out_data.length = interpolate1D(getParticleLength(0u), getParticleLength(1u), getParticleLength(2u), getParticleLength(3u)); - #endif - - #if defined (MeshEmitter) - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - _out_data.TBN = interpolateMat3(getVertexTBN(0u), getVertexTBN(1u), getVertexTBN(2u), getVertexTBN(3u)); - #else - _out_data.normal = interpolate3D(getVertexNormal(0u), getVertexNormal(1u), getVertexNormal(2u), getVertexNormal(3u)); - #endif - #endif - - #if defined (InitialColor_MODULE) - _out_data.color = interpolate4D(getParticleColor(0u), getParticleColor(1u), getParticleColor(2u), getParticleColor(3u)); - #endif - - #if defined (SubUV_MODULE) - _out_data.subUV = interpolate4D(getParticleSubUV(0u), getParticleSubUV(1u), getParticleSubUV(2u), getParticleSubUV(3u)); - #endif - - #if defined (CustomMaterial_MODULE) - _out_data.properties = interpolate4D(getParticleProperties(0u), getParticleProperties(1u), getParticleProperties(2u), getParticleProperties(3u)); - #endif - - #if defined (InitialRotation_MODULE) || defined (Time_MODULE) - _out_data.rotation = interpolate3D(getParticleRotation(0u), getParticleRotation(1u), getParticleRotation(2u), getParticleRotation(3u)); - _out_data.time = interpolate1D(getParticleTime(0u), getParticleTime(1u), getParticleTime(2u), getParticleTime(3u)); - #endif - - #if defined (SpriteEmitter) && defined (InitialVelocity_MODULE) - _out_data.velocity = interpolate3D(getParticleVelocity(0u), getParticleVelocity(1u), getParticleVelocity(2u), getParticleVelocity(3u)); - #endif - - #if defined (BeamEmitter) && (defined (InitialVelocity_MODULE) || defined (InitialSize_Module)) - _out_data.velocity = interpolate3D(getParticleVelocity(0u), getParticleVelocity(1u), getParticleVelocity(2u), getParticleVelocity(3u)); - _out_data.size = interpolate1D(getParticleSize(0u), getParticleSize(1u), getParticleSize(2u), getParticleSize(3u)); - #endif - - #if defined (Lifetime_MODULE) || defined (Acceleration_MODULE) - _out_data.acceleration = interpolate3D(getParticleAcceleration(0u), getParticleAcceleration(1u), getParticleAcceleration(2u), getParticleAcceleration(3u)); - _out_data.lifetime = interpolate1D(getParticleLifetime(0u), getParticleLifetime(1u), getParticleLifetime(2u), getParticleLifetime(3u)); - #endif - - #if defined (SpriteEmitter) - _out_data.size = interpolate1D(getParticleSize(0u), getParticleSize(1u), getParticleSize(2u), getParticleSize(3u)); - #endif - #else - #if defined (MATERIAL_NORMAL) && defined (NORMAL_MAPPING) - _out_data.TBN = interpolateMat3(getVertexTBN(0u), getVertexTBN(1u), getVertexTBN(2u), getVertexTBN(3u)); - #else - _out_data.normal = interpolate3D(getVertexNormal(0u), getVertexNormal(1u), getVertexNormal(2u), getVertexNormal(3u)); - #endif - - _out_data.world_position = interpolate3D(getVertexPosition(0u), getVertexPosition(1u), getVertexPosition(2u), getVertexPosition(3u)); - _out_data.uv = interpolate2D(getVertexUV(0u), getVertexUV(1u), getVertexUV(2u), getVertexUV(3u)); - #endif - - { - vec3 world_position = _out_data.world_position; - - _MATERIAL_TESSELLATION_SNIPPET - - gl_Position = getViewProjection() * vec4(world_position, 1.0); - } -} \ No newline at end of file diff --git a/shaders/text/text.frag b/shaders/text/text.frag deleted file mode 100644 index 4b2ce9ad..00000000 --- a/shaders/text/text.frag +++ /dev/null @@ -1,13 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -in vec2 vs_uv; - -out vec4 FragColor; - -uniform sampler2D bitmap; -uniform vec4 color; - -void main() { - FragColor = vec4(color.rgb, texture(bitmap, vs_uv).r * color.a); -} \ No newline at end of file diff --git a/shaders/text/text.vert b/shaders/text/text.vert deleted file mode 100644 index de00ce43..00000000 --- a/shaders/text/text.vert +++ /dev/null @@ -1,17 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout (location = 0) in vec2 position; -layout (location = 1) in vec2 uv; - -out vec2 vs_uv; - -uniform mat4 model; - -uniform mat4 proj; - -void main() -{ - gl_Position = proj * model * vec4(position, 0.0, 1.0); - vs_uv = uv; -} \ No newline at end of file diff --git a/shaders/text/text_selection.frag b/shaders/text/text_selection.frag deleted file mode 100644 index 5866a180..00000000 --- a/shaders/text/text_selection.frag +++ /dev/null @@ -1,11 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -out vec4 FragColor; - -uniform vec4 color; - -void main() -{ - FragColor = color; -} \ No newline at end of file diff --git a/shaders/text/text_selection.vert b/shaders/text/text_selection.vert deleted file mode 100644 index 757be085..00000000 --- a/shaders/text/text_selection.vert +++ /dev/null @@ -1,13 +0,0 @@ -Limitless::GLSL_VERSION -Limitless::Extensions - -layout (location = 0) in vec2 position; - -uniform mat4 model; - -uniform mat4 proj; - -void main() -{ - gl_Position = proj * model * vec4(position, 0.0, 1.0); -} \ No newline at end of file diff --git a/shaders_ref/functions/brdf.glsl b/shaders_ref/functions/brdf.glsl index e1ee1038..9d50b6c9 100644 --- a/shaders_ref/functions/brdf.glsl +++ b/shaders_ref/functions/brdf.glsl @@ -1,4 +1,3 @@ - #if defined (ENGINE_MATERIAL_QUALITY_HIGH) #define ENGINE_MATERIAL_DIFFUSE_BURLEY #define ENGINE_MATERIAL_SPECULAR_GGX @@ -82,37 +81,4 @@ float Fd_Wrap(float NoL, float w) { float w1 = 1.0 + w; float x = w1 * w1; return (NoL + w) / x; -} - -vec3 DiffuseBRDF(const ShadingContext sctx, const LightingContext lctx) { -#if defined (ENGINE_MATERIAL_DIFFUSE_BURLEY) - return sctx.diffuseColor * Fd_Burley(sctx.roughness, sctx.NoV, lctx.NoL, lctx.LoH); -#elif defined (ENGINE_MATERIAL_DIFFUSE_LAMBERT) - return sctx.diffuseColor * Fd_Lambert(); -#endif -} - -vec3 SpecularBRDF(const ShadingContext sctx, const LightingContext lctx) { - float D = D_GGX(sctx.roughness, lctx.NoH); -#if defined (ENGINE_MATERIAL_SPECULAR_GGX) - float V = V_SmithGGXCorrelated(sctx.NoV, lctx.NoL, sctx.a2, lctxlambdaV); -#elif defined (ENGINE_MATERIAL_SPECULAR_GGX_FAST) - float V = V_SmithGGXCorrelatedFast(sctx.roughness, sctx.NoV, lctx.NoL); -#endif - vec3 F = SpecularF(sctx.F0, lctx.LoH); - return (D * V) * F; -} - -vec3 DiffuseBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { - vec3 diffuse = DiffuseBRDF(sctx, lctx); -#if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) - diffuse *= Fd_Wrap(lsctx.NoL, 0.5); -#endif - return diffuse; -} - -vec3 SpecularBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { - float D = D_Charlie(sctx.roughness, lctx.NoH); - float V = V_Neubelt(sctx.NoV, lctx.NoL); - return (D * V) * sctx.F0; -} +} \ No newline at end of file diff --git a/shaders_ref/functions/brdf_ctx.glsl b/shaders_ref/functions/brdf_ctx.glsl new file mode 100644 index 00000000..971c5cd2 --- /dev/null +++ b/shaders_ref/functions/brdf_ctx.glsl @@ -0,0 +1,32 @@ +vec3 DiffuseBRDF(const ShadingContext sctx, const LightingContext lctx) { + #if defined (ENGINE_MATERIAL_DIFFUSE_BURLEY) + return sctx.diffuseColor * Fd_Burley(sctx.roughness, sctx.NoV, lctx.NoL, lctx.LoH); + #elif defined (ENGINE_MATERIAL_DIFFUSE_LAMBERT) + return sctx.diffuseColor * Fd_Lambert(); + #endif +} + +vec3 SpecularBRDF(const ShadingContext sctx, const LightingContext lctx) { + float D = D_GGX(sctx.roughness, lctx.NoH); + #if defined (ENGINE_MATERIAL_SPECULAR_GGX) + float V = V_SmithGGXCorrelated(sctx.NoV, lctx.NoL, sctx.a2, lctxlambdaV); + #elif defined (ENGINE_MATERIAL_SPECULAR_GGX_FAST) + float V = V_SmithGGXCorrelatedFast(sctx.roughness, sctx.NoV, lctx.NoL); + #endif + vec3 F = SpecularF(sctx.F0, lctx.LoH); + return (D * V) * F; +} + +vec3 DiffuseBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { + vec3 diffuse = DiffuseBRDF(sctx, lctx); + #if defined (ENGINE_MATERIAL_SUBSURFACE_COLOR) + diffuse *= Fd_Wrap(lsctx.NoL, 0.5); + #endif + return diffuse; +} + +vec3 SpecularBRDF_Cloth(const ShadingContext sctx, const LightingContext lctx) { + float D = D_Charlie(sctx.roughness, lctx.NoH); + float V = V_Neubelt(sctx.NoV, lctx.NoL); + return (D * V) * sctx.F0; +} \ No newline at end of file diff --git a/shaders/functions/cheap_contrast.glsl b/shaders_ref/functions/cheap_contrast.glsl similarity index 100% rename from shaders/functions/cheap_contrast.glsl rename to shaders_ref/functions/cheap_contrast.glsl diff --git a/shaders/functions/elipse.glsl b/shaders_ref/functions/elipse.glsl similarity index 100% rename from shaders/functions/elipse.glsl rename to shaders_ref/functions/elipse.glsl diff --git a/shaders/functions/fxaa.glsl b/shaders_ref/functions/fxaa.glsl similarity index 100% rename from shaders/functions/fxaa.glsl rename to shaders_ref/functions/fxaa.glsl diff --git a/shaders/functions/gamma_correction.glsl b/shaders_ref/functions/gamma_correction.glsl similarity index 100% rename from shaders/functions/gamma_correction.glsl rename to shaders_ref/functions/gamma_correction.glsl diff --git a/shaders/functions/math.glsl b/shaders_ref/functions/math.glsl similarity index 100% rename from shaders/functions/math.glsl rename to shaders_ref/functions/math.glsl diff --git a/shaders/functions/polar_coordinates.glsl b/shaders_ref/functions/polar_coordinates.glsl similarity index 100% rename from shaders/functions/polar_coordinates.glsl rename to shaders_ref/functions/polar_coordinates.glsl diff --git a/shaders/functions/radial_shear.glsl b/shaders_ref/functions/radial_shear.glsl similarity index 100% rename from shaders/functions/radial_shear.glsl rename to shaders_ref/functions/radial_shear.glsl diff --git a/shaders/functions/random.glsl b/shaders_ref/functions/random.glsl similarity index 100% rename from shaders/functions/random.glsl rename to shaders_ref/functions/random.glsl diff --git a/shaders/functions/reconstruct_normal.glsl b/shaders_ref/functions/reconstruct_normal.glsl similarity index 100% rename from shaders/functions/reconstruct_normal.glsl rename to shaders_ref/functions/reconstruct_normal.glsl diff --git a/shaders_ref/functions/reconstruct_position.glsl b/shaders_ref/functions/reconstruct_position.glsl index fa8a00c0..59cd8dd3 100644 --- a/shaders_ref/functions/reconstruct_position.glsl +++ b/shaders_ref/functions/reconstruct_position.glsl @@ -1,5 +1,5 @@ #include "./linearize_depth.glsl" -#include "../scene.glsl" +#include "../pipeline/scene.glsl" vec3 reconstructPosition(vec2 uv, float depth) { vec4 p = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); diff --git a/shaders/functions/rectangle.glsl b/shaders_ref/functions/rectangle.glsl similarity index 100% rename from shaders/functions/rectangle.glsl rename to shaders_ref/functions/rectangle.glsl diff --git a/shaders/functions/rotate_uv.glsl b/shaders_ref/functions/rotate_uv.glsl similarity index 100% rename from shaders/functions/rotate_uv.glsl rename to shaders_ref/functions/rotate_uv.glsl diff --git a/shaders/functions/scale_uv_by_center.glsl b/shaders_ref/functions/scale_uv_by_center.glsl similarity index 100% rename from shaders/functions/scale_uv_by_center.glsl rename to shaders_ref/functions/scale_uv_by_center.glsl diff --git a/shaders/functions/sphere_mask.glsl b/shaders_ref/functions/sphere_mask.glsl similarity index 100% rename from shaders/functions/sphere_mask.glsl rename to shaders_ref/functions/sphere_mask.glsl diff --git a/shaders/functions/spherize_uv.glsl b/shaders_ref/functions/spherize_uv.glsl similarity index 100% rename from shaders/functions/spherize_uv.glsl rename to shaders_ref/functions/spherize_uv.glsl diff --git a/shaders/functions/tiling_offset.glsl b/shaders_ref/functions/tiling_offset.glsl similarity index 100% rename from shaders/functions/tiling_offset.glsl rename to shaders_ref/functions/tiling_offset.glsl diff --git a/shaders/functions/trace_ray.glsl b/shaders_ref/functions/trace_ray.glsl similarity index 99% rename from shaders/functions/trace_ray.glsl rename to shaders_ref/functions/trace_ray.glsl index cbd627da..34703246 100644 --- a/shaders/functions/trace_ray.glsl +++ b/shaders_ref/functions/trace_ray.glsl @@ -60,7 +60,7 @@ bool traceScreenSpaceRay( vec2 P0 = H0.xy * k0; vec2 P1 = H1.xy * k1; -#ifdef SCREEN_SPACE_REFLECTIONS_CLIP_TO_FRUSTRUM +#ifdef ENGINE_SETTINGS_SSR_CLIP_TO_FRUSTRUM float xMax = texture_resolution.x - 0.5, xMin = 0.5, yMax = texture_resolution.y - 0.5, yMin = 0.5; float alpha = 0.0; @@ -175,7 +175,7 @@ bool traceScreenSpaceRay( hit = false; } -#ifdef SCREEN_SPACE_REFLECTIONS_REFINEMENT +#ifdef ENGINE_SETTINGS_SSR_REFINEMENT if (stride > 1.0 && hit) { // Refine the hit point within the last large-stride step diff --git a/shaders/functions/twirl.glsl b/shaders_ref/functions/twirl.glsl similarity index 100% rename from shaders/functions/twirl.glsl rename to shaders_ref/functions/twirl.glsl diff --git a/shaders_ref/lighting/directional_shadows.vert b/shaders_ref/lighting/directional_shadows.vert index d1a983e6..3e06c9dc 100644 --- a/shaders_ref/lighting/directional_shadows.vert +++ b/shaders_ref/lighting/directional_shadows.vert @@ -2,7 +2,7 @@ ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/vertex.glsl" -#include "../scene.glsl" +#include "../pipeline/scene.glsl" #include "../instance/instance.glsl" #include "../material/material.glsl" #include "../interface_block/pass_through.glsl" diff --git a/shaders_ref/lighting/lighting.glsl b/shaders_ref/lighting/lighting.glsl index 743f5e47..de8bc710 100644 --- a/shaders_ref/lighting/lighting.glsl +++ b/shaders_ref/lighting/lighting.glsl @@ -1,5 +1,5 @@ #include "./lighting_context.glsl" -#include "../scene.glsl" +#include "../pipeline/scene.glsl" #include "../shading/regular.glsl" #include "../shading/custom.glsl" @@ -60,6 +60,10 @@ vec3 computeDirectionalLight(const ShadingContext sctx) { vec3 computeLights(const ShadingContext sctx) { vec3 color = computeDirectionalLight(sctx); +#if defined (ENGINE_SETTINGS_SSR) + color += sctx.indirect_lighting; +#endif + for (uint i = 0u; i < getLightCount(); ++i) { Light light = getLight(i); diff --git a/shaders_ref/lighting/ssao.glsl b/shaders_ref/lighting/ssao.glsl new file mode 100644 index 00000000..c1191055 --- /dev/null +++ b/shaders_ref/lighting/ssao.glsl @@ -0,0 +1,7 @@ +#if defined (ENGINE_SETTINGS_SSAO) + uniform sampler2D _ssao_texture; + + float getSSAO(vec2 uv) { + return texture(_ssao_texture, uv).r; + } +#endif diff --git a/shaders_ref/lighting/ssr.glsl b/shaders_ref/lighting/ssr.glsl new file mode 100644 index 00000000..f0b06f0b --- /dev/null +++ b/shaders_ref/lighting/ssr.glsl @@ -0,0 +1,8 @@ +#if defined (ENGINE_SETTINGS_SSR) + uniform sampler2D _ssr_texture; + uniform float _ssr_strength; + + vec3 getSSR(vec2 uv) { + return texture(_ssr_texture, uv).rgb * _ssr_strength; + } +#endif diff --git a/shaders_ref/pipeline/color_picker.vert b/shaders_ref/pipeline/color_picker.vert index 0532caf2..1079b748 100644 --- a/shaders_ref/pipeline/color_picker.vert +++ b/shaders_ref/pipeline/color_picker.vert @@ -2,7 +2,7 @@ ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/vertex.glsl" -#include "../scene.glsl" +#include "../pipeline/scene.glsl" #include "../instance/instance.glsl" #include "../material/material.glsl" #include "../interface_block/pass_through.glsl" diff --git a/shaders_ref/pipeline/deferred.frag b/shaders_ref/pipeline/deferred.frag index beb87ff8..01dae304 100644 --- a/shaders_ref/pipeline/deferred.frag +++ b/shaders_ref/pipeline/deferred.frag @@ -1,33 +1,12 @@ ENGINE::COMMON -#include "../shading/shading_gctx.glsl" - in vec2 uv; -out vec3 color; - -//#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) -// uniform sampler2D ssao_texture; -//#endif - -//TODO: refactor - separate responsibilities +#include "../shading/shading_gctx.glsl" -//#ifdef SCREEN_SPACE_REFLECTIONS -// uniform sampler2D ssr_texture; -// uniform float _ssr_strength; -//#endif +out vec3 color; void main() { -//#if defined (SCREEN_SPACE_AMBIENT_OCCLUSION) -// base.a *= texture(ssao_texture, uv).r; -//#endif - const GBufferContext gctx = computeGBufferContext(uv); color = shadeFragment(gctx); - -// just add for now for test -//#ifdef SCREEN_SPACE_REFLECTIONS -// // TODO: move to indirect lighting -// color += texture(ssr_texture, uv).rgb *_ssr_strength; -//#endif -} +} \ No newline at end of file diff --git a/shaders_ref/pipeline/depth.vert b/shaders_ref/pipeline/depth.vert index 0532caf2..8a436e5d 100644 --- a/shaders_ref/pipeline/depth.vert +++ b/shaders_ref/pipeline/depth.vert @@ -2,7 +2,7 @@ ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/vertex.glsl" -#include "../scene.glsl" +#include "./scene.glsl" #include "../instance/instance.glsl" #include "../material/material.glsl" #include "../interface_block/pass_through.glsl" diff --git a/shaders_ref/pipeline/forward.vert b/shaders_ref/pipeline/forward.vert index 0532caf2..8a436e5d 100644 --- a/shaders_ref/pipeline/forward.vert +++ b/shaders_ref/pipeline/forward.vert @@ -2,7 +2,7 @@ ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/vertex.glsl" -#include "../scene.glsl" +#include "./scene.glsl" #include "../instance/instance.glsl" #include "../material/material.glsl" #include "../interface_block/pass_through.glsl" diff --git a/shaders_ref/pipeline/gbuffer.frag b/shaders_ref/pipeline/gbuffer.frag index d14c802d..a55009d1 100644 --- a/shaders_ref/pipeline/gbuffer.frag +++ b/shaders_ref/pipeline/gbuffer.frag @@ -2,7 +2,7 @@ ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/fragment.glsl" -#include "../scene.glsl" +#include "./scene.glsl" #include "../material/material_context.glsl" layout (location = 0) out vec4 albedo; diff --git a/shaders_ref/pipeline/gbuffer.vert b/shaders_ref/pipeline/gbuffer.vert index 0532caf2..1079b748 100644 --- a/shaders_ref/pipeline/gbuffer.vert +++ b/shaders_ref/pipeline/gbuffer.vert @@ -2,7 +2,7 @@ ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/vertex.glsl" -#include "../scene.glsl" +#include "../pipeline/scene.glsl" #include "../instance/instance.glsl" #include "../material/material.glsl" #include "../interface_block/pass_through.glsl" diff --git a/shaders/pipeline/scene.glsl b/shaders_ref/pipeline/scene.glsl similarity index 100% rename from shaders/pipeline/scene.glsl rename to shaders_ref/pipeline/scene.glsl diff --git a/shaders_ref/pipeline/skybox.vert b/shaders_ref/pipeline/skybox.vert index de015540..61c94f9e 100644 --- a/shaders_ref/pipeline/skybox.vert +++ b/shaders_ref/pipeline/skybox.vert @@ -2,7 +2,7 @@ ENGINE::COMMON ENGINE::MATERIALDEPENDENT #include "../interface_block/vertex.glsl" -#include "../scene.glsl" +#include "./scene.glsl" #include "../instance/instance.glsl" #include "../material/material.glsl" #include "../interface_block/pass_through.glsl" diff --git a/shaders_ref/postprocessing/ssao/ssao.frag b/shaders_ref/postprocessing/ssao/ssao.frag index 35dfb698..2931695f 100644 --- a/shaders_ref/postprocessing/ssao/ssao.frag +++ b/shaders_ref/postprocessing/ssao/ssao.frag @@ -1,5 +1,4 @@ -Limitless::GLSL_VERSION -Limitless::Extensions +ENGINE::COMMON in vec2 uv; @@ -7,7 +6,7 @@ in vec2 uv; #include "../../functions/reconstruct_position.glsl" #include "../../functions/reconstruct_normal.glsl" #include "../../functions/random.glsl" -#include "../../pipeline/shading/common.glsl" +#include "../../functions/common.glsl" layout (std140) uniform SSAO_BUFFER { vec2 sample_count; diff --git a/shaders_ref/postprocessing/ssao/ssao.vert b/shaders_ref/postprocessing/ssao/ssao.vert index ba2e8301..4be5a84b 100644 --- a/shaders_ref/postprocessing/ssao/ssao.vert +++ b/shaders_ref/postprocessing/ssao/ssao.vert @@ -1,5 +1,4 @@ -Limitless::GLSL_VERSION -Limitless::Extensions +ENGINE::COMMON layout(location = 0) in vec3 vertex_position; layout(location = 1) in vec2 vertex_uv; diff --git a/shaders_ref/postprocessing/ssao/ssao_blur.frag b/shaders_ref/postprocessing/ssao/ssao_blur.frag index b983ada1..94328e58 100644 --- a/shaders_ref/postprocessing/ssao/ssao_blur.frag +++ b/shaders_ref/postprocessing/ssao/ssao_blur.frag @@ -1,5 +1,4 @@ -Limitless::GLSL_VERSION -Limitless::Extensions +ENGINE::COMMON #include "../../pipeline/scene.glsl" #include "../../functions/random.glsl" diff --git a/shaders_ref/postprocessing/ssao/ssao_blur.vert b/shaders_ref/postprocessing/ssao/ssao_blur.vert index ba2e8301..4be5a84b 100644 --- a/shaders_ref/postprocessing/ssao/ssao_blur.vert +++ b/shaders_ref/postprocessing/ssao/ssao_blur.vert @@ -1,5 +1,4 @@ -Limitless::GLSL_VERSION -Limitless::Extensions +ENGINE::COMMON layout(location = 0) in vec3 vertex_position; layout(location = 1) in vec2 vertex_uv; diff --git a/shaders_ref/postprocessing/ssr/ssr.frag b/shaders_ref/postprocessing/ssr/ssr.frag index 55223616..0e8c685b 100644 --- a/shaders_ref/postprocessing/ssr/ssr.frag +++ b/shaders_ref/postprocessing/ssr/ssr.frag @@ -1,14 +1,12 @@ -Limitless::GLSL_VERSION -Limitless::Extensions +ENGINE::COMMON #include "../../pipeline/scene.glsl" - #include "../../functions/reconstruct_position.glsl" #include "../../functions/random.glsl" #include "../../functions/math.glsl" #include "../../functions/trace_ray.glsl" -#include "../../pipeline/shading/common.glsl" -#include "../../pipeline/shading/brdf.glsl" +#include "../../functions/common.glsl" +#include "../../functions/brdf.glsl" // input normalized uv in vec2 uv; @@ -20,7 +18,6 @@ out vec3 color; uniform sampler2D normal_texture; uniform sampler2D depth_texture; uniform sampler2D props_texture; - uniform sampler2D base_color_texture; // SSR settings @@ -42,19 +39,19 @@ uniform float reflection_falloff_exp = 1.0; float compute_attenuation(ivec2 hitPixel, vec2 hitUV, vec3 vsRayOrigin, vec3 vsHitPoint, float maxRayDistance, float numIterations) { float attenuation = 1.0; -#ifdef SCREEN_SPACE_REFLECTIONS_BORDERS_ATTENUATION +#ifdef ENGINE_SETTINGS_SSR_BORDERS_ATTENUATION // Attenuation against the border of the screen vec2 dCoords = smoothstep(0.2, 0.6, abs(vec2(0.5) - hitUV.xy)); attenuation *= clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0); #endif -#ifdef SCREEN_SPACE_REFLECTIONS_INTERSECTION_DISTANCE_ATTENUATION +#ifdef ENGINE_SETTINGS_SSR_INTERSECTION_DISTANCE_ATTENUATION // Attenuation based on the distance between the origin of the reflection ray and the intersection point attenuation *= 1.0 - clamp(distance(vsRayOrigin, vsHitPoint) / maxRayDistance, 0.0, 1.0); #endif -#ifdef SCREEN_SPACE_REFLECTIONS_ITERATION_COUNT_ATTENUATION +#ifdef ENGINE_SETTINGS_SSR_ITERATION_COUNT_ATTENUATION // Attenuation based on the number of iterations performed to find the intersection attenuation *= 1.0 - (numIterations / max_steps); #endif @@ -104,7 +101,7 @@ void main() { vec3 vs_ray_direction = mul_mat3_vec3(getView(), ws_ray_direction); float attenuation = 1.0; -#ifdef SCREEN_SPACE_REFLECTIONS_CAMERA_FACING_ATTENUATION +#ifdef ENGINE_SETTINGS_SSR_CAMERA_FACING_ATTENUATION // This will check the direction of the reflection vector with the view direction, // and if they are pointing in the same direction, it will drown out those reflections // since we are limited to pixels visible on screen. Attenuate reflections for angles between @@ -156,7 +153,7 @@ void main() { vs_max_distance, numIterations); -#ifdef SCREEN_SPACE_REFLECTIONS_FRESNEL_ATTENUATION +#ifdef ENGINE_SETTINGS_SSR_FRESNEL_ATTENUATION vec3 F0 = computeF0(base_color, metallic, 1.0); vec3 scatter = F_Schlick(F0, 1.0, max(dot(ws_normal, -ws_view_dir), 0.0)); diff --git a/shaders_ref/postprocessing/ssr/ssr.vert b/shaders_ref/postprocessing/ssr/ssr.vert index cc36e2df..175cfed4 100644 --- a/shaders_ref/postprocessing/ssr/ssr.vert +++ b/shaders_ref/postprocessing/ssr/ssr.vert @@ -1,5 +1,4 @@ -Limitless::GLSL_VERSION -Limitless::Extensions +ENGINE::COMMON layout(location = 0) in vec3 position; layout(location = 1) in vec2 v_uv; diff --git a/shaders_ref/scene.glsl b/shaders_ref/scene.glsl deleted file mode 100644 index 618a48c6..00000000 --- a/shaders_ref/scene.glsl +++ /dev/null @@ -1,67 +0,0 @@ -/* - mat4 getProjection(); - mat4 getProjectionInverse(); - mat4 getView(); - mat4 getViewInverse(); - mat4 getViewProjection(); - mat4 getViewProjectionInverse(); - vec3 getCameraPosition(); -*/ - -layout (std140) uniform scene_data { - mat4 _projection; - mat4 _projection_inverse; - mat4 _view_to_screen; - mat4 _view; - mat4 _view_inverse; - mat4 _VP; - mat4 _VP_inverse; - vec4 _camera_position; - vec2 _resolution; - float _far_plane; - float _near_plane; -}; - -mat4 getProjection() { - return _projection; -} - -mat4 getProjectionInverse() { - return _projection_inverse; -} - -mat4 getViewToScreen() { - return _view_to_screen; -} - -mat4 getView() { - return _view; -} - -mat4 getViewInverse() { - return _view_inverse; -} - -mat4 getViewProjection() { - return _VP; -} - -mat4 getViewProjectionInverse() { - return _VP_inverse; -} - -vec3 getCameraPosition() { - return _camera_position.xyz; -} - -float getCameraFarPlane() { - return _far_plane; -} - -float getCameraNearPlane() { - return _near_plane; -} - -vec2 getResolution() { - return _resolution; -} diff --git a/shaders_ref/shading/regular.glsl b/shaders_ref/shading/regular.glsl index 5b402927..9111a2f9 100644 --- a/shaders_ref/shading/regular.glsl +++ b/shaders_ref/shading/regular.glsl @@ -1,4 +1,5 @@ #include "../functions/brdf.glsl" +#include "../functions/brdf_ctx.glsl" /** * Computes color for lit material with regular PBR shading model. diff --git a/shaders_ref/shading/shading_context.glsl b/shaders_ref/shading/shading_context.glsl index a43ddb4b..ca4e08a4 100644 --- a/shaders_ref/shading/shading_context.glsl +++ b/shaders_ref/shading/shading_context.glsl @@ -1,5 +1,5 @@ #include "../functions/common.glsl" -#include "../scene.glsl" +#include "../pipeline/scene.glsl" #define ENGINE_SHADING_UNLIT 0u #define ENGINE_SHADING_LIT 1u @@ -22,8 +22,9 @@ struct ShadingContext { float ambientOcclusion; vec3 emissive_color; - float alpha; + + vec3 indirect_lighting; uint shading_model; }; @@ -36,7 +37,8 @@ ShadingContext computeShadingContext( const vec3 N, float ambientOcclusion, vec3 emissive_color, - uint shading_model + uint shading_model, + vec3 indirect_lighting ) { ShadingContext context; @@ -73,5 +75,7 @@ ShadingContext computeShadingContext( pixel.anisotropicB = normalize(cross(getWorldGeometricNormalVector(), pixel.anisotropicT)); #endif + context.indirect_lighting = indirect_lighting; + return context; } \ No newline at end of file diff --git a/shaders_ref/shading/shading_context_from_gctx.glsl b/shaders_ref/shading/shading_context_from_gctx.glsl index 89e29d2b..c2b5227d 100644 --- a/shaders_ref/shading/shading_context_from_gctx.glsl +++ b/shaders_ref/shading/shading_context_from_gctx.glsl @@ -1,7 +1,20 @@ #include "./shading_context.glsl" #include "../pipeline/gbuffer_context.glsl" +#include "../lighting/ssao.glsl" +#include "../lighting/ssr.glsl" ShadingContext computeShadingContext(const GBufferContext gctx) { + float ao = gctx.ao; + +#if defined (ENGINE_SETTINGS_SSAO) + ao = min(ao, getSSAO(uv)); +#endif + + vec3 indirect_lighting = vec3(0.0); +#if defined (ENGINE_SETTINGS_SSR) + indirect_lighting = getSSR(uv); +#endif + return computeShadingContext( gctx.color, 1.0, // deferred shading, no alpha channel @@ -9,8 +22,9 @@ ShadingContext computeShadingContext(const GBufferContext gctx) { gctx.position, gctx.roughness, gctx.normal, - gctx.ao, + ao, gctx.emissive_color, - gctx.shading_model + gctx.shading_model, + indirect_lighting ); } diff --git a/shaders_ref/shading/shading_context_from_mctx.glsl b/shaders_ref/shading/shading_context_from_mctx.glsl index 283a0b17..6176cc6c 100644 --- a/shaders_ref/shading/shading_context_from_mctx.glsl +++ b/shaders_ref/shading/shading_context_from_mctx.glsl @@ -16,6 +16,7 @@ ShadingContext computeShadingContext(const MaterialContext mctx) { normal, ao, emissive_color, - mctx.shading_model + mctx.shading_model, + vec3(0.0) ); } \ No newline at end of file diff --git a/src/limitless/core/uniform/uniform.cpp b/src/limitless/core/uniform/uniform.cpp index da6b195e..4d7150bd 100644 --- a/src/limitless/core/uniform/uniform.cpp +++ b/src/limitless/core/uniform/uniform.cpp @@ -43,6 +43,14 @@ void Uniform::setLocation(GLint loc) noexcept { location = loc; } +Uniform::Uniform(const Uniform& rhs) noexcept + : name {rhs.name} + , location {rhs.location} + , type {rhs.type} + , value_type {rhs.value_type} + , changed {true} { +} + bool Limitless::operator==(const Uniform& lhs, const Uniform& rhs) noexcept { return !(lhs < rhs) && !(rhs < lhs); } diff --git a/src/limitless/fx/effect_renderer.cpp b/src/limitless/fx/effect_renderer.cpp index 0829a3d7..fbfffdec 100644 --- a/src/limitless/fx/effect_renderer.cpp +++ b/src/limitless/fx/effect_renderer.cpp @@ -17,7 +17,7 @@ void EffectRenderer::visitEmitters(const Instances& instances, EmitterVisitor& e } }; - std::function visitor = [&] (const AbstractInstance& instance) { + std::function visitor = [&] (const Instance& instance) { for (const auto& [_, attachment] : instance.getAttachments()) { visitor(*attachment); } diff --git a/src/limitless/instances/effect_instance.cpp b/src/limitless/instances/effect_instance.cpp index 4d1e93b2..a9657bc3 100644 --- a/src/limitless/instances/effect_instance.cpp +++ b/src/limitless/instances/effect_instance.cpp @@ -41,11 +41,11 @@ void EffectInstance::updateEmitters(Context& context, const Camera& camera) cons } EffectInstance::EffectInstance() noexcept - : AbstractInstance(InstanceType::Effect, glm::vec3{0.0f}) { + : Instance(InstanceType::Effect, glm::vec3{0.0f}) { } EffectInstance::EffectInstance(const std::shared_ptr& effect, const glm::vec3& position) noexcept - : AbstractInstance(InstanceType::Effect, position) { + : Instance(InstanceType::Effect, position) { emitters.reserve(effect->emitters.size()); for (const auto& [emitter_name, emitter] : effect->emitters) { emitters.emplace(emitter_name, emitter->clone()); @@ -53,19 +53,19 @@ EffectInstance::EffectInstance(const std::shared_ptr& effect, co } EffectInstance::EffectInstance(const EffectInstance& effect) noexcept - : AbstractInstance {effect} { + : Instance {effect} { emitters.reserve(effect.emitters.size()); for (const auto& [emitter_name, emitter] : effect.emitters) { emitters.emplace(emitter_name, emitter->clone()); } } -std::unique_ptr EffectInstance::clone() noexcept { +std::unique_ptr EffectInstance::clone() noexcept { return std::make_unique(*this); } void EffectInstance::update(Context& context, const Camera& camera) { - AbstractInstance::update(context, camera); + Instance::update(context, camera); updateEmitters(context, camera); done = isDone(); } diff --git a/src/limitless/instances/abstract_instance.cpp b/src/limitless/instances/instance.cpp similarity index 59% rename from src/limitless/instances/abstract_instance.cpp rename to src/limitless/instances/instance.cpp index fe05581f..b1393418 100644 --- a/src/limitless/instances/abstract_instance.cpp +++ b/src/limitless/instances/instance.cpp @@ -1,15 +1,16 @@ -#include -#include "limitless/core/uniform/uniform_setter.hpp" +#include +#include +#include using namespace Limitless; -AbstractInstance::AbstractInstance(InstanceType _shader_type, const glm::vec3& _position) noexcept +Instance::Instance(InstanceType _shader_type, const glm::vec3& _position) noexcept : id {next_id++} , shader_type {_shader_type} , position {_position} { } -AbstractInstance::AbstractInstance(const AbstractInstance& rhs) +Instance::Instance(const Instance& rhs) : InstanceAttachment {rhs} , id {next_id++} , shader_type {rhs.shader_type} @@ -28,7 +29,7 @@ AbstractInstance::AbstractInstance(const AbstractInstance& rhs) } -void AbstractInstance::updateModelMatrix() noexcept { +void Instance::updateModelMatrix() noexcept { const auto translation_matrix = glm::translate(glm::mat4{1.0f}, position); const auto rotation_matrix = glm::toMat4(rotation); const auto scale_matrix = glm::scale(glm::mat4{1.0f}, scale); @@ -36,89 +37,89 @@ void AbstractInstance::updateModelMatrix() noexcept { model_matrix = translation_matrix * rotation_matrix * scale_matrix; } -void AbstractInstance::updateFinalMatrix() noexcept { +void Instance::updateFinalMatrix() noexcept { final_matrix = parent * transformation_matrix * model_matrix; } -void AbstractInstance::reveal() noexcept { +void Instance::reveal() noexcept { hidden = false; for (const auto& [_, attachment]: getAttachments()) { attachment->reveal(); } } -void AbstractInstance::hide() noexcept { +void Instance::hide() noexcept { hidden = true; for (const auto& [_, attachment]: getAttachments()) { attachment->hide(); } } -bool AbstractInstance::isHidden() const noexcept { +bool Instance::isHidden() const noexcept { return hidden; } -void AbstractInstance::kill() noexcept { +void Instance::kill() noexcept { done = true; } -bool AbstractInstance::isKilled() const noexcept { +bool Instance::isKilled() const noexcept { return done; } -void AbstractInstance::castShadow() noexcept { +void Instance::castShadow() noexcept { shadow_cast = true; for (const auto& [_, attachment]: getAttachments()) { attachment->castShadow(); } } -void AbstractInstance::removeShadow() noexcept { +void Instance::removeShadow() noexcept { shadow_cast = false; for (const auto& [_, attachment]: getAttachments()) { attachment->removeShadow(); } } -bool AbstractInstance::doesCastShadow() const noexcept { +bool Instance::doesCastShadow() const noexcept { return shadow_cast; } -AbstractInstance& AbstractInstance::setPosition(const glm::vec3& _position) noexcept { +Instance& Instance::setPosition(const glm::vec3& _position) noexcept { position = _position; return *this; } -AbstractInstance& AbstractInstance::setRotation(const glm::quat& _rotation) noexcept { +Instance& Instance::setRotation(const glm::quat& _rotation) noexcept { rotation = _rotation; return *this; } -AbstractInstance& AbstractInstance::rotateBy(const glm::quat& _rotation) noexcept { +Instance& Instance::rotateBy(const glm::quat& _rotation) noexcept { rotation = _rotation * rotation; return *this; } -AbstractInstance& AbstractInstance::setScale(const glm::vec3& _scale) noexcept { +Instance& Instance::setScale(const glm::vec3& _scale) noexcept { scale = _scale; return *this; } -AbstractInstance& AbstractInstance::setTransformation(const glm::mat4& transformation) { +Instance& Instance::setTransformation(const glm::mat4& transformation) { transformation_matrix = transformation; return *this; } -AbstractInstance& AbstractInstance::setParent(const glm::mat4& _parent) noexcept { +Instance& Instance::setParent(const glm::mat4& _parent) noexcept { parent = _parent; return *this; } -void AbstractInstance::draw(Context& ctx, const Assets& assets, ShaderType material_shader_type, ms::Blending blending) { +void Instance::draw(Context& ctx, const Assets& assets, ShaderType material_shader_type, ms::Blending blending) { draw(ctx, assets, material_shader_type, blending, UniformSetter {}); } -void AbstractInstance::update(Context& context, const Camera& camera) { +void Instance::update(Context& context, const Camera& camera) { // updates current model matrices updateModelMatrix(); updateFinalMatrix(); @@ -129,20 +130,26 @@ void AbstractInstance::update(Context& context, const Camera& camera) { InstanceAttachment::updateAttachments(context, camera); } -void AbstractInstance::removeOutline() noexcept { +void Instance::removeOutline() noexcept { outlined = false; for (const auto& [_, attachment]: getAttachments()) { attachment->removeOutline(); } } -void AbstractInstance::makeOutlined() noexcept { +void Instance::makeOutlined() noexcept { outlined = true; for (const auto& [_, attachment]: getAttachments()) { attachment->makeOutlined(); } } -bool AbstractInstance::isOutlined() const noexcept { +bool Instance::isOutlined() const noexcept { return outlined; } + +Instance::Builder Instance::builder() noexcept { + return {}; +} + + diff --git a/src/limitless/instances/instance_attachment.cpp b/src/limitless/instances/instance_attachment.cpp index 0d9c78f7..1d8a0d55 100644 --- a/src/limitless/instances/instance_attachment.cpp +++ b/src/limitless/instances/instance_attachment.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -31,7 +31,7 @@ InstanceAttachment& InstanceAttachment::setAttachmentsParent(const glm::mat4& pa return *this; } -void InstanceAttachment::attach(std::shared_ptr attachment) { +void InstanceAttachment::attach(std::shared_ptr attachment) { attachments.emplace(AttachmentID {attachment->getId(), AttachmentType::Basic}, std::move(attachment)); } @@ -45,7 +45,7 @@ void InstanceAttachment::detach(uint64_t id) { } } -const AbstractInstance& InstanceAttachment::getAttachment(uint64_t id) const { +const Instance& InstanceAttachment::getAttachment(uint64_t id) const { auto it = std::find_if(attachments.begin(), attachments.end(), [&] (const auto& att) { return att.first.id == id; }); @@ -57,7 +57,7 @@ const AbstractInstance& InstanceAttachment::getAttachment(uint64_t id) const { } } -AbstractInstance& InstanceAttachment::getAttachment(uint64_t id) { +Instance& InstanceAttachment::getAttachment(uint64_t id) { auto it = std::find_if(attachments.begin(), attachments.end(), [&] (const auto& att) { return att.first.id == id; }); diff --git a/src/limitless/instances/instance_builder.cpp b/src/limitless/instances/instance_builder.cpp index 126f0912..26bcb034 100644 --- a/src/limitless/instances/instance_builder.cpp +++ b/src/limitless/instances/instance_builder.cpp @@ -5,7 +5,7 @@ using namespace Limitless; -void AbstractInstance::Builder::initialize(const std::shared_ptr& instance) { +void Instance::Builder::initialize(const std::shared_ptr& instance) { // apply properties instance->setPosition(position_); instance->setRotation(rotation_); @@ -42,42 +42,52 @@ void AbstractInstance::Builder::initialize(const std::shared_ptr& } } -AbstractInstance::Builder& AbstractInstance::Builder::model(const std::shared_ptr& model) { +Instance::Builder& Instance::Builder::model(const std::shared_ptr& model) { model_ = model; return *this; } -AbstractInstance::Builder &AbstractInstance::Builder::position(const glm::vec3& position) { +Instance::Builder &Instance::Builder::position(const glm::vec3& position) { position_ = position; return *this; } -AbstractInstance::Builder &AbstractInstance::Builder::rotation(const glm::quat& rotation) { +Instance::Builder &Instance::Builder::rotation(const glm::quat& rotation) { rotation_ = rotation; return *this; } -AbstractInstance::Builder &AbstractInstance::Builder::scale(const glm::vec3& scale) { +Instance::Builder &Instance::Builder::scale(const glm::vec3& scale) { scale_ = scale; return *this; } -AbstractInstance::Builder &AbstractInstance::Builder::cast_shadow(bool cast_shadow) { +Instance::Builder &Instance::Builder::cast_shadow(bool cast_shadow) { cast_shadow_ = cast_shadow; return *this; } -std::shared_ptr AbstractInstance::Builder::asModel() { +std::shared_ptr Instance::Builder::asModel() { if (dynamic_cast(model_.get())) { auto instance = std::make_shared(model_, position_); initialize(instance); return instance; - } else { - throw instance_builder_exception {model_->getName() + " is not Model!"}; } + + if (dynamic_cast(model_.get())) { + if (global_material) { + auto instance = std::make_shared(model_, global_material, position_); + initialize(instance); + return instance; + } else { + throw instance_builder_exception {"Material for Elementary model is not set!"}; + } + } + + throw instance_builder_exception {"Invalid parameters for instance builder!"}; } -std::shared_ptr AbstractInstance::Builder::asSkeletal() { +std::shared_ptr Instance::Builder::asSkeletal() { if (dynamic_cast(model_.get())) { auto instance = std::make_shared(model_, position_); initialize(instance); @@ -87,50 +97,79 @@ std::shared_ptr AbstractInstance::Builder::asSkeletal() { } } -std::shared_ptr AbstractInstance::Builder::build() { - if (dynamic_cast(model_.get())) { - return asSkeletal(); - } +std::shared_ptr Instance::Builder::build() { + if (model_) { + if (dynamic_cast(model_.get())) { + return asSkeletal(); + } - if (dynamic_cast(model_.get())) { - return asModel(); - } + if (dynamic_cast(model_.get())) { + return asModel(); + } - if (dynamic_cast(model_.get())) { - if (global_material) { - auto instance = std::make_shared(model_, global_material, position_); - initialize(instance); - return instance; - } else { - throw instance_builder_exception {"Material for Elementary model is not set!"}; + if (dynamic_cast(model_.get())) { + if (global_material) { + auto instance = std::make_shared(model_, global_material, position_); + initialize(instance); + return instance; + } else { + throw instance_builder_exception {"Material for Elementary model is not set!"}; + } } + + throw instance_builder_exception {"Invalid parameters for instance builder!"}; + } + + if (effect_) { + auto instance = std::make_shared(effect_, position_); +// instance->setPosition(position_); +// instance->setRotation(rotation_); +// instance->setScale(scale_); + return instance; } throw instance_builder_exception {"Invalid parameters for instance builder!"}; } -AbstractInstance::Builder& AbstractInstance::Builder::material(uint32_t mesh_index, const std::shared_ptr& material) { +Instance::Builder& Instance::Builder::material(uint32_t mesh_index, const std::shared_ptr& material) { changed_materials.emplace_back(MaterialChange{mesh_index, {}, material}); return *this; } -AbstractInstance::Builder& AbstractInstance::Builder::material(const std::string& mesh_name, const std::shared_ptr& material) { +Instance::Builder& Instance::Builder::material(const std::string& mesh_name, const std::shared_ptr& material) { changed_materials.emplace_back(MaterialChange{0, mesh_name, material}); return *this; } -AbstractInstance::Builder& AbstractInstance::Builder::material(const std::shared_ptr& material) { +Instance::Builder& Instance::Builder::material(const std::shared_ptr& material) { global_material = material; return *this; } -AbstractInstance::Builder& AbstractInstance::Builder::attach(const std::shared_ptr& instance) { +Instance::Builder& Instance::Builder::attach(const std::shared_ptr& instance) { attachments.emplace_back(instance); return *this; } -AbstractInstance::Builder& AbstractInstance::Builder::attach(const std::string& bone_name, const std::shared_ptr& instance) { +Instance::Builder& Instance::Builder::attach(const std::string& bone_name, const std::shared_ptr& instance) { bone_attachments.emplace_back(SocketAttachment{bone_name, instance}); return *this; } + +Instance::Builder& Instance::Builder::effect(const std::shared_ptr& effect) { + effect_ = effect; + return *this; +} + +std::shared_ptr Instance::Builder::asEffect() { + if (effect_) { + auto instance = std::make_shared(effect_, position_); +// instance->setPosition(position_); +// instance->setRotation(rotation_); +// instance->setScale(scale_); + return instance; + } else { + throw instance_builder_exception {"Instance builder does not have effect to build!"}; + } +} diff --git a/src/limitless/instances/model_instance.cpp b/src/limitless/instances/model_instance.cpp index 779bdde0..4a03a7b3 100644 --- a/src/limitless/instances/model_instance.cpp +++ b/src/limitless/instances/model_instance.cpp @@ -8,7 +8,7 @@ using namespace Limitless; ModelInstance::ModelInstance(InstanceType shader, decltype(model) _model, const glm::vec3& position) - : AbstractInstance(shader, position) + : Instance(shader, position) , model {std::move(_model)} { try { auto& simple_model = dynamic_cast(*model); @@ -28,7 +28,7 @@ ModelInstance::ModelInstance(decltype(model) _model, const glm::vec3& _position) } ModelInstance::ModelInstance(decltype(model) _model, std::shared_ptr material, const glm::vec3& position) - : AbstractInstance(InstanceType::Model, position) + : Instance(InstanceType::Model, position) , model {std::move(_model)} { try { auto& elementary_model = dynamic_cast(*model); @@ -65,7 +65,7 @@ MeshInstance& ModelInstance::operator[](uint32_t index) { return std::next(meshes.begin(), index)->second; } -std::unique_ptr ModelInstance::clone() noexcept { +std::unique_ptr ModelInstance::clone() noexcept { return std::make_unique(*this); } @@ -75,7 +75,7 @@ void ModelInstance::updateBoundingBox() noexcept { } void ModelInstance::update(Context& context, const Camera& camera) { - AbstractInstance::update(context, camera); + Instance::update(context, camera); for (auto& [_, mesh] : meshes) { mesh.update(); diff --git a/src/limitless/instances/skeletal_instance.cpp b/src/limitless/instances/skeletal_instance.cpp index 89cb82ea..b3261ae5 100644 --- a/src/limitless/instances/skeletal_instance.cpp +++ b/src/limitless/instances/skeletal_instance.cpp @@ -128,7 +128,7 @@ SkeletalInstance::SkeletalInstance(const SkeletalInstance& rhs) noexcept } -std::unique_ptr SkeletalInstance::clone() noexcept { +std::unique_ptr SkeletalInstance::clone() noexcept { return std::make_unique(*this); } diff --git a/src/limitless/instances/socket_attachment.cpp b/src/limitless/instances/socket_attachment.cpp index 66319e34..725dc3e6 100644 --- a/src/limitless/instances/socket_attachment.cpp +++ b/src/limitless/instances/socket_attachment.cpp @@ -44,7 +44,7 @@ void SocketAttachment::updateSocketAttachments() { } } -void SocketAttachment::attachToBone(std::string bone_name, std::shared_ptr instance) { +void SocketAttachment::attachToBone(std::string bone_name, std::shared_ptr instance) { auto& skeletal_instance = static_cast(*this); //NOLINT const auto& skeletal = static_cast(skeletal_instance.getAbstractModel()); //NOLINT const auto& bone_map = skeletal.getBoneMap(); diff --git a/src/limitless/lighting/cascade_shadows.cpp b/src/limitless/lighting/cascade_shadows.cpp index 7f5e773e..166beedd 100644 --- a/src/limitless/lighting/cascade_shadows.cpp +++ b/src/limitless/lighting/cascade_shadows.cpp @@ -7,7 +7,7 @@ #include "limitless/core/uniform/uniform.hpp" #include -#include +#include #include #include diff --git a/src/limitless/pipeline/common/render_debug_pass.cpp b/src/limitless/pipeline/common/render_debug_pass.cpp index 1d812656..e141e96b 100644 --- a/src/limitless/pipeline/common/render_debug_pass.cpp +++ b/src/limitless/pipeline/common/render_debug_pass.cpp @@ -22,6 +22,6 @@ void RenderDebugPass::draw(Instances& instances, Context& ctx, const Assets& ass } void RenderDebugPass::update(Scene& scene, [[maybe_unused]] Instances& instances, [[maybe_unused]] Context& ctx, [[maybe_unused]] const Camera& camera) { - lighting = &scene.lighting; + lighting = &scene.getLighting(); } diff --git a/src/limitless/pipeline/common/sceneupdate_pass.cpp b/src/limitless/pipeline/common/sceneupdate_pass.cpp index 2e36df35..4b33de95 100644 --- a/src/limitless/pipeline/common/sceneupdate_pass.cpp +++ b/src/limitless/pipeline/common/sceneupdate_pass.cpp @@ -14,7 +14,7 @@ void SceneUpdatePass::update(Scene& scene, Instances& instances, Context& ctx, c scene_data.update(ctx, camera); - instances = scene.getWrappers(); + instances = scene.getInstances(); } void SceneUpdatePass::onFramebufferChange(glm::uvec2 size) { diff --git a/src/limitless/pipeline/common/shadow_pass.cpp b/src/limitless/pipeline/common/shadow_pass.cpp index e48f6542..404399e0 100644 --- a/src/limitless/pipeline/common/shadow_pass.cpp +++ b/src/limitless/pipeline/common/shadow_pass.cpp @@ -30,5 +30,5 @@ void DirectionalShadowPass::addSetter(UniformSetter& setter) { } void DirectionalShadowPass::update(Scene& scene, [[maybe_unused]] Instances& instances, [[maybe_unused]] Context& ctx, [[maybe_unused]] const Camera& camera) { - light = &scene.lighting.getDirectionalLight(); + light = &scene.getLighting().getDirectionalLight(); } diff --git a/src/limitless/pipeline/common/ssao_pass.cpp b/src/limitless/pipeline/common/ssao_pass.cpp index 142d41c6..b9943405 100644 --- a/src/limitless/pipeline/common/ssao_pass.cpp +++ b/src/limitless/pipeline/common/ssao_pass.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -44,7 +44,7 @@ void SSAOPass::update(Scene &scene, Instances &instances, Context &ctx, const Ca void SSAOPass::addSetter(Limitless::UniformSetter &setter) { setter.add([&](ShaderProgram& shader){ - shader.setUniform("ssao_texture", getResult()); + shader.setUniform("_ssao_texture", getResult()); }); } diff --git a/src/limitless/pipeline/common/ssr_pass.cpp b/src/limitless/pipeline/common/ssr_pass.cpp index 23c57035..af869d58 100644 --- a/src/limitless/pipeline/common/ssr_pass.cpp +++ b/src/limitless/pipeline/common/ssr_pass.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -46,7 +46,8 @@ void SSRPass::onFramebufferChange(glm::uvec2 size) { // void SSRPass::addSetter(Limitless::UniformSetter &setter) { setter.add([&](ShaderProgram& shader){ - shader.setUniform("ssr_texture", getResult()); + shader.setUniform("_ssr_texture", getResult()); + shader.setUniform("_ssr_strength", 1.0f); }); ssr.addSetter(setter); diff --git a/src/limitless/pipeline/deferred/depth_pass.cpp b/src/limitless/pipeline/deferred/depth_pass.cpp index 07f45a26..c4997042 100644 --- a/src/limitless/pipeline/deferred/depth_pass.cpp +++ b/src/limitless/pipeline/deferred/depth_pass.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/limitless/pipeline/deferred/gbuffer_pass.cpp b/src/limitless/pipeline/deferred/gbuffer_pass.cpp index beb23cc9..b4ed7fc4 100644 --- a/src/limitless/pipeline/deferred/gbuffer_pass.cpp +++ b/src/limitless/pipeline/deferred/gbuffer_pass.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/src/limitless/pipeline/deferred/translucent_pass.cpp b/src/limitless/pipeline/deferred/translucent_pass.cpp index 67c9841a..b99da86c 100644 --- a/src/limitless/pipeline/deferred/translucent_pass.cpp +++ b/src/limitless/pipeline/deferred/translucent_pass.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include "limitless/core/uniform/uniform.hpp" diff --git a/src/limitless/pipeline/forward/color_pass.cpp b/src/limitless/pipeline/forward/color_pass.cpp index bd87bd21..3c6e224d 100644 --- a/src/limitless/pipeline/forward/color_pass.cpp +++ b/src/limitless/pipeline/forward/color_pass.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include using namespace Limitless; diff --git a/src/limitless/renderer/render_settings_shader_definer.cpp b/src/limitless/renderer/render_settings_shader_definer.cpp index ca3a3953..809601b0 100644 --- a/src/limitless/renderer/render_settings_shader_definer.cpp +++ b/src/limitless/renderer/render_settings_shader_definer.cpp @@ -26,37 +26,37 @@ std::string RenderSettingsShaderDefiner::getDefine(const RenderSettings &setting s.append("#define ENGINE_SETTINGS_SSAO\n"); } -// if (settings.screen_space_reflections) { -// s.append("#define SCREEN_SPACE_REFLECTIONS\n"); -// -// if (settings.screen_space_reflections_settings.intersection_distance_attenuation) { -// s.append("#define SCREEN_SPACE_REFLECTIONS_INTERSECTION_DISTANCE_ATTENUATION\n"); -// } -// -// if (settings.screen_space_reflections_settings.iteration_count_attenuation) { -// s.append("#define SCREEN_SPACE_REFLECTIONS_ITERATION_COUNT_ATTENUATION\n"); -// } -// -// if (settings.screen_space_reflections_settings.borders_attenuation) { -// s.append("#define SCREEN_SPACE_REFLECTIONS_BORDERS_ATTENUATION\n"); -// } -// -// if (settings.screen_space_reflections_settings.fresnel_attenuation) { -// s.append("#define SCREEN_SPACE_REFLECTIONS_FRESNEL_ATTENUATION\n"); -// } -// -// if (settings.screen_space_reflections_settings.camera_facing_attenuation) { -// s.append("#define SCREEN_SPACE_REFLECTIONS_CAMERA_FACING_ATTENUATION\n"); -// } -// -// if (settings.screen_space_reflections_settings.clip_to_frustrum) { -// s.append("#define SCREEN_SPACE_REFLECTIONS_CLIP_TO_FRUSTRUM\n"); -// } -// -// if (settings.screen_space_reflections_settings.refiniment) { -// s.append("#define SCREEN_SPACE_REFLECTIONS_REFINEMENT\n"); -// } -// } + if (settings.screen_space_reflections) { + s.append("#define ENGINE_SETTINGS_SSR\n"); + + if (settings.screen_space_reflections_settings.intersection_distance_attenuation) { + s.append("#define ENGINE_SETTINGS_SSR_INTERSECTION_DISTANCE_ATTENUATION\n"); + } + + if (settings.screen_space_reflections_settings.iteration_count_attenuation) { + s.append("#define ENGINE_SETTINGS_SSR_ITERATION_COUNT_ATTENUATION\n"); + } + + if (settings.screen_space_reflections_settings.borders_attenuation) { + s.append("#define ENGINE_SETTINGS_SSR_BORDERS_ATTENUATION\n"); + } + + if (settings.screen_space_reflections_settings.fresnel_attenuation) { + s.append("#define ENGINE_SETTINGS_SSR_FRESNEL_ATTENUATION\n"); + } + + if (settings.screen_space_reflections_settings.camera_facing_attenuation) { + s.append("#define ENGINE_SETTINGS_SSR_CAMERA_FACING_ATTENUATION\n"); + } + + if (settings.screen_space_reflections_settings.clip_to_frustrum) { + s.append("#define ENGINE_SETTINGS_SSR_CLIP_TO_FRUSTRUM\n"); + } + + if (settings.screen_space_reflections_settings.refiniment) { + s.append("#define ENGINE_SETTINGS_SSR_REFINEMENT\n"); + } + } if (settings.csm_micro_shadowing) { s.append("#define ENGINE_SETTINGS_MICRO_SHADOWING\n"); diff --git a/src/limitless/scene.cpp b/src/limitless/scene.cpp index 332c515b..cffee1e6 100644 --- a/src/limitless/scene.cpp +++ b/src/limitless/scene.cpp @@ -8,13 +8,105 @@ Scene::Scene(Context& context) : lighting {context} { } -AbstractInstance& Scene::operator[](uint64_t id) noexcept { return *instances[id]; } -AbstractInstance& Scene::at(uint64_t id) { return *instances.at(id); } +void Scene::removeDeadInstances() noexcept { + for (auto it = instances.cbegin(); it != instances.cend(); ) { + if (it->second->isKilled()) { + it = instances.erase(it); + } else { + ++it; + } + } +} + +void Scene::add(const std::shared_ptr& instance) { + instances.emplace(instance->getId(), instance); +} + +void Scene::remove(const std::shared_ptr& instance) { + remove(instance->getId()); +} + +void Scene::remove(uint64_t id) { + instances.erase(id); +} + +void Scene::removeAll() { + instances.clear(); +} + +std::shared_ptr Scene::getInstance(uint64_t id) { + try { + return instances.at(id); + } catch (const std::out_of_range& ex) { + throw scene_exception {"Instance with id = " + std::to_string(id) + " not found!"}; + } +} + +std::shared_ptr Scene::getModelInstance(uint64_t id) { + try { + auto instance = instances.at(id); + if (instance->getInstanceType() == InstanceType::Model) { + return std::static_pointer_cast(instance); + } else { + throw scene_exception {"Instance with id = " + std::to_string(id) + " is not ModelInstance!"}; + } + } catch (const std::out_of_range& ex) { + throw scene_exception {"Instance with id = " + std::to_string(id) + " not found!"}; + } +} + +std::shared_ptr Scene::getSkeletalInstance(uint64_t id) { + try { + auto instance = instances.at(id); + if (instance->getInstanceType() == InstanceType::Skeletal) { + return std::static_pointer_cast(instance); + } else { + throw scene_exception {"Instance with id = " + std::to_string(id) + " is not SkeletalInstance!"}; + } + } catch (const std::out_of_range& ex) { + throw scene_exception {"Instance with id = " + std::to_string(id) + " not found!"}; + } +} + +std::shared_ptr Scene::getEffectInstance(uint64_t id) { + try { + auto instance = instances.at(id); + if (instance->getInstanceType() == InstanceType::Effect) { + return std::static_pointer_cast(instance); + } else { + throw scene_exception {"Instance with id = " + std::to_string(id) + " is not EffectInstance!"}; + } + } catch (const std::out_of_range& ex) { + throw scene_exception {"Instance with id = " + std::to_string(id) + " not found!"}; + } +} + +const Lighting& Scene::getLighting() const noexcept { + return lighting; +} -void Scene::remove(uint64_t id) { instances.erase(id); } +Lighting &Scene::getLighting() noexcept { + return lighting; +} -void Scene::setSkybox(std::shared_ptr _skybox) { - skybox = std::move(_skybox); +Light& Scene::add(Light&& light) { + return lighting.add(std::move(light)); +} + +Light& Scene::add(const Light &light) { + return lighting.add(light); +} + +const std::shared_ptr &Scene::getSkybox() const noexcept { + return skybox; +} + +std::shared_ptr &Scene::getSkybox() noexcept { + return skybox; +} + +void Scene::setSkybox(const std::shared_ptr& skybox_) { + skybox = skybox_; } void Scene::update(Context& context, const Camera& camera) { @@ -22,7 +114,6 @@ void Scene::update(Context& context, const Camera& camera) { removeDeadInstances(); - //TODO: why is here two updates? for (auto& [_, instance] : instances) { if (instance->getInstanceType() != InstanceType::Effect) { instance->update(context, camera); @@ -36,21 +127,11 @@ void Scene::update(Context& context, const Camera& camera) { } } -void Scene::removeDeadInstances() noexcept { - for (auto it = instances.cbegin(); it != instances.cend(); ) { - if (it->second->isKilled()) { - it = instances.erase(it); - } else { - ++it; - } - } -} - -Instances Scene::getWrappers() noexcept { +Instances Scene::getInstances() const noexcept { Instances wrappers; wrappers.reserve(instances.size()); - const std::function visitor = [&] (AbstractInstance& instance) { + const std::function visitor = [&] (Instance& instance) { wrappers.emplace_back(std::ref(instance)); for (auto& [_, attachment] : instance.getAttachments()) { @@ -63,8 +144,4 @@ Instances Scene::getWrappers() noexcept { } return wrappers; -} - -void Scene::clear() { - instances.clear(); -} +} \ No newline at end of file diff --git a/src/limitless/shader_storage.cpp b/src/limitless/shader_storage.cpp index c9aaaff2..b9b40b2c 100644 --- a/src/limitless/shader_storage.cpp +++ b/src/limitless/shader_storage.cpp @@ -111,19 +111,18 @@ void ShaderStorage::initialize(Context& ctx, const RenderSettings& settings, con add("brightness", compiler.compile(shader_dir / "postprocessing/bloom/brightness")); } -//TODO: check -// if (settings.pipeline == RenderPipeline::Forward) { -// add("blur", compiler.compile(shader_dir / "postprocessing/blur")); -// add("postprocess", compiler.compile(shader_dir / "postprocessing/postprocess")); -// } - if (settings.pipeline == RenderPipeline::Deferred) { add("deferred", compiler.compile(shader_dir / "pipeline/deferred")); add("composite", compiler.compile(shader_dir / "pipeline/composite")); -// add("ssao", compiler.compile(shader_dir / "postprocessing/ssao/ssao")); -// add("ssao_blur", compiler.compile(shader_dir / "postprocessing/ssao/ssao_blur")); + } -// + if (settings.screen_space_ambient_occlusion) { + add("ssao", compiler.compile(shader_dir / "postprocessing/ssao/ssao")); + add("ssao_blur", compiler.compile(shader_dir / "postprocessing/ssao/ssao_blur")); + } + + if (settings.screen_space_reflections) { + add("ssr", compiler.compile(shader_dir / "postprocessing/ssr/ssr")); } if (settings.fast_approximate_antialiasing) { @@ -134,8 +133,6 @@ void ShaderStorage::initialize(Context& ctx, const RenderSettings& settings, con add("dof", compiler.compile(shader_dir / "postprocessing/dof")); } -// add("ssr", compiler.compile(shader_dir / "postprocessing/ssr/ssr")); - add("quad", compiler.compile(shader_dir / "pipeline/quad")); add("text", compiler.compile(shader_dir / "text/text")); diff --git a/src/limitless/util/color_picker.cpp b/src/limitless/util/color_picker.cpp index 403a8183..e1d2dc2f 100644 --- a/src/limitless/util/color_picker.cpp +++ b/src/limitless/util/color_picker.cpp @@ -7,7 +7,7 @@ using namespace Limitless; void ColorPicker::onPick(Context& ctx, Assets& assets, Scene& scene, glm::uvec2 coords, std::function callback) { - onPick(ctx, assets, scene.getWrappers(), coords, std::move(callback)); + onPick(ctx, assets, scene.getInstances(), coords, std::move(callback)); } void ColorPicker::onPick(Context& ctx, Assets& assets, const Instances& instances, glm::uvec2 coords, std::function callback) { diff --git a/src/limitless/util/sorter.cpp b/src/limitless/util/sorter.cpp index 82f66e51..ccd97742 100644 --- a/src/limitless/util/sorter.cpp +++ b/src/limitless/util/sorter.cpp @@ -1,11 +1,11 @@ #include -#include +#include #include using namespace Limitless; -bool FrontToBackSorter::operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept { +bool FrontToBackSorter::operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept { const auto& a_pos = lhs.get().getPosition(); const auto& b_pos = rhs.get().getPosition(); const auto& c_pos = camera.getPosition(); @@ -14,7 +14,7 @@ bool FrontToBackSorter::operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept { +bool BackToFrontSorter::operator()(const std::reference_wrapper& lhs, const std::reference_wrapper& rhs) const noexcept { const auto& a_pos = lhs.get().getPosition(); const auto& b_pos = rhs.get().getPosition(); const auto& c_pos = camera.getPosition(); diff --git a/test/limitless/instance/instance_attachment_test.cpp b/test/limitless/instance/instance_attachment_test.cpp index 13ee9e5c..f2e8501c 100644 --- a/test/limitless/instance/instance_attachment_test.cpp +++ b/test/limitless/instance/instance_attachment_test.cpp @@ -24,9 +24,9 @@ TEST_CASE("InstanceAttachment tests") { InstanceAttachment attachment = InstanceAttachment(); - std::unique_ptr instance = std::make_unique(assets.models.at("backpack"), glm::vec3{0.0f}); + std::unique_ptr instance = std::make_unique(assets.models.at("backpack"), glm::vec3{0.0f}); - std::unique_ptr instance1 = std::make_unique(assets.models.at("backpack"), glm::vec3{0.0f}); + std::unique_ptr instance1 = std::make_unique(assets.models.at("backpack"), glm::vec3{0.0f}); auto id = instance->getId(); auto id1 = instance1->getId(); diff --git a/test/limitless/instance/model_instance_test.cpp b/test/limitless/instance/model_instance_test.cpp index 460d1240..e8759db9 100644 --- a/test/limitless/instance/model_instance_test.cpp +++ b/test/limitless/instance/model_instance_test.cpp @@ -122,7 +122,7 @@ TEST_CASE("ModelInstance clone") { instance.update(context, camera); - std::unique_ptr copy = instance.clone(); + std::unique_ptr copy = instance.clone(); REQUIRE(instance.getId() != copy->getId()); REQUIRE(instance.getFinalMatrix() == copy->getFinalMatrix()); diff --git a/test/limitless/instance/skeletal_instance_test.cpp b/test/limitless/instance/skeletal_instance_test.cpp index c4b478c1..a9f2a0fc 100644 --- a/test/limitless/instance/skeletal_instance_test.cpp +++ b/test/limitless/instance/skeletal_instance_test.cpp @@ -80,7 +80,7 @@ TEST_CASE("SkeletalInstance clone") { instance.update(context, camera); - std::unique_ptr copy = instance.clone(); + std::unique_ptr copy = instance.clone(); REQUIRE(instance.getId() != copy->getId()); REQUIRE(instance.getFinalMatrix() == copy->getFinalMatrix()); diff --git a/test/limitless/instance/socket_attachment_test.cpp b/test/limitless/instance/socket_attachment_test.cpp index 79e22919..b784d50f 100644 --- a/test/limitless/instance/socket_attachment_test.cpp +++ b/test/limitless/instance/socket_attachment_test.cpp @@ -22,9 +22,9 @@ TEST_CASE("SocketAttachment tests") { }})); SkeletalInstance instance = SkeletalInstance(assets.models.at("boblamp"), glm::vec3{0.0f}); - std::unique_ptr instance1 = std::make_unique(assets.models.at("boblamp"), glm::vec3{0.0f}); - std::unique_ptr instance2 = std::make_unique(assets.models.at("boblamp"), glm::vec3{0.0f}); - std::unique_ptr instance3 = std::make_unique(assets.models.at("boblamp"), glm::vec3{0.0f}); + std::unique_ptr instance1 = std::make_unique(assets.models.at("boblamp"), glm::vec3{0.0f}); + std::unique_ptr instance2 = std::make_unique(assets.models.at("boblamp"), glm::vec3{0.0f}); + std::unique_ptr instance3 = std::make_unique(assets.models.at("boblamp"), glm::vec3{0.0f}); auto id = instance2->getId(); auto id3 = instance3->getId(); From 151b561b24d51a3e54ac1042b1964c2e565c3dd7 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Tue, 28 Nov 2023 20:12:51 +0300 Subject: [PATCH 12/15] another ref --- demo/demo.cpp | 44 ------------------- .../limitless/renderer/render_settings.hpp | 2 +- {shaders_ref => shaders}/functions/brdf.glsl | 0 .../functions/brdf_ctx.glsl | 0 .../functions/cheap_contrast.glsl | 0 .../functions/circle.glsl | 0 .../functions/common.glsl | 0 .../functions/elipse.glsl | 0 .../functions/fresnel.glsl | 0 {shaders_ref => shaders}/functions/fxaa.glsl | 0 .../functions/gamma_correction.glsl | 0 .../functions/hue_shift.glsl | 0 .../functions/linearize_depth.glsl | 0 {shaders_ref => shaders}/functions/math.glsl | 0 .../functions/polar_coordinates.glsl | 0 .../functions/radial_shear.glsl | 0 .../functions/random.glsl | 0 .../functions/reconstruct_normal.glsl | 0 .../functions/reconstruct_position.glsl | 0 .../functions/rectangle.glsl | 0 .../functions/refraction_sphere.glsl | 0 .../functions/rotate_uv.glsl | 0 .../functions/scale_uv_by_center.glsl | 0 .../functions/sphere_mask.glsl | 0 .../functions/spherize_uv.glsl | 0 .../functions/tiling_offset.glsl | 0 .../functions/tone_mapping.glsl | 0 .../functions/trace_ray.glsl | 0 {shaders_ref => shaders}/functions/twirl.glsl | 0 .../instance/instance.glsl | 0 .../interface_block/effect_fs.glsl | 0 .../interface_block/effect_vs.glsl | 0 .../interface_block/fragment.glsl | 0 .../interface_block/mesh_fs.glsl | 0 .../interface_block/mesh_vs.glsl | 0 .../interface_block/pass_through.glsl | 0 .../interface_block/tess_control_input.glsl | 0 .../interface_block/tess_control_output.glsl | 0 .../interface_block/tess_control_pass.glsl | 0 .../interface_block/vertex.glsl | 0 .../lighting/ambient.glsl | 0 .../lighting/directional_shadows.frag | 0 .../lighting/directional_shadows.vert | 0 {shaders_ref => shaders}/lighting/light.glsl | 0 .../lighting/lighting.glsl | 0 .../lighting/lighting_context.glsl | 0 .../lighting/refraction.glsl | 0 .../lighting/scene_lighting.glsl | 0 .../lighting/shadows.glsl | 0 {shaders_ref => shaders}/lighting/ssao.glsl | 0 {shaders_ref => shaders}/lighting/ssr.glsl | 0 .../material/material.glsl | 0 .../material/material_context.glsl | 0 .../pipeline/color_picker.frag | 0 .../pipeline/color_picker.vert | 0 .../pipeline/composite.frag | 0 .../pipeline/composite.vert | 0 .../pipeline/deferred.frag | 0 .../pipeline/deferred.vert | 0 {shaders_ref => shaders}/pipeline/depth.frag | 0 {shaders_ref => shaders}/pipeline/depth.vert | 0 .../pipeline/forward.frag | 0 .../pipeline/forward.vert | 0 .../pipeline/gbuffer.frag | 0 .../pipeline/gbuffer.glsl | 0 .../pipeline/gbuffer.vert | 0 .../pipeline/gbuffer_context.glsl | 0 {shaders_ref => shaders}/pipeline/quad.frag | 0 {shaders_ref => shaders}/pipeline/quad.vert | 0 {shaders_ref => shaders}/pipeline/scene.glsl | 0 {shaders_ref => shaders}/pipeline/skybox.frag | 0 {shaders_ref => shaders}/pipeline/skybox.vert | 0 .../postprocessing/bloom/blur_downsample.frag | 0 .../postprocessing/bloom/blur_downsample.vert | 0 .../postprocessing/bloom/blur_upsample.frag | 0 .../postprocessing/bloom/blur_upsample.vert | 0 .../postprocessing/bloom/brightness.frag | 0 .../postprocessing/bloom/brightness.vert | 0 .../postprocessing/dof.frag | 0 .../postprocessing/dof.vert | 0 .../postprocessing/fxaa.frag | 0 .../postprocessing/fxaa.vert | 0 .../postprocessing/postprocess.frag | 0 .../postprocessing/postprocess.vert | 0 .../postprocessing/ssao/ssao.frag | 0 .../postprocessing/ssao/ssao.vert | 0 .../postprocessing/ssao/ssao_blur.frag | 0 .../postprocessing/ssao/ssao_blur.vert | 0 .../postprocessing/ssr/ssr.frag | 0 .../postprocessing/ssr/ssr.vert | 0 {shaders_ref => shaders}/shading/custom.glsl | 0 {shaders_ref => shaders}/shading/regular.glsl | 0 .../shading/shading_context.glsl | 0 .../shading/shading_context_from_gctx.glsl | 0 .../shading/shading_context_from_mctx.glsl | 0 .../shading/shading_gctx.glsl | 0 .../shading/shading_mctx.glsl | 0 {shaders_ref => shaders}/text/text.frag | 0 {shaders_ref => shaders}/text/text.vert | 0 .../text/text_selection.frag | 0 .../text/text_selection.vert | 0 .../vertex_streams/beam_emitter.glsl | 0 .../vertex_streams/mesh_emitter.glsl | 0 .../vertex_streams/model_mesh.glsl | 0 .../vertex_streams/sprite_emitter.glsl | 0 .../vertex_streams/vertex_stream.glsl | 0 shaders_ref/API.md | 36 --------------- src/limitless/assets.cpp | 2 +- 108 files changed, 2 insertions(+), 82 deletions(-) rename {shaders_ref => shaders}/functions/brdf.glsl (100%) rename {shaders_ref => shaders}/functions/brdf_ctx.glsl (100%) rename {shaders_ref => shaders}/functions/cheap_contrast.glsl (100%) rename {shaders_ref => shaders}/functions/circle.glsl (100%) rename {shaders_ref => shaders}/functions/common.glsl (100%) rename {shaders_ref => shaders}/functions/elipse.glsl (100%) rename {shaders_ref => shaders}/functions/fresnel.glsl (100%) rename {shaders_ref => shaders}/functions/fxaa.glsl (100%) rename {shaders_ref => shaders}/functions/gamma_correction.glsl (100%) rename {shaders_ref => shaders}/functions/hue_shift.glsl (100%) rename {shaders_ref => shaders}/functions/linearize_depth.glsl (100%) rename {shaders_ref => shaders}/functions/math.glsl (100%) rename {shaders_ref => shaders}/functions/polar_coordinates.glsl (100%) rename {shaders_ref => shaders}/functions/radial_shear.glsl (100%) rename {shaders_ref => shaders}/functions/random.glsl (100%) rename {shaders_ref => shaders}/functions/reconstruct_normal.glsl (100%) rename {shaders_ref => shaders}/functions/reconstruct_position.glsl (100%) rename {shaders_ref => shaders}/functions/rectangle.glsl (100%) rename {shaders_ref => shaders}/functions/refraction_sphere.glsl (100%) rename {shaders_ref => shaders}/functions/rotate_uv.glsl (100%) rename {shaders_ref => shaders}/functions/scale_uv_by_center.glsl (100%) rename {shaders_ref => shaders}/functions/sphere_mask.glsl (100%) rename {shaders_ref => shaders}/functions/spherize_uv.glsl (100%) rename {shaders_ref => shaders}/functions/tiling_offset.glsl (100%) rename {shaders_ref => shaders}/functions/tone_mapping.glsl (100%) rename {shaders_ref => shaders}/functions/trace_ray.glsl (100%) rename {shaders_ref => shaders}/functions/twirl.glsl (100%) rename {shaders_ref => shaders}/instance/instance.glsl (100%) rename {shaders_ref => shaders}/interface_block/effect_fs.glsl (100%) rename {shaders_ref => shaders}/interface_block/effect_vs.glsl (100%) rename {shaders_ref => shaders}/interface_block/fragment.glsl (100%) rename {shaders_ref => shaders}/interface_block/mesh_fs.glsl (100%) rename {shaders_ref => shaders}/interface_block/mesh_vs.glsl (100%) rename {shaders_ref => shaders}/interface_block/pass_through.glsl (100%) rename {shaders_ref => shaders}/interface_block/tess_control_input.glsl (100%) rename {shaders_ref => shaders}/interface_block/tess_control_output.glsl (100%) rename {shaders_ref => shaders}/interface_block/tess_control_pass.glsl (100%) rename {shaders_ref => shaders}/interface_block/vertex.glsl (100%) rename {shaders_ref => shaders}/lighting/ambient.glsl (100%) rename {shaders_ref => shaders}/lighting/directional_shadows.frag (100%) rename {shaders_ref => shaders}/lighting/directional_shadows.vert (100%) rename {shaders_ref => shaders}/lighting/light.glsl (100%) rename {shaders_ref => shaders}/lighting/lighting.glsl (100%) rename {shaders_ref => shaders}/lighting/lighting_context.glsl (100%) rename {shaders_ref => shaders}/lighting/refraction.glsl (100%) rename {shaders_ref => shaders}/lighting/scene_lighting.glsl (100%) rename {shaders_ref => shaders}/lighting/shadows.glsl (100%) rename {shaders_ref => shaders}/lighting/ssao.glsl (100%) rename {shaders_ref => shaders}/lighting/ssr.glsl (100%) rename {shaders_ref => shaders}/material/material.glsl (100%) rename {shaders_ref => shaders}/material/material_context.glsl (100%) rename {shaders_ref => shaders}/pipeline/color_picker.frag (100%) rename {shaders_ref => shaders}/pipeline/color_picker.vert (100%) rename {shaders_ref => shaders}/pipeline/composite.frag (100%) rename {shaders_ref => shaders}/pipeline/composite.vert (100%) rename {shaders_ref => shaders}/pipeline/deferred.frag (100%) rename {shaders_ref => shaders}/pipeline/deferred.vert (100%) rename {shaders_ref => shaders}/pipeline/depth.frag (100%) rename {shaders_ref => shaders}/pipeline/depth.vert (100%) rename {shaders_ref => shaders}/pipeline/forward.frag (100%) rename {shaders_ref => shaders}/pipeline/forward.vert (100%) rename {shaders_ref => shaders}/pipeline/gbuffer.frag (100%) rename {shaders_ref => shaders}/pipeline/gbuffer.glsl (100%) rename {shaders_ref => shaders}/pipeline/gbuffer.vert (100%) rename {shaders_ref => shaders}/pipeline/gbuffer_context.glsl (100%) rename {shaders_ref => shaders}/pipeline/quad.frag (100%) rename {shaders_ref => shaders}/pipeline/quad.vert (100%) rename {shaders_ref => shaders}/pipeline/scene.glsl (100%) rename {shaders_ref => shaders}/pipeline/skybox.frag (100%) rename {shaders_ref => shaders}/pipeline/skybox.vert (100%) rename {shaders_ref => shaders}/postprocessing/bloom/blur_downsample.frag (100%) rename {shaders_ref => shaders}/postprocessing/bloom/blur_downsample.vert (100%) rename {shaders_ref => shaders}/postprocessing/bloom/blur_upsample.frag (100%) rename {shaders_ref => shaders}/postprocessing/bloom/blur_upsample.vert (100%) rename {shaders_ref => shaders}/postprocessing/bloom/brightness.frag (100%) rename {shaders_ref => shaders}/postprocessing/bloom/brightness.vert (100%) rename {shaders_ref => shaders}/postprocessing/dof.frag (100%) rename {shaders_ref => shaders}/postprocessing/dof.vert (100%) rename {shaders_ref => shaders}/postprocessing/fxaa.frag (100%) rename {shaders_ref => shaders}/postprocessing/fxaa.vert (100%) rename {shaders_ref => shaders}/postprocessing/postprocess.frag (100%) rename {shaders_ref => shaders}/postprocessing/postprocess.vert (100%) rename {shaders_ref => shaders}/postprocessing/ssao/ssao.frag (100%) rename {shaders_ref => shaders}/postprocessing/ssao/ssao.vert (100%) rename {shaders_ref => shaders}/postprocessing/ssao/ssao_blur.frag (100%) rename {shaders_ref => shaders}/postprocessing/ssao/ssao_blur.vert (100%) rename {shaders_ref => shaders}/postprocessing/ssr/ssr.frag (100%) rename {shaders_ref => shaders}/postprocessing/ssr/ssr.vert (100%) rename {shaders_ref => shaders}/shading/custom.glsl (100%) rename {shaders_ref => shaders}/shading/regular.glsl (100%) rename {shaders_ref => shaders}/shading/shading_context.glsl (100%) rename {shaders_ref => shaders}/shading/shading_context_from_gctx.glsl (100%) rename {shaders_ref => shaders}/shading/shading_context_from_mctx.glsl (100%) rename {shaders_ref => shaders}/shading/shading_gctx.glsl (100%) rename {shaders_ref => shaders}/shading/shading_mctx.glsl (100%) rename {shaders_ref => shaders}/text/text.frag (100%) rename {shaders_ref => shaders}/text/text.vert (100%) rename {shaders_ref => shaders}/text/text_selection.frag (100%) rename {shaders_ref => shaders}/text/text_selection.vert (100%) rename {shaders_ref => shaders}/vertex_streams/beam_emitter.glsl (100%) rename {shaders_ref => shaders}/vertex_streams/mesh_emitter.glsl (100%) rename {shaders_ref => shaders}/vertex_streams/model_mesh.glsl (100%) rename {shaders_ref => shaders}/vertex_streams/sprite_emitter.glsl (100%) rename {shaders_ref => shaders}/vertex_streams/vertex_stream.glsl (100%) delete mode 100644 shaders_ref/API.md diff --git a/demo/demo.cpp b/demo/demo.cpp index 1c367528..1ba63671 100644 --- a/demo/demo.cpp +++ b/demo/demo.cpp @@ -3,56 +3,13 @@ #include #include -#include #include -#include #include #include #include -#include using namespace Limitless; -std::ostream& operator<<(std::ostream& stream, const StackFrame& stackframe) { - return stream << stackframe.module << ": " << stackframe.func << std::endl; -} - -std::ostream& operator<<(std::ostream& stream, const StackTrace& stacktrace) { - for (const auto& frame : stacktrace) { - stream << frame; - } - return stream; -} - -static void terminationHandler() { - std::cerr << "The application has to be terminated due to a fatal error"; - bool printed_stack_trace = false; - - auto exception = std::current_exception(); - if (exception) { - try { - std::rethrow_exception(exception); - } - catch (const std::runtime_error& ex) { - std::cerr << ": " << ex.what() << std::endl; -// std::cerr << ex.stack_trace; - printed_stack_trace = true; - } - catch (const std::exception& ex) { - std::cerr << ": " << ex.what() << std::endl; - } - catch (...) { - std::cerr << "." << std::endl; - } - } else { - std::cerr << "." << std::endl; - } - - if (!printed_stack_trace) { - std::cerr << getStackTrace(1) << std::endl; - } - std::abort(); -} class Game : public MouseMoveObserver, public KeyObserver, public FramebufferObserver { private: @@ -172,7 +129,6 @@ class Game : public MouseMoveObserver, public KeyObserver, public FramebufferObs }; int main() { -// std::set_terminate(terminationHandler); Game game; game.gameLoop(); return 0; diff --git a/include/limitless/renderer/render_settings.hpp b/include/limitless/renderer/render_settings.hpp index bbdd1099..266f1b01 100644 --- a/include/limitless/renderer/render_settings.hpp +++ b/include/limitless/renderer/render_settings.hpp @@ -32,7 +32,7 @@ namespace Limitless { /** * Screen Space Reflections */ - bool screen_space_reflections {true}; + bool screen_space_reflections {false}; SSR::Settings screen_space_reflections_settings; /** diff --git a/shaders_ref/functions/brdf.glsl b/shaders/functions/brdf.glsl similarity index 100% rename from shaders_ref/functions/brdf.glsl rename to shaders/functions/brdf.glsl diff --git a/shaders_ref/functions/brdf_ctx.glsl b/shaders/functions/brdf_ctx.glsl similarity index 100% rename from shaders_ref/functions/brdf_ctx.glsl rename to shaders/functions/brdf_ctx.glsl diff --git a/shaders_ref/functions/cheap_contrast.glsl b/shaders/functions/cheap_contrast.glsl similarity index 100% rename from shaders_ref/functions/cheap_contrast.glsl rename to shaders/functions/cheap_contrast.glsl diff --git a/shaders_ref/functions/circle.glsl b/shaders/functions/circle.glsl similarity index 100% rename from shaders_ref/functions/circle.glsl rename to shaders/functions/circle.glsl diff --git a/shaders_ref/functions/common.glsl b/shaders/functions/common.glsl similarity index 100% rename from shaders_ref/functions/common.glsl rename to shaders/functions/common.glsl diff --git a/shaders_ref/functions/elipse.glsl b/shaders/functions/elipse.glsl similarity index 100% rename from shaders_ref/functions/elipse.glsl rename to shaders/functions/elipse.glsl diff --git a/shaders_ref/functions/fresnel.glsl b/shaders/functions/fresnel.glsl similarity index 100% rename from shaders_ref/functions/fresnel.glsl rename to shaders/functions/fresnel.glsl diff --git a/shaders_ref/functions/fxaa.glsl b/shaders/functions/fxaa.glsl similarity index 100% rename from shaders_ref/functions/fxaa.glsl rename to shaders/functions/fxaa.glsl diff --git a/shaders_ref/functions/gamma_correction.glsl b/shaders/functions/gamma_correction.glsl similarity index 100% rename from shaders_ref/functions/gamma_correction.glsl rename to shaders/functions/gamma_correction.glsl diff --git a/shaders_ref/functions/hue_shift.glsl b/shaders/functions/hue_shift.glsl similarity index 100% rename from shaders_ref/functions/hue_shift.glsl rename to shaders/functions/hue_shift.glsl diff --git a/shaders_ref/functions/linearize_depth.glsl b/shaders/functions/linearize_depth.glsl similarity index 100% rename from shaders_ref/functions/linearize_depth.glsl rename to shaders/functions/linearize_depth.glsl diff --git a/shaders_ref/functions/math.glsl b/shaders/functions/math.glsl similarity index 100% rename from shaders_ref/functions/math.glsl rename to shaders/functions/math.glsl diff --git a/shaders_ref/functions/polar_coordinates.glsl b/shaders/functions/polar_coordinates.glsl similarity index 100% rename from shaders_ref/functions/polar_coordinates.glsl rename to shaders/functions/polar_coordinates.glsl diff --git a/shaders_ref/functions/radial_shear.glsl b/shaders/functions/radial_shear.glsl similarity index 100% rename from shaders_ref/functions/radial_shear.glsl rename to shaders/functions/radial_shear.glsl diff --git a/shaders_ref/functions/random.glsl b/shaders/functions/random.glsl similarity index 100% rename from shaders_ref/functions/random.glsl rename to shaders/functions/random.glsl diff --git a/shaders_ref/functions/reconstruct_normal.glsl b/shaders/functions/reconstruct_normal.glsl similarity index 100% rename from shaders_ref/functions/reconstruct_normal.glsl rename to shaders/functions/reconstruct_normal.glsl diff --git a/shaders_ref/functions/reconstruct_position.glsl b/shaders/functions/reconstruct_position.glsl similarity index 100% rename from shaders_ref/functions/reconstruct_position.glsl rename to shaders/functions/reconstruct_position.glsl diff --git a/shaders_ref/functions/rectangle.glsl b/shaders/functions/rectangle.glsl similarity index 100% rename from shaders_ref/functions/rectangle.glsl rename to shaders/functions/rectangle.glsl diff --git a/shaders_ref/functions/refraction_sphere.glsl b/shaders/functions/refraction_sphere.glsl similarity index 100% rename from shaders_ref/functions/refraction_sphere.glsl rename to shaders/functions/refraction_sphere.glsl diff --git a/shaders_ref/functions/rotate_uv.glsl b/shaders/functions/rotate_uv.glsl similarity index 100% rename from shaders_ref/functions/rotate_uv.glsl rename to shaders/functions/rotate_uv.glsl diff --git a/shaders_ref/functions/scale_uv_by_center.glsl b/shaders/functions/scale_uv_by_center.glsl similarity index 100% rename from shaders_ref/functions/scale_uv_by_center.glsl rename to shaders/functions/scale_uv_by_center.glsl diff --git a/shaders_ref/functions/sphere_mask.glsl b/shaders/functions/sphere_mask.glsl similarity index 100% rename from shaders_ref/functions/sphere_mask.glsl rename to shaders/functions/sphere_mask.glsl diff --git a/shaders_ref/functions/spherize_uv.glsl b/shaders/functions/spherize_uv.glsl similarity index 100% rename from shaders_ref/functions/spherize_uv.glsl rename to shaders/functions/spherize_uv.glsl diff --git a/shaders_ref/functions/tiling_offset.glsl b/shaders/functions/tiling_offset.glsl similarity index 100% rename from shaders_ref/functions/tiling_offset.glsl rename to shaders/functions/tiling_offset.glsl diff --git a/shaders_ref/functions/tone_mapping.glsl b/shaders/functions/tone_mapping.glsl similarity index 100% rename from shaders_ref/functions/tone_mapping.glsl rename to shaders/functions/tone_mapping.glsl diff --git a/shaders_ref/functions/trace_ray.glsl b/shaders/functions/trace_ray.glsl similarity index 100% rename from shaders_ref/functions/trace_ray.glsl rename to shaders/functions/trace_ray.glsl diff --git a/shaders_ref/functions/twirl.glsl b/shaders/functions/twirl.glsl similarity index 100% rename from shaders_ref/functions/twirl.glsl rename to shaders/functions/twirl.glsl diff --git a/shaders_ref/instance/instance.glsl b/shaders/instance/instance.glsl similarity index 100% rename from shaders_ref/instance/instance.glsl rename to shaders/instance/instance.glsl diff --git a/shaders_ref/interface_block/effect_fs.glsl b/shaders/interface_block/effect_fs.glsl similarity index 100% rename from shaders_ref/interface_block/effect_fs.glsl rename to shaders/interface_block/effect_fs.glsl diff --git a/shaders_ref/interface_block/effect_vs.glsl b/shaders/interface_block/effect_vs.glsl similarity index 100% rename from shaders_ref/interface_block/effect_vs.glsl rename to shaders/interface_block/effect_vs.glsl diff --git a/shaders_ref/interface_block/fragment.glsl b/shaders/interface_block/fragment.glsl similarity index 100% rename from shaders_ref/interface_block/fragment.glsl rename to shaders/interface_block/fragment.glsl diff --git a/shaders_ref/interface_block/mesh_fs.glsl b/shaders/interface_block/mesh_fs.glsl similarity index 100% rename from shaders_ref/interface_block/mesh_fs.glsl rename to shaders/interface_block/mesh_fs.glsl diff --git a/shaders_ref/interface_block/mesh_vs.glsl b/shaders/interface_block/mesh_vs.glsl similarity index 100% rename from shaders_ref/interface_block/mesh_vs.glsl rename to shaders/interface_block/mesh_vs.glsl diff --git a/shaders_ref/interface_block/pass_through.glsl b/shaders/interface_block/pass_through.glsl similarity index 100% rename from shaders_ref/interface_block/pass_through.glsl rename to shaders/interface_block/pass_through.glsl diff --git a/shaders_ref/interface_block/tess_control_input.glsl b/shaders/interface_block/tess_control_input.glsl similarity index 100% rename from shaders_ref/interface_block/tess_control_input.glsl rename to shaders/interface_block/tess_control_input.glsl diff --git a/shaders_ref/interface_block/tess_control_output.glsl b/shaders/interface_block/tess_control_output.glsl similarity index 100% rename from shaders_ref/interface_block/tess_control_output.glsl rename to shaders/interface_block/tess_control_output.glsl diff --git a/shaders_ref/interface_block/tess_control_pass.glsl b/shaders/interface_block/tess_control_pass.glsl similarity index 100% rename from shaders_ref/interface_block/tess_control_pass.glsl rename to shaders/interface_block/tess_control_pass.glsl diff --git a/shaders_ref/interface_block/vertex.glsl b/shaders/interface_block/vertex.glsl similarity index 100% rename from shaders_ref/interface_block/vertex.glsl rename to shaders/interface_block/vertex.glsl diff --git a/shaders_ref/lighting/ambient.glsl b/shaders/lighting/ambient.glsl similarity index 100% rename from shaders_ref/lighting/ambient.glsl rename to shaders/lighting/ambient.glsl diff --git a/shaders_ref/lighting/directional_shadows.frag b/shaders/lighting/directional_shadows.frag similarity index 100% rename from shaders_ref/lighting/directional_shadows.frag rename to shaders/lighting/directional_shadows.frag diff --git a/shaders_ref/lighting/directional_shadows.vert b/shaders/lighting/directional_shadows.vert similarity index 100% rename from shaders_ref/lighting/directional_shadows.vert rename to shaders/lighting/directional_shadows.vert diff --git a/shaders_ref/lighting/light.glsl b/shaders/lighting/light.glsl similarity index 100% rename from shaders_ref/lighting/light.glsl rename to shaders/lighting/light.glsl diff --git a/shaders_ref/lighting/lighting.glsl b/shaders/lighting/lighting.glsl similarity index 100% rename from shaders_ref/lighting/lighting.glsl rename to shaders/lighting/lighting.glsl diff --git a/shaders_ref/lighting/lighting_context.glsl b/shaders/lighting/lighting_context.glsl similarity index 100% rename from shaders_ref/lighting/lighting_context.glsl rename to shaders/lighting/lighting_context.glsl diff --git a/shaders_ref/lighting/refraction.glsl b/shaders/lighting/refraction.glsl similarity index 100% rename from shaders_ref/lighting/refraction.glsl rename to shaders/lighting/refraction.glsl diff --git a/shaders_ref/lighting/scene_lighting.glsl b/shaders/lighting/scene_lighting.glsl similarity index 100% rename from shaders_ref/lighting/scene_lighting.glsl rename to shaders/lighting/scene_lighting.glsl diff --git a/shaders_ref/lighting/shadows.glsl b/shaders/lighting/shadows.glsl similarity index 100% rename from shaders_ref/lighting/shadows.glsl rename to shaders/lighting/shadows.glsl diff --git a/shaders_ref/lighting/ssao.glsl b/shaders/lighting/ssao.glsl similarity index 100% rename from shaders_ref/lighting/ssao.glsl rename to shaders/lighting/ssao.glsl diff --git a/shaders_ref/lighting/ssr.glsl b/shaders/lighting/ssr.glsl similarity index 100% rename from shaders_ref/lighting/ssr.glsl rename to shaders/lighting/ssr.glsl diff --git a/shaders_ref/material/material.glsl b/shaders/material/material.glsl similarity index 100% rename from shaders_ref/material/material.glsl rename to shaders/material/material.glsl diff --git a/shaders_ref/material/material_context.glsl b/shaders/material/material_context.glsl similarity index 100% rename from shaders_ref/material/material_context.glsl rename to shaders/material/material_context.glsl diff --git a/shaders_ref/pipeline/color_picker.frag b/shaders/pipeline/color_picker.frag similarity index 100% rename from shaders_ref/pipeline/color_picker.frag rename to shaders/pipeline/color_picker.frag diff --git a/shaders_ref/pipeline/color_picker.vert b/shaders/pipeline/color_picker.vert similarity index 100% rename from shaders_ref/pipeline/color_picker.vert rename to shaders/pipeline/color_picker.vert diff --git a/shaders_ref/pipeline/composite.frag b/shaders/pipeline/composite.frag similarity index 100% rename from shaders_ref/pipeline/composite.frag rename to shaders/pipeline/composite.frag diff --git a/shaders_ref/pipeline/composite.vert b/shaders/pipeline/composite.vert similarity index 100% rename from shaders_ref/pipeline/composite.vert rename to shaders/pipeline/composite.vert diff --git a/shaders_ref/pipeline/deferred.frag b/shaders/pipeline/deferred.frag similarity index 100% rename from shaders_ref/pipeline/deferred.frag rename to shaders/pipeline/deferred.frag diff --git a/shaders_ref/pipeline/deferred.vert b/shaders/pipeline/deferred.vert similarity index 100% rename from shaders_ref/pipeline/deferred.vert rename to shaders/pipeline/deferred.vert diff --git a/shaders_ref/pipeline/depth.frag b/shaders/pipeline/depth.frag similarity index 100% rename from shaders_ref/pipeline/depth.frag rename to shaders/pipeline/depth.frag diff --git a/shaders_ref/pipeline/depth.vert b/shaders/pipeline/depth.vert similarity index 100% rename from shaders_ref/pipeline/depth.vert rename to shaders/pipeline/depth.vert diff --git a/shaders_ref/pipeline/forward.frag b/shaders/pipeline/forward.frag similarity index 100% rename from shaders_ref/pipeline/forward.frag rename to shaders/pipeline/forward.frag diff --git a/shaders_ref/pipeline/forward.vert b/shaders/pipeline/forward.vert similarity index 100% rename from shaders_ref/pipeline/forward.vert rename to shaders/pipeline/forward.vert diff --git a/shaders_ref/pipeline/gbuffer.frag b/shaders/pipeline/gbuffer.frag similarity index 100% rename from shaders_ref/pipeline/gbuffer.frag rename to shaders/pipeline/gbuffer.frag diff --git a/shaders_ref/pipeline/gbuffer.glsl b/shaders/pipeline/gbuffer.glsl similarity index 100% rename from shaders_ref/pipeline/gbuffer.glsl rename to shaders/pipeline/gbuffer.glsl diff --git a/shaders_ref/pipeline/gbuffer.vert b/shaders/pipeline/gbuffer.vert similarity index 100% rename from shaders_ref/pipeline/gbuffer.vert rename to shaders/pipeline/gbuffer.vert diff --git a/shaders_ref/pipeline/gbuffer_context.glsl b/shaders/pipeline/gbuffer_context.glsl similarity index 100% rename from shaders_ref/pipeline/gbuffer_context.glsl rename to shaders/pipeline/gbuffer_context.glsl diff --git a/shaders_ref/pipeline/quad.frag b/shaders/pipeline/quad.frag similarity index 100% rename from shaders_ref/pipeline/quad.frag rename to shaders/pipeline/quad.frag diff --git a/shaders_ref/pipeline/quad.vert b/shaders/pipeline/quad.vert similarity index 100% rename from shaders_ref/pipeline/quad.vert rename to shaders/pipeline/quad.vert diff --git a/shaders_ref/pipeline/scene.glsl b/shaders/pipeline/scene.glsl similarity index 100% rename from shaders_ref/pipeline/scene.glsl rename to shaders/pipeline/scene.glsl diff --git a/shaders_ref/pipeline/skybox.frag b/shaders/pipeline/skybox.frag similarity index 100% rename from shaders_ref/pipeline/skybox.frag rename to shaders/pipeline/skybox.frag diff --git a/shaders_ref/pipeline/skybox.vert b/shaders/pipeline/skybox.vert similarity index 100% rename from shaders_ref/pipeline/skybox.vert rename to shaders/pipeline/skybox.vert diff --git a/shaders_ref/postprocessing/bloom/blur_downsample.frag b/shaders/postprocessing/bloom/blur_downsample.frag similarity index 100% rename from shaders_ref/postprocessing/bloom/blur_downsample.frag rename to shaders/postprocessing/bloom/blur_downsample.frag diff --git a/shaders_ref/postprocessing/bloom/blur_downsample.vert b/shaders/postprocessing/bloom/blur_downsample.vert similarity index 100% rename from shaders_ref/postprocessing/bloom/blur_downsample.vert rename to shaders/postprocessing/bloom/blur_downsample.vert diff --git a/shaders_ref/postprocessing/bloom/blur_upsample.frag b/shaders/postprocessing/bloom/blur_upsample.frag similarity index 100% rename from shaders_ref/postprocessing/bloom/blur_upsample.frag rename to shaders/postprocessing/bloom/blur_upsample.frag diff --git a/shaders_ref/postprocessing/bloom/blur_upsample.vert b/shaders/postprocessing/bloom/blur_upsample.vert similarity index 100% rename from shaders_ref/postprocessing/bloom/blur_upsample.vert rename to shaders/postprocessing/bloom/blur_upsample.vert diff --git a/shaders_ref/postprocessing/bloom/brightness.frag b/shaders/postprocessing/bloom/brightness.frag similarity index 100% rename from shaders_ref/postprocessing/bloom/brightness.frag rename to shaders/postprocessing/bloom/brightness.frag diff --git a/shaders_ref/postprocessing/bloom/brightness.vert b/shaders/postprocessing/bloom/brightness.vert similarity index 100% rename from shaders_ref/postprocessing/bloom/brightness.vert rename to shaders/postprocessing/bloom/brightness.vert diff --git a/shaders_ref/postprocessing/dof.frag b/shaders/postprocessing/dof.frag similarity index 100% rename from shaders_ref/postprocessing/dof.frag rename to shaders/postprocessing/dof.frag diff --git a/shaders_ref/postprocessing/dof.vert b/shaders/postprocessing/dof.vert similarity index 100% rename from shaders_ref/postprocessing/dof.vert rename to shaders/postprocessing/dof.vert diff --git a/shaders_ref/postprocessing/fxaa.frag b/shaders/postprocessing/fxaa.frag similarity index 100% rename from shaders_ref/postprocessing/fxaa.frag rename to shaders/postprocessing/fxaa.frag diff --git a/shaders_ref/postprocessing/fxaa.vert b/shaders/postprocessing/fxaa.vert similarity index 100% rename from shaders_ref/postprocessing/fxaa.vert rename to shaders/postprocessing/fxaa.vert diff --git a/shaders_ref/postprocessing/postprocess.frag b/shaders/postprocessing/postprocess.frag similarity index 100% rename from shaders_ref/postprocessing/postprocess.frag rename to shaders/postprocessing/postprocess.frag diff --git a/shaders_ref/postprocessing/postprocess.vert b/shaders/postprocessing/postprocess.vert similarity index 100% rename from shaders_ref/postprocessing/postprocess.vert rename to shaders/postprocessing/postprocess.vert diff --git a/shaders_ref/postprocessing/ssao/ssao.frag b/shaders/postprocessing/ssao/ssao.frag similarity index 100% rename from shaders_ref/postprocessing/ssao/ssao.frag rename to shaders/postprocessing/ssao/ssao.frag diff --git a/shaders_ref/postprocessing/ssao/ssao.vert b/shaders/postprocessing/ssao/ssao.vert similarity index 100% rename from shaders_ref/postprocessing/ssao/ssao.vert rename to shaders/postprocessing/ssao/ssao.vert diff --git a/shaders_ref/postprocessing/ssao/ssao_blur.frag b/shaders/postprocessing/ssao/ssao_blur.frag similarity index 100% rename from shaders_ref/postprocessing/ssao/ssao_blur.frag rename to shaders/postprocessing/ssao/ssao_blur.frag diff --git a/shaders_ref/postprocessing/ssao/ssao_blur.vert b/shaders/postprocessing/ssao/ssao_blur.vert similarity index 100% rename from shaders_ref/postprocessing/ssao/ssao_blur.vert rename to shaders/postprocessing/ssao/ssao_blur.vert diff --git a/shaders_ref/postprocessing/ssr/ssr.frag b/shaders/postprocessing/ssr/ssr.frag similarity index 100% rename from shaders_ref/postprocessing/ssr/ssr.frag rename to shaders/postprocessing/ssr/ssr.frag diff --git a/shaders_ref/postprocessing/ssr/ssr.vert b/shaders/postprocessing/ssr/ssr.vert similarity index 100% rename from shaders_ref/postprocessing/ssr/ssr.vert rename to shaders/postprocessing/ssr/ssr.vert diff --git a/shaders_ref/shading/custom.glsl b/shaders/shading/custom.glsl similarity index 100% rename from shaders_ref/shading/custom.glsl rename to shaders/shading/custom.glsl diff --git a/shaders_ref/shading/regular.glsl b/shaders/shading/regular.glsl similarity index 100% rename from shaders_ref/shading/regular.glsl rename to shaders/shading/regular.glsl diff --git a/shaders_ref/shading/shading_context.glsl b/shaders/shading/shading_context.glsl similarity index 100% rename from shaders_ref/shading/shading_context.glsl rename to shaders/shading/shading_context.glsl diff --git a/shaders_ref/shading/shading_context_from_gctx.glsl b/shaders/shading/shading_context_from_gctx.glsl similarity index 100% rename from shaders_ref/shading/shading_context_from_gctx.glsl rename to shaders/shading/shading_context_from_gctx.glsl diff --git a/shaders_ref/shading/shading_context_from_mctx.glsl b/shaders/shading/shading_context_from_mctx.glsl similarity index 100% rename from shaders_ref/shading/shading_context_from_mctx.glsl rename to shaders/shading/shading_context_from_mctx.glsl diff --git a/shaders_ref/shading/shading_gctx.glsl b/shaders/shading/shading_gctx.glsl similarity index 100% rename from shaders_ref/shading/shading_gctx.glsl rename to shaders/shading/shading_gctx.glsl diff --git a/shaders_ref/shading/shading_mctx.glsl b/shaders/shading/shading_mctx.glsl similarity index 100% rename from shaders_ref/shading/shading_mctx.glsl rename to shaders/shading/shading_mctx.glsl diff --git a/shaders_ref/text/text.frag b/shaders/text/text.frag similarity index 100% rename from shaders_ref/text/text.frag rename to shaders/text/text.frag diff --git a/shaders_ref/text/text.vert b/shaders/text/text.vert similarity index 100% rename from shaders_ref/text/text.vert rename to shaders/text/text.vert diff --git a/shaders_ref/text/text_selection.frag b/shaders/text/text_selection.frag similarity index 100% rename from shaders_ref/text/text_selection.frag rename to shaders/text/text_selection.frag diff --git a/shaders_ref/text/text_selection.vert b/shaders/text/text_selection.vert similarity index 100% rename from shaders_ref/text/text_selection.vert rename to shaders/text/text_selection.vert diff --git a/shaders_ref/vertex_streams/beam_emitter.glsl b/shaders/vertex_streams/beam_emitter.glsl similarity index 100% rename from shaders_ref/vertex_streams/beam_emitter.glsl rename to shaders/vertex_streams/beam_emitter.glsl diff --git a/shaders_ref/vertex_streams/mesh_emitter.glsl b/shaders/vertex_streams/mesh_emitter.glsl similarity index 100% rename from shaders_ref/vertex_streams/mesh_emitter.glsl rename to shaders/vertex_streams/mesh_emitter.glsl diff --git a/shaders_ref/vertex_streams/model_mesh.glsl b/shaders/vertex_streams/model_mesh.glsl similarity index 100% rename from shaders_ref/vertex_streams/model_mesh.glsl rename to shaders/vertex_streams/model_mesh.glsl diff --git a/shaders_ref/vertex_streams/sprite_emitter.glsl b/shaders/vertex_streams/sprite_emitter.glsl similarity index 100% rename from shaders_ref/vertex_streams/sprite_emitter.glsl rename to shaders/vertex_streams/sprite_emitter.glsl diff --git a/shaders_ref/vertex_streams/vertex_stream.glsl b/shaders/vertex_streams/vertex_stream.glsl similarity index 100% rename from shaders_ref/vertex_streams/vertex_stream.glsl rename to shaders/vertex_streams/vertex_stream.glsl diff --git a/shaders_ref/API.md b/shaders_ref/API.md deleted file mode 100644 index b8ef458d..00000000 --- a/shaders_ref/API.md +++ /dev/null @@ -1,36 +0,0 @@ -Material shading models: - unlit - lit (pbr) - cloth - subsurface - custom - -lit pbr - color - diffuse albedo - metallic - roughness - reflectance - ambient occlusion - normal - emissive - ior - absorption - transmission - - -How final surface color is calculated: - -1) You should compute MaterialContext - MaterialContext already contains default material parameters and user invoked code to customize this parameters -2) You should compute ShadingContext from MaterialContext or pass parameters yourself -3) Lighting is calculated from ShadingContext -4) - - -transmission/ absorption / energyconserv ? - -refraction works only on translucent objects = forward render after deferred - - -make shaders include-consistent \ No newline at end of file diff --git a/src/limitless/assets.cpp b/src/limitless/assets.cpp index c2438af2..9d220af7 100644 --- a/src/limitless/assets.cpp +++ b/src/limitless/assets.cpp @@ -19,7 +19,7 @@ using namespace Limitless; Assets::Assets(const fs::path& _base_dir) noexcept : base_dir {_base_dir} - , shader_dir {_base_dir / "../shaders_ref"} { + , shader_dir {_base_dir / "../shaders"} { } Assets::Assets(fs::path _base_dir, fs::path _shader_dir) noexcept From 368702590f2712c2a0f00572c8ae0c190fd1b134 Mon Sep 17 00:00:00 2001 From: hotstreams Date: Tue, 28 Nov 2023 22:51:10 +0300 Subject: [PATCH 13/15] another ref --- demo/lighting_demoscene.cpp | 2 +- demo/materials_demoscene.cpp | 15 +++++++++++++-- include/limitless/renderer/render_settings.hpp | 2 +- shaders/lighting/lighting_context.glsl | 2 +- src/limitless/lighting/cascade_shadows.cpp | 9 ++++++++- src/limitless/util/renderer_helper.cpp | 9 +++++---- 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/demo/lighting_demoscene.cpp b/demo/lighting_demoscene.cpp index c284910d..e92144a6 100644 --- a/demo/lighting_demoscene.cpp +++ b/demo/lighting_demoscene.cpp @@ -75,7 +75,7 @@ LightingScene::LightingScene(Limitless::Context& ctx, const Limitless::Assets& a scene.getLighting().getAmbientColor().a = 0.7f; scene.add(Light::builder() .color(glm::vec4(1.0, 1.0, 0.5, 1.0f)) - .direction(glm::vec3{1.0f}) + .direction(glm::vec3{-1.0f}) .build() ); } diff --git a/demo/materials_demoscene.cpp b/demo/materials_demoscene.cpp index c7ae4310..7f5e0937 100644 --- a/demo/materials_demoscene.cpp +++ b/demo/materials_demoscene.cpp @@ -12,18 +12,20 @@ MaterialsScene::MaterialsScene(Limitless::Context& ctx, Limitless::Assets& asset : scene(ctx) { addModels(assets); + scene.getLighting().setAmbientColor(glm::vec4(1.0f)); + scene.setSkybox(assets.skyboxes.at("skybox")); scene.add(Light::builder() .color(glm::vec4(1.0, 1.0, 1.0, 1.0f)) - .direction(glm::vec3{-1.0f}) + .direction(glm::vec3{0.0f, -1.0f, 0.0f}) .build() ); scene.add(Light::builder() .position({0.0f, 0.5f, 0.0f}) .color({1.0f, 0.0f, 0.0f, 2.0f}) - .radius(2.0f) + .radius(1.0f) .build() ); @@ -40,6 +42,15 @@ MaterialsScene::MaterialsScene(Limitless::Context& ctx, Limitless::Assets& asset .radius(2.0f) .build() ); + + scene.add(Light::builder() + .position({5.0f, 0.5f, 5.0f}) + .color({0.0f, 0.0f, 1.0f, 1.0f}) + .cone(30.0f, 15.0f) + .direction({0.0f, -1.0f, 0.0f}) + .radius(1.0f) + .build() + ); } void MaterialsScene::addModels(const Limitless::Assets& assets) { diff --git a/include/limitless/renderer/render_settings.hpp b/include/limitless/renderer/render_settings.hpp index 266f1b01..9557667d 100644 --- a/include/limitless/renderer/render_settings.hpp +++ b/include/limitless/renderer/render_settings.hpp @@ -88,7 +88,7 @@ namespace Limitless { /** * Render lights impact area */ - bool light_radius = false; + bool light_radius = true; /** * Render System Axes diff --git a/shaders/lighting/lighting_context.glsl b/shaders/lighting/lighting_context.glsl index 874ebb41..8d8c0cf2 100644 --- a/shaders/lighting/lighting_context.glsl +++ b/shaders/lighting/lighting_context.glsl @@ -29,7 +29,7 @@ float getAttenuation(const ShadingContext sctx, const Light light) { attenuation = attenuation / max(distanceSquare, 1e-4); if (light.type == LIGHT_TYPE_SPOT) { - float cd = dot(-light.direction.xyz, L); + float cd = dot(-light.direction.xyz, normalize(light.position.xyz - sctx.worldPos)); float att = saturate(cd * light.scale_offset.x + light.scale_offset.y); float att2 = att * att; attenuation *= att2; diff --git a/src/limitless/lighting/cascade_shadows.cpp b/src/limitless/lighting/cascade_shadows.cpp index 166beedd..92b464ef 100644 --- a/src/limitless/lighting/cascade_shadows.cpp +++ b/src/limitless/lighting/cascade_shadows.cpp @@ -15,6 +15,7 @@ #include #include +#include using namespace Limitless; @@ -130,7 +131,13 @@ void CascadeShadows::updateLightMatrices(const Light& light) { // clear matrices light_space.clear(); - const auto view = glm::lookAt(-light.getDirection(), { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }); + auto up = glm::vec3{0.0f, 1.0f, 0.0f}; + + if (glm::abs(glm::dot(up, light.getDirection())) > 0.999f) { + up = {0.0f, 0.0f, 1.0f}; + } + + const auto view = glm::lookAt(-light.getDirection(), { 0.0f, 0.0f, 0.0f }, up); for (auto& frustum : frustums) { glm::vec3 max = {std::numeric_limits::min(), std::numeric_limits::min(), 0.0f}; glm::vec3 min = {std::numeric_limits::max(), std::numeric_limits::max(), 0.0f}; diff --git a/src/limitless/util/renderer_helper.cpp b/src/limitless/util/renderer_helper.cpp index 186aafe7..f802e497 100644 --- a/src/limitless/util/renderer_helper.cpp +++ b/src/limitless/util/renderer_helper.cpp @@ -21,7 +21,7 @@ RendererHelper::RendererHelper(const RenderSettings& _settings) } void RendererHelper::renderLightsVolume(Context& context, const Lighting& lighting, const Assets& assets, const Camera& camera) { - if (lighting.getLights().size() != 0) { + if (lighting.getLights().empty()) { return; } @@ -41,21 +41,22 @@ void RendererHelper::renderLightsVolume(Context& context, const Lighting& lighti sphere_instance.draw(context, assets, ShaderType::Forward, ms::Blending::Opaque); } if (light.isSpot()) { - auto cone = std::make_shared(0.0f, light.getRadius() * std::sin(glm::acos(light.getCone().x)), light.getRadius()); + auto cone = std::make_shared(0.0f, light.getRadius() / 1.5f * glm::sin(glm::acos(glm::radians(light.getCone().y))), light.getRadius()); auto cone_instance = ModelInstance(cone, assets.materials.at("default"), glm::vec3(0.0f)); cone_instance.setPosition(light.getPosition()); auto y = glm::vec3{0.0f, 1.0f, 0.0f}; auto a = glm::cross(y, light.getDirection()); + if (a == glm::vec3(0.0f)) { + a = glm::vec3(1.0f, 0.0f, 0.0f); + } auto angle = glm::acos(glm::dot(y, light.getDirection())); cone_instance.setRotation(a * angle); cone_instance.update(context, camera); cone_instance.draw(context, assets, ShaderType::Forward, ms::Blending::Opaque); } - - } context.setPolygonMode(CullFace::FrontBack, PolygonMode::Fill); From 7e3a35b22c375c35322cb872f7648ca30e26eaaf Mon Sep 17 00:00:00 2001 From: hotstreams Date: Sun, 3 Dec 2023 15:40:26 +0300 Subject: [PATCH 14/15] ref --- include/limitless/renderer/render_settings.hpp | 4 ++-- src/limitless/pipeline/common/ssao_pass.cpp | 2 +- src/limitless/postprocessing/ssr.cpp | 2 +- src/limitless/util/stack_trace.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/limitless/renderer/render_settings.hpp b/include/limitless/renderer/render_settings.hpp index 9557667d..36cd63a3 100644 --- a/include/limitless/renderer/render_settings.hpp +++ b/include/limitless/renderer/render_settings.hpp @@ -88,12 +88,12 @@ namespace Limitless { /** * Render lights impact area */ - bool light_radius = true; + bool light_radius = false; /** * Render System Axes */ - bool coordinate_system_axes = true; + bool coordinate_system_axes = false; /** * Render bounding boxes diff --git a/src/limitless/pipeline/common/ssao_pass.cpp b/src/limitless/pipeline/common/ssao_pass.cpp index b9943405..604e01ee 100644 --- a/src/limitless/pipeline/common/ssao_pass.cpp +++ b/src/limitless/pipeline/common/ssao_pass.cpp @@ -38,7 +38,7 @@ void SSAOPass::onFramebufferChange(glm::uvec2 size) { ssao.onFramebufferChange(size); } -void SSAOPass::update(Scene &scene, Instances &instances, Context &ctx, const Camera &camera) { +void SSAOPass::update([[maybe_unused]] Scene &scene, [[maybe_unused]] Instances &instances, [[maybe_unused]] Context &ctx, const Camera &camera) { ssao.update(camera); } diff --git a/src/limitless/postprocessing/ssr.cpp b/src/limitless/postprocessing/ssr.cpp index 9c409319..c22e561d 100644 --- a/src/limitless/postprocessing/ssr.cpp +++ b/src/limitless/postprocessing/ssr.cpp @@ -47,7 +47,7 @@ SSR::SSR(ContextEventObserver &ctx, glm::uvec2 frame_size) framebuffer.unbind(); } -void SSR::draw(Context& ctx, const Assets& assets, const Camera& camera, +void SSR::draw(Context& ctx, const Assets& assets, [[maybe_unused]] const Camera& camera, const std::shared_ptr& depth, const std::shared_ptr& normal, const std::shared_ptr& props, diff --git a/src/limitless/util/stack_trace.cpp b/src/limitless/util/stack_trace.cpp index 77424c63..f1635ac2 100644 --- a/src/limitless/util/stack_trace.cpp +++ b/src/limitless/util/stack_trace.cpp @@ -124,7 +124,7 @@ StackTrace Limitless::getStackTrace(size_t frames_to_skip, size_t max_frames) { for (USHORT i = 0; i < frame_num; ++i) { DWORD64 displacement; - DWORD disp; + //DWORD disp; bool has_symbol {false}; // bool has_line {false}; From 38095cd53a8e58e9c73ba54ebd90ac06d43447ab Mon Sep 17 00:00:00 2001 From: hotstreams Date: Sun, 3 Dec 2023 16:15:02 +0300 Subject: [PATCH 15/15] fix --- demo/effects_demoscene.cpp | 38 +++++++------- src/limitless/loaders/gltf_model_loader.cpp | 58 ++++++++++----------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/demo/effects_demoscene.cpp b/demo/effects_demoscene.cpp index faa6450f..51011520 100644 --- a/demo/effects_demoscene.cpp +++ b/demo/effects_demoscene.cpp @@ -55,25 +55,25 @@ void EffectsScene::addInstances(Limitless::Assets& assets) { .build() ); - auto bob = Instance::builder() - .model(assets.models.at("bob")) - .position({29.0f, 1.0f, 19.0f}) - .rotation(glm::vec3{0.0f, -M_PI_2, M_PI}) - .scale(glm::vec3(0.025f)) - .asSkeletal(); - bob->play(""); - scene.add(bob); - - auto mod = Instance::builder() - .effect(assets.effects.at("modeldrop")) - .position({0.0f, 0.0f, 0.0f}) - .asEffect(); - - const auto& module = mod->get("sparks") - .getModule(fx::ModuleType::InitialMeshLocation); - dynamic_cast&>(*module) - .attachModelInstance(bob.get()); - scene.add(mod); +// auto bob = Instance::builder() +// .model(assets.models.at("bob")) +// .position({29.0f, 1.0f, 19.0f}) +// .rotation(glm::vec3{0.0f, -M_PI_2, M_PI}) +// .scale(glm::vec3(0.025f)) +// .asSkeletal(); +// bob->play(""); +// scene.add(bob); + +// auto mod = Instance::builder() +// .effect(assets.effects.at("modeldrop")) +// .position({0.0f, 0.0f, 0.0f}) +// .asEffect(); +// +// const auto& module = mod->get("sparks") +// .getModule(fx::ModuleType::InitialMeshLocation); +// dynamic_cast&>(*module) +// .attachModelInstance(bob.get()); +// scene.add(mod); scene.add(Instance::builder() .effect(assets.effects.at("skeleton")) diff --git a/src/limitless/loaders/gltf_model_loader.cpp b/src/limitless/loaders/gltf_model_loader.cpp index dc049230..bed61909 100644 --- a/src/limitless/loaders/gltf_model_loader.cpp +++ b/src/limitless/loaders/gltf_model_loader.cpp @@ -655,26 +655,25 @@ static std::shared_ptr loadMaterial( const std::string& model_name, size_t material_index ) { - ms::MaterialBuilder builder {assets}; + ms::Material::Builder builder = ms::Material::builder(); builder - .setName( + .name( material.name ? std::string(material.name) : generateMaterialName(model_name, material_index) ) - .setShading(material.unlit ? ms::Shading::Unlit : ms::Shading::Lit) - .setTwoSided(material.double_sided); + .shading(material.unlit ? ms::Shading::Unlit : ms::Shading::Lit) + .two_sided(material.double_sided); switch (material.alpha_mode) { case cgltf_alpha_mode_opaque: - builder.setBlending(ms::Blending::Opaque); + builder.blending(ms::Blending::Opaque); break; case cgltf_alpha_mode_blend: - builder.setBlending(ms::Blending::Translucent); + builder.blending(ms::Blending::Translucent); break; default: - throw ModelLoadError { - "alpha mode " + std::to_string(material.alpha_mode) + " not supported"}; + throw ModelLoadError {"alpha mode " + std::to_string(material.alpha_mode) + " not supported"}; } if (!material.has_pbr_metallic_roughness) { @@ -686,7 +685,7 @@ static std::shared_ptr loadMaterial( if (base_color_tex == nullptr) { // no texture, this means that base color factor is the color. - builder.add(ms::Property::Color, toVec4(pbr_mr.base_color_factor)); + builder.color(toVec4(pbr_mr.base_color_factor)); } else { if (base_color_tex->image == nullptr) { @@ -700,8 +699,8 @@ static std::shared_ptr loadMaterial( const auto flags = TextureLoaderFlags(TextureLoaderFlags::Space::sRGB); // TODO: deduce other flags from cgltf sampler. - builder.add(ms::Property::Diffuse, TextureLoader::load(assets, path, flags)); - builder.add(ms::Property::Color, toVec4(pbr_mr.base_color_factor)); + builder.diffuse(TextureLoader::load(assets, path, flags)); + builder.color(toVec4(pbr_mr.base_color_factor)); // TODO: recall why this was here. // builder.setFragmentSnippet( // "data.baseColor.rgb = getMaterialDiffuse(getVertexUV()).rrr;" @@ -715,9 +714,9 @@ static std::shared_ptr loadMaterial( // These values MUST be encoded with a linear transfer function. const auto flags = TextureLoaderFlags(TextureLoaderFlags::Space::Linear); - builder.add(ms::Property::ORM, TextureLoader::load(assets, path, flags)); - builder.add(ms::Property::Metallic, pbr_mr.metallic_factor); - builder.add(ms::Property::Roughness, pbr_mr.roughness_factor); + builder.orm(TextureLoader::load(assets, path, flags)); + builder.metallic(pbr_mr.metallic_factor); + builder.roughness(pbr_mr.roughness_factor); } auto* normal_tex = material.normal_texture.texture; @@ -727,11 +726,12 @@ static std::shared_ptr loadMaterial( // These values MUST be encoded with a linear transfer function. const auto flags = TextureLoaderFlags(TextureLoaderFlags::Space::Linear); - builder.add(ms::Property::Normal, TextureLoader::load(assets, path, flags)); + builder.normal(TextureLoader::load(assets, path, flags)); } if (material.has_ior) { - builder.add(ms::Property::IoR, material.ior.ior); + builder.refraction(true); + builder.ior(material.ior.ior); } auto* emissive_tex = material.emissive_texture.texture; @@ -742,20 +742,20 @@ static std::shared_ptr loadMaterial( // function const auto flags = TextureLoaderFlags(TextureLoaderFlags::Space::sRGB); - builder.add(ms::Property::EmissiveMask, TextureLoader::load(assets, path, flags)); + builder.emissive_mask(TextureLoader::load(assets, path, flags)); } glm::vec3 emissive_rgb = toVec3(material.emissive_factor); if (emissive_rgb != glm::vec3(0.f)) { - glm::vec4 emissive_color(toVec3(material.emissive_factor), 1.0f); + glm::vec3 emissive_color(toVec3(material.emissive_factor)); if (material.has_emissive_strength) { - emissive_color.w = material.emissive_strength.emissive_strength; + emissive_color *= material.emissive_strength.emissive_strength; } - builder.add(ms::Property::EmissiveColor, emissive_color); + builder.emissive_color(emissive_color); } - return builder.setModelShaders(instance_types).build(); + return builder.models(instance_types).build(assets); } static std::vector> loadMaterials( @@ -780,13 +780,13 @@ static std::vector> loadMaterials( static std::shared_ptr makeDummyMaterial( Assets& assets, const std::string& model_name, const InstanceTypes& instance_types ) { - return ms::MaterialBuilder(assets) - .setName(generateMaterialName(model_name, 0)) - .setTwoSided(true) - .setShading(ms::Shading::Unlit) - .add(ms::Property::Color, glm::vec4(1.f, 0.f, 1.f, 1.f)) - .setModelShaders(instance_types) - .build(); + return ms::Material::builder() + .name(generateMaterialName(model_name, 0)) + .two_sided(true) + .shading(ms::Shading::Unlit) + .color({1.f, 0.f, 1.f, 1.f}) + .models(instance_types) + .build(assets); } // Fill in missing mesh materials with a dummy one if required. @@ -954,7 +954,7 @@ loadModel(Assets& assets, const fs::path& path, const cgltf_data& src) { } std::shared_ptr -GltfModelLoader::loadModel(Assets& assets, const fs::path& path, const ModelLoaderFlags& flags) { +GltfModelLoader::loadModel(Assets& assets, const fs::path& path, [[maybe_unused]] const ModelLoaderFlags& flags) { cgltf_options opts = cgltf_options { cgltf_file_type_invalid, // autodetect 0, // auto json token count