Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -31,6 +31,5 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf);
|
result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf);
|
||||||
}
|
}
|
||||||
result += brdf.evaluateAmbient();
|
result += brdf.evaluateAmbient();
|
||||||
// gamma correction
|
|
||||||
return float4(result, brdf.getAlpha());
|
return float4(result, brdf.getAlpha());
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ void taskMain(
|
|||||||
viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]);
|
viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]);
|
||||||
meshVisible = true;
|
meshVisible = true;
|
||||||
#ifdef DEPTH_CULLING
|
#ifdef DEPTH_CULLING
|
||||||
meshVisible = mesh.bounding.insideFrustum(viewFrustum) && isBoxVisible(mesh.bounding);
|
//meshVisible = mesh.bounding.insideFrustum(viewFrustum) && isBoxVisible(mesh.bounding);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
|
||||||
|
struct HistogramParameters
|
||||||
|
{
|
||||||
|
float minLogLum;
|
||||||
|
float inverseLogLumRange;
|
||||||
|
float timeCoeff;
|
||||||
|
uint numPixels;
|
||||||
|
Texture2D hdrImage;
|
||||||
|
globallycoherent RWStructuredBuffer<uint> histogram;
|
||||||
|
RWStructuredBuffer<float> averageLuminance;
|
||||||
|
};
|
||||||
|
ParameterBlock<HistogramParameters> pHistogramParams;
|
||||||
|
|
||||||
|
static const float3 RGB_TO_LUMINANCE = float3(0.2125, 0.7154, 0.0721);
|
||||||
|
static const float eps = 0.005;
|
||||||
|
|
||||||
|
uint colorToBin(float3 hdrColor) {
|
||||||
|
float lum = dot(hdrColor, RGB_TO_LUMINANCE);
|
||||||
|
|
||||||
|
if(lum < eps) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float logLum = clamp((log2(lum) - pHistogramParams.minLogLum) * pHistogramParams.inverseLogLumRange, 0, 1);
|
||||||
|
|
||||||
|
return uint(logLum * 254.0 + 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupshared uint histogramShared[256];
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(16, 16, 1)]
|
||||||
|
void histogram(uint threadID : SV_GroupIndex, uint2 globalThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
histogramShared[threadID] = 0;
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|
||||||
|
uint2 dim;
|
||||||
|
pHistogramParams.hdrImage.GetDimensions(dim.x, dim.y);
|
||||||
|
if(globalThreadID.x < dim.x && globalThreadID.y < dim.y) {
|
||||||
|
float3 hdrColor = pHistogramParams.hdrImage.Load(int3(globalThreadID, 0)).xyz;
|
||||||
|
uint binIndex = colorToBin(hdrColor);
|
||||||
|
|
||||||
|
InterlockedAdd(histogramShared[binIndex], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|
||||||
|
InterlockedAdd(pHistogramParams.histogram[threadID], histogramShared[threadID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(256, 1, 1)]
|
||||||
|
void exposure(uint threadID : SV_GroupThreadID)
|
||||||
|
{
|
||||||
|
uint countForThisBin = pHistogramParams.histogram[threadID];
|
||||||
|
histogramShared[threadID] = countForThisBin * threadID;
|
||||||
|
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|
||||||
|
pHistogramParams.histogram[threadID] = 0;
|
||||||
|
|
||||||
|
for(uint cutoff = (256 >> 1); cutoff > 0; cutoff >>= 1) {
|
||||||
|
if(uint(threadID) < cutoff) {
|
||||||
|
histogramShared[threadID] += histogramShared[threadID + cutoff];
|
||||||
|
}
|
||||||
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
}
|
||||||
|
if(threadID == 0) {
|
||||||
|
float weightedLogAverage = (histogramShared[0] / max(pHistogramParams.numPixels - float(countForThisBin), 1.0f)) - 1.0f;
|
||||||
|
|
||||||
|
float weightedAvgLum = exp2(((weightedLogAverage / 254.0f) * pHistogramParams.inverseLogLumRange) + pHistogramParams.minLogLum);
|
||||||
|
|
||||||
|
float lumLastFrame = pHistogramParams.averageLuminance[0];
|
||||||
|
float adaptedLum = lumLastFrame + (weightedAvgLum - lumLastFrame) * pHistogramParams.timeCoeff;
|
||||||
|
pHistogramParams.averageLuminance[0] = adaptedLum;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Placeholder",
|
|
||||||
"params": {
|
|
||||||
},
|
|
||||||
"code": [
|
|
||||||
{
|
|
||||||
"exp": "BRDF",
|
|
||||||
"profile": "BlinnPhong",
|
|
||||||
"values": {
|
|
||||||
"baseColor": "float3(0, 1, 0)",
|
|
||||||
"normal": "float3(0, 0, 1)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -101,5 +101,5 @@ float4 fragmentMain(
|
|||||||
|
|
||||||
float factor = (output.texCoords.y - lowerLimit) / (upperLimit - lowerLimit);
|
float factor = (output.texCoords.y - lowerLimit) / (upperLimit - lowerLimit);
|
||||||
factor = clamp(factor, 0.0, 1.0);
|
factor = clamp(factor, 0.0, 1.0);
|
||||||
return lerp(float4(pSkyboxData.fogBlend.xyz, 1), finalColor, factor);
|
return lerp(float4(pSkyboxData.fogBlend.xyz, 1), finalColor, factor) * 100;
|
||||||
}
|
}
|
||||||
@@ -31,8 +31,9 @@ struct Parameters
|
|||||||
float sat = 1.0;
|
float sat = 1.0;
|
||||||
Texture2D hdrInputTexture;
|
Texture2D hdrInputTexture;
|
||||||
SamplerState hdrSampler;
|
SamplerState hdrSampler;
|
||||||
|
StructuredBuffer<float> averageLuminance;
|
||||||
};
|
};
|
||||||
ParameterBlock<Parameters> pParams;
|
ParameterBlock<Parameters> pToneMappingParams;
|
||||||
|
|
||||||
// AgX
|
// AgX
|
||||||
// ->
|
// ->
|
||||||
@@ -83,7 +84,7 @@ float3 agxEotf(float3 val) {
|
|||||||
val = mul(agx_mat_inv, val);
|
val = mul(agx_mat_inv, val);
|
||||||
|
|
||||||
// sRGB IEC 61966-2-1 2.2 Exponent Reference EOTF Display
|
// sRGB IEC 61966-2-1 2.2 Exponent Reference EOTF Display
|
||||||
//val = pow(val, float3(2.2));
|
val = pow(val, float3(2.2));
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -93,10 +94,10 @@ float3 agxLook(float3 val) {
|
|||||||
float luma = dot(val, lw);
|
float luma = dot(val, lw);
|
||||||
|
|
||||||
// Default
|
// Default
|
||||||
float3 offset = pParams.offset.xyz;
|
float3 offset = pToneMappingParams.offset.xyz;
|
||||||
float3 slope = pParams.slope.xyz;
|
float3 slope = pToneMappingParams.slope.xyz;
|
||||||
float3 power = pParams.power.xyz;
|
float3 power = pToneMappingParams.power.xyz;
|
||||||
float sat = pParams.sat;
|
float sat = pToneMappingParams.sat;
|
||||||
|
|
||||||
// ASC CDL
|
// ASC CDL
|
||||||
val = pow(val * slope + offset, power);
|
val = pow(val * slope + offset, power);
|
||||||
@@ -106,12 +107,11 @@ float3 agxLook(float3 val) {
|
|||||||
[shader("pixel")]
|
[shader("pixel")]
|
||||||
float4 toneMapping(float2 uv : UV) : SV_Target
|
float4 toneMapping(float2 uv : UV) : SV_Target
|
||||||
{
|
{
|
||||||
float3 hdrValue = pParams.hdrInputTexture.Sample(pParams.hdrSampler, uv).rgb;
|
float3 hdrValue = pToneMappingParams.hdrInputTexture.Sample(pToneMappingParams.hdrSampler, uv).rgb;
|
||||||
//float3 value = agx(hdrValue);
|
|
||||||
//value = agxLook(value);
|
|
||||||
//value = agxEotf(value);
|
|
||||||
|
|
||||||
float3 value = hdrValue / (hdrValue + float3(10));
|
float3 value = agx(hdrValue / 1000);
|
||||||
|
value = agxLook(value);
|
||||||
|
value = agxEotf(value);
|
||||||
|
|
||||||
return float4(value, 1);
|
return float4(value, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ struct DirectionalLight : ILightEnv
|
|||||||
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
||||||
{
|
{
|
||||||
float3 dir_WS = -normalize(direction.xyz);
|
float3 dir_WS = -normalize(direction.xyz);
|
||||||
return brdf.evaluate(params.viewDir_WS, dir_WS, color.xyz);
|
return brdf.evaluate(params.viewDir_WS, dir_WS, color.xyz * color.w);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ struct PointLight : ILightEnv
|
|||||||
float3 lightDir_WS = position_WS.xyz - params.position_WS;
|
float3 lightDir_WS = position_WS.xyz - params.position_WS;
|
||||||
float d = length(lightDir_WS);
|
float d = length(lightDir_WS);
|
||||||
float illuminance = max(1 - d / colorRange.w, 0);
|
float illuminance = max(1 - d / colorRange.w, 0);
|
||||||
return illuminance * brdf.evaluate(params.viewDir_WS, normalize(lightDir_WS), colorRange.xyz);
|
return illuminance * brdf.evaluate(params.viewDir_WS, normalize(lightDir_WS), colorRange.xyz * position_WS.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insidePlane(Plane plane, float3 position)
|
bool insidePlane(Plane plane, float3 position)
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import StaticMeshVertexData;
|
|||||||
[shader("anyhit")]
|
[shader("anyhit")]
|
||||||
void anyhit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttributes attr)
|
void anyhit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttributes attr)
|
||||||
{
|
{
|
||||||
if(RayTCurrent() > hitValue.t)
|
|
||||||
return;
|
|
||||||
const float3 barycentricCoords = float3(1.0f - attr.barycentrics.x - attr.barycentrics.y, attr.barycentrics.x, attr.barycentrics.y);
|
const float3 barycentricCoords = float3(1.0f - attr.barycentrics.x - attr.barycentrics.y, attr.barycentrics.x, attr.barycentrics.y);
|
||||||
|
|
||||||
InstanceData inst = pScene.instances[InstanceID()];
|
InstanceData inst = pScene.instances[InstanceID()];
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
const static float2 positions[3] = {
|
|
||||||
float2(0.0, -0.5),
|
|
||||||
float2(0.5, 0.5),
|
|
||||||
float2(-0.5, 0.5)
|
|
||||||
};
|
|
||||||
|
|
||||||
const static float3 colors[3] = {
|
|
||||||
float3(1.0, 1.0, 0.0),
|
|
||||||
float3(0.0, 1.0, 1.0),
|
|
||||||
float3(1.0, 0.0, 1.0)
|
|
||||||
};
|
|
||||||
struct Vertex
|
|
||||||
{
|
|
||||||
float4 pos : SV_Position;
|
|
||||||
float3 color : Color;
|
|
||||||
int index : Index;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static uint MAX_VERTS = 12;
|
|
||||||
const static uint MAX_PRIMS = 4;
|
|
||||||
|
|
||||||
[outputtopology("triangle")]
|
|
||||||
[shader("mesh")]
|
|
||||||
[numthreads(3, 1, 1)]
|
|
||||||
void meshMain(
|
|
||||||
in uint tig : SV_GroupIndex,
|
|
||||||
out Vertices<Vertex, MAX_VERTS> verts,
|
|
||||||
out Indices<uint3, MAX_PRIMS> triangles)
|
|
||||||
{
|
|
||||||
const uint numVertices = 12;
|
|
||||||
const uint numPrimitives = 4;
|
|
||||||
SetMeshOutputCounts(numVertices, numPrimitives);
|
|
||||||
|
|
||||||
for(uint i = tig; i < numVertices; ++i)
|
|
||||||
{
|
|
||||||
const int tri = i / 3;
|
|
||||||
verts[i] = {float4(positions[i % 3], 0, 1), colors[i % 3], tri};
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint i = tig; i < numPrimitives; ++i)
|
|
||||||
{
|
|
||||||
triangles[i] = i * 3 + uint3(0,1,2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,8 +4,8 @@ using namespace Seele;
|
|||||||
|
|
||||||
DirectionalLightActor::DirectionalLightActor(PScene scene) : Actor(scene) { attachComponent<Component::DirectionalLight>(); }
|
DirectionalLightActor::DirectionalLightActor(PScene scene) : Actor(scene) { attachComponent<Component::DirectionalLight>(); }
|
||||||
|
|
||||||
DirectionalLightActor::DirectionalLightActor(PScene scene, Vector color, Vector direction) : Actor(scene) {
|
DirectionalLightActor::DirectionalLightActor(PScene scene, Vector color, float intensity, Vector direction) : Actor(scene) {
|
||||||
attachComponent<Component::DirectionalLight>(Vector4(color, 0), Vector4(direction, 0));
|
attachComponent<Component::DirectionalLight>(Vector4(color, intensity), Vector4(direction, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectionalLightActor::~DirectionalLightActor() {}
|
DirectionalLightActor::~DirectionalLightActor() {}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Seele {
|
|||||||
class DirectionalLightActor : public Actor {
|
class DirectionalLightActor : public Actor {
|
||||||
public:
|
public:
|
||||||
DirectionalLightActor(PScene scene);
|
DirectionalLightActor(PScene scene);
|
||||||
DirectionalLightActor(PScene scene, Vector color, Vector direction);
|
DirectionalLightActor(PScene scene, Vector color, float intensity, Vector direction);
|
||||||
virtual ~DirectionalLightActor();
|
virtual ~DirectionalLightActor();
|
||||||
Component::DirectionalLight& getDirectionalLightComponent();
|
Component::DirectionalLight& getDirectionalLightComponent();
|
||||||
const Component::DirectionalLight& getDirectionalLightComponent() const;
|
const Component::DirectionalLight& getDirectionalLightComponent() const;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ using namespace Seele;
|
|||||||
|
|
||||||
PointLightActor::PointLightActor(PScene scene) : Actor(scene) { attachComponent<Component::PointLight>(); }
|
PointLightActor::PointLightActor(PScene scene) : Actor(scene) { attachComponent<Component::PointLight>(); }
|
||||||
|
|
||||||
PointLightActor::PointLightActor(PScene scene, Vector position, Vector color, float attenuation) : Actor(scene) {
|
PointLightActor::PointLightActor(PScene scene, Vector position, float intensity, Vector color, float attenuation) : Actor(scene) {
|
||||||
attachComponent<Component::PointLight>(Vector4(position, 1), Vector4(color, attenuation));
|
attachComponent<Component::PointLight>(Vector4(position, intensity), Vector4(color, attenuation));
|
||||||
}
|
}
|
||||||
|
|
||||||
PointLightActor::~PointLightActor() {}
|
PointLightActor::~PointLightActor() {}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Seele {
|
|||||||
class PointLightActor : public Actor {
|
class PointLightActor : public Actor {
|
||||||
public:
|
public:
|
||||||
PointLightActor(PScene scene);
|
PointLightActor(PScene scene);
|
||||||
PointLightActor(PScene scene, Vector position, Vector color, float attenuation);
|
PointLightActor(PScene scene, Vector position, float intensity, Vector color, float attenuation);
|
||||||
virtual ~PointLightActor();
|
virtual ~PointLightActor();
|
||||||
Component::PointLight& getPointLightComponent();
|
Component::PointLight& getPointLightComponent();
|
||||||
const Component::PointLight& getPointLightComponent() const;
|
const Component::PointLight& getPointLightComponent() const;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class Asset {
|
|||||||
std::string name;
|
std::string name;
|
||||||
std::string assetId;
|
std::string assetId;
|
||||||
Status status;
|
Status status;
|
||||||
uint64 byteSize;
|
uint64 byteSize = 0;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Asset)
|
DEFINE_REF(Asset)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Component {
|
namespace Component {
|
||||||
struct DirectionalLight {
|
struct DirectionalLight {
|
||||||
Vector4 color;
|
Vector4 colorIntensity;
|
||||||
Vector4 direction;
|
Vector4 direction;
|
||||||
};
|
};
|
||||||
} // namespace Component
|
} // namespace Component
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace Seele {
|
|||||||
namespace Component {
|
namespace Component {
|
||||||
struct PointLight {
|
struct PointLight {
|
||||||
// give the lights a radius so that they are not actual points
|
// give the lights a radius so that they are not actual points
|
||||||
Vector4 positionWSRadius;
|
Vector4 positionWS;
|
||||||
Vector4 colorRange;
|
Vector4 colorRange;
|
||||||
};
|
};
|
||||||
} // namespace Component
|
} // namespace Component
|
||||||
|
|||||||
@@ -3,43 +3,121 @@
|
|||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
ToneMappingPass::ToneMappingPass(Gfx::PGraphics graphics) : RenderPass(graphics) {
|
ToneMappingPass::ToneMappingPass(Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||||
layout = graphics->createDescriptorLayout("ToneMappingDescriptor");
|
tonemappingLayout = graphics->createDescriptorLayout("ToneMappingDescriptor");
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "offset",
|
.name = "offset",
|
||||||
.uniformLength = sizeof(Vector4),
|
.uniformLength = sizeof(Vector4),
|
||||||
});
|
});
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "slope",
|
.name = "slope",
|
||||||
.uniformLength = sizeof(Vector4),
|
.uniformLength = sizeof(Vector4),
|
||||||
});
|
});
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "power",
|
.name = "power",
|
||||||
.uniformLength = sizeof(Vector4),
|
.uniformLength = sizeof(Vector4),
|
||||||
});
|
});
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "sat",
|
.name = "sat",
|
||||||
.uniformLength = sizeof(float),
|
.uniformLength = sizeof(float),
|
||||||
});
|
});
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "hdrInputTexture",
|
.name = "hdrInputTexture",
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
});
|
});
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "hdrSampler",
|
.name = "hdrSampler",
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
});
|
});
|
||||||
layout->create();
|
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
pipelineLayout = graphics->createPipelineLayout("ToneMappingLayout");
|
.name = "averageLuminance",
|
||||||
pipelineLayout->addDescriptorLayout(layout);
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
tonemappingLayout->create();
|
||||||
|
tonemappingPipelineLayout = graphics->createPipelineLayout("ToneMappingLayout");
|
||||||
|
tonemappingPipelineLayout->addDescriptorLayout(tonemappingLayout);
|
||||||
|
|
||||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
.name = "ToneMapping",
|
.name = "ToneMapping",
|
||||||
.modules = {"FullScreenQuad", "ToneMapping"},
|
.modules = {"FullScreenQuad", "ToneMapping"},
|
||||||
.entryPoints = {{"quadMain", "FullScreenQuad"}, {"toneMapping", "ToneMapping"}},
|
.entryPoints =
|
||||||
.rootSignature = pipelineLayout,
|
{
|
||||||
|
{"quadMain", "FullScreenQuad"},
|
||||||
|
{"toneMapping", "ToneMapping"},
|
||||||
|
},
|
||||||
|
.rootSignature = tonemappingPipelineLayout,
|
||||||
});
|
});
|
||||||
pipelineLayout->create();
|
tonemappingPipelineLayout->create();
|
||||||
vert = graphics->createVertexShader({0});
|
vert = graphics->createVertexShader({0});
|
||||||
frag = graphics->createFragmentShader({1});
|
frag = graphics->createFragmentShader({1});
|
||||||
|
|
||||||
|
histogramLayout = graphics->createDescriptorLayout("pHistogramParams");
|
||||||
|
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "minLogLum",
|
||||||
|
.uniformLength = sizeof(float),
|
||||||
|
});
|
||||||
|
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "inverseLogLumRange",
|
||||||
|
.uniformLength = sizeof(float),
|
||||||
|
});
|
||||||
|
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "timeCoeff",
|
||||||
|
.uniformLength = sizeof(float),
|
||||||
|
});
|
||||||
|
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "numPixels",
|
||||||
|
.uniformLength = sizeof(uint32),
|
||||||
|
});
|
||||||
|
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "hdrImage",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
});
|
||||||
|
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "histogram",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "averageLuminance",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
histogramLayout->create();
|
||||||
|
histogramPipelineLayout = graphics->createPipelineLayout("HistogramPipelineLayout");
|
||||||
|
histogramPipelineLayout->addDescriptorLayout(histogramLayout);
|
||||||
|
|
||||||
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
|
.name = "Exposure",
|
||||||
|
.modules = {"Exposure"},
|
||||||
|
.entryPoints =
|
||||||
|
{
|
||||||
|
{"histogram", "Exposure"},
|
||||||
|
{"exposure", "Exposure"},
|
||||||
|
},
|
||||||
|
.rootSignature = histogramPipelineLayout,
|
||||||
|
});
|
||||||
|
histogramPipelineLayout->create();
|
||||||
|
histogramShader = graphics->createComputeShader({0});
|
||||||
|
histogramPipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = histogramShader,
|
||||||
|
.pipelineLayout = histogramPipelineLayout,
|
||||||
|
});
|
||||||
|
exposureShader = graphics->createComputeShader({1});
|
||||||
|
exposurePipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = exposureShader,
|
||||||
|
.pipelineLayout = histogramPipelineLayout,
|
||||||
|
});
|
||||||
|
histogramBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = sizeof(uint32) * 256,
|
||||||
|
},
|
||||||
|
.name = "HistogramBuffer",
|
||||||
|
});
|
||||||
|
luminanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = sizeof(uint32),
|
||||||
|
},
|
||||||
|
.name = "LuminanceBuffer",
|
||||||
|
});
|
||||||
sampler = graphics->createSampler({});
|
sampler = graphics->createSampler({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,18 +128,56 @@ void ToneMappingPass::beginFrame(const Component::Camera& cam) { RenderPass::beg
|
|||||||
void ToneMappingPass::render() {
|
void ToneMappingPass::render() {
|
||||||
hdrInputTexture.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
hdrInputTexture.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
|
||||||
layout->reset();
|
histogramLayout->reset();
|
||||||
set = layout->allocateDescriptorSet();
|
Gfx::PDescriptorSet histogramSet = histogramLayout->allocateDescriptorSet();
|
||||||
set->updateTexture("hdrInputTexture", 0, hdrInputTexture.getTexture());
|
histogramSet->updateConstants("minLogLum", 0, &minLogLum);
|
||||||
set->updateSampler("hdrSampler", 0, sampler);
|
histogramSet->updateConstants("inverseLogLumRange", 0, &inverseLogLumRange);
|
||||||
set->writeChanges();
|
histogramSet->updateConstants("timeCoeff", 0, &timeCoeff);
|
||||||
|
histogramSet->updateConstants("numPixels", 0, &numPixels);
|
||||||
|
histogramSet->updateTexture("hdrImage", 0, hdrInputTexture.getTexture());
|
||||||
|
histogramSet->updateBuffer("histogram", 0, histogramBuffer);
|
||||||
|
histogramSet->updateBuffer("averageLuminance", 0, luminanceBuffer);
|
||||||
|
histogramSet->writeChanges();
|
||||||
|
|
||||||
|
{
|
||||||
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("HistogramCommand");
|
||||||
|
computeCommand->bindPipeline(histogramPipeline);
|
||||||
|
computeCommand->bindDescriptor({histogramSet});
|
||||||
|
computeCommand->dispatch(threadGroups.x, threadGroups.y, 1);
|
||||||
|
graphics->executeCommands(std::move(computeCommand));
|
||||||
|
}
|
||||||
|
histogramBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
{
|
||||||
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("ExposureCommand");
|
||||||
|
computeCommand->bindPipeline(exposurePipeline);
|
||||||
|
computeCommand->bindDescriptor({histogramSet});
|
||||||
|
computeCommand->dispatch(1, 1, 1);
|
||||||
|
graphics->executeCommands(std::move(computeCommand));
|
||||||
|
}
|
||||||
|
luminanceBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
|
tonemappingLayout->reset();
|
||||||
|
Gfx::PDescriptorSet tonemappingSet = tonemappingLayout->allocateDescriptorSet();
|
||||||
|
tonemappingSet->updateConstants("offset", 0, &offset);
|
||||||
|
tonemappingSet->updateConstants("slope", 0, &slope);
|
||||||
|
tonemappingSet->updateConstants("power", 0, &power);
|
||||||
|
tonemappingSet->updateConstants("sat", 0, &sat);
|
||||||
|
tonemappingSet->updateTexture("hdrInputTexture", 0, hdrInputTexture.getTexture());
|
||||||
|
tonemappingSet->updateSampler("hdrSampler", 0, sampler);
|
||||||
|
tonemappingSet->updateBuffer("averageLuminance", 0, luminanceBuffer);
|
||||||
|
tonemappingSet->writeChanges();
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Gfx::ORenderCommand command = graphics->createRenderCommand("ToneMapping");
|
Gfx::ORenderCommand command = graphics->createRenderCommand("ToneMapping");
|
||||||
command->setViewport(viewport);
|
command->setViewport(viewport);
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
command->bindDescriptor({set});
|
command->bindDescriptor({tonemappingSet});
|
||||||
command->draw(3, 1, 0, 0);
|
command->draw(3, 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(command));
|
graphics->executeCommands(std::move(command));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
@@ -70,6 +186,8 @@ void ToneMappingPass::render() {
|
|||||||
void ToneMappingPass::endFrame() {}
|
void ToneMappingPass::endFrame() {}
|
||||||
|
|
||||||
void ToneMappingPass::publishOutputs() {
|
void ToneMappingPass::publishOutputs() {
|
||||||
|
numPixels = viewport->getWidth() * viewport->getHeight();
|
||||||
|
threadGroups = UVector2((viewport->getWidth() + 15) / 16, (viewport->getHeight() + 15) / 16);
|
||||||
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
resources->registerRenderPassOutput("TONEMAPPING_COLOR", colorAttachment);
|
resources->registerRenderPassOutput("TONEMAPPING_COLOR", colorAttachment);
|
||||||
@@ -103,7 +221,7 @@ void ToneMappingPass::createRenderPass() {
|
|||||||
.vertexShader = vert,
|
.vertexShader = vert,
|
||||||
.fragmentShader = frag,
|
.fragmentShader = frag,
|
||||||
.renderPass = renderPass,
|
.renderPass = renderPass,
|
||||||
.pipelineLayout = pipelineLayout,
|
.pipelineLayout = tonemappingPipelineLayout,
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
{
|
{
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
|
|||||||
@@ -19,13 +19,31 @@ class ToneMappingPass : public RenderPass {
|
|||||||
private:
|
private:
|
||||||
// non-hdr swapchain output
|
// non-hdr swapchain output
|
||||||
Gfx::RenderTargetAttachment colorAttachment;
|
Gfx::RenderTargetAttachment colorAttachment;
|
||||||
|
Gfx::OShaderBuffer histogramBuffer;
|
||||||
|
Gfx::OShaderBuffer luminanceBuffer;
|
||||||
|
|
||||||
|
float minLogLum = 1;
|
||||||
|
float inverseLogLumRange = 1;
|
||||||
|
float timeCoeff = 1;
|
||||||
|
uint32 numPixels;
|
||||||
|
UVector2 threadGroups;
|
||||||
|
Gfx::ODescriptorLayout histogramLayout;
|
||||||
|
Gfx::PDescriptorSet histogramSet;
|
||||||
|
Gfx::OPipelineLayout histogramPipelineLayout;
|
||||||
|
Gfx::OComputeShader histogramShader;
|
||||||
|
Gfx::PComputePipeline histogramPipeline;
|
||||||
|
Gfx::OComputeShader exposureShader;
|
||||||
|
Gfx::PComputePipeline exposurePipeline;
|
||||||
|
|
||||||
Gfx::RenderTargetAttachment hdrInputTexture;
|
Gfx::RenderTargetAttachment hdrInputTexture;
|
||||||
Gfx::OSampler sampler;
|
Gfx::OSampler sampler;
|
||||||
|
|
||||||
Gfx::ODescriptorLayout layout;
|
Vector4 offset = Vector4(0.0);
|
||||||
Gfx::PDescriptorSet set;
|
Vector4 slope = Vector4(1.0);
|
||||||
Gfx::OPipelineLayout pipelineLayout;
|
Vector4 power = Vector4(1.0);
|
||||||
|
float sat = 1.0;
|
||||||
|
Gfx::ODescriptorLayout tonemappingLayout;
|
||||||
|
Gfx::OPipelineLayout tonemappingPipelineLayout;
|
||||||
Gfx::OVertexShader vert;
|
Gfx::OVertexShader vert;
|
||||||
Gfx::OFragmentShader frag;
|
Gfx::OFragmentShader frag;
|
||||||
Gfx::PGraphicsPipeline pipeline;
|
Gfx::PGraphicsPipeline pipeline;
|
||||||
|
|||||||
@@ -5,10 +5,6 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <vma/vk_mem_alloc.h>
|
#include <vma/vk_mem_alloc.h>
|
||||||
|
|
||||||
uint64 bufferSize = 0;
|
|
||||||
|
|
||||||
uint64 getBufferSize() { return bufferSize; }
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
|
|
||||||
@@ -26,9 +22,6 @@ BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name,
|
|||||||
.pObjectName = name.c_str(),
|
.pObjectName = name.c_str(),
|
||||||
};
|
};
|
||||||
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
||||||
if (!(properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
|
||||||
bufferSize += size;
|
|
||||||
}
|
|
||||||
if (bufferInfo.usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
|
if (bufferInfo.usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
|
||||||
VkBufferDeviceAddressInfo addrInfo = {
|
VkBufferDeviceAddressInfo addrInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
|
||||||
@@ -41,9 +34,6 @@ BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name,
|
|||||||
|
|
||||||
BufferAllocation::~BufferAllocation() {
|
BufferAllocation::~BufferAllocation() {
|
||||||
if (buffer != VK_NULL_HANDLE) {
|
if (buffer != VK_NULL_HANDLE) {
|
||||||
if (!(properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
|
||||||
bufferSize -= size;
|
|
||||||
}
|
|
||||||
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
|
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
#include "Graphics/Enums.h"
|
#include "Graphics/Enums.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
|
|
||||||
uint64 getBufferSize();
|
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
DECLARE_REF(Command)
|
DECLARE_REF(Command)
|
||||||
|
|||||||
Reference in New Issue
Block a user