diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp index c159d0b89..29568e75d 100644 --- a/Editor/MaterialWindow.cpp +++ b/Editor/MaterialWindow.cpp @@ -305,7 +305,7 @@ void MaterialWindow::Create(EditorComponent* _editor) }); AddWidget(&refractionSlider); - pomSlider.Create(0, 0.1f, 0.0f, 1000, "Par Occl Mapping: "); + pomSlider.Create(0, 1.0f, 0.0f, 1000, "Par Occl Mapping: "); pomSlider.SetSize(XMFLOAT2(wid, hei)); pomSlider.SetPos(XMFLOAT2(x, y += step)); pomSlider.OnSlide([&](wi::gui::EventArgs args) { @@ -315,7 +315,7 @@ void MaterialWindow::Create(EditorComponent* _editor) }); AddWidget(&pomSlider); - displacementMappingSlider.Create(0, 0.1f, 0.0f, 1000, "Displacement: "); + displacementMappingSlider.Create(0, 10.0f, 0.0f, 1000, "Displacement: "); displacementMappingSlider.SetTooltip("Adjust how much the bump map should modulate the geometry when using tessellation."); displacementMappingSlider.SetSize(XMFLOAT2(wid, hei)); displacementMappingSlider.SetPos(XMFLOAT2(x, y += step)); @@ -652,8 +652,18 @@ void MaterialWindow::Create(EditorComponent* _editor) params.extensions = wi::resourcemanager::GetSupportedImageExtensions(); wi::helper::FileDialog(params, [this, material, slot](std::string fileName) { wi::eventhandler::Subscribe_Once(wi::eventhandler::EVENT_THREAD_SAFE_POINT, [=](uint64_t userdata) { + wi::resourcemanager::Flags flags = wi::resourcemanager::Flags::IMPORT_RETAIN_FILEDATA; + switch (slot) + { + case MaterialComponent::NORMALMAP: + case MaterialComponent::CLEARCOATNORMALMAP: + flags |= wi::resourcemanager::Flags::IMPORT_NORMALMAP; + break; + default: + break; + }; + material->textures[slot].resource = wi::resourcemanager::Load(fileName, flags); material->textures[slot].name = fileName; - material->CreateRenderData(); material->SetDirty(); textureSlotLabel.SetText(wi::helper::GetFileNameFromPath(fileName)); }); @@ -779,12 +789,10 @@ void MaterialWindow::SetEntity(Entity entity) case MaterialComponent::SHADERTYPE_PBR_ANISOTROPIC: pomSlider.SetText("Anisotropy: "); pomSlider.SetTooltip("Adjust anisotropy specular effect. \nOnly works with PBR + Anisotropic shader."); - pomSlider.SetRange(0, 0.99f); break; case MaterialComponent::SHADERTYPE_PBR_PARALLAXOCCLUSIONMAPPING: pomSlider.SetText("Par Occl Mapping: "); pomSlider.SetTooltip("[Parallax Occlusion Mapping] Adjust how much the bump map should modulate the surface parallax effect. \nOnly works with PBR + Parallax shader."); - pomSlider.SetRange(0, 0.1f); break; default: pomSlider.SetEnabled(false); diff --git a/Editor/PaintToolWindow.cpp b/Editor/PaintToolWindow.cpp index 89183f109..58c768169 100644 --- a/Editor/PaintToolWindow.cpp +++ b/Editor/PaintToolWindow.cpp @@ -243,12 +243,12 @@ void PaintToolWindow::Create(EditorComponent* _editor) if (material == nullptr) continue; - Texture editTexture = GetEditTextureSlot(*material); + TextureSlot editTexture = GetEditTextureSlot(*material); uint64_t sel = textureSlotComboBox.GetItemUserData(textureSlotComboBox.GetSelected()); wi::vector texturefiledata; - if (wi::helper::saveTextureToMemoryFile(editTexture, "PNG", texturefiledata)) + if (wi::helper::saveTextureToMemoryFile(editTexture.texture, "PNG", texturefiledata)) { material->textures[sel].resource.SetFileData(texturefiledata); } @@ -484,10 +484,10 @@ void PaintToolWindow::Update(float dt) break; int uvset = 0; - Texture editTexture = GetEditTextureSlot(*material, &uvset); - if (!editTexture.IsValid()) + TextureSlot editTexture = GetEditTextureSlot(*material, &uvset); + if (!editTexture.texture.IsValid()) break; - const TextureDesc& desc = editTexture.GetDesc(); + const TextureDesc& desc = editTexture.texture.GetDesc(); auto& vertex_uvset = uvset == 0 ? mesh->vertex_uvset_0 : mesh->vertex_uvset_1; const float u = intersect.bary.x; @@ -535,7 +535,7 @@ void PaintToolWindow::Update(float dt) { device->BindResource(wi::texturehelper::getWhite(), 1, cmd); } - device->BindUAV(&editTexture, 0, cmd); + device->BindUAV(&editTexture.texture, 0, cmd); PaintTextureCB cb; cb.xPaintBrushCenter = center; @@ -561,9 +561,9 @@ void PaintToolWindow::Update(float dt) }; device->Barrier(barriers, arraysize(barriers), cmd); - if (editTexture.desc.mip_levels > 1) + if (editTexture.texture.desc.mip_levels > 1) { - wi::renderer::GenerateMipChain(editTexture, wi::renderer::MIPGENFILTER::MIPGENFILTER_LINEAR, cmd); + wi::renderer::GenerateMipChain(editTexture.texture, wi::renderer::MIPGENFILTER::MIPGENFILTER_LINEAR, cmd); } } if(substep == substep_count - 1) @@ -1316,22 +1316,36 @@ void PaintToolWindow::RecordHistory(bool start, CommandList cmd) { // Make a copy of texture to edit and replace material resource: GraphicsDevice* device = wi::graphics::GetDevice(); - Texture newTex; - TextureDesc desc = editTexture.GetDesc(); + TextureSlot newslot; + TextureDesc desc = editTexture.texture.GetDesc(); desc.format = Format::R8G8B8A8_UNORM; // force format to one that is writable by GPU desc.bind_flags |= BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS; - device->CreateTexture(&desc, nullptr, &newTex); - for (uint32_t i = 0; i < newTex.GetDesc().mip_levels; ++i) + desc.misc_flags = ResourceMiscFlag::TYPED_FORMAT_CASTING; + device->CreateTexture(&desc, nullptr, &newslot.texture); + for (uint32_t i = 0; i < newslot.texture.GetDesc().mip_levels; ++i) { int subresource_index; - subresource_index = device->CreateSubresource(&newTex, SubresourceType::SRV, 0, 1, i, 1); + subresource_index = device->CreateSubresource(&newslot.texture, SubresourceType::SRV, 0, 1, i, 1); assert(subresource_index == i); - subresource_index = device->CreateSubresource(&newTex, SubresourceType::UAV, 0, 1, i, 1); + subresource_index = device->CreateSubresource(&newslot.texture, SubresourceType::UAV, 0, 1, i, 1); assert(subresource_index == i); } + // This part must be AFTER mip level subresource creation: + int srgb_subresource = -1; + { + Format srgb_format = GetFormatSRGB(desc.format); + newslot.srgb_subresource = device->CreateSubresource( + &newslot.texture, + SubresourceType::SRV, + 0, -1, + 0, -1, + &srgb_format + ); + } assert(cmd.IsValid()); - wi::renderer::CopyTexture2D(newTex, -1, 0, 0, editTexture, 0, cmd); - ReplaceEditTextureSlot(*material, newTex); + device->CopyResource(&newslot.texture, &editTexture.texture, cmd); + + ReplaceEditTextureSlot(*material, newslot); } } @@ -1556,21 +1570,24 @@ void PaintToolWindow::ConsumeHistoryOperation(wi::Archive& archive, bool undo) } } } -Texture PaintToolWindow::GetEditTextureSlot(const MaterialComponent& material, int* uvset) +PaintToolWindow::TextureSlot PaintToolWindow::GetEditTextureSlot(const MaterialComponent& material, int* uvset) { uint64_t sel = textureSlotComboBox.GetItemUserData(textureSlotComboBox.GetSelected()); if (!material.textures[sel].resource.IsValid()) { - return Texture(); + return {}; } if (uvset) *uvset = material.textures[sel].uvset; - return material.textures[sel].resource.GetTexture(); + TextureSlot retVal; + retVal.texture = material.textures[sel].resource.GetTexture(); + retVal.srgb_subresource = material.textures[sel].resource.GetTextureSRGBSubresource(); + return retVal; } -void PaintToolWindow::ReplaceEditTextureSlot(wi::scene::MaterialComponent& material, const Texture& texture) +void PaintToolWindow::ReplaceEditTextureSlot(wi::scene::MaterialComponent& material, const TextureSlot& textureslot) { uint64_t sel = textureSlotComboBox.GetItemUserData(textureSlotComboBox.GetSelected()); - material.textures[sel].resource.SetTexture(texture); + material.textures[sel].resource.SetTexture(textureslot.texture, textureslot.srgb_subresource); material.SetDirty(); } diff --git a/Editor/PaintToolWindow.h b/Editor/PaintToolWindow.h index 4f0d01fea..960d396a3 100644 --- a/Editor/PaintToolWindow.h +++ b/Editor/PaintToolWindow.h @@ -13,9 +13,14 @@ class PaintToolWindow : public wi::gui::Window bool history_needs_recording_end = false; size_t history_redo_jump_position = 0; size_t history_textureIndex = 0; - wi::vector history_textures; // we'd like to keep history textures in GPU memory to avoid GPU readback - wi::graphics::Texture GetEditTextureSlot(const wi::scene::MaterialComponent& material, int* uvset = nullptr); - void ReplaceEditTextureSlot(wi::scene::MaterialComponent& material, const wi::graphics::Texture& texture); + struct TextureSlot + { + wi::graphics::Texture texture; + int srgb_subresource = -1; + }; + wi::vector history_textures; + TextureSlot GetEditTextureSlot(const wi::scene::MaterialComponent& material, int* uvset = nullptr); + void ReplaceEditTextureSlot(wi::scene::MaterialComponent& material, const TextureSlot& textureslot); struct SculptingIndex { diff --git a/WickedEngine/shaders/objectHF.hlsli b/WickedEngine/shaders/objectHF.hlsli index ef7888e9f..360c2f6cd 100644 --- a/WickedEngine/shaders/objectHF.hlsli +++ b/WickedEngine/shaders/objectHF.hlsli @@ -227,6 +227,7 @@ struct VertexSurface tangent.xyz = normalize(mul((float3x3)input.GetInstance().transformInverseTranspose.GetMatrix(), tangent.xyz)); uvsets = input.GetUVSets(); + uvsets.xy = mad(uvsets.xy, material.texMulAdd.xy, material.texMulAdd.zw); atlas = input.GetAtlasUV(); @@ -1049,11 +1050,6 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target const float2 ScreenCoord = pixel * GetCamera().internal_resolution_rcp; float3 bumpColor = 0; -#ifdef OBJECTSHADER_USE_UVSETS - float4 uvsets = input.uvsets; - uvsets.xy = mad(uvsets.xy, GetMaterial().texMulAdd.xy, GetMaterial().texMulAdd.zw); -#endif // OBJECTSHADER_USE_UVSETS - #ifndef DISABLE_ALPHATEST #ifndef TRANSPARENT #ifndef ENVMAPRENDERING @@ -1087,7 +1083,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target #ifdef OBJECTSHADER_USE_TANGENT #if 0 - float3x3 TBN = compute_tangent_frame(surface.N, surface.P, uvsets.xy); + float3x3 TBN = compute_tangent_frame(surface.N, surface.P, input.uvsets.xy); #else surface.T = input.tan; surface.T.xyz = normalize(surface.T.xyz); @@ -1096,7 +1092,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target #endif #ifdef POM - ParallaxOcclusionMapping(uvsets, surface.V, TBN); + ParallaxOcclusionMapping(input.uvsets, surface.V, TBN); #endif // POM #endif // OBJECTSHADER_USE_TANGENT @@ -1113,7 +1109,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target if (GetMaterial().textures[BASECOLORMAP].IsValid() && (GetFrame().options & OPTION_BIT_DISABLE_ALBEDO_MAPS) == 0) #endif // PREPASS { - float4 baseColorMap = GetMaterial().textures[BASECOLORMAP].Sample(sampler_objectshader, uvsets); + float4 baseColorMap = GetMaterial().textures[BASECOLORMAP].Sample(sampler_objectshader, input.uvsets); color *= baseColorMap; } #endif // OBJECTSHADER_USE_UVSETS @@ -1137,7 +1133,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target #ifndef WATER #ifdef OBJECTSHADER_USE_TANGENT - NormalMapping(uvsets, surface.N, TBN, bumpColor); + NormalMapping(input.uvsets, surface.N, TBN, bumpColor); #endif // OBJECTSHADER_USE_TANGENT #endif // WATER @@ -1148,7 +1144,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target [branch] if (GetMaterial().textures[SURFACEMAP].IsValid()) { - surfaceMap = GetMaterial().textures[SURFACEMAP].Sample(sampler_objectshader, uvsets); + surfaceMap = GetMaterial().textures[SURFACEMAP].Sample(sampler_objectshader, input.uvsets); } #endif // OBJECTSHADER_USE_UVSETS @@ -1159,7 +1155,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target [branch] if (GetMaterial().textures[SPECULARMAP].IsValid()) { - specularMap = GetMaterial().textures[SPECULARMAP].Sample(sampler_objectshader, uvsets); + specularMap = GetMaterial().textures[SPECULARMAP].Sample(sampler_objectshader, input.uvsets); } #endif // OBJECTSHADER_USE_UVSETS @@ -1175,7 +1171,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target [branch] if (any(surface.emissiveColor) && GetMaterial().textures[EMISSIVEMAP].IsValid()) { - float4 emissiveMap = GetMaterial().textures[EMISSIVEMAP].Sample(sampler_objectshader, uvsets); + float4 emissiveMap = GetMaterial().textures[EMISSIVEMAP].Sample(sampler_objectshader, input.uvsets); surface.emissiveColor *= emissiveMap.rgb * emissiveMap.a; } #endif // OBJECTSHADER_USE_UVSETS @@ -1192,7 +1188,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target [branch] if (GetMaterial().IsOcclusionEnabled_Secondary() && GetMaterial().textures[OCCLUSIONMAP].IsValid()) { - surface.occlusion *= GetMaterial().textures[OCCLUSIONMAP].Sample(sampler_objectshader, uvsets).r; + surface.occlusion *= GetMaterial().textures[OCCLUSIONMAP].Sample(sampler_objectshader, input.uvsets).r; } #endif // OBJECTSHADER_USE_UVSETS @@ -1225,12 +1221,12 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target [branch] if (GetMaterial().textures[SHEENCOLORMAP].IsValid()) { - surface.sheen.color = GetMaterial().textures[SHEENCOLORMAP].Sample(sampler_objectshader, uvsets).rgb; + surface.sheen.color = GetMaterial().textures[SHEENCOLORMAP].Sample(sampler_objectshader, input.uvsets).rgb; } [branch] if (GetMaterial().textures[SHEENROUGHNESSMAP].IsValid()) { - surface.sheen.roughness = GetMaterial().textures[SHEENROUGHNESSMAP].Sample(sampler_objectshader, uvsets).a; + surface.sheen.roughness = GetMaterial().textures[SHEENROUGHNESSMAP].Sample(sampler_objectshader, input.uvsets).a; } #endif // OBJECTSHADER_USE_UVSETS #endif // SHEEN @@ -1245,18 +1241,18 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target [branch] if (GetMaterial().textures[CLEARCOATMAP].IsValid()) { - surface.clearcoat.factor = GetMaterial().textures[CLEARCOATMAP].Sample(sampler_objectshader, uvsets).r; + surface.clearcoat.factor = GetMaterial().textures[CLEARCOATMAP].Sample(sampler_objectshader, input.uvsets).r; } [branch] if (GetMaterial().textures[CLEARCOATROUGHNESSMAP].IsValid()) { - surface.clearcoat.roughness = GetMaterial().textures[CLEARCOATROUGHNESSMAP].Sample(sampler_objectshader, uvsets).g; + surface.clearcoat.roughness = GetMaterial().textures[CLEARCOATROUGHNESSMAP].Sample(sampler_objectshader, input.uvsets).g; } #ifdef OBJECTSHADER_USE_TANGENT [branch] if (GetMaterial().textures[CLEARCOATNORMALMAP].IsValid()) { - float3 clearcoatNormalMap = float3(GetMaterial().textures[CLEARCOATNORMALMAP].Sample(sampler_objectshader, uvsets).rg, 1); + float3 clearcoatNormalMap = float3(GetMaterial().textures[CLEARCOATNORMALMAP].Sample(sampler_objectshader, input.uvsets).rg, 1); clearcoatNormalMap = clearcoatNormalMap * 2 - 1; surface.clearcoat.N = mul(clearcoatNormalMap, TBN); } @@ -1296,7 +1292,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target if (GetMaterial().textures[NORMALMAP].IsValid()) { Texture2D texture_normalmap = bindless_textures[GetMaterial().textures[NORMALMAP].texture_descriptor]; - const float2 UV_normalMap = GetMaterial().textures[NORMALMAP].GetUVSet() == 0 ? uvsets.xy : uvsets.zw; + const float2 UV_normalMap = GetMaterial().textures[NORMALMAP].GetUVSet() == 0 ? input.uvsets.xy : input.uvsets.zw; bumpColor0 = 2 * texture_normalmap.Sample(sampler_objectshader, UV_normalMap - GetMaterial().texMulAdd.ww).rg - 1; bumpColor1 = 2 * texture_normalmap.Sample(sampler_objectshader, UV_normalMap + GetMaterial().texMulAdd.zw).rg - 1; } @@ -1332,7 +1328,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target [branch] if (GetMaterial().textures[TRANSMISSIONMAP].IsValid()) { - float transmissionMap = GetMaterial().textures[TRANSMISSIONMAP].Sample(sampler_objectshader, uvsets).r; + float transmissionMap = GetMaterial().textures[TRANSMISSIONMAP].Sample(sampler_objectshader, input.uvsets).r; surface.transmission *= transmissionMap; } #endif // OBJECTSHADER_USE_UVSETS diff --git a/WickedEngine/shaders/objectPS_paintradius.hlsl b/WickedEngine/shaders/objectPS_paintradius.hlsl index 2480da8c6..00a0aa5c5 100644 --- a/WickedEngine/shaders/objectPS_paintradius.hlsl +++ b/WickedEngine/shaders/objectPS_paintradius.hlsl @@ -6,7 +6,6 @@ [earlydepthstencil] float4 main(PixelInput input) : SV_TARGET { - input.uvsets.xy = mad(input.uvsets.xy, GetMaterial().texMulAdd.xy, GetMaterial().texMulAdd.zw); const float2 pixel = (xPaintRadUVSET == 0 ? input.uvsets.xy : input.uvsets.zw) * xPaintRadResolution; const float2x2 rot = float2x2( diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index eee19d517..52dcf0a10 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 = 91; + const int revision = 92; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);