diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp index 6604ac17e..7e6070d71 100644 --- a/Editor/MaterialWindow.cpp +++ b/Editor/MaterialWindow.cpp @@ -113,7 +113,7 @@ MaterialWindow::MaterialWindow(wiGUI* gui) : GUI(gui) materialWindow->AddWidget(metalnessSlider); alphaSlider = new wiSlider(0, 1, 1.0f, 1000, "Alpha: "); - alphaSlider->SetTooltip("Adjusts the overall transparency of the surface."); + alphaSlider->SetTooltip("Adjusts the overall transparency of the surface. Don't forget to set a Blend mode or refraction index to take effect."); alphaSlider->SetSize(XMFLOAT2(100, 30)); alphaSlider->SetPos(XMFLOAT2(x, y += step)); alphaSlider->OnSlide([&](wiEventArgs args) { diff --git a/README.md b/README.md index a9c569f56..d79f42d01 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,6 @@ The Editor supports the importing of some common model formats (the list will po The Engine itself can open the serialized model format (WISCENE) only. The preferred workflow is to import models into the editor, and save them out to WISCENE, then any WickedEngine application can open them.
The old Blender exporter script is now not supported! (from version 0.21.0) -![Sponza](https://turanszkij.files.wordpress.com/2018/11/sponza.png) +![Sponza](https://turanszkij.files.wordpress.com/2018/12/sponza.png) diff --git a/WickedEngine/objectHF.hlsli b/WickedEngine/objectHF.hlsli index 4b4470ef8..c580c8a41 100644 --- a/WickedEngine/objectHF.hlsli +++ b/WickedEngine/objectHF.hlsli @@ -178,15 +178,19 @@ inline void ParallaxOcclusionMapping(inout float2 UV, in float3 V, in float3x3 T UV = finalTexCoords; } -inline void Refraction(in float2 ScreenCoord, in float2 normal2D, in float3 bumpColor, inout Surface surface, inout float4 color) +inline void Refraction(in float2 ScreenCoord, in float2 normal2D, in float3 bumpColor, inout Surface surface, inout float4 color, inout float3 diffuse) { - float2 size; - float mipLevels; - xRefraction.GetDimensions(0, size.x, size.y, mipLevels); - float2 perturbatedRefrTexCoords = ScreenCoord.xy + (normal2D + bumpColor.rg) * g_xMat_refractionIndex; - float4 refractiveColor = xRefraction.SampleLevel(sampler_linear_clamp, perturbatedRefrTexCoords, (g_xFrame_AdvancedRefractions ? surface.roughness * mipLevels : 0)); - surface.albedo.rgb *= lerp(refractiveColor.rgb, 1, color.a); - color.a = 1; + if (g_xMat_refractionIndex > 0) + { + float2 size; + float mipLevels; + xRefraction.GetDimensions(0, size.x, size.y, mipLevels); + float2 perturbatedRefrTexCoords = ScreenCoord.xy + (normal2D + bumpColor.rg) * g_xMat_refractionIndex; + float4 refractiveColor = xRefraction.SampleLevel(sampler_linear_clamp, perturbatedRefrTexCoords, (g_xFrame_AdvancedRefractions ? surface.roughness * mipLevels : 0)); + surface.albedo.rgb = lerp(refractiveColor.rgb, surface.albedo.rgb, color.a); + diffuse = lerp(1, diffuse, color.a); + color.a = 1; + } } inline void ForwardLighting(inout Surface surface, inout float3 diffuse, inout float3 specular, inout float3 reflection) @@ -604,8 +608,7 @@ GBUFFEROutputType_Thin main(PIXELINPUT input) #ifdef TRANSPARENT - Refraction(ScreenCoord, input.nor2D, bumpColor, surface, color); - diffuse = lerp(1, diffuse, opacity); + Refraction(ScreenCoord, input.nor2D, bumpColor, surface, color, diffuse); #else float4 ssr = xSSR.SampleLevel(sampler_linear_clamp, ReprojectedScreenCoord, 0); reflection = lerp(reflection, ssr.rgb, ssr.a); diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index e5630a3cb..b8f77e899 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -352,6 +352,7 @@ enum BSTYPES BSTYPE_TRANSPARENT, BSTYPE_INVERSE, BSTYPE_ADDITIVE, + BSTYPE_PREMULTIPLIED, BSTYPE_COLORWRITEDISABLE, BSTYPE_DEFERREDLIGHT, BSTYPE_ENVIRONMENTALLIGHT, diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index b53a2e7df..27185bb98 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -614,7 +614,7 @@ enum OBJECTRENDERING_POM OBJECTRENDERING_POM_ENABLED, OBJECTRENDERING_POM_COUNT }; -GraphicsPSO* PSO_object[SHADERTYPE_COUNT][OBJECTRENDERING_DOUBLESIDED_COUNT][OBJECTRENDERING_TESSELLATION_COUNT][OBJECTRENDERING_ALPHATEST_COUNT][OBJECTRENDERING_TRANSPARENCY_COUNT][OBJECTRENDERING_NORMALMAP_COUNT][OBJECTRENDERING_PLANARREFLECTION_COUNT][OBJECTRENDERING_POM_COUNT] = {}; +GraphicsPSO* PSO_object[SHADERTYPE_COUNT][BLENDMODE_COUNT][OBJECTRENDERING_DOUBLESIDED_COUNT][OBJECTRENDERING_TESSELLATION_COUNT][OBJECTRENDERING_ALPHATEST_COUNT][OBJECTRENDERING_TRANSPARENCY_COUNT][OBJECTRENDERING_NORMALMAP_COUNT][OBJECTRENDERING_PLANARREFLECTION_COUNT][OBJECTRENDERING_POM_COUNT] = {}; GraphicsPSO* PSO_object_water[SHADERTYPE_COUNT] = {}; GraphicsPSO* PSO_object_wire = nullptr; GraphicsPSO* GetObjectPSO(SHADERTYPE shaderType, bool doublesided, bool tessellation, const MaterialComponent& material, bool forceAlphaTestForDithering) @@ -637,13 +637,14 @@ GraphicsPSO* GetObjectPSO(SHADERTYPE shaderType, bool doublesided, bool tessella return PSO_object_water[shaderType]; } - bool alphatest = material.IsAlphaTestEnabled() || forceAlphaTestForDithering; - bool transparent = material.IsTransparent(); - bool normalmap = material.GetNormalMap() != nullptr; - bool planarreflection = material.HasPlanarReflection(); - bool pom = material.parallaxOcclusionMapping > 0; + const bool alphatest = material.IsAlphaTestEnabled() || forceAlphaTestForDithering; + const bool transparent = material.IsTransparent(); + const bool normalmap = material.GetNormalMap() != nullptr; + const bool planarreflection = material.HasPlanarReflection(); + const bool pom = material.parallaxOcclusionMapping > 0; + const BLENDMODE blendMode = material.blendMode; - return PSO_object[shaderType][doublesided][tessellation][alphatest][transparent][normalmap][planarreflection][pom]; + return PSO_object[shaderType][blendMode][doublesided][tessellation][alphatest][transparent][normalmap][planarreflection][pom]; } @@ -2022,169 +2023,190 @@ void LoadShaders() // default objectshaders: for (int shaderType = 0; shaderType < SHADERTYPE_COUNT; ++shaderType) { - for (int doublesided = 0; doublesided < OBJECTRENDERING_DOUBLESIDED_COUNT; ++doublesided) + for (int blendMode = 0; blendMode < BLENDMODE_COUNT; ++blendMode) { - for (int tessellation = 0; tessellation < OBJECTRENDERING_TESSELLATION_COUNT; ++tessellation) + for (int doublesided = 0; doublesided < OBJECTRENDERING_DOUBLESIDED_COUNT; ++doublesided) { - for (int alphatest = 0; alphatest < OBJECTRENDERING_ALPHATEST_COUNT; ++alphatest) + for (int tessellation = 0; tessellation < OBJECTRENDERING_TESSELLATION_COUNT; ++tessellation) { - for (int transparency = 0; transparency < OBJECTRENDERING_TRANSPARENCY_COUNT; ++transparency) + for (int alphatest = 0; alphatest < OBJECTRENDERING_ALPHATEST_COUNT; ++alphatest) { - for (int normalmap = 0; normalmap < OBJECTRENDERING_NORMALMAP_COUNT; ++normalmap) + for (int transparency = 0; transparency < OBJECTRENDERING_TRANSPARENCY_COUNT; ++transparency) { - for (int planarreflection = 0; planarreflection < OBJECTRENDERING_PLANARREFLECTION_COUNT; ++planarreflection) + for (int normalmap = 0; normalmap < OBJECTRENDERING_NORMALMAP_COUNT; ++normalmap) { - for (int pom = 0; pom < OBJECTRENDERING_POM_COUNT; ++pom) + for (int planarreflection = 0; planarreflection < OBJECTRENDERING_PLANARREFLECTION_COUNT; ++planarreflection) { - VSTYPES realVS = GetVSTYPE((SHADERTYPE)shaderType, tessellation, alphatest, transparency); - VLTYPES realVL = GetVLTYPE((SHADERTYPE)shaderType, tessellation, alphatest, transparency); - HSTYPES realHS = GetHSTYPE((SHADERTYPE)shaderType, tessellation); - DSTYPES realDS = GetDSTYPE((SHADERTYPE)shaderType, tessellation); - GSTYPES realGS = GetGSTYPE((SHADERTYPE)shaderType, alphatest); - PSTYPES realPS = GetPSTYPE((SHADERTYPE)shaderType, alphatest, transparency, normalmap, planarreflection, pom); - - if (tessellation && (realHS == HSTYPE_NULL || realDS == DSTYPE_NULL)) + for (int pom = 0; pom < OBJECTRENDERING_POM_COUNT; ++pom) { - continue; - } + VSTYPES realVS = GetVSTYPE((SHADERTYPE)shaderType, tessellation, alphatest, transparency); + VLTYPES realVL = GetVLTYPE((SHADERTYPE)shaderType, tessellation, alphatest, transparency); + HSTYPES realHS = GetHSTYPE((SHADERTYPE)shaderType, tessellation); + DSTYPES realDS = GetDSTYPE((SHADERTYPE)shaderType, tessellation); + GSTYPES realGS = GetGSTYPE((SHADERTYPE)shaderType, alphatest); + PSTYPES realPS = GetPSTYPE((SHADERTYPE)shaderType, alphatest, transparency, normalmap, planarreflection, pom); - GraphicsPSODesc desc; - desc.vs = vertexShaders[realVS]; - desc.il = vertexLayouts[realVL]; - desc.hs = hullShaders[realHS]; - desc.ds = domainShaders[realDS]; - desc.gs = geometryShaders[realGS]; - desc.ps = pixelShaders[realPS]; - - switch (shaderType) - { - case SHADERTYPE_DEPTHONLY: - case SHADERTYPE_SHADOW: - case SHADERTYPE_SHADOWCUBE: - desc.bs = blendStates[transparency ? BSTYPE_TRANSPARENTSHADOWMAP : BSTYPE_COLORWRITEDISABLE]; - break; - default: - desc.bs = blendStates[transparency ? BSTYPE_TRANSPARENT : BSTYPE_OPAQUE]; - break; - } - - switch (shaderType) - { - case SHADERTYPE_SHADOW: - case SHADERTYPE_SHADOWCUBE: - desc.dss = depthStencils[transparency ? DSSTYPE_DEPTHREAD : DSSTYPE_SHADOW]; - break; - case SHADERTYPE_TILEDFORWARD: - desc.dss = depthStencils[transparency ? DSSTYPE_DEFAULT : DSSTYPE_DEPTHREADEQUAL]; - break; - case SHADERTYPE_ENVMAPCAPTURE: - desc.dss = depthStencils[DSSTYPE_ENVMAP]; - break; - case SHADERTYPE_VOXELIZE: - desc.dss = depthStencils[DSSTYPE_XRAY]; - break; - default: - desc.dss = depthStencils[DSSTYPE_DEFAULT]; - break; - } - - switch (shaderType) - { - case SHADERTYPE_SHADOW: - case SHADERTYPE_SHADOWCUBE: - desc.rs = rasterizers[doublesided ? RSTYPE_SHADOW_DOUBLESIDED : RSTYPE_SHADOW]; - break; - case SHADERTYPE_VOXELIZE: - desc.rs = rasterizers[RSTYPE_VOXELIZE]; - break; - default: - desc.rs = rasterizers[doublesided ? RSTYPE_DOUBLESIDED : RSTYPE_FRONT]; - break; - } - - switch (shaderType) - { - case SHADERTYPE_TEXTURE: - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_hdr; - desc.DSFormat = DSFormat_full; - break; - case SHADERTYPE_DEFERRED: - desc.numRTs = 5; - desc.RTFormats[0] = RTFormat_gbuffer_0; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.RTFormats[2] = RTFormat_gbuffer_2; - desc.RTFormats[3] = RTFormat_deferred_lightbuffer; - desc.RTFormats[4] = RTFormat_deferred_lightbuffer; - desc.DSFormat = DSFormat_full; - break; - case SHADERTYPE_FORWARD: - if (transparency) + if (tessellation && (realHS == HSTYPE_NULL || realDS == DSTYPE_NULL)) { + continue; + } + + GraphicsPSODesc desc; + desc.vs = vertexShaders[realVS]; + desc.il = vertexLayouts[realVL]; + desc.hs = hullShaders[realHS]; + desc.ds = domainShaders[realDS]; + desc.gs = geometryShaders[realGS]; + desc.ps = pixelShaders[realPS]; + + switch (blendMode) + { + case BLENDMODE_OPAQUE: + desc.bs = blendStates[BSTYPE_OPAQUE]; + break; + case BLENDMODE_ALPHA: + desc.bs = blendStates[BSTYPE_TRANSPARENT]; + break; + case BLENDMODE_ADDITIVE: + desc.bs = blendStates[BSTYPE_ADDITIVE]; + break; + case BLENDMODE_PREMULTIPLIED: + desc.bs = blendStates[BSTYPE_PREMULTIPLIED]; + break; + default: + assert(0); + break; + } + + switch (shaderType) + { + case SHADERTYPE_DEPTHONLY: + case SHADERTYPE_SHADOW: + case SHADERTYPE_SHADOWCUBE: + desc.bs = blendStates[transparency ? BSTYPE_TRANSPARENTSHADOWMAP : BSTYPE_COLORWRITEDISABLE]; + break; + default: + break; + } + + switch (shaderType) + { + case SHADERTYPE_SHADOW: + case SHADERTYPE_SHADOWCUBE: + desc.dss = depthStencils[transparency ? DSSTYPE_DEPTHREAD : DSSTYPE_SHADOW]; + break; + case SHADERTYPE_TILEDFORWARD: + desc.dss = depthStencils[transparency ? DSSTYPE_DEFAULT : DSSTYPE_DEPTHREADEQUAL]; + break; + case SHADERTYPE_ENVMAPCAPTURE: + desc.dss = depthStencils[DSSTYPE_ENVMAP]; + break; + case SHADERTYPE_VOXELIZE: + desc.dss = depthStencils[DSSTYPE_XRAY]; + break; + default: + desc.dss = depthStencils[DSSTYPE_DEFAULT]; + break; + } + + switch (shaderType) + { + case SHADERTYPE_SHADOW: + case SHADERTYPE_SHADOWCUBE: + desc.rs = rasterizers[doublesided ? RSTYPE_SHADOW_DOUBLESIDED : RSTYPE_SHADOW]; + break; + case SHADERTYPE_VOXELIZE: + desc.rs = rasterizers[RSTYPE_VOXELIZE]; + break; + default: + desc.rs = rasterizers[doublesided ? RSTYPE_DOUBLESIDED : RSTYPE_FRONT]; + break; + } + + switch (shaderType) + { + case SHADERTYPE_TEXTURE: desc.numRTs = 1; - } - else - { - desc.numRTs = 2; - } - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.DSFormat = DSFormat_full; - break; - case SHADERTYPE_TILEDFORWARD: - if (transparency) - { - desc.numRTs = 1; - } - else - { - desc.numRTs = 2; - } - desc.RTFormats[0] = RTFormat_hdr; - desc.RTFormats[1] = RTFormat_gbuffer_1; - desc.DSFormat = DSFormat_full; - break; - case SHADERTYPE_DEPTHONLY: - desc.numRTs = 0; - desc.DSFormat = DSFormat_full; - break; - case SHADERTYPE_ENVMAPCAPTURE: - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_envprobe; - desc.DSFormat = DSFormat_small; - break; - case SHADERTYPE_SHADOW: - if (transparency) - { - desc.numRTs = 1; - desc.RTFormats[0] = RTFormat_ldr; - } - else - { + desc.RTFormats[0] = RTFormat_hdr; + desc.DSFormat = DSFormat_full; + break; + case SHADERTYPE_DEFERRED: + desc.numRTs = 5; + desc.RTFormats[0] = RTFormat_gbuffer_0; + desc.RTFormats[1] = RTFormat_gbuffer_1; + desc.RTFormats[2] = RTFormat_gbuffer_2; + desc.RTFormats[3] = RTFormat_deferred_lightbuffer; + desc.RTFormats[4] = RTFormat_deferred_lightbuffer; + desc.DSFormat = DSFormat_full; + break; + case SHADERTYPE_FORWARD: + if (transparency) + { + desc.numRTs = 1; + } + else + { + desc.numRTs = 2; + } + desc.RTFormats[0] = RTFormat_hdr; + desc.RTFormats[1] = RTFormat_gbuffer_1; + desc.DSFormat = DSFormat_full; + break; + case SHADERTYPE_TILEDFORWARD: + if (transparency) + { + desc.numRTs = 1; + } + else + { + desc.numRTs = 2; + } + desc.RTFormats[0] = RTFormat_hdr; + desc.RTFormats[1] = RTFormat_gbuffer_1; + desc.DSFormat = DSFormat_full; + break; + case SHADERTYPE_DEPTHONLY: desc.numRTs = 0; + desc.DSFormat = DSFormat_full; + break; + case SHADERTYPE_ENVMAPCAPTURE: + desc.numRTs = 1; + desc.RTFormats[0] = RTFormat_envprobe; + desc.DSFormat = DSFormat_small; + break; + case SHADERTYPE_SHADOW: + if (transparency) + { + desc.numRTs = 1; + desc.RTFormats[0] = RTFormat_ldr; + } + else + { + desc.numRTs = 0; + } + desc.DSFormat = DSFormat_small; + break; + case SHADERTYPE_SHADOWCUBE: + desc.numRTs = 0; + desc.DSFormat = DSFormat_small; + break; + case SHADERTYPE_VOXELIZE: + desc.numRTs = 0; + break; } - desc.DSFormat = DSFormat_small; - break; - case SHADERTYPE_SHADOWCUBE: - desc.numRTs = 0; - desc.DSFormat = DSFormat_small; - break; - case SHADERTYPE_VOXELIZE: - desc.numRTs = 0; - break; - } - if (tessellation) - { - desc.pt = PATCHLIST; - } - else - { - desc.pt = TRIANGLELIST; - } + if (tessellation) + { + desc.pt = PATCHLIST; + } + else + { + desc.pt = TRIANGLELIST; + } - RECREATE(PSO_object[shaderType][doublesided][tessellation][alphatest][transparency][normalmap][planarreflection][pom]); - device->CreateGraphicsPSO(&desc, PSO_object[shaderType][doublesided][tessellation][alphatest][transparency][normalmap][planarreflection][pom]); + RECREATE(PSO_object[shaderType][blendMode][doublesided][tessellation][alphatest][transparency][normalmap][planarreflection][pom]); + device->CreateGraphicsPSO(&desc, PSO_object[shaderType][blendMode][doublesided][tessellation][alphatest][transparency][normalmap][planarreflection][pom]); + } } } } @@ -3268,6 +3290,18 @@ void SetUpStates() bd.IndependentBlendEnable = false; device->CreateBlendState(&bd, blendStates[BSTYPE_TRANSPARENT]); + bd.RenderTarget[0].BlendEnable = true; + bd.RenderTarget[0].SrcBlend = BLEND_ONE; + bd.RenderTarget[0].DestBlend = BLEND_INV_SRC_ALPHA; + bd.RenderTarget[0].BlendOp = BLEND_OP_ADD; + bd.RenderTarget[0].SrcBlendAlpha = BLEND_ONE; + bd.RenderTarget[0].DestBlendAlpha = BLEND_ONE; + bd.RenderTarget[0].BlendOpAlpha = BLEND_OP_ADD; + bd.RenderTarget[0].RenderTargetWriteMask = COLOR_WRITE_ENABLE_ALL; + bd.IndependentBlendEnable = false; + bd.AlphaToCoverageEnable = false; + device->CreateBlendState(&bd, blendStates[BSTYPE_PREMULTIPLIED]); + bd.RenderTarget[0].BlendEnable = true; bd.RenderTarget[0].SrcBlend = BLEND_SRC_ALPHA; diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index f5f73d045..6c8cb5d34 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -163,7 +163,7 @@ namespace wiSceneSystem inline void SetPlanarReflections(bool value) { if (value) { _flags |= PLANAR_REFLECTION; } else { _flags &= ~PLANAR_REFLECTION; } } inline void SetWater(bool value) { if (value) { _flags |= WATER; } else { _flags &= ~WATER; } } - inline bool IsTransparent() const { return GetOpacity() < 1.0f; } + inline bool IsTransparent() const { return GetOpacity() < 1.0f || blendMode != BLENDMODE_OPAQUE; } inline bool IsWater() const { return _flags & WATER; } inline bool HasPlanarReflection() const { return (_flags & PLANAR_REFLECTION) || IsWater(); } inline bool IsCastingShadow() const { return _flags & CAST_SHADOW; } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index e306eabf2..a3f690872 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 24; // minor bug fixes, alterations, refactors, updates - const int revision = 14; + const int revision = 15; long GetVersion()