diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp index d38132049..9be2bd20e 100644 --- a/Editor/MaterialWindow.cpp +++ b/Editor/MaterialWindow.cpp @@ -307,31 +307,25 @@ MaterialWindow::MaterialWindow(wiGUI* gui) : GUI(gui) materialWindow->AddWidget(blendModeComboBox); - //shaderTypeComboBox = new wiComboBox("Custom Shader: "); - //shaderTypeComboBox->SetPos(XMFLOAT2(x, y += step)); - //shaderTypeComboBox->SetSize(XMFLOAT2(100, 25)); - //shaderTypeComboBox->OnSelect([&](wiEventArgs args) { - // MaterialComponent* material = wiRenderer::GetScene().materials.GetComponent(entity); - // if (material != nullptr) - // { - // if (args.iValue == 0) - // { - // material->customShader = nullptr; - // } - // else if (args.iValue > 0) - // { - // material->customShader = Material::customShaderPresets[args.iValue - 1]; - // } - // } - //}); - //shaderTypeComboBox->AddItem("None"); - //for (auto& x : Material::customShaderPresets) - //{ - // shaderTypeComboBox->AddItem(x->name); - //} - //shaderTypeComboBox->SetEnabled(false); - //shaderTypeComboBox->SetTooltip("Set the custom shader of the material."); - //materialWindow->AddWidget(shaderTypeComboBox); + shaderTypeComboBox = new wiComboBox("Custom Shader: "); + shaderTypeComboBox->SetTooltip("Select a custom shader for his material. See wiRenderer:RegisterCustomShader() for more info."); + shaderTypeComboBox->SetPos(XMFLOAT2(x, y += step)); + shaderTypeComboBox->SetSize(XMFLOAT2(100, 25)); + shaderTypeComboBox->OnSelect([&](wiEventArgs args) { + MaterialComponent* material = wiRenderer::GetScene().materials.GetComponent(entity); + if (material != nullptr) + { + material->SetCustomShaderID(args.iValue - 1); + } + }); + shaderTypeComboBox->AddItem("None"); + for (auto& x : wiRenderer::GetCustomShaders()) + { + shaderTypeComboBox->AddItem(x.name); + } + shaderTypeComboBox->SetEnabled(false); + shaderTypeComboBox->SetTooltip("Set the custom shader of the material."); + materialWindow->AddWidget(shaderTypeComboBox); // Textures: @@ -660,6 +654,7 @@ void MaterialWindow::SetEntity(Entity entity) baseColorPicker->SetEnabled(true); emissiveColorPicker->SetEnabled(true); blendModeComboBox->SetSelected((int)material->blendMode); + shaderTypeComboBox->SetSelected(max(0, material->GetCustomShaderID() + 1)); texture_baseColor_Button->SetText(wiHelper::GetFileNameFromPath(material->baseColorMapName)); texture_normal_Button->SetText(wiHelper::GetFileNameFromPath(material->normalMapName)); diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj b/WickedEngine/WickedEngine_SHADERS.vcxproj index 3aac676b4..d614d5b4c 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj @@ -364,6 +364,10 @@ Pixel + + Pixel + 5.0 + Vertex diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters index f16c8bc8c..de4de997f 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters @@ -867,6 +867,9 @@ VS + + PS + diff --git a/WickedEngine/captureImpostorPS_normal.hlsl b/WickedEngine/captureImpostorPS_normal.hlsl index 7224a3dce..525ff0997 100644 --- a/WickedEngine/captureImpostorPS_normal.hlsl +++ b/WickedEngine/captureImpostorPS_normal.hlsl @@ -12,6 +12,6 @@ float4 main(PixelInputType input) : SV_Target0 float3 bumpColor; NormalMapping(UV, P, N, TBN, bumpColor); - return float4(mul(N, transpose(TBN)), 1); + return float4(N * 0.5f + 0.5f, 1); } diff --git a/WickedEngine/impostorHF.hlsli b/WickedEngine/impostorHF.hlsli index 021626ddc..a37801e66 100644 --- a/WickedEngine/impostorHF.hlsli +++ b/WickedEngine/impostorHF.hlsli @@ -8,7 +8,6 @@ struct VSOut nointerpolation float dither : DITHER; float3 pos3D : WORLDPOSITION; uint instanceColor : INSTANCECOLOR; - float3 nor : NORMAL; float4 pos2D : SCREENPOSITION; float4 pos2DPrev : SCREENPOSITIONPREV; }; diff --git a/WickedEngine/impostorPS_deferred.hlsl b/WickedEngine/impostorPS_deferred.hlsl index 40cbfa2f6..97bc7e0d4 100644 --- a/WickedEngine/impostorPS_deferred.hlsl +++ b/WickedEngine/impostorPS_deferred.hlsl @@ -8,23 +8,23 @@ GBUFFEROutputType main(VSOut input) clip(dither(input.pos.xy + GetTemporalAASampleRotation()) - input.dither); float3 uv_col = input.tex; - float3 uv_nor = uv_col + impostorCaptureAngles; - float3 uv_sur = uv_nor + impostorCaptureAngles; + float3 uv_nor = uv_col; + uv_nor.z += impostorCaptureAngles; + float3 uv_sur = uv_nor; + uv_sur.z += impostorCaptureAngles; float4 color = impostorTex.Sample(sampler_linear_clamp, uv_col); ALPHATEST(color.a); - float4 normal = impostorTex.Sample(sampler_linear_clamp, uv_nor); + float3 N = impostorTex.Sample(sampler_linear_clamp, uv_nor).rgb * 2 - 1; float4 surfaceparams = impostorTex.Sample(sampler_linear_clamp, uv_sur); - float3 N = normal.rgb; - float ao = surfaceparams.r; float roughness = surfaceparams.g; float metalness = surfaceparams.b; float reflectance = surfaceparams.a; - Surface surface = CreateSurface(0, input.nor, 0, color, ao, roughness, metalness, reflectance); + Surface surface = CreateSurface(0, N, 0, color, ao, roughness, metalness, reflectance); float2 velocity = ((input.pos2DPrev.xy / input.pos2DPrev.w - g_xFrame_TemporalAAJitterPrev) - (input.pos2D.xy / input.pos2D.w - g_xFrame_TemporalAAJitter)) * float2(0.5f, -0.5f); diff --git a/WickedEngine/impostorPS_forward.hlsl b/WickedEngine/impostorPS_forward.hlsl index 4a97fde0c..5a9475652 100644 --- a/WickedEngine/impostorPS_forward.hlsl +++ b/WickedEngine/impostorPS_forward.hlsl @@ -7,17 +7,17 @@ GBUFFEROutputType_Thin main(VSOut input) clip(dither(input.pos.xy + GetTemporalAASampleRotation()) - input.dither); float3 uv_col = input.tex; - float3 uv_nor = uv_col + impostorCaptureAngles; - float3 uv_sur = uv_nor + impostorCaptureAngles; + float3 uv_nor = uv_col; + uv_nor.z += impostorCaptureAngles; + float3 uv_sur = uv_nor; + uv_sur.z += impostorCaptureAngles; float4 color = impostorTex.Sample(sampler_linear_clamp, uv_col); ALPHATEST(color.a); - float4 normal = impostorTex.Sample(sampler_linear_clamp, uv_nor); + float3 N = impostorTex.Sample(sampler_linear_clamp, uv_nor).rgb * 2 - 1; float4 surfaceparams = impostorTex.Sample(sampler_linear_clamp, uv_sur); - float3 N = normal.rgb; - float ao = surfaceparams.r; float roughness = surfaceparams.g; float metalness = surfaceparams.b; @@ -26,7 +26,7 @@ GBUFFEROutputType_Thin main(VSOut input) float3 V = g_xCamera_CamPos - input.pos3D; float dist = length(V); V /= dist; - Surface surface = CreateSurface(input.pos3D, input.nor, V, color, ao, roughness, reflectance, metalness); + Surface surface = CreateSurface(input.pos3D, N, V, color, ao, roughness, reflectance, metalness); float2 pixel = input.pos.xy; float depth = input.pos.z; float3 diffuse = 0; diff --git a/WickedEngine/impostorPS_tiledforward.hlsl b/WickedEngine/impostorPS_tiledforward.hlsl index ae0b58fcf..53555ff8e 100644 --- a/WickedEngine/impostorPS_tiledforward.hlsl +++ b/WickedEngine/impostorPS_tiledforward.hlsl @@ -6,15 +6,15 @@ GBUFFEROutputType_Thin main(VSOut input) { float3 uv_col = input.tex; - float3 uv_nor = uv_col + impostorCaptureAngles; - float3 uv_sur = uv_nor + impostorCaptureAngles; + float3 uv_nor = uv_col; + uv_nor.z += impostorCaptureAngles; + float3 uv_sur = uv_nor; + uv_sur.z += impostorCaptureAngles; float4 color = impostorTex.Sample(sampler_linear_clamp, uv_col); - float4 normal = impostorTex.Sample(sampler_linear_clamp, uv_nor); + float3 N = impostorTex.Sample(sampler_linear_clamp, uv_nor).rgb * 2 - 1; float4 surfaceparams = impostorTex.Sample(sampler_linear_clamp, uv_sur); - float3 N = normal.rgb; - float ao = surfaceparams.r; float roughness = surfaceparams.g; float metalness = surfaceparams.b; @@ -23,7 +23,7 @@ GBUFFEROutputType_Thin main(VSOut input) float3 V = g_xCamera_CamPos - input.pos3D; float dist = length(V); V /= dist; - Surface surface = CreateSurface(input.pos3D, input.nor, V, color, ao, roughness, metalness, reflectance); + Surface surface = CreateSurface(input.pos3D, N, V, color, ao, roughness, metalness, reflectance); float2 pixel = input.pos.xy; float depth = input.pos.z; float3 diffuse = 0; diff --git a/WickedEngine/impostorPS_wire.hlsl b/WickedEngine/impostorPS_wire.hlsl new file mode 100644 index 000000000..be3a9ae1b --- /dev/null +++ b/WickedEngine/impostorPS_wire.hlsl @@ -0,0 +1,4 @@ +float4 main() : SV_TARGET +{ + return float4(1,1,1,1); +} diff --git a/WickedEngine/impostorVS.hlsl b/WickedEngine/impostorVS.hlsl index cf99b36f7..4515c8bb1 100644 --- a/WickedEngine/impostorVS.hlsl +++ b/WickedEngine/impostorVS.hlsl @@ -46,7 +46,7 @@ VSOut main(uint fakeIndex : SV_VERTEXID) { angle = 2 - angle; } - angle /= 2.0f; + angle *= 0.5f; tex.z += floor(saturate(angle) * impostorCaptureAngles); VSOut Out; @@ -55,7 +55,6 @@ VSOut main(uint fakeIndex : SV_VERTEXID) Out.tex = tex; Out.dither = instance.color_dither.a; Out.instanceColor = 0xFFFFFFFF; // todo - Out.nor = face; Out.pos2D = Out.pos; Out.pos2DPrev = mul(float4(Out.pos3D, 1), g_xFrame_MainCamera_PrevVP); diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index c1146140f..a352a1abb 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -30,6 +30,7 @@ enum RENDERTYPE RENDERTYPE_OPAQUE = 1, RENDERTYPE_TRANSPARENT = 2, RENDERTYPE_WATER = 4, + RENDERTYPE_ALL = RENDERTYPE_OPAQUE | RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER }; enum RENDERPASS @@ -196,6 +197,7 @@ enum PSTYPES PSTYPE_OBJECT_ALPHATESTONLY, PSTYPE_IMPOSTOR_ALPHATESTONLY, PSTYPE_IMPOSTOR_SIMPLE, + PSTYPE_IMPOSTOR_WIRE, PSTYPE_SHADOW_ALPHATEST, PSTYPE_SHADOW_TRANSPARENT, diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 2d6236615..2d61fba5e 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -667,6 +667,31 @@ GraphicsPSO* GetObjectPSO(RENDERPASS renderPass, bool doublesided, bool tessella return PSO_object[renderPass][blendMode][doublesided][tessellation][alphatest][transparent][normalmap][planarreflection][pom]; } +GraphicsPSO* PSO_object_hologram = nullptr; +std::vector customShaders; +int RegisterCustomShader(const CustomShader& customShader) +{ + int result = (int)customShaders.size(); + customShaders.push_back(customShader); + return result; +} +const std::vector& GetCustomShaders() +{ + return customShaders; +} +GraphicsPSO* GetCustomShaderPSO(RENDERPASS renderPass, uint32_t renderTypeFlags, int customShaderID) +{ + if (customShaderID >= 0 && customShaderID < customShaders.size()) + { + const CustomShader& customShader = customShaders[customShaderID]; + const CustomShader::Pass& customPass = customShader.passes[renderPass]; + if (customPass.renderTypeFlags & renderTypeFlags) + { + return customPass.pso; + } + } + return nullptr; +} VLTYPES GetVLTYPE(RENDERPASS renderPass, bool tessellation, bool alphatest, bool transparent) { @@ -1104,6 +1129,7 @@ PSTYPES GetPSTYPE(RENDERPASS renderPass, bool alphatest, bool transparent, bool GraphicsPSO* PSO_decal = nullptr; GraphicsPSO* PSO_occlusionquery = nullptr; GraphicsPSO* PSO_impostor[RENDERPASS_COUNT] = {}; +GraphicsPSO* PSO_impostor_wire = nullptr; GraphicsPSO* PSO_captureimpostor_albedo = nullptr; GraphicsPSO* PSO_captureimpostor_normal = nullptr; GraphicsPSO* PSO_captureimpostor_surface = nullptr; @@ -1117,7 +1143,7 @@ GraphicsPSO* GetImpostorPSO(RENDERPASS renderPass) case RENDERPASS_DEFERRED: case RENDERPASS_FORWARD: case RENDERPASS_TILEDFORWARD: - return PSO_object_wire; + return PSO_impostor_wire; } return nullptr; } @@ -1571,7 +1597,16 @@ void RenderMeshes(const RenderQueue& renderQueue, RENDERPASS renderPass, UINT re } const MaterialComponent& material = *scene.materials.GetComponent(subset.materialID); - GraphicsPSO* pso = GetObjectPSO(renderPass, mesh.IsDoubleSided(), tessellatorRequested, material, forceAlphaTestForDithering); + GraphicsPSO* pso = nullptr; + if (material.IsCustomShader()) + { + pso = GetCustomShaderPSO(renderPass, renderTypeFlags, material.GetCustomShaderID()); + } + else + { + pso = GetObjectPSO(renderPass, mesh.IsDoubleSided(), tessellatorRequested, material, forceAlphaTestForDithering); + } + if (pso == nullptr) { continue; @@ -2036,6 +2071,7 @@ void LoadShaders() pixelShaders[PSTYPE_OBJECT_ALPHATESTONLY] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "objectPS_alphatestonly.cso", wiResourceManager::PIXELSHADER)); pixelShaders[PSTYPE_IMPOSTOR_ALPHATESTONLY] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "impostorPS_alphatestonly.cso", wiResourceManager::PIXELSHADER)); pixelShaders[PSTYPE_IMPOSTOR_SIMPLE] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "impostorPS_simple.cso", wiResourceManager::PIXELSHADER)); + pixelShaders[PSTYPE_IMPOSTOR_WIRE] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "impostorPS_wire.cso", wiResourceManager::PIXELSHADER)); pixelShaders[PSTYPE_ENVIRONMENTALLIGHT] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "environmentalLightPS.cso", wiResourceManager::PIXELSHADER)); pixelShaders[PSTYPE_DIRLIGHT] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "dirLightPS.cso", wiResourceManager::PIXELSHADER)); pixelShaders[PSTYPE_POINTLIGHT] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "pointLightPS.cso", wiResourceManager::PIXELSHADER)); @@ -2320,40 +2356,37 @@ void LoadShaders() } } - //// Custom objectshader presets: - //for (auto& x : Material::customShaderPresets) - //{ - // SAFE_DELETE(x); - //} - //Material::customShaderPresets.clear(); + // Clear custom shaders (Custom shaders coming from user will need to be handled by the user in case of shader reload): + customShaders.clear(); - //// Hologram: - //{ - // VSTYPES realVS = GetVSTYPE(RENDERPASS_FORWARD, false, false, true); - // VLTYPES realVL = GetVLTYPE(RENDERPASS_FORWARD, false, false, true); + // Hologram sample shader will be registered as custom shader: + { + VSTYPES realVS = GetVSTYPE(RENDERPASS_FORWARD, false, false, true); + VLTYPES realVL = GetVLTYPE(RENDERPASS_FORWARD, false, false, true); - // GraphicsPSODesc desc; - // desc.vs = vertexShaders[realVS]; - // desc.il = vertexLayouts[realVL]; - // desc.ps = pixelShaders[PSTYPE_OBJECT_HOLOGRAM]; + GraphicsPSODesc desc; + desc.vs = vertexShaders[realVS]; + desc.il = vertexLayouts[realVL]; + desc.ps = pixelShaders[PSTYPE_OBJECT_HOLOGRAM]; - // desc.bs = blendStates[BSTYPE_ADDITIVE]; - // desc.rs = rasterizers[DSSTYPE_DEFAULT]; - // desc.dss = depthStencils[DSSTYPE_DEPTHREAD]; - // desc.pt = TRIANGLELIST; + desc.bs = blendStates[BSTYPE_ADDITIVE]; + desc.rs = rasterizers[DSSTYPE_DEFAULT]; + desc.dss = depthStencils[DSSTYPE_DEPTHREAD]; + desc.pt = TRIANGLELIST; - // desc.numRTs = 1; - // desc.RTFormats[0] = RTFormat_hdr; - // desc.DSFormat = DSFormat_full; + desc.numRTs = 1; + desc.RTFormats[0] = RTFormat_hdr; + desc.DSFormat = DSFormat_full; - // Material::CustomShader* customShader = new Material::CustomShader; - // customShader->name = "Hologram"; - // customShader->passes[RENDERPASS_FORWARD].pso = new GraphicsPSO; - // device->CreateGraphicsPSO(&desc, customShader->passes[RENDERPASS_FORWARD].pso); - // customShader->passes[RENDERPASS_TILEDFORWARD].pso = new GraphicsPSO; - // device->CreateGraphicsPSO(&desc, customShader->passes[RENDERPASS_TILEDFORWARD].pso); - // Material::customShaderPresets.push_back(customShader); - //} + RECREATE(PSO_object_hologram); + device->CreateGraphicsPSO(&desc, PSO_object_hologram); + + CustomShader customShader; + customShader.name = "Hologram"; + customShader.passes[RENDERPASS_FORWARD].pso = PSO_object_hologram; + customShader.passes[RENDERPASS_TILEDFORWARD].pso = PSO_object_hologram; + RegisterCustomShader(customShader); + } { @@ -2442,7 +2475,7 @@ void LoadShaders() } GraphicsPSODesc desc; - desc.rs = rasterizers[RSTYPE_FRONT]; + desc.rs = rasterizers[RSTYPE_DOUBLESIDED]; // well, we don't need double sided impostors, but might be helpful if something breaks desc.bs = blendStates[BSTYPE_OPAQUE]; desc.dss = depthStencils[renderPass == RENDERPASS_TILEDFORWARD ? DSSTYPE_DEPTHREADEQUAL : DSSTYPE_DEFAULT]; desc.il = nullptr; @@ -2487,6 +2520,22 @@ void LoadShaders() RECREATE(PSO_impostor[renderPass]); device->CreateGraphicsPSO(&desc, PSO_impostor[renderPass]); } + { + GraphicsPSODesc desc; + desc.vs = vertexShaders[VSTYPE_IMPOSTOR]; + desc.ps = pixelShaders[PSTYPE_IMPOSTOR_WIRE]; + desc.rs = rasterizers[RSTYPE_WIRE]; + desc.bs = blendStates[BSTYPE_OPAQUE]; + desc.dss = depthStencils[DSSTYPE_DEFAULT]; + desc.il = nullptr; + + desc.numRTs = 1; + desc.RTFormats[0] = RTFormat_hdr; + desc.DSFormat = DSFormat_full; + + RECREATE(PSO_impostor_wire); + device->CreateGraphicsPSO(&desc, PSO_impostor_wire); + } { GraphicsPSODesc desc; desc.vs = vertexShaders[VSTYPE_OBJECT_COMMON]; @@ -6285,30 +6334,22 @@ void RefreshImpostors(GRAPHICSTHREAD threadID) device->SetName(&depthStencil, "ImpostorDepthTarget"); } - bool state_set = false; - GraphicsDevice::GPUAllocation mem; struct InstBuf { Instance instance; InstancePrev instancePrev; InstanceAtlas instanceAtlas; }; + GraphicsDevice::GPUAllocation mem = device->AllocateGPU(sizeof(InstBuf), threadID); + volatile InstBuf* buff = (volatile InstBuf*)mem.data; + buff->instance.Create(IDENTITYMATRIX); + buff->instancePrev.Create(IDENTITYMATRIX); + buff->instanceAtlas.Create(XMFLOAT4(1, 1, 0, 0)); for (uint32_t impostorIndex : impostorsToRefresh) { const ImpostorComponent& impostor = scene.impostors[impostorIndex]; - if (!state_set) - { - mem = device->AllocateGPU(sizeof(InstBuf), threadID); - volatile InstBuf* buff = (volatile InstBuf*)mem.data; - buff->instance.Create(IDENTITYMATRIX); - buff->instancePrev.Create(IDENTITYMATRIX); - buff->instanceAtlas.Create(XMFLOAT4(1, 1, 0, 0)); - - state_set = true; - } - Entity entity = scene.impostors.GetEntity(impostorIndex); const MeshComponent& mesh = *scene.meshes.GetComponent(entity); @@ -6318,12 +6359,14 @@ void RefreshImpostors(GRAPHICSTHREAD threadID) GPUBuffer* vbs[] = { mesh.IsSkinned() ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), mesh.vertexBuffer_TEX.get(), + mesh.vertexBuffer_ATL.get(), mesh.IsSkinned() ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), mem.buffer }; UINT strides[] = { sizeof(MeshComponent::Vertex_POS), sizeof(MeshComponent::Vertex_TEX), + sizeof(MeshComponent::Vertex_TEX), sizeof(MeshComponent::Vertex_POS), sizeof(InstBuf) }; @@ -6331,6 +6374,7 @@ void RefreshImpostors(GRAPHICSTHREAD threadID) 0, 0, 0, + 0, mem.offset }; device->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, threadID); diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 2a9889a07..052fd3ff1 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -348,7 +348,21 @@ namespace wiRenderer // returns INVALID_ENTITY if attached argument was false, else it returns the base entity handle wiECS::Entity LoadModel(const std::string& fileName, const XMMATRIX& transformMatrix = XMMatrixIdentity(), bool attached = false); + struct CustomShader + { + std::string name; + struct Pass + { + uint32_t renderTypeFlags = RENDERTYPE_TRANSPARENT; + wiGraphicsTypes::GraphicsPSO* pso = nullptr; + }; + Pass passes[RENDERPASS_COUNT] = {}; + }; + // Registers a custom shader that can be set to materials. + // Returns the ID of the custom shader that can be used with MaterialComponent::SetCustomShaderID() + int RegisterCustomShader(const CustomShader& customShader); + const std::vector& GetCustomShaders(); // Helper utility to manage async GPU query readback from the CPU // GPUQueryRing here latency specifies the ring size of queries and diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp index 494177e9b..228794929 100644 --- a/WickedEngine/wiSceneSystem.cpp +++ b/WickedEngine/wiSceneSystem.cpp @@ -1701,18 +1701,25 @@ namespace wiSceneSystem if (material != nullptr) { - if (material->IsTransparent()) + if (material->IsCustomShader()) { - object.rendertypeMask |= RENDERTYPE_TRANSPARENT; + object.rendertypeMask |= RENDERTYPE_ALL; } else { - object.rendertypeMask |= RENDERTYPE_OPAQUE; - } + if (material->IsTransparent()) + { + object.rendertypeMask |= RENDERTYPE_TRANSPARENT; + } + else + { + object.rendertypeMask |= RENDERTYPE_OPAQUE; + } - if (material->IsWater()) - { - object.rendertypeMask |= RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER; + if (material->IsWater()) + { + object.rendertypeMask |= RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER; + } } if (material->HasPlanarReflection()) diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index a84a2dfd6..6e01feb8c 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -143,6 +143,8 @@ namespace wiSceneSystem const wiGraphicsTypes::Texture2D* emissiveMap = nullptr; std::unique_ptr constantBuffer; + int customShaderID = -1; // for now, this is not serialized; need to consider actual proper use case first + inline void SetUserStencilRef(uint8_t value) { assert(value < 128); @@ -161,6 +163,7 @@ namespace wiSceneSystem inline float GetOpacity() const { return baseColor.w; } inline float GetEmissiveStrength() const { return emissiveColor.w; } + inline int GetCustomShaderID() const { return customShaderID; } inline void SetDirty(bool value = true) { if (value) { _flags |= DIRTY; } else { _flags &= ~DIRTY; } } inline bool IsDirty() const { return _flags & DIRTY; } @@ -169,12 +172,13 @@ 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 || blendMode != BLENDMODE_OPAQUE; } + inline bool IsTransparent() const { return GetOpacity() < 1.0f || blendMode != BLENDMODE_OPAQUE || IsCustomShader(); } inline bool IsWater() const { return _flags & WATER; } inline bool HasPlanarReflection() const { return (_flags & PLANAR_REFLECTION) || IsWater(); } inline bool IsCastingShadow() const { return _flags & CAST_SHADOW; } inline bool IsAlphaTestEnabled() const { return alphaRef <= 1.0f - 1.0f / 256.0f; } inline bool IsFlipNormalMap() const { return _flags & FLIP_NORMALMAP; } + inline bool IsCustomShader() const { return customShaderID >= 0; } inline void SetBaseColor(const XMFLOAT4& value) { SetDirty(); baseColor = value; } inline void SetEmissiveColor(const XMFLOAT4& value) { SetDirty(); emissiveColor = value; } @@ -189,6 +193,8 @@ namespace wiSceneSystem inline void SetOpacity(float value) { SetDirty(); baseColor.w = value; } inline void SetAlphaRef(float value) { SetDirty(); alphaRef = value; } inline void SetFlipNormalMap(bool value) { SetDirty(); if (value) { _flags |= FLIP_NORMALMAP; } else { _flags &= ~FLIP_NORMALMAP; } } + inline void SetCustomShaderID(int id) { customShaderID = id; } + inline void DisableCustomShader() { customShaderID = -1; } void Serialize(wiArchive& archive, uint32_t seed = 0); }; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index d85f1c2f0..4a24e90dc 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 = 46; + const int revision = 47; long GetVersion() diff --git a/WickedEngine/wiWidget.cpp b/WickedEngine/wiWidget.cpp index 7aabf313e..d1cfd49c7 100644 --- a/WickedEngine/wiWidget.cpp +++ b/WickedEngine/wiWidget.cpp @@ -1022,8 +1022,13 @@ void wiComboBox::Update(wiGUI* gui, float dt) } if (state == ACTIVE && combostate == COMBOSTATE_SELECTING) { + hovered = -1; gui->DeactivateWidget(this); } + if (state == IDLE && combostate == COMBOSTATE_SELECTING) + { + combostate = COMBOSTATE_INACTIVE; + } hitBox.pos.x = translation.x; hitBox.pos.y = translation.y; @@ -1107,8 +1112,8 @@ void wiComboBox::Update(wiGUI* gui, float dt) if (hovered >= 0) { SetSelected(hovered); - gui->DeactivateWidget(this); - combostate = COMBOSTATE_INACTIVE; + //gui->DeactivateWidget(this); + //combostate = COMBOSTATE_INACTIVE; } } }