resurrected mesh wind; added wind paint tool;

This commit is contained in:
turanszkij
2020-04-11 12:35:53 +01:00
parent a2ca7d2bcf
commit ed0b3fed07
16 changed files with 282 additions and 89 deletions
+13 -2
View File
@@ -14,11 +14,11 @@ MaterialWindow::MaterialWindow(EditorComponent* editor) : GUI(&editor->GetGUI())
assert(GUI && "Invalid GUI!");
materialWindow = new wiWindow(GUI, "Material Window");
materialWindow->SetSize(XMFLOAT2(700, 760));
materialWindow->SetSize(XMFLOAT2(700, 770));
GUI->AddWidget(materialWindow);
float x = 540, y = 0;
float step = 25;
float step = 24;
waterCheckBox = new wiCheckBox("Water: ");
waterCheckBox->SetTooltip("Set material as special water material.");
@@ -100,6 +100,16 @@ MaterialWindow::MaterialWindow(EditorComponent* editor) : GUI(&editor->GetGUI())
});
materialWindow->AddWidget(occlusionSecondaryCheckBox);
windCheckBox = new wiCheckBox("Wind: ");
windCheckBox->SetTooltip("If enabled, vertex wind weights will affect how much wind offset affects the subset.");
windCheckBox->SetPos(XMFLOAT2(670, y += step));
windCheckBox->OnClick([&](wiEventArgs args) {
MaterialComponent* material = wiScene::GetScene().materials.GetComponent(entity);
if (material != nullptr)
material->SetUseWind(args.bValue);
});
materialWindow->AddWidget(windCheckBox);
step = 30;
float hei = 25;
@@ -789,6 +799,7 @@ void MaterialWindow::SetEntity(Entity entity)
specularGlossinessCheckBox->SetCheck(material->IsUsingSpecularGlossinessWorkflow());
occlusionPrimaryCheckBox->SetCheck(material->IsOcclusionEnabled_Primary());
occlusionSecondaryCheckBox->SetCheck(material->IsOcclusionEnabled_Secondary());
windCheckBox->SetCheck(material->IsUsingWind());
normalMapSlider->SetValue(material->normalMapStrength);
roughnessSlider->SetValue(material->roughness);
reflectanceSlider->SetValue(material->reflectance);
+1
View File
@@ -34,6 +34,7 @@ public:
wiCheckBox* specularGlossinessCheckBox;
wiCheckBox* occlusionPrimaryCheckBox;
wiCheckBox* occlusionSecondaryCheckBox;
wiCheckBox* windCheckBox;
wiSlider* normalMapSlider;
wiSlider* roughnessSlider;
wiSlider* reflectanceSlider;
+112 -13
View File
@@ -33,6 +33,7 @@ PaintToolWindow::PaintToolWindow(EditorComponent* editor) : editor(editor)
modeComboBox->AddItem("Hairparticle - Add Triangle");
modeComboBox->AddItem("Hairparticle - Remove Triangle");
modeComboBox->AddItem("Hairparticle - Length (Alpha)");
modeComboBox->AddItem("Wind weight (Alpha)");
modeComboBox->SetSelected(0);
modeComboBox->OnSelect([&](wiEventArgs args) {
textureSlotComboBox->SetEnabled(false);
@@ -71,6 +72,9 @@ PaintToolWindow::PaintToolWindow(EditorComponent* editor) : editor(editor)
case MODE_HAIRPARTICLE_LENGTH:
infoLabel->SetText("In hair particle length mode, you can adjust length of hair particles with the colorpicker Alpha channel (A). The Alpha channel is 0-255, but the length will be normalized to 0-1 range.\nThis will NOT modify random distribution of hair!");
break;
case MODE_WIND:
infoLabel->SetText("Paint the wind affection amount onto the vertices. Use the Alpha channel to control the amount.");
break;
}
});
window->AddWidget(modeComboBox);
@@ -354,6 +358,7 @@ void PaintToolWindow::Update(float dt)
break;
case MODE_VERTEXCOLOR:
case MODE_WIND:
{
ObjectComponent* object = scene.objects.GetComponent(entity);
if (object == nullptr || object->meshID == INVALID_ENTITY)
@@ -371,14 +376,30 @@ void PaintToolWindow::Update(float dt)
material = scene.materials.GetComponent(x.materialID);
if (material != nullptr)
{
material->SetUseVertexColors(true);
switch (mode)
{
case MODE_VERTEXCOLOR:
material->SetUseVertexColors(true);
break;
case MODE_WIND:
material->SetUseWind(true);
break;
}
}
}
material = nullptr;
}
else
{
material->SetUseVertexColors(true);
switch (mode)
{
case MODE_VERTEXCOLOR:
material->SetUseVertexColors(true);
break;
case MODE_WIND:
material->SetUseWind(true);
break;
}
}
const ArmatureComponent* armature = mesh->IsSkinned() ? scene.armatures.GetComponent(mesh->armatureID) : nullptr;
@@ -390,11 +411,25 @@ void PaintToolWindow::Update(float dt)
const XMMATRIX W = XMLoadFloat4x4(&transform->world);
bool rebuild = false;
if (mesh->vertex_colors.empty())
switch (mode)
{
mesh->vertex_colors.resize(mesh->vertex_positions.size());
std::fill(mesh->vertex_colors.begin(), mesh->vertex_colors.end(), 0xFFFFFFFF); // fill white
rebuild = true;
case MODE_VERTEXCOLOR:
if (mesh->vertex_colors.empty())
{
mesh->vertex_colors.resize(mesh->vertex_positions.size());
std::fill(mesh->vertex_colors.begin(), mesh->vertex_colors.end(), wiColor::White().rgba); // fill white
rebuild = true;
}
break;
case MODE_WIND:
if (mesh->vertex_windweights.empty())
{
mesh->vertex_windweights.resize(mesh->vertex_positions.size());
std::fill(mesh->vertex_windweights.begin(), mesh->vertex_windweights.end(), 0xFF); // fill max affection
rebuild = true;
}
break;
}
if (painting)
@@ -429,11 +464,26 @@ void PaintToolWindow::Update(float dt)
if (z >= 0 && z <= 1 && dist <= radius)
{
RecordHistory(true);
wiColor vcol = mesh->vertex_colors[j];
const float affection = amount * std::powf(1 - (dist / radius), falloff);
vcol = wiColor::lerp(vcol, color, affection);
mesh->vertex_colors[j] = vcol.rgba;
rebuild = true;
const float affection = amount * std::powf(1 - (dist / radius), falloff);
switch (mode)
{
case MODE_VERTEXCOLOR:
{
wiColor vcol = mesh->vertex_colors[j];
vcol = wiColor::lerp(vcol, color, affection);
mesh->vertex_colors[j] = vcol.rgba;
}
break;
case MODE_WIND:
{
wiColor vcol = wiColor(0, 0, 0, mesh->vertex_windweights[j]);
vcol = wiColor::lerp(vcol, color, affection);
mesh->vertex_windweights[j] = vcol.getA();
}
break;
}
}
}
}
@@ -460,9 +510,18 @@ void PaintToolWindow::Update(float dt)
XMStoreFloat3(&tri.positionA, P[0]);
XMStoreFloat3(&tri.positionB, P[1]);
XMStoreFloat3(&tri.positionC, P[2]);
tri.colorA.w = 0.8f;
tri.colorB.w = 0.8f;
tri.colorC.w = 0.8f;
if (mode == MODE_WIND)
{
tri.colorA = wiColor(mesh->vertex_windweights[triangle[0]], 0, 0, 255);
tri.colorB = wiColor(mesh->vertex_windweights[triangle[1]], 0, 0, 255);
tri.colorC = wiColor(mesh->vertex_windweights[triangle[2]], 0, 0, 255);
}
else
{
tri.colorA.w = 0.8f;
tri.colorB.w = 0.8f;
tri.colorC.w = 0.8f;
}
wiRenderer::DrawTriangle(tri, true);
}
}
@@ -952,6 +1011,19 @@ void PaintToolWindow::RecordHistory(bool start, CommandList cmd)
archive << mesh->vertex_colors;
}
break;
case PaintToolWindow::MODE_WIND:
{
ObjectComponent* object = scene.objects.GetComponent(entity);
if (object == nullptr || object->meshID == INVALID_ENTITY)
break;
MeshComponent* mesh = scene.meshes.GetComponent(object->meshID);
if (mesh == nullptr)
break;
archive << mesh->vertex_windweights;
}
break;
case PaintToolWindow::MODE_SCULPTING_ADD:
case PaintToolWindow::MODE_SCULPTING_SUBTRACT:
{
@@ -1073,6 +1145,33 @@ void PaintToolWindow::ConsumeHistoryOperation(wiArchive& archive, bool undo)
mesh->CreateRenderData();
}
break;
case PaintToolWindow::MODE_WIND:
{
ObjectComponent* object = scene.objects.GetComponent(entity);
if (object == nullptr || object->meshID == INVALID_ENTITY)
break;
MeshComponent* mesh = scene.meshes.GetComponent(object->meshID);
if (mesh == nullptr)
break;
MeshComponent undo_mesh;
archive >> undo_mesh.vertex_windweights;
MeshComponent redo_mesh;
archive >> redo_mesh.vertex_windweights;
if (undo)
{
mesh->vertex_windweights = undo_mesh.vertex_windweights;
}
else
{
mesh->vertex_windweights = redo_mesh.vertex_windweights;
}
mesh->CreateRenderData();
}
break;
case PaintToolWindow::MODE_SCULPTING_ADD:
case PaintToolWindow::MODE_SCULPTING_SUBTRACT:
{
+1
View File
@@ -60,6 +60,7 @@ public:
MODE_HAIRPARTICLE_ADD_TRIANGLE,
MODE_HAIRPARTICLE_REMOVE_TRIANGLE,
MODE_HAIRPARTICLE_LENGTH,
MODE_WIND,
};
MODE GetMode() const;
void SetEntity(wiECS::Entity value, int subsetindex = -1);
+25
View File
@@ -37,6 +37,20 @@ void RenderPath3D_PathTracing::ResizeBuffers()
desc.Height = wiRenderer::GetInternalResolution().y;
device->CreateTexture(&desc, nullptr, &rtPostprocess_LDR[0]);
device->SetName(&rtPostprocess_LDR[0], "rtPostprocess_LDR[0]");
desc.Width /= 4;
desc.Height /= 4;
desc.BindFlags = BIND_UNORDERED_ACCESS | BIND_SHADER_RESOURCE;
device->CreateTexture(&desc, nullptr, &rtGUIBlurredBackground[0]);
device->SetName(&rtGUIBlurredBackground[0], "rtGUIBlurredBackground[0]");
desc.Width /= 4;
desc.Height /= 4;
device->CreateTexture(&desc, nullptr, &rtGUIBlurredBackground[1]);
device->SetName(&rtGUIBlurredBackground[1], "rtGUIBlurredBackground[1]");
device->CreateTexture(&desc, nullptr, &rtGUIBlurredBackground[2]);
device->SetName(&rtGUIBlurredBackground[2], "rtGUIBlurredBackground[2]");
}
{
@@ -153,6 +167,17 @@ void RenderPath3D_PathTracing::Render() const
false,
nullptr
);
// GUI Background blurring:
{
auto range = wiProfiler::BeginRangeGPU("GUI Background Blur", cmd);
device->EventBegin("GUI Background Blur", cmd);
wiRenderer::Postprocess_Downsample4x(rtPostprocess_LDR[0], rtGUIBlurredBackground[0], cmd);
wiRenderer::Postprocess_Downsample4x(rtGUIBlurredBackground[0], rtGUIBlurredBackground[2], cmd);
wiRenderer::Postprocess_Blur_Gaussian(rtGUIBlurredBackground[2], rtGUIBlurredBackground[1], rtGUIBlurredBackground[2], cmd);
device->EventEnd(cmd);
wiProfiler::EndRange(range);
}
});
RenderPath2D::Render();
+2
View File
@@ -7,6 +7,7 @@ static const uint SHADERMATERIAL_OPTION_BIT_USE_VERTEXCOLORS = 1 << 0;
static const uint SHADERMATERIAL_OPTION_BIT_SPECULARGLOSSINESS_WORKFLOW = 1 << 1;
static const uint SHADERMATERIAL_OPTION_BIT_OCCLUSION_PRIMARY = 1 << 2;
static const uint SHADERMATERIAL_OPTION_BIT_OCCLUSION_SECONDARY = 1 << 3;
static const uint SHADERMATERIAL_OPTION_BIT_USE_WIND = 1 << 4;
struct ShaderMaterial
{
@@ -43,6 +44,7 @@ struct ShaderMaterial
inline bool IsUsingSpecularGlossinessWorkflow() { return options & SHADERMATERIAL_OPTION_BIT_SPECULARGLOSSINESS_WORKFLOW; }
inline bool IsOcclusionEnabled_Primary() { return options & SHADERMATERIAL_OPTION_BIT_OCCLUSION_PRIMARY; }
inline bool IsOcclusionEnabled_Secondary() { return options & SHADERMATERIAL_OPTION_BIT_OCCLUSION_SECONDARY; }
inline bool IsUsingWind() { return options & SHADERMATERIAL_OPTION_BIT_USE_WIND; }
};
struct ShaderEntity
+2 -1
View File
@@ -12,6 +12,7 @@ RAWBUFFER(meshVertexBuffer_POS, TEXSLOT_ONDEMAND2);
TYPEDBUFFER(meshVertexBuffer_UV0, float2, TEXSLOT_ONDEMAND3);
TYPEDBUFFER(meshVertexBuffer_UV1, float2, TEXSLOT_ONDEMAND4);
TYPEDBUFFER(meshVertexBuffer_COL, float4, TEXSLOT_ONDEMAND5);
TYPEDBUFFER(meshVertexBuffer_SUB, uint, TEXSLOT_ONDEMAND6);
RWSTRUCTUREDBUFFER(primitiveIDBuffer, uint, 0);
RWSTRUCTUREDBUFFER(primitiveBuffer, BVHPrimitive, 1);
@@ -40,7 +41,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
uint nor_u = asuint(pos_nor0.w);
float3 nor0 = unpack_unitvector(nor_u);
uint subsetIndex = (nor_u >> 24) & 0x000000FF;
uint subsetIndex = meshVertexBuffer_SUB[i0];
nor_u = asuint(pos_nor1.w);
float3 nor1 = unpack_unitvector(nor_u);
+48 -19
View File
@@ -23,19 +23,19 @@ struct Input_InstanceAtlas
struct Input_Object_POS
{
float4 pos : POSITION_NORMAL_SUBSETINDEX;
float4 pos : POSITION_NORMAL_WIND;
Input_Instance inst;
};
struct Input_Object_POS_TEX
{
float4 pos : POSITION_NORMAL_SUBSETINDEX;
float4 pos : POSITION_NORMAL_WIND;
float2 uv0 : UVSET0;
float2 uv1 : UVSET1;
Input_Instance inst;
};
struct Input_Object_ALL
{
float4 pos : POSITION_NORMAL_SUBSETINDEX;
float4 pos : POSITION_NORMAL_WIND;
float2 uv0 : UVSET0;
float2 uv1 : UVSET1;
float2 atl : ATLAS;
@@ -72,7 +72,6 @@ struct VertexSurface
float2 atlas;
float4 color;
float3 normal;
uint subsetIndex;
float4 prevPos;
};
inline VertexSurface MakeVertexSurfaceFromInput(Input_Object_POS input)
@@ -83,11 +82,21 @@ inline VertexSurface MakeVertexSurfaceFromInput(Input_Object_POS input)
surface.color = g_xMaterial.baseColor * unpack_rgba(input.inst.userdata.x);
uint normal_subsetIndex = asuint(input.pos.w);
surface.normal.x = (float)((normal_subsetIndex >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.y = (float)((normal_subsetIndex >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.z = (float)((normal_subsetIndex >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.subsetIndex = (normal_subsetIndex >> 24) & 0x000000FF;
uint normal_wind = asuint(input.pos.w);
surface.normal.x = (float)((normal_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.y = (float)((normal_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.z = (float)((normal_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
if (g_xMaterial.IsUsingWind())
{
const float windweight = ((normal_wind >> 24) & 0x000000FF) / 255.0f;
const float waveoffset = dot(surface.position.xyz, g_xFrame_WindDirection) * g_xFrame_WindWaveSize + (surface.position.x + surface.position.y + surface.position.z) * g_xFrame_WindRandomness;
const float3 wavedir = g_xFrame_WindDirection * windweight;
const float3 wind = sin(g_xFrame_Time * g_xFrame_WindSpeed + waveoffset) * wavedir;
const float3 windPrev = sin(g_xFrame_TimePrev * g_xFrame_WindSpeed + waveoffset) * wavedir;
surface.position.xyz += wind;
surface.prevPos.xyz += windPrev;
}
return surface;
}
@@ -99,11 +108,21 @@ inline VertexSurface MakeVertexSurfaceFromInput(Input_Object_POS_TEX input)
surface.color = g_xMaterial.baseColor * unpack_rgba(input.inst.userdata.x);
uint normal_subsetIndex = asuint(input.pos.w);
surface.normal.x = (float)((normal_subsetIndex >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.y = (float)((normal_subsetIndex >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.z = (float)((normal_subsetIndex >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.subsetIndex = (normal_subsetIndex >> 24) & 0x000000FF;
uint normal_wind = asuint(input.pos.w);
surface.normal.x = (float)((normal_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.y = (float)((normal_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.z = (float)((normal_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
if (g_xMaterial.IsUsingWind())
{
const float windweight = ((normal_wind >> 24) & 0x000000FF) / 255.0f;
const float waveoffset = dot(surface.position.xyz, g_xFrame_WindDirection) * g_xFrame_WindWaveSize + (surface.position.x + surface.position.y + surface.position.z) * g_xFrame_WindRandomness;
const float3 wavedir = g_xFrame_WindDirection * windweight;
const float3 wind = sin(g_xFrame_Time * g_xFrame_WindSpeed + waveoffset) * wavedir;
const float3 windPrev = sin(g_xFrame_TimePrev * g_xFrame_WindSpeed + waveoffset) * wavedir;
surface.position.xyz += wind;
surface.prevPos.xyz += windPrev;
}
surface.uvsets = float4(input.uv0 * g_xMaterial.texMulAdd.xy + g_xMaterial.texMulAdd.zw, input.uv1);
@@ -122,11 +141,21 @@ inline VertexSurface MakeVertexSurfaceFromInput(Input_Object_ALL input)
surface.color *= input.col;
}
uint normal_subsetIndex = asuint(input.pos.w);
surface.normal.x = (float)((normal_subsetIndex >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.y = (float)((normal_subsetIndex >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.z = (float)((normal_subsetIndex >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.subsetIndex = (normal_subsetIndex >> 24) & 0x000000FF;
uint normal_wind = asuint(input.pos.w);
surface.normal.x = (float)((normal_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.y = (float)((normal_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
surface.normal.z = (float)((normal_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
if (g_xMaterial.IsUsingWind())
{
const float windweight = ((normal_wind >> 24) & 0x000000FF) / 255.0f;
const float waveoffset = dot(surface.position.xyz, g_xFrame_WindDirection) * g_xFrame_WindWaveSize + (surface.position.x + surface.position.y + surface.position.z) * g_xFrame_WindRandomness;
const float3 wavedir = g_xFrame_WindDirection * windweight;
const float3 wind = sin(g_xFrame_Time * g_xFrame_WindSpeed + waveoffset) * wavedir;
const float3 windPrev = sin(g_xFrame_TimePrev * g_xFrame_WindSpeed + waveoffset) * wavedir;
surface.position.xyz += wind;
surface.prevPos.xyz += windPrev;
}
surface.uvsets = float4(input.uv0 * g_xMaterial.texMulAdd.xy + g_xMaterial.texMulAdd.zw, input.uv1);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "globals.hlsli"
float4 main(float4 inPos : POSITION_NORMAL_SUBSETINDEX) : SV_POSITION
float4 main(float4 inPos : POSITION_NORMAL_WIND) : SV_POSITION
{
float4 pos = mul(g_xTransform, float4(inPos.xyz, 1));
+5 -5
View File
@@ -4,7 +4,7 @@
struct Input
{
float4 pos : POSITION_NORMAL_SUBSETINDEX;
float4 pos : POSITION_NORMAL_WIND;
float2 atl : ATLAS;
Input_InstancePrev instance;
};
@@ -32,10 +32,10 @@ Output main(Input input)
output.pos3D = mul(WORLD, float4(input.pos.xyz, 1)).xyz;
uint normal_wind_matID = asuint(input.pos.w);
output.normal.x = (float)((normal_wind_matID >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
output.normal.y = (float)((normal_wind_matID >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
output.normal.z = (float)((normal_wind_matID >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
uint normal_wind = asuint(input.pos.w);
output.normal.x = (float)((normal_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
output.normal.y = (float)((normal_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
output.normal.z = (float)((normal_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
return output;
}
+2 -2
View File
@@ -85,7 +85,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID)
nor.x = (float)((pos_nor_u.w >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor.y = (float)((pos_nor_u.w >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor.z = (float)((pos_nor_u.w >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor.w = (float)((pos_nor_u.w >> 24) & 0x000000FF) / 255.0f; // subsetindex
nor.w = (float)((pos_nor_u.w >> 24) & 0x000000FF) / 255.0f; // wind
}
@@ -125,7 +125,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID)
pos_nor_u.w |= (uint)((nor.x * 0.5f + 0.5f) * 255.0f) << 0;
pos_nor_u.w |= (uint)((nor.y * 0.5f + 0.5f) * 255.0f) << 8;
pos_nor_u.w |= (uint)((nor.z * 0.5f + 0.5f) * 255.0f) << 16;
pos_nor_u.w |= (uint)(nor.w * 255.0f) << 24; // subsetindex
pos_nor_u.w |= (uint)(nor.w * 255.0f) << 24; // wind
}
// Store data:
+1
View File
@@ -411,6 +411,7 @@ void wiGPUBVH::Build(const Scene& scene, CommandList cmd)
&mesh.vertexBuffer_UV0,
&mesh.vertexBuffer_UV1,
&mesh.vertexBuffer_COL,
&mesh.vertexBuffer_SUB,
};
device->BindResources(CS, res, TEXSLOT_ONDEMAND0, arraysize(res), cmd);
+7 -7
View File
@@ -1043,7 +1043,7 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [device] {
InputLayoutDesc layout[] =
{
{ "POSITION_NORMAL_SUBSETINDEX", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
};
LoadShader(VS, vertexShaders[VSTYPE_OBJECT_DEBUG], "objectVS_debug.cso");
device->CreateInputLayout(layout, arraysize(layout), &vertexShaders[VSTYPE_OBJECT_DEBUG], &inputLayouts[ILTYPE_OBJECT_DEBUG]);
@@ -1052,7 +1052,7 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [device] {
InputLayoutDesc layout[] =
{
{ "POSITION_NORMAL_SUBSETINDEX", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "UVSET", 0, MeshComponent::Vertex_TEX::FORMAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "UVSET", 1, MeshComponent::Vertex_TEX::FORMAT, 2, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "ATLAS", 0, MeshComponent::Vertex_TEX::FORMAT, 3, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
@@ -1075,7 +1075,7 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [device] {
InputLayoutDesc layout[] =
{
{ "POSITION_NORMAL_SUBSETINDEX", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "INSTANCEMATRIX", 0, FORMAT_R32G32B32A32_FLOAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_INSTANCE_DATA, 1 },
{ "INSTANCEMATRIX", 1, FORMAT_R32G32B32A32_FLOAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_INSTANCE_DATA, 1 },
@@ -1090,7 +1090,7 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [device] {
InputLayoutDesc layout[] =
{
{ "POSITION_NORMAL_SUBSETINDEX", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "UVSET", 0, MeshComponent::Vertex_TEX::FORMAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "UVSET", 1, MeshComponent::Vertex_TEX::FORMAT, 2, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
@@ -1107,7 +1107,7 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [device] {
InputLayoutDesc layout[] =
{
{ "POSITION_NORMAL_SUBSETINDEX", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "INSTANCEMATRIX", 0, FORMAT_R32G32B32A32_FLOAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_INSTANCE_DATA, 1 },
{ "INSTANCEMATRIX", 1, FORMAT_R32G32B32A32_FLOAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_INSTANCE_DATA, 1 },
@@ -1122,7 +1122,7 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [device] {
InputLayoutDesc layout[] =
{
{ "POSITION_NORMAL_SUBSETINDEX", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "UVSET", 0, MeshComponent::Vertex_TEX::FORMAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "UVSET", 1, MeshComponent::Vertex_TEX::FORMAT, 2, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
@@ -1162,7 +1162,7 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [device] {
InputLayoutDesc layout[] =
{
{ "POSITION_NORMAL_SUBSETINDEX", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "POSITION_NORMAL_WIND", 0, MeshComponent::Vertex_POS::FORMAT, 0, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "ATLAS", 0, MeshComponent::Vertex_TEX::FORMAT, 1, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
{ "INSTANCEMATRIXPREV", 0, FORMAT_R32G32B32A32_FLOAT, 2, InputLayoutDesc::APPEND_ALIGNED_ELEMENT, INPUT_PER_INSTANCE_DATA, 1 },
+38 -18
View File
@@ -300,6 +300,10 @@ namespace wiScene
{
retVal.options |= SHADERMATERIAL_OPTION_BIT_OCCLUSION_SECONDARY;
}
if (IsUsingWind())
{
retVal.options |= SHADERMATERIAL_OPTION_BIT_USE_WIND;
}
return retVal;
}
@@ -356,29 +360,16 @@ namespace wiScene
XMFLOAT3 _min = XMFLOAT3(FLT_MAX, FLT_MAX, FLT_MAX);
XMFLOAT3 _max = XMFLOAT3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
// vertexBuffer - POSITION + NORMAL + SUBSETINDEX:
// vertexBuffer - POSITION + NORMAL + WIND:
{
vertex_subsets.resize(vertex_positions.size());
uint32_t subsetCounter = 0;
for (auto& subset : subsets)
{
for (uint32_t i = 0; i < subset.indexCount; ++i)
{
uint32_t index = indices[subset.indexOffset + i];
vertex_subsets[index] = subsetCounter;
}
subsetCounter++;
}
std::vector<Vertex_POS> vertices(vertex_positions.size());
for (size_t i = 0; i < vertices.size(); ++i)
{
const XMFLOAT3& pos = vertex_positions[i];
XMFLOAT3& nor = vertex_normals.empty() ? XMFLOAT3(1, 1, 1) : vertex_normals[i];
XMStoreFloat3(&nor, XMVector3Normalize(XMLoadFloat3(&nor)));
uint32_t subsetIndex = vertex_subsets[i];
vertices[i].FromFULL(pos, nor, subsetIndex);
const uint8_t wind = vertex_windweights.empty() ? 0xFF : vertex_windweights[i];
vertices[i].FromFULL(pos, nor, wind);
_min = wiMath::Min(_min, pos);
_max = wiMath::Max(_max, pos);
@@ -523,6 +514,35 @@ namespace wiScene
device->CreateBuffer(&bd, &InitData, &vertexBuffer_ATL);
}
// vertexBuffer - SUBSETS
{
vertex_subsets.resize(vertex_positions.size());
uint32_t subsetCounter = 0;
for (auto& subset : subsets)
{
for (uint32_t i = 0; i < subset.indexCount; ++i)
{
uint32_t index = indices[subset.indexOffset + i];
vertex_subsets[index] = subsetCounter;
}
subsetCounter++;
}
GPUBufferDesc bd;
bd.Usage = USAGE_IMMUTABLE;
bd.CPUAccessFlags = 0;
bd.BindFlags = BIND_VERTEX_BUFFER | BIND_SHADER_RESOURCE;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(uint8_t);
bd.ByteWidth = (uint32_t)(bd.StructureByteStride * vertex_subsets.size());
bd.Format = FORMAT_R8_UINT;
SubresourceData InitData;
InitData.pSysMem = vertex_subsets.data();
device->CreateBuffer(&bd, &InitData, &vertexBuffer_SUB);
}
// vertexBuffer_PRE will be created on demand later!
vertexBuffer_PRE = GPUBuffer();
@@ -966,8 +986,8 @@ namespace wiScene
XMStoreFloat3(&pos, XMVector3Transform(XMLoadFloat3(&pos), W));
XMFLOAT3 nor = mesh.vertex_normals.empty() ? XMFLOAT3(1, 1, 1) : mesh.vertex_normals[i];
XMStoreFloat3(&nor, XMVector3Normalize(XMVector3TransformNormal(XMLoadFloat3(&nor), W)));
uint32_t subsetIndex = mesh.vertex_subsets[i];
vertex_positions_simulation[i].FromFULL(pos, nor, subsetIndex);
const uint8_t wind = mesh.vertex_windweights.empty() ? 0xFF : mesh.vertex_windweights[i];
vertex_positions_simulation[i].FromFULL(pos, nor, wind);
_min = wiMath::Min(_min, pos);
_max = wiMath::Max(_max, pos);
}
+23 -20
View File
@@ -116,6 +116,7 @@ namespace wiScene
SPECULAR_GLOSSINESS_WORKFLOW = 1 << 6,
OCCLUSION_PRIMARY = 1 << 7,
OCCLUSION_SECONDARY = 1 << 8,
USE_WIND = 1 << 9,
};
uint32_t _flags = DIRTY | CAST_SHADOW;
@@ -205,6 +206,7 @@ namespace wiScene
inline bool IsAlphaTestEnabled() const { return alphaRef <= 1.0f - 1.0f / 256.0f; }
inline bool IsFlipNormalMap() const { return _flags & FLIP_NORMALMAP; }
inline bool IsUsingVertexColors() const { return _flags & USE_VERTEXCOLORS; }
inline bool IsUsingWind() const { return _flags & USE_WIND; }
inline bool IsUsingSpecularGlossinessWorkflow() const { return _flags & SPECULAR_GLOSSINESS_WORKFLOW; }
inline bool IsOcclusionEnabled_Primary() const { return _flags & OCCLUSION_PRIMARY; }
inline bool IsOcclusionEnabled_Secondary() const { return _flags & OCCLUSION_SECONDARY; }
@@ -225,6 +227,7 @@ namespace wiScene
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 SetUseVertexColors(bool value) { SetDirty(); if (value) { _flags |= USE_VERTEXCOLORS; } else { _flags &= ~USE_VERTEXCOLORS; } }
inline void SetUseWind(bool value) { SetDirty(); if (value) { _flags |= USE_WIND; } else { _flags &= ~USE_WIND; } }
inline void SetUseSpecularGlossinessWorkflow(bool value) { SetDirty(); if (value) { _flags |= SPECULAR_GLOSSINESS_WORKFLOW; } else { _flags &= ~SPECULAR_GLOSSINESS_WORKFLOW; } }
inline void SetCustomShaderID(int id) { customShaderID = id; }
inline void DisableCustomShader() { customShaderID = -1; }
@@ -260,6 +263,7 @@ namespace wiScene
std::vector<XMFLOAT4> vertex_boneweights;
std::vector<XMFLOAT2> vertex_atlas;
std::vector<uint32_t> vertex_colors;
std::vector<uint8_t> vertex_windweights;
std::vector<uint32_t> indices;
struct MeshSubset
@@ -293,6 +297,7 @@ namespace wiScene
wiGraphics::GPUBuffer vertexBuffer_ATL;
wiGraphics::GPUBuffer vertexBuffer_PRE;
wiGraphics::GPUBuffer streamoutBuffer_POS;
wiGraphics::GPUBuffer vertexBuffer_SUB;
std::vector<uint8_t> vertex_subsets;
@@ -330,14 +335,14 @@ namespace wiScene
struct Vertex_POS
{
XMFLOAT3 pos = XMFLOAT3(0.0f, 0.0f, 0.0f);
uint32_t normal_subsetIndex = 0;
uint32_t normal_wind = 0;
void FromFULL(const XMFLOAT3& _pos, const XMFLOAT3& _nor, uint32_t subsetIndex)
void FromFULL(const XMFLOAT3& _pos, const XMFLOAT3& _nor, uint8_t wind)
{
pos.x = _pos.x;
pos.y = _pos.y;
pos.z = _pos.z;
MakeFromParams(_nor, subsetIndex);
MakeFromParams(_nor, wind);
}
inline XMVECTOR LoadPOS() const
{
@@ -349,36 +354,34 @@ namespace wiScene
}
inline void MakeFromParams(const XMFLOAT3& normal)
{
normal_subsetIndex = normal_subsetIndex & 0xFF000000; // reset only the normals
normal_wind = normal_wind & 0xFF000000; // reset only the normals
normal_subsetIndex |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
normal_subsetIndex |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
normal_subsetIndex |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
normal_wind |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
normal_wind |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
normal_wind |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
}
inline void MakeFromParams(const XMFLOAT3& normal, uint32_t subsetIndex)
inline void MakeFromParams(const XMFLOAT3& normal, uint8_t wind)
{
assert(subsetIndex < 256); // subsetIndex is packed onto 8 bits
normal_wind = 0;
normal_subsetIndex = 0;
normal_subsetIndex |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
normal_subsetIndex |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
normal_subsetIndex |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
normal_subsetIndex |= (subsetIndex & 0x000000FF) << 24;
normal_wind |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0;
normal_wind |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8;
normal_wind |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16;
normal_wind |= (uint32_t)wind << 24;
}
inline XMFLOAT3 GetNor_FULL() const
{
XMFLOAT3 nor_FULL(0, 0, 0);
nor_FULL.x = (float)((normal_subsetIndex >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor_FULL.y = (float)((normal_subsetIndex >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor_FULL.z = (float)((normal_subsetIndex >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor_FULL.x = (float)((normal_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor_FULL.y = (float)((normal_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
nor_FULL.z = (float)((normal_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f;
return nor_FULL;
}
inline uint32_t GetMaterialIndex() const
inline uint8_t GetWind() const
{
return (normal_subsetIndex >> 24) & 0x000000FF;
return (normal_wind >> 24) & 0x000000FF;
}
static const wiGraphics::FORMAT FORMAT = wiGraphics::FORMAT::FORMAT_R32G32B32A32_FLOAT;
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 39;
// minor bug fixes, alterations, refactors, updates
const int revision = 49;
const int revision = 50;
long GetVersion()