resurrected mesh wind; added wind paint tool;
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
wiCheckBox* specularGlossinessCheckBox;
|
||||
wiCheckBox* occlusionPrimaryCheckBox;
|
||||
wiCheckBox* occlusionSecondaryCheckBox;
|
||||
wiCheckBox* windCheckBox;
|
||||
wiSlider* normalMapSlider;
|
||||
wiSlider* roughnessSlider;
|
||||
wiSlider* reflectanceSlider;
|
||||
|
||||
+112
-13
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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));
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user