diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp index 37fb7e120..fb45fb9b1 100644 --- a/Editor/MaterialWindow.cpp +++ b/Editor/MaterialWindow.cpp @@ -405,6 +405,22 @@ void MaterialWindow::Create(EditorComponent* _editor) }); AddWidget(&emissiveSlider); + cloakSlider.Create(0, 1.0f, 0.02f, 1000, "Cloak: "); + cloakSlider.SetTooltip("The cloak effect is a combination of transmission, refraction and roughness, without color tinging."); + cloakSlider.SetSize(XMFLOAT2(wid, hei)); + cloakSlider.SetPos(XMFLOAT2(x, y += step)); + cloakSlider.OnSlide([&](wi::gui::EventArgs args) { + wi::scene::Scene& scene = editor->GetCurrentScene(); + for (auto& x : editor->translator.selected) + { + MaterialComponent* material = get_material(scene, x); + if (material == nullptr) + continue; + material->SetCloakAmount(args.fValue); + } + }); + AddWidget(&cloakSlider); + transmissionSlider.Create(0, 1.0f, 0.02f, 1000, "Transmission: "); transmissionSlider.SetTooltip("Adjust the transmissiveness. More transmissiveness means more diffuse light is transmitted instead of absorbed."); transmissionSlider.SetSize(XMFLOAT2(wid, hei)); @@ -1000,6 +1016,7 @@ void MaterialWindow::SetEntity(Entity entity) roughnessSlider.SetValue(material->roughness); reflectanceSlider.SetValue(material->reflectance); metalnessSlider.SetValue(material->metalness); + cloakSlider.SetValue(material->cloak); transmissionSlider.SetValue(material->transmission); refractionSlider.SetValue(material->refraction); emissiveSlider.SetValue(material->emissiveColor.w); @@ -1181,6 +1198,7 @@ void MaterialWindow::ResizeLayout() add(reflectanceSlider); add(metalnessSlider); add(emissiveSlider); + add(cloakSlider); add(transmissionSlider); add(refractionSlider); add(pomSlider); diff --git a/Editor/MaterialWindow.h b/Editor/MaterialWindow.h index 34fbb8e83..05feea0f0 100644 --- a/Editor/MaterialWindow.h +++ b/Editor/MaterialWindow.h @@ -30,6 +30,7 @@ public: wi::gui::Slider reflectanceSlider; wi::gui::Slider metalnessSlider; wi::gui::Slider emissiveSlider; + wi::gui::Slider cloakSlider; wi::gui::Slider transmissionSlider; wi::gui::Slider refractionSlider; wi::gui::Slider pomSlider; diff --git a/WickedEngine/shaders/ShaderInterop_Renderer.h b/WickedEngine/shaders/ShaderInterop_Renderer.h index cd2940500..0575fbf28 100644 --- a/WickedEngine/shaders/ShaderInterop_Renderer.h +++ b/WickedEngine/shaders/ShaderInterop_Renderer.h @@ -328,7 +328,7 @@ struct alignas(16) ShaderMaterial uint2 normalmap_pom_alphatest_displacement; uint2 roughness_reflectance_metalness_refraction; - uint2 emissive; + uint2 emissive_cloak; uint2 subsurfaceScattering; uint2 subsurfaceScattering_inv; @@ -356,7 +356,7 @@ struct alignas(16) ShaderMaterial normalmap_pom_alphatest_displacement = uint2(0, 0); roughness_reflectance_metalness_refraction = uint2(0, 0); - emissive = uint2(0, 0); + emissive_cloak = uint2(0, 0); subsurfaceScattering = uint2(0, 0); subsurfaceScattering_inv = uint2(0, 0); @@ -386,7 +386,8 @@ struct alignas(16) ShaderMaterial inline half4 GetBaseColor() { return unpack_half4(baseColor); } inline half4 GetSSS() { return unpack_half4(subsurfaceScattering); } inline half4 GetSSSInverse() { return unpack_half4(subsurfaceScattering_inv); } - inline half3 GetEmissive() { return unpack_half3(emissive); } + inline half3 GetEmissive() { return unpack_half4(emissive_cloak).rgb; } + inline half GetCloak() { return unpack_half4(emissive_cloak).a; } inline half3 GetSpecular() { return unpack_half3(specular); } inline half3 GetSheenColor() { return unpack_half3(sheenColor); } inline half GetRoughness() { return unpack_half4(roughness_reflectance_metalness_refraction).x; } diff --git a/WickedEngine/shaders/objectHF.hlsli b/WickedEngine/shaders/objectHF.hlsli index d6071a7c8..e81da927a 100644 --- a/WickedEngine/shaders/objectHF.hlsli +++ b/WickedEngine/shaders/objectHF.hlsli @@ -930,11 +930,11 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target #ifdef TRANSPARENT + surface.transmission = lerp(material.GetTransmission(), 1, material.GetCloak()); + [branch] - if (material.GetTransmission() > 0) + if (surface.transmission > 0) { - surface.transmission = material.GetTransmission(); - #ifdef OBJECTSHADER_USE_UVSETS [branch] if (material.textures[TRANSMISSIONMAP].IsValid()) @@ -952,9 +952,9 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target float mipLevels; texture_refraction.GetDimensions(0, size.x, size.y, mipLevels); const float2 normal2D = mul((float3x3)GetCamera().view, surface.N.xyz).xy; - float2 perturbatedRefrTexCoords = ScreenCoord.xy + normal2D * material.GetRefraction(); - half4 refractiveColor = texture_refraction.SampleLevel(sampler_linear_clamp, perturbatedRefrTexCoords, surface.roughness * mipLevels); - surface.refraction.rgb = surface.albedo * refractiveColor.rgb; + float2 perturbatedRefrTexCoords = ScreenCoord.xy + normal2D * lerp(material.GetRefraction(), 0.1, material.GetCloak()); + half4 refractiveColor = texture_refraction.SampleLevel(sampler_linear_clamp, perturbatedRefrTexCoords, lerp(surface.roughness, 0.1, material.GetCloak()) * mipLevels); + surface.refraction.rgb = lerp(surface.albedo, 1, material.GetCloak()) * refractiveColor.rgb; surface.refraction.a = surface.transmission; } } diff --git a/WickedEngine/shaders/raytraceCS.hlsl b/WickedEngine/shaders/raytraceCS.hlsl index 2b88cff60..1fbe8167e 100644 --- a/WickedEngine/shaders/raytraceCS.hlsl +++ b/WickedEngine/shaders/raytraceCS.hlsl @@ -339,7 +339,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) if (!surface.load(prim, q.CandidateTriangleBarycentrics())) break; - shadow *= lerp(1, surface.albedo * surface.transmission, surface.opacity); + shadow *= lerp(1, lerp(surface.albedo, 1, surface.material.GetCloak()) * surface.transmission, surface.opacity); [branch] if (!any(shadow)) @@ -375,10 +375,10 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) if (rng.next_float() < surface.transmission) { // Refraction - const float3 R = refract(ray.Direction, surface.N, 1 - surface.material.GetRefraction()); - float roughnessBRDF = sqr(clamp(surface.roughness, min_roughness, 1)); + const float3 R = refract(ray.Direction, surface.N, 1 - lerp(surface.material.GetRefraction(), 0.1, surface.material.GetCloak())); + float roughnessBRDF = sqr(clamp(lerp(surface.roughness, 0.1, surface.material.GetCloak()), min_roughness, 1)); ray.Direction = lerp(R, sample_hemisphere_cos(R, rng), roughnessBRDF); - energy *= surface.albedo / max(0.001, surface.transmission); + energy *= lerp(surface.albedo, 1, surface.material.GetCloak()) / max(0.001, surface.transmission); // Add a new bounce iteration, otherwise the transparent effect can disappear: bounce--; diff --git a/WickedEngine/shaders/shadowPS_transparent.hlsl b/WickedEngine/shaders/shadowPS_transparent.hlsl index 7892c0847..ddb7c799a 100644 --- a/WickedEngine/shaders/shadowPS_transparent.hlsl +++ b/WickedEngine/shaders/shadowPS_transparent.hlsl @@ -32,11 +32,13 @@ float4 main(PixelInput input) : SV_TARGET clip(color.a - material.GetAlphaTest() - meshinstance.alphaTest); float opacity = color.a; + + float transmission = lerp(material.GetTransmission(), 1, material.GetCloak()); + color.rgb = lerp(color.rgb, 1, material.GetCloak()); [branch] - if (material.GetTransmission() > 0) + if (transmission > 0) { - float transmission = material.GetTransmission(); [branch] if (material.textures[TRANSMISSIONMAP].IsValid()) { diff --git a/WickedEngine/shaders/surfaceHF.hlsli b/WickedEngine/shaders/surfaceHF.hlsli index 8ef44eaa8..322a8ee0d 100644 --- a/WickedEngine/shaders/surfaceHF.hlsli +++ b/WickedEngine/shaders/surfaceHF.hlsli @@ -880,7 +880,8 @@ struct Surface } } - transmission = material.GetTransmission(); + transmission = lerp(material.GetTransmission(), 1, material.GetCloak()); + [branch] if (material.textures[TRANSMISSIONMAP].IsValid()) { diff --git a/WickedEngine/wiRenderPath3D.cpp b/WickedEngine/wiRenderPath3D.cpp index 80edc95f5..fa8b45056 100644 --- a/WickedEngine/wiRenderPath3D.cpp +++ b/WickedEngine/wiRenderPath3D.cpp @@ -1633,8 +1633,6 @@ namespace wi RenderVolumetrics(cmd); - RenderSceneMIPChain(cmd); - RenderTransparents(cmd); // Depth buffers expect a non-pixel shader resource state as they are generated on compute queue: @@ -1949,6 +1947,10 @@ namespace wi { GraphicsDevice* device = wi::graphics::GetDevice(); + device->EventBegin("Copy scene tex only mip0 for ocean", cmd); + wi::renderer::Postprocess_Downsample4x(rtMain, rtSceneCopy, cmd); + device->EventEnd(cmd); + // Water ripple rendering: if (!scene->waterRipples.empty()) { @@ -2020,6 +2022,12 @@ namespace wi wi::renderer::DRAWSCENE_OCEAN ); + device->RenderPassEnd(cmd); + + RenderSceneMIPChain(cmd); + + device->RenderPassBegin(rp, getMSAASampleCount() > 1 ? 3 : 2, cmd); + // Note: volumetrics and light shafts are blended before transparent scene, because they used depth of the opaques // But the ocean is special, because it does have depth for them implicitly computed from ocean plane diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 885f68545..19026e98b 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -32,7 +32,7 @@ namespace wi::scene wi::ecs::ComponentManager& layers = componentLibrary.Register("wi::scene::Scene::layers"); wi::ecs::ComponentManager& transforms = componentLibrary.Register("wi::scene::Scene::transforms"); wi::ecs::ComponentManager& hierarchy = componentLibrary.Register("wi::scene::Scene::hierarchy"); - wi::ecs::ComponentManager& materials = componentLibrary.Register("wi::scene::Scene::materials", 5); // version = 5 + wi::ecs::ComponentManager& materials = componentLibrary.Register("wi::scene::Scene::materials", 6); // version = 6 wi::ecs::ComponentManager& meshes = componentLibrary.Register("wi::scene::Scene::meshes", 3); // version = 3 wi::ecs::ComponentManager& impostors = componentLibrary.Register("wi::scene::Scene::impostors"); wi::ecs::ComponentManager& objects = componentLibrary.Register("wi::scene::Scene::objects", 3); // version = 3 diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp index e6c664756..3959b172c 100644 --- a/WickedEngine/wiScene_BindLua.cpp +++ b/WickedEngine/wiScene_BindLua.cpp @@ -4433,6 +4433,7 @@ Luna::PropertyType MaterialComponent_BindLua::propert lunaproperty(MaterialComponent_BindLua, DisplacementMapping), lunaproperty(MaterialComponent_BindLua, Refraction), lunaproperty(MaterialComponent_BindLua, Transmission), + lunaproperty(MaterialComponent_BindLua, Cloak), lunaproperty(MaterialComponent_BindLua, AlphaRef), lunaproperty(MaterialComponent_BindLua, SheenColor), lunaproperty(MaterialComponent_BindLua, SheenRoughness), diff --git a/WickedEngine/wiScene_BindLua.h b/WickedEngine/wiScene_BindLua.h index b8c0b1410..5b477281b 100644 --- a/WickedEngine/wiScene_BindLua.h +++ b/WickedEngine/wiScene_BindLua.h @@ -418,6 +418,7 @@ namespace wi::lua::scene DisplacementMapping = FloatProperty(&component->displacementMapping); Refraction = FloatProperty(&component->refraction); Transmission = FloatProperty(&component->transmission); + Cloak = FloatProperty(&component->cloak); AlphaRef = FloatProperty(&component->alphaRef); SheenColor = VectorProperty(&component->sheenColor); SheenRoughness = FloatProperty(&component->sheenRoughness); @@ -453,6 +454,7 @@ namespace wi::lua::scene FloatProperty DisplacementMapping; FloatProperty Refraction; FloatProperty Transmission; + FloatProperty Cloak; FloatProperty AlphaRef; VectorProperty SheenColor; FloatProperty SheenRoughness; @@ -478,6 +480,7 @@ namespace wi::lua::scene PropertyFunction(DisplacementMapping) PropertyFunction(Refraction) PropertyFunction(Transmission) + PropertyFunction(Cloak) PropertyFunction(AlphaRef) PropertyFunction(SheenColor) PropertyFunction(SheenRoughness) diff --git a/WickedEngine/wiScene_Components.cpp b/WickedEngine/wiScene_Components.cpp index ea6a8fd0e..238e7391f 100644 --- a/WickedEngine/wiScene_Components.cpp +++ b/WickedEngine/wiScene_Components.cpp @@ -272,7 +272,7 @@ namespace wi::scene ShaderMaterial material; material.init(); material.baseColor = pack_half4(baseColor); - material.emissive = pack_half3(XMFLOAT3(emissiveColor.x * emissiveColor.w, emissiveColor.y * emissiveColor.w, emissiveColor.z * emissiveColor.w)); + material.emissive_cloak = pack_half4(XMFLOAT4(emissiveColor.x * emissiveColor.w, emissiveColor.y * emissiveColor.w, emissiveColor.z * emissiveColor.w, cloak)); material.specular = pack_half3(XMFLOAT3(specularColor.x * specularColor.w, specularColor.y * specularColor.w, specularColor.z * specularColor.w)); material.texMulAdd = texMulAdd; material.roughness_reflectance_metalness_refraction = pack_half4(roughness, reflectance, metalness, refraction); @@ -438,7 +438,7 @@ namespace wi::scene { return FILTER_TRANSPARENT | FILTER_WATER; } - if (transmission > 0) + if (transmission > 0 || cloak > 0) { return FILTER_TRANSPARENT; } diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index bd9ccc83f..f6b8bdda8 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -188,6 +188,7 @@ namespace wi::scene float anisotropy_strength = 0; float anisotropy_rotation = 0; //radians, counter-clockwise float blend_with_terrain_height = 0; + float cloak = 0; XMFLOAT4 sheenColor = XMFLOAT4(1, 1, 1, 1); float sheenRoughness = 0; @@ -292,6 +293,7 @@ namespace wi::scene inline void SetMetalness(float value) { SetDirty(); metalness = value; } inline void SetEmissiveStrength(float value) { SetDirty(); emissiveColor.w = value; } inline void SetTransmissionAmount(float value) { SetDirty(); transmission = value; } + inline void SetCloakAmount(float value) { SetDirty(); cloak = value; } inline void SetRefractionAmount(float value) { SetDirty(); refraction = value; } inline void SetNormalMapStrength(float value) { SetDirty(); normalMapStrength = value; } inline void SetParallaxOcclusionMapping(float value) { SetDirty(); parallaxOcclusionMapping = value; } diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp index 4a40f8972..0870fa925 100644 --- a/WickedEngine/wiScene_Serializers.cpp +++ b/WickedEngine/wiScene_Serializers.cpp @@ -244,6 +244,10 @@ namespace wi::scene { archive >> extinctionColor; } + if (seri.GetVersion() >= 6) + { + archive >> cloak; + } for (auto& x : textures) { @@ -397,6 +401,10 @@ namespace wi::scene { archive << extinctionColor; } + if (seri.GetVersion() >= 6) + { + archive << cloak; + } } } void MeshComponent::Serialize(wi::Archive& archive, EntitySerializer& seri) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index eb6f88c5f..cc3a8f3e5 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 536; + const int revision = 537; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);