hair particle updates

This commit is contained in:
Turanszki Janos
2019-11-10 14:24:14 +00:00
parent 83dee7d9db
commit a8c218661e
11 changed files with 176 additions and 115 deletions
@@ -316,9 +316,15 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
</FxCompile>
<FxCompile Include="hairparticlePS_forward_transparent.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
</FxCompile>
<FxCompile Include="hairparticlePS_simplest.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
</FxCompile>
<FxCompile Include="hairparticlePS_tiledforward_transparent.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
</FxCompile>
<FxCompile Include="hairparticle_simulateCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
@@ -810,6 +810,12 @@
<FxCompile Include="chromatic_aberrationCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
<FxCompile Include="hairparticlePS_forward_transparent.hlsl">
<Filter>PS</Filter>
</FxCompile>
<FxCompile Include="hairparticlePS_tiledforward_transparent.hlsl">
<Filter>PS</Filter>
</FxCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="PS">
@@ -3,7 +3,7 @@
void main(VertexToPixel input)
{
clip(dither(input.pos.xy) - input.fade);
clip(dither(input.pos.xy + GetTemporalAASampleRotation()) - input.fade);
float4 color = texture_0.Sample(sampler_linear_clamp,input.tex);
ALPHATEST(color.a)
+1 -1
View File
@@ -4,7 +4,7 @@
GBUFFEROutputType main(VertexToPixel input)
{
clip(dither(input.pos.xy) - input.fade);
clip(dither(input.pos.xy + GetTemporalAASampleRotation()) - input.fade);
float4 color = texture_0.Sample(sampler_linear_clamp, input.tex);
color.rgb = DEGAMMA(color.rgb);
+7 -1
View File
@@ -2,12 +2,18 @@
#include "objectHF.hlsli"
#include "hairparticleHF.hlsli"
#ifndef TRANSPARENT
[earlydepthstencil]
#endif // TRANSPARENT
GBUFFEROutputType_Thin main(VertexToPixel input)
{
float4 color = texture_0.Sample(sampler_linear_clamp, input.tex);
color.rgb = DEGAMMA(color.rgb);
color.rgb *= input.color;
ALPHATEST(color.a)
#ifdef TRANSPARENT
color.a *= 1.0 - input.fade;
clip(color.a - 1.0f / 255.0f); // cancel heaviest overdraw for the alpha composition effect
#endif // TRANSPARENT
float opacity = 1; // keep edge diffuse shading
float3 V = g_xCamera_CamPos - input.pos3D;
float dist = length(V);
@@ -0,0 +1,2 @@
#define TRANSPARENT
#include "hairparticlePS_forward.hlsl"
@@ -4,14 +4,18 @@
#include "objectHF.hlsli"
#include "hairparticleHF.hlsli"
#ifndef TRANSPARENT
[earlydepthstencil]
#endif // TRANSPARENT
GBUFFEROutputType_Thin main(VertexToPixel input)
{
float4 color = texture_0.Sample(sampler_linear_wrap, input.tex);
color.rgb = DEGAMMA(color.rgb);
color.rgb *= input.color;
#ifdef TRANSPARENT
color.a *= 1.0 - input.fade;
clip(color.a - 1.0f / 255.0f); // cancel heaviest overdraw for the alpha composition effect
#endif // TRANSPARENT
float opacity = 1;
float3 V = g_xCamera_CamPos - input.pos3D;
float dist = length(V);
@@ -0,0 +1,2 @@
#define TRANSPARENT
#include "hairparticlePS_tiledforward.hlsl"
+64 -57
View File
@@ -2,8 +2,6 @@
#include "hairparticleHF.hlsli"
#include "ShaderInterop_HairParticle.h"
static const float hairPopDistanceThreshold = 0.9f;
// billboard cross section:
static const float3 HAIRPATCH[] = {
float3(-1, -1, 0),
@@ -32,75 +30,84 @@ VertexToPixel main(uint fakeIndex : SV_VERTEXID)
const uint segmentID = (fakeIndex / 12) % xHairSegmentCount;
const uint particleID = fakeIndex / 12;
// convert the raw loaded particle data:
float3 position = particleBuffer[particleID].position;
uint tangent_random = particleBuffer[particleID].tangent_random;
float3 normal = particleBuffer[particleID].normal;
uint binormal_length = particleBuffer[particleID].binormal_length;
Out.fade = saturate(distance(position.xyz, g_xCamera_CamPos.xyz) / xHairViewDistance);
Out.fade = saturate(Out.fade - 0.8f) * 5.0f; // fade will be on edge and inwards 20%
float3 tangent;
tangent.x = (tangent_random >> 0) & 0x000000FF;
tangent.y = (tangent_random >> 8) & 0x000000FF;
tangent.z = (tangent_random >> 16) & 0x000000FF;
tangent = tangent / 255.0f * 2 - 1;
[branch]
if (Out.fade < 1.0 - 1.0f / 255.0f)
{
uint tangent_random = particleBuffer[particleID].tangent_random;
float3 normal = particleBuffer[particleID].normal;
uint binormal_length = particleBuffer[particleID].binormal_length;
uint rand = (tangent_random >> 24) & 0x000000FF;
float3 tangent;
tangent.x = (tangent_random >> 0) & 0x000000FF;
tangent.y = (tangent_random >> 8) & 0x000000FF;
tangent.z = (tangent_random >> 16) & 0x000000FF;
tangent = tangent / 255.0f * 2 - 1;
float3 binormal;
binormal.x = (binormal_length >> 0) & 0x000000FF;
binormal.y = (binormal_length >> 8) & 0x000000FF;
binormal.z = (binormal_length >> 16) & 0x000000FF;
binormal = binormal / 255.0f * 2 - 1;
uint rand = (tangent_random >> 24) & 0x000000FF;
float len = (binormal_length >> 24) & 0x000000FF;
len /= 255.0f;
len += 1;
len *= xLength;
float3 binormal;
binormal.x = (binormal_length >> 0) & 0x000000FF;
binormal.y = (binormal_length >> 8) & 0x000000FF;
binormal.z = (binormal_length >> 16) & 0x000000FF;
binormal = binormal / 255.0f * 2 - 1;
// expand the particle into a billboard cross section, the patch:
float3 patchPos = HAIRPATCH[vertexID];
float2 uv = vertexID < 6 ? patchPos.xy : patchPos.zy;
uv = uv * float2(0.5f, 0.5f) + 0.5f;
uv.y = lerp((float)segmentID / (float)xHairSegmentCount, ((float)segmentID + 1) / (float)xHairSegmentCount, uv.y);
uv.y = 1 - uv.y;
uv.x = rand % 2 == 0 ? uv.x : 1 - uv.x;
patchPos.y += 1;
float len = (binormal_length >> 24) & 0x000000FF;
len /= 255.0f;
len += 1;
len *= xLength;
// scale the billboard by the texture aspect:
float2 frame;
texture_0.GetDimensions(frame.x, frame.y);
frame.xy /= frame.y;
frame.xy *= len;
patchPos.xyz *= frame.xyx * 0.5f;
// expand the particle into a billboard cross section, the patch:
float3 patchPos = HAIRPATCH[vertexID];
float2 uv = vertexID < 6 ? patchPos.xy : patchPos.zy;
uv = uv * float2(0.5f, 0.5f) + 0.5f;
uv.y = lerp((float)segmentID / (float)xHairSegmentCount, ((float)segmentID + 1) / (float)xHairSegmentCount, uv.y);
uv.y = 1 - uv.y;
uv.x = rand % 2 == 0 ? uv.x : 1 - uv.x;
patchPos.y += 1;
// 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;
// scale the billboard by the texture aspect:
float2 frame;
texture_0.GetDimensions(frame.x, frame.y);
frame.xy /= frame.y;
frame.xy *= len;
patchPos.xyz *= frame.xyx * 0.5f;
// 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!
patchPos = mul(patchPos, TBN);
// 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;
// inset to the emitter a bit, to avoid disconnect:
position.xyz -= normal * 0.1 * len;
// 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!
patchPos = mul(patchPos, TBN);
// inset to the emitter a bit, to avoid disconnect:
position.xyz -= normal * 0.1 * len;
// copy to output:
Out.pos = float4(position, 1);
Out.pos.xyz += patchPos;
float3 savedPos = Out.pos.xyz;
Out.pos.xyz += wind;
Out.pos3D = Out.pos.xyz;
Out.pos = mul(g_xCamera_VP, Out.pos);
// copy to output:
Out.pos = float4(position, 1);
Out.pos.xyz += patchPos;
float3 savedPos = Out.pos.xyz;
Out.pos.xyz += wind;
Out.pos3D = Out.pos.xyz;
Out.pos = mul(g_xCamera_VP, Out.pos);
Out.nor = normal;
Out.tex = uv;
Out.fade = pow(saturate(distance(position.xyz, g_xCamera_CamPos.xyz) / (xHairViewDistance*hairPopDistanceThreshold)), 10);
Out.pos2D = Out.pos;
Out.pos2DPrev = mul(g_xFrame_MainCamera_PrevVP, float4(savedPos + windPrev, 1));
Out.nor = normal;
Out.tex = uv;
Out.color = xColor.rgb;
Out.pos2D = Out.pos;
Out.pos2DPrev = mul(g_xFrame_MainCamera_PrevVP, float4(savedPos + windPrev, 1));
Out.color = xColor.rgb;
}
else
{
Out = (VertexToPixel)0;
}
return Out;
}
+82 -54
View File
@@ -19,7 +19,12 @@ namespace wiSceneSystem
{
static const VertexShader *vs = nullptr;
static const PixelShader *ps[RENDERPASS_COUNT] = {};
static const PixelShader* ps_alphatestonly = nullptr;
static const PixelShader* ps_deferred = nullptr;
static const PixelShader* ps_forward = nullptr;
static const PixelShader* ps_forward_transparent = nullptr;
static const PixelShader* ps_tiledforward = nullptr;
static const PixelShader* ps_tiledforward_transparent = nullptr;
static const PixelShader *ps_simplest = nullptr;
static const ComputeShader *cs_simulate = nullptr;
static DepthStencilState dss_default, dss_equal, dss_rejectopaque_keeptransparent;
@@ -213,68 +218,91 @@ void wiHairParticle::LoadShaders()
vs = static_cast<const VertexShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticleVS.cso", wiResourceManager::VERTEXSHADER));
ps[RENDERPASS_DEPTHONLY] = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_alphatestonly.cso", wiResourceManager::PIXELSHADER));
ps[RENDERPASS_DEFERRED] = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_deferred.cso", wiResourceManager::PIXELSHADER));
ps[RENDERPASS_FORWARD] = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_forward.cso", wiResourceManager::PIXELSHADER));
ps[RENDERPASS_TILEDFORWARD] = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_tiledforward.cso", wiResourceManager::PIXELSHADER));
ps_alphatestonly = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_alphatestonly.cso", wiResourceManager::PIXELSHADER));
ps_deferred = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_deferred.cso", wiResourceManager::PIXELSHADER));
ps_forward = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_forward.cso", wiResourceManager::PIXELSHADER));
ps_forward_transparent = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_forward_transparent.cso", wiResourceManager::PIXELSHADER));
ps_tiledforward = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_tiledforward.cso", wiResourceManager::PIXELSHADER));
ps_tiledforward_transparent = static_cast<const PixelShader*>(wiResourceManager::GetShaderManager().add(path + "hairparticlePS_tiledforward_transparent.cso", wiResourceManager::PIXELSHADER));
GraphicsDevice* device = wiRenderer::GetDevice();
for (int i = 0; i < RENDERPASS_COUNT; ++i)
{
if (ps[i] == nullptr)
if (i == RENDERPASS_DEPTHONLY || i == RENDERPASS_DEFERRED || i == RENDERPASS_FORWARD || i == RENDERPASS_TILEDFORWARD)
{
continue;
}
for (int j = 0; j < 2; ++j)
{
if ((i == RENDERPASS_DEPTHONLY || i == RENDERPASS_DEFERRED) && j == 1)
for (int j = 0; j < 2; ++j)
{
continue;
if ((i == RENDERPASS_DEPTHONLY || i == RENDERPASS_DEFERRED) && j == 1)
{
continue;
}
PipelineStateDesc desc;
desc.vs = vs;
desc.bs = &bs[j];
desc.rs = &ncrs;
desc.dss = &dss_default;
desc.DSFormat = wiRenderer::DSFormat_full;
switch (i)
{
case RENDERPASS_DEPTHONLY:
desc.ps = ps_alphatestonly;
break;
case RENDERPASS_DEFERRED:
desc.ps = ps_deferred;
break;
case RENDERPASS_FORWARD:
if (j == 0)
{
desc.ps = ps_forward;
}
else
{
desc.ps = ps_forward_transparent;
}
break;
case RENDERPASS_TILEDFORWARD:
if (j == 0)
{
desc.ps = ps_tiledforward;
}
else
{
desc.ps = ps_tiledforward_transparent;
}
break;
}
switch (i)
{
case RENDERPASS_FORWARD:
case RENDERPASS_TILEDFORWARD:
desc.numRTs = 2;
desc.RTFormats[0] = wiRenderer::RTFormat_hdr;
desc.RTFormats[1] = wiRenderer::RTFormat_gbuffer_1;
desc.dss = &dss_equal; // opaque
break;
case RENDERPASS_DEFERRED:
desc.numRTs = 5;
desc.RTFormats[0] = wiRenderer::RTFormat_gbuffer_0;
desc.RTFormats[1] = wiRenderer::RTFormat_gbuffer_1;
desc.RTFormats[2] = wiRenderer::RTFormat_gbuffer_2;
desc.RTFormats[3] = wiRenderer::RTFormat_deferred_lightbuffer;
desc.RTFormats[4] = wiRenderer::RTFormat_deferred_lightbuffer;
}
if (j == 1)
{
desc.dss = &dss_rejectopaque_keeptransparent; // transparent
desc.numRTs = 1;
}
device->CreatePipelineState(&desc, &PSO[i][j]);
}
PipelineStateDesc desc;
desc.vs = vs;
desc.ps = ps[i];
desc.bs = &bs[j];
desc.rs = &ncrs;
desc.dss = &dss_default;
desc.DSFormat = wiRenderer::DSFormat_full;
switch (i)
{
case RENDERPASS_TEXTURE:
desc.numRTs = 1;
desc.RTFormats[0] = wiRenderer::RTFormat_hdr;
break;
case RENDERPASS_FORWARD:
case RENDERPASS_TILEDFORWARD:
desc.numRTs = 2;
desc.RTFormats[0] = wiRenderer::RTFormat_hdr;
desc.RTFormats[1] = wiRenderer::RTFormat_gbuffer_1;
desc.dss = &dss_equal; // opaque
break;
case RENDERPASS_DEFERRED:
desc.numRTs = 5;
desc.RTFormats[0] = wiRenderer::RTFormat_gbuffer_0;
desc.RTFormats[1] = wiRenderer::RTFormat_gbuffer_1;
desc.RTFormats[2] = wiRenderer::RTFormat_gbuffer_2;
desc.RTFormats[3] = wiRenderer::RTFormat_deferred_lightbuffer;
desc.RTFormats[4] = wiRenderer::RTFormat_deferred_lightbuffer;
default:
break;
}
if (j == 1)
{
desc.dss = &dss_rejectopaque_keeptransparent; // transparent
desc.numRTs = 1;
}
device->CreatePipelineState(&desc, &PSO[i][j]);
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 31;
// minor bug fixes, alterations, refactors, updates
const int revision = 9;
const int revision = 10;
long GetVersion()