hairparticle, wind, water, ocean updates

This commit is contained in:
turanszkij
2020-04-03 22:23:15 +01:00
parent 3db0a7e6ca
commit 182ec5bd88
9 changed files with 61 additions and 23 deletions
+30 -6
View File
@@ -68,23 +68,38 @@ WeatherWindow::WeatherWindow(wiGUI* gui) : GUI(gui)
});
weatherWindow->AddWidget(cloudSpeedSlider);
windSpeedSlider = new wiSlider(0.001f, 0.2f, 0.1f, 10000, "Wind Speed: ");
windSpeedSlider = new wiSlider(0.0f, 0.2f, 0.0f, 10000, "Wind Speed: ");
windSpeedSlider->SetSize(XMFLOAT2(100, 30));
windSpeedSlider->SetPos(XMFLOAT2(x, y += step));
windSpeedSlider->OnSlide([&](wiEventArgs args) {
UpdateWind();
});
weatherWindow->AddWidget(windSpeedSlider);
windDirectionSlider = new wiSlider(0, 1, 0, 10000, "Wind Direction: ");
windDirectionSlider->SetSize(XMFLOAT2(100, 30));
windDirectionSlider->SetPos(XMFLOAT2(x, y += step));
windDirectionSlider->OnSlide([&](wiEventArgs args) {
XMMATRIX rot = XMMatrixRotationY(args.fValue * XM_PI * 2);
XMVECTOR dir = XMVectorSet(1, 0, 0, 0);
dir = XMVector3TransformNormal(dir, rot);
dir *= windSpeedSlider->GetValue();
XMStoreFloat3(&GetWeather().windDirection, dir);
UpdateWind();
});
weatherWindow->AddWidget(windDirectionSlider);
windWaveSizeSlider = new wiSlider(0, 1, 0, 10000, "Wind Wave Size: ");
windWaveSizeSlider->SetSize(XMFLOAT2(100, 30));
windWaveSizeSlider->SetPos(XMFLOAT2(x, y += step));
windWaveSizeSlider->OnSlide([&](wiEventArgs args) {
GetWeather().windWaveSize = args.fValue;
});
weatherWindow->AddWidget(windWaveSizeSlider);
windRandomnessSlider = new wiSlider(0, 1, 0, 10000, "Wind Randomness: ");
windRandomnessSlider->SetSize(XMFLOAT2(100, 30));
windRandomnessSlider->SetPos(XMFLOAT2(x, y += step));
windRandomnessSlider->OnSlide([&](wiEventArgs args) {
GetWeather().windRandomness = args.fValue;
});
weatherWindow->AddWidget(windRandomnessSlider);
skyButton = new wiButton("Load Sky");
skyButton->SetTooltip("Load a skybox cubemap texture...");
@@ -508,3 +523,12 @@ void WeatherWindow::InvalidateProbes() const
scene.probes[i].SetDirty();
}
}
void WeatherWindow::UpdateWind()
{
XMMATRIX rot = XMMatrixRotationY(windDirectionSlider->GetValue() * XM_PI * 2);
XMVECTOR dir = XMVectorSet(1, 0, 0, 0);
dir = XMVector3TransformNormal(dir, rot);
dir *= windSpeedSlider->GetValue();
XMStoreFloat3(&GetWeather().windDirection, dir);
}
+3
View File
@@ -10,6 +10,7 @@ class wiButton;
class WeatherWindow
{
void UpdateWind();
public:
WeatherWindow(wiGUI* gui);
~WeatherWindow();
@@ -30,6 +31,8 @@ public:
wiSlider* cloudSpeedSlider;
wiSlider* windSpeedSlider;
wiSlider* windDirectionSlider;
wiSlider* windWaveSizeSlider;
wiSlider* windRandomnessSlider;
wiButton* skyButton;
wiColorPicker* ambientColorPicker;
wiColorPicker* horizonColorPicker;
+3 -2
View File
@@ -76,8 +76,9 @@ VertexToPixel main(uint fakeIndex : SV_VERTEXID)
patchPos.xyz *= frame.xyx * 0.5f;
// simplistic wind effect only affects the top, but leaves the base as is:
float3 wind = sin(g_xFrame_Time + (position.x + position.y + position.z)) * g_xFrame_WindDirection.xyz * patchPos.y * 0.03f;
float3 windPrev = sin(g_xFrame_TimePrev + (position.x + position.y + position.z)) * g_xFrame_WindDirection.xyz * patchPos.y * 0.03f;
const float3 posrand = (position.x + position.y + position.z) * g_xFrame_WindRandomness;
float3 wind = sin(g_xFrame_Time * (1 + g_xFrame_WindWaveSize) + posrand) * g_xFrame_WindDirection * patchPos.y;
float3 windPrev = sin(g_xFrame_TimePrev * (1 + g_xFrame_WindWaveSize) + posrand) * g_xFrame_WindDirection * patchPos.y;
// rotate the patch into the tangent space of the emitting triangle:
float3x3 TBN = float3x3(tangent, normal, binormal); // don't derive binormal, because we want the shear!
+18 -5
View File
@@ -17,7 +17,16 @@ struct LDS_ForceField
float range_rcp;
float3 normal;
};
groupshared LDS_ForceField forceFields[NUM_LDS_FORCEFIELDS];
groupshared LDS_ForceField forceFields[NUM_LDS_FORCEFIELDS];
// https://www.shadertoy.com/view/llGSzw
float hash1(uint n)
{
// integer hash copied from Hugo Elias
n = (n << 13U) ^ n;
n = n * (n * n * 15731U + 789221U) + 1376312589U;
return float(n & 0x7fffffffU) / float(0x7fffffff);
}
[numthreads(THREADCOUNT_SIMULATEHAIR, 1, 1)]
void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex)
@@ -35,14 +44,16 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
forceFields[groupIndex].range_rcp = forceField.range; // it is actually uploaded from CPU as 1.0f / range
forceFields[groupIndex].normal = forceField.directionWS;
}
GroupMemoryBarrierWithGroupSync();
if (DTid.x >= xHairParticleCount)
return;
// Generate patch:
float2 uv = float2((Gid.x + 1.0f) / (float)xHairNumDispatchGroups, (DTid.x + 1.0f) / (float)THREADCOUNT_SIMULATEHAIR);
float seed = xHairRandomSeed;
// random triangle on emitter surface:
uint tri = (uint)((xHairBaseMeshIndexCount / 3) * rand(seed, uv));
// (Note that the usual rand() function is not used because that introduces unnatural clustering with high triangle count)
uint tri = (uint)((xHairBaseMeshIndexCount / 3) * hash1(DTid.x));
// load indices of triangle from index buffer
uint i0 = meshIndexBuffer[tri * 3 + 0];
@@ -61,6 +72,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
float length2 = meshVertexBuffer_length[i2];
// random barycentric coords:
float2 uv = hammersley2d(DTid.x, xHairStrandCount);
float seed = xHairRandomSeed;
float f = rand(seed, uv);
float g = rand(seed, uv);
[flatten]
@@ -95,10 +108,10 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
// Transform particle by the emitter object matrix:
float3 base = mul(xWorld, float4(position.xyz, 1)).xyz;
target = normalize(mul((float3x3)xWorld, target));
const float3 root = base;
float3 normal = 0;
GroupMemoryBarrierWithGroupSync();
for (uint segmentID = 0; segmentID < xHairSegmentCount; ++segmentID)
{
// Identifies the hair strand segment particle:
+2 -5
View File
@@ -753,7 +753,6 @@ GBUFFEROutputType_Thin main(PIXELINPUT input)
#ifndef SIMPLE_INPUT
float3 bumpColor = 0;
float opacity = color.a;
float depth = input.pos.z;
#ifndef ENVMAPRENDERING
input.pos2D.xy /= input.pos2D.w;
@@ -900,9 +899,6 @@ GBUFFEROutputType_Thin main(PIXELINPUT input)
#endif // ENVMAPRENDERING
#endif // WATER
ApplyLighting(surface, lighting, color);
#ifdef WATER
// REFRACTION
const float lineardepth = input.pos2D.w;
@@ -911,9 +907,10 @@ GBUFFEROutputType_Thin main(PIXELINPUT input)
const float3 refractiveColor = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + bumpColor.rg * saturate(0.5 * depth_difference), 0).rgb;
// WATER FOG
color.rgb = lerp(refractiveColor, color.rgb, saturate(surface.baseColor.a * 0.1f * depth_difference));
surface.albedo = lerp(refractiveColor, color.rgb, saturate(surface.baseColor.a * 0.1f * depth_difference));
#endif // WATER
ApplyLighting(surface, lighting, color);
ApplyFog(dist, color);
+3 -3
View File
@@ -37,8 +37,6 @@ float4 main(PSIn input) : SV_TARGET
TiledLighting(pixel, surface, lighting);
ApplyLighting(surface, lighting, color);
// REFRACTION
const float lineardepth = input.pos2D.w;
const float sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy + surface.N.xz * 0.04f, 0) * g_xCamera_ZFarP;
@@ -46,7 +44,9 @@ float4 main(PSIn input) : SV_TARGET
const float3 refractiveColor = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + surface.N.xz * 0.04f * saturate(0.5 * depth_difference), 0).rgb;
// WATER FOG
color.rgb = lerp(refractiveColor, color.rgb, saturate(0.1f * depth_difference));
surface.albedo = lerp(refractiveColor, color.rgb, saturate(0.1f * depth_difference));
ApplyLighting(surface, lighting, color);
ApplyFog(dist, color);
+1 -1
View File
@@ -168,7 +168,7 @@ void wiHairParticle::UpdateGPU(const MeshComponent& mesh, const MaterialComponen
hcb.xHairBaseMeshIndexCount = (indices.empty() ? (uint)mesh.indices.size() : (uint)indices.size());
hcb.xHairBaseMeshVertexPositionStride = sizeof(MeshComponent::Vertex_POS);
// segmentCount will be loop in the shader, not a threadgroup so we don't need it here:
hcb.xHairNumDispatchGroups = (uint)ceilf((float)strandCount / (float)THREADCOUNT_SIMULATEHAIR);
hcb.xHairNumDispatchGroups = (hcb.xHairParticleCount + THREADCOUNT_SIMULATEHAIR - 1) / THREADCOUNT_SIMULATEHAIR;
device->UpdateBuffer(&cb, &hcb, cmd);
device->BindConstantBuffer(CS, &cb, CB_GETBINDSLOT(HairParticleCB), cmd);
+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 = 34;
const int revision = 35;
long GetVersion()
Binary file not shown.