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;
}
}
}