...
 
Commits (3)
...@@ -59,6 +59,7 @@ add_library( ...@@ -59,6 +59,7 @@ add_library(
src/Lib/src/Util/FileIo.cpp src/Lib/src/Util/FileIo.cpp
src/Lib/src/Util/Logging.cpp src/Lib/src/Util/Logging.cpp
src/Lib/src/Util/VectorConversions.cpp src/Lib/src/Util/VectorConversions.cpp
src/Lib/src/Util/PerlinGenerator.cpp
src/Lib/src/VkUtil/CompileShader.cpp src/Lib/src/VkUtil/CompileShader.cpp
src/Lib/src/VkUtil/AccelerationStructureBase.cpp src/Lib/src/VkUtil/AccelerationStructureBase.cpp
......
...@@ -7,5 +7,49 @@ layout(location = 0) out vec4 color; ...@@ -7,5 +7,49 @@ layout(location = 0) out vec4 color;
layout(binding = 0) uniform sampler2D texSampler; layout(binding = 0) uniform sampler2D texSampler;
void main() { void main() {
color = vec4(texture(texSampler, texCoord).rgb, 1.0); vec2 offsets[9] = {
{-1, 1}, {0, 1}, {1, 1},
{-1, 0}, {0, 0}, {1, 0},
{-1, -1}, {0, -1}, {1, -1},
};
float edgeDetectKernel[9] = {
0, 1, 0,
1, -4, 1,
0, 1, 0,
};
float blurKernel[9] = {
1.0 / 84.0, 4.0 / 84.0, 1.0 / 84.0,
4.0 / 84.0, 16.0 / 84.0, 4.0 / 84.0,
1.0 / 84.0, 4.0 / 84.0, 1.0 / 84.0,
};
vec2 relativePixelSize = vec2(1.0) / textureSize(texSampler, 0);
vec4 samples[9];
for(int i = 0; i < 9; i++) {
samples[i] = texture(texSampler, texCoord + offsets[i] * relativePixelSize);
}
vec3 edge = vec3(0);
for(int i = 0; i < 9; i++) {
edge += samples[i].rgb * edgeDetectKernel[i];
}
vec3 blur = vec3(0);
for(int i = 0; i < 9; i++) {
blur += samples[i].rgb * blurKernel[i];
}
float l = length(edge);
vec3 res = vec3(0);
res = l * blur + (1 - l) * samples[5].rgb;
color = vec4(vec3(samples[5].a * 0.5), 1.0);
// color = vec4(res, 1.0);
} }
\ No newline at end of file
#version 450 #version 450
// #extension GL_GOOGLE_include_directive : enable #extension GL_GOOGLE_include_directive : enable
// #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_separate_shader_objects : enable
layout(location = 0) out vec2 texCoord; layout(location = 0) out vec2 texCoord;
......
...@@ -39,5 +39,5 @@ void main() ...@@ -39,5 +39,5 @@ void main()
vec3 res = payload.value; vec3 res = payload.value;
imageStore(image, ivec2(gl_LaunchIDNV.xy), vec4(res, 0)); imageStore(image, ivec2(gl_LaunchIDNV.xy), vec4(res, length(res)));
} }
\ No newline at end of file
\section{Problem: Darstellung von Godrays/Strahlenbüscheln} \section{Problem: Darstellung von Godrays/Strahlenbüscheln}
\subsection{Physikalische Grundlagen} \subsection{Physikalische Grundlagen}
Wenn Licht an mikroskopisch kleinen Teilchen in einem Medium (z.B. Luft oder Wasser) gestreut wird und der Wenn Licht an mikroskopisch kleinen Teilchen in einem Medium (z.B. Luft oder Wasser) gestreut wird und die
Beobachter im Schatten steht, zeichnen sich die Lichtstrahlen im Medium ab (siehe \ref{g:1}). Lichtquelle größtenteils verdeckt ist, zeichnen sich die Lichtstrahlen im Medium ab (siehe \ref{g:1}).
Dieser Effekt wird Tyndall-Effekt \footnote{Siehe z.B. \url{https://de.wikipedia.org/wiki/Tyndall-Effekt}} Dieser Effekt wird Tyndall-Effekt \footnote{Siehe z.B. \url{https://de.wikipedia.org/wiki/Tyndall-Effekt}}
genannt. Diese sichtbaren Strahlen werden auch Strahlenbüschel genannt und verdienen den Namen genannt.
\gquote{Godrays} (also göttliche Strahlen) ihrer äußerst eindrucksvollen Wirkung. Diese sichtbaren Strahlen werden auch Strahlenbüschel genannt und verdienen den Namen
Der Effekt lässt sich besonders gut während der Morgen- und Abenddämmerung beobachten oder wenn eine kleine \gquote{Godrays} (also göttliche Strahlen) ihrer äußerst eindrucksvollen Wirkung und der Tatsache, dass sie in
Wolke die Sonne verdeckt. der Natur vor allem aus Löchern in Wolkendecken auf die Erde herabscheinen.
Auch unter Wasser oder wenn die Sonne in einen nebligen Wald scheint, lässt sich der Effekt Aufgrund der Eindrücklichkeit des Effekts kann er eine computergrafisch dargestellte Szene
beobachten. Aufgrund der Eindrücklichkeit des Effekts kann er eine computergrafisch dargestellte Szene
extrem bereichern. extrem bereichern.
\\
Der Effekt lässt sich auch gut während der Morgen- und Abenddämmerung beobachten.
Auch unter Wasser oder wenn die Sonne in einen nebligen Wald scheint, lässt sich der Effekt
beobachten. Ein künstlich erzeugtes Beispiel ist die Sichtbarmachung de Verlaufs eines Lasers durch Staub
oder Puder. Der Effekt lässt sich auch umgekehrt beobachten, das heißt, dass der Großteil eines Mediums von
Strahlenbüscheln erfüllt ist, dadurch heller aussieht und es aussieht als würden Objekte Schatten im Medium
erzeugen. Hieraus folgt auch die Überlegung, dass die Streuung von Licht im Medium praktisch immer auftritt,
jedoch normalerweise unbemerkt bleibt, weil das Licht an jedem Punkt des Mediums ähnlich gestreut wird.
% %
\begin{figure}[ht] \begin{figure}[ht]
\centering \centering
......
...@@ -69,7 +69,7 @@ Im Gegensatz zu der Arbeit aus ...@@ -69,7 +69,7 @@ Im Gegensatz zu der Arbeit aus
\ref{ss:RealTimeUnderwaterCausticsAndGodRays} werden hier physikalische Aspekte beleuchtet und eine Formel zur \ref{ss:RealTimeUnderwaterCausticsAndGodRays} werden hier physikalische Aspekte beleuchtet und eine Formel zur
Berechnung der Lichtintensität vorgestellt. Diese Formel wurde letztendlich Berechnung der Lichtintensität vorgestellt. Diese Formel wurde letztendlich
aus der Strahlungstransportgleichung entwickelt. Die Hauptaussage dieser Gleichung ist die Ermittlung des aus der Strahlungstransportgleichung entwickelt. Die Hauptaussage dieser Gleichung ist die Ermittlung des
eingestreuten Lichtes durch Integration entlang des Strahls. Das Integral lässt dabei als endliche Summe eingestreuten Lichtes durch Integration entlang des Strahls. Das Integral lässt sich dabei als endliche Summe
annähern, was letztendlich zur Überlegung führt mehrere Samples entlang des Strahls zu verrechnen.\\ annähern, was letztendlich zur Überlegung führt mehrere Samples entlang des Strahls zu verrechnen.\\
Neben den physikalischen Überlegungen stellt das Paper auch Neben den physikalischen Überlegungen stellt das Paper auch
eine Effizienzüberlegung an, die in einem Raytracing-Algorithmus integriert werden könnte: eine Effizienzüberlegung an, die in einem Raytracing-Algorithmus integriert werden könnte:
......
\section{Umsetzung} \section{Umsetzung}
Es soll versucht werden Strahlenbüschel mittels Raytracing umzusetzen. Für die folgenden Überlegungen sei noch Es soll versucht werden, die realistische und physikalisch plausible Darstellung von Strahlenbüscheln mittels
der Begriff \gquote{dichtes Medium} definiert: Raytracing umzusetzen. Die zuvor genannten Quellen nutzen vor allem Post-Processing-Effekte und basieren auf
\gquote{traditionellen} Techniken wie Light-Space-Ray-Marching und Shadow-Mapping. Dies könnte auch mit
Raytracing so umgesetzt werden. Z.B. könnte Raytracing genutzt werden um einen G-Buffer zu erstellen und alle
Lichtberechnungen wie beim Deferred Shading auszuführen. Damit würde man jedoch die Möglichkeiten und Vorteile
von Raytracing (z.B. exakte Verdeckungsberechnungen) wegwerfen. Daher ist das Ziel, einen Algorithmus zu
entwickeln, der die Vorteile von Raytracing ausnutzt um Strahlenbüschel physikalisch plausibel darzustellen.
\\
Dazu muss auch eine geeignete Szene erstellt werden. Es kann dabei angenommen werden, dass das Medium, in
welchem eine signifikante Lichtstreuung geschieht entweder die gesamte Szene umfasst oder durch ein Mesh
modelliert ist (zum Beispiel für räumlich begrenzten Nebel).
Die folgenden beiden Ansätze erscheinen sinnvoll:
% %
\paragraph{Dichtes Medium:} Ein Medium, in dem viele Partikel vorhanden sind, die das Licht streuen und
so die Entstehung von Strahlenbüscheln ermöglichen. Dies kann zum Beispiel staubige Luft, Nebel, oder einfach
Wasser sein. Das Medium wird durch ein Objekt in der Szene umrissen.
\subsection{Umsetzung mittels Sampling der Lichtquelle aus dem Medium heraus} \subsection{Umsetzung mittels Sampling der Lichtquelle aus dem Medium heraus}
% %
Ein möglicher Algorithmus zur Lösung des Problems besteht darin, beim Durchgang eines Strahls durch ein Ein möglicher Algorithmus zur Lösung des Problems besteht darin, beim Durchgang eines Strahls durch ein
dichtes Medium mittels Schattenfühlern abzutasten, inwiefern der Strahl von der Lichtquelle aus erreichbar ist Medium mittels Schattenfühlern abzutasten, inwiefern der Strahl von der Lichtquelle aus erreichbar ist
und daraufhin zu berechnen, wieviel Licht entlang des Strahls zum Beobachter zurückgeworfen wird. Das grobe und daraufhin zu berechnen, wieviel Licht entlang des Strahls zum Beobachter zurückgeworfen wird. Das grobe
Vorgehen ist das folgende: Vorgehen ist das folgende:
% %
\begin{enumerate} \begin{enumerate}
\item Strahl trifft auf dichtes Medium \item Strahl trifft auf Medium (falls Medium als Mesh modelliert ist)
% %
\begin{enumerate} \begin{enumerate}
\item Der Eintrittspunkt wird in der Ray-Payload vermerkt. \item Der Eintrittspunkt wird in der Ray-Payload vermerkt. (Falls das Medium die gesamte Szene
umfasst ist der Eintrittspunkt der Augpunkt)
\end{enumerate} \end{enumerate}
% %
\item Strahl trifft auf anderes Objekt oder tritt aus dichtem Medium aus \item Strahl trifft auf anderes Objekt oder tritt aus dichtem Medium aus
...@@ -48,7 +55,8 @@ Vorgehen ist das folgende: ...@@ -48,7 +55,8 @@ Vorgehen ist das folgende:
% %
Dabei ist natürlich vor allem auf die Performance zu achten. Je mehr Schattenfühler genutzt werden, desto Dabei ist natürlich vor allem auf die Performance zu achten. Je mehr Schattenfühler genutzt werden, desto
genauer wird das Ergebnis, desto teurer wird jedoch auch die Berechnung. Auch für die genaue Art der genauer wird das Ergebnis, desto teurer wird jedoch auch die Berechnung. Auch für die genaue Art der
Verrechnung der einzelnen Samples muss eine Formel entwickelt werden. Verrechnung der einzelnen Samples muss eine Formel gesucht werden. Optimierungspotenzial liegt in redundanten
Schattenfühlern, bzw. viele ähnliche Schattenfühlern.
\subsection{Umsetzung mittels Berechnung von der Lichtquelle aus} \subsection{Umsetzung mittels Berechnung von der Lichtquelle aus}
Der zweite Lösungsansatz verfolgt einen ähnlichen Ansatz wie Photon-Mapping, indem versucht wird die Der zweite Lösungsansatz verfolgt einen ähnlichen Ansatz wie Photon-Mapping, indem versucht wird die
......
...@@ -37,9 +37,9 @@ ...@@ -37,9 +37,9 @@
\input{components/preamble.tex} \input{components/preamble.tex}
\input{components/grundlagen.tex} \input{components/grundlagen.tex}
\input{components/problem.tex} \input{components/problem.tex}
\input{components/quellen.tex}
\input{components/umsetzung.tex} \input{components/umsetzung.tex}
\input{components/bewertung.tex} \input{components/bewertung.tex}
\input{components/quellen.tex}
\input{components/gliederung.tex} \input{components/gliederung.tex}
\input{components/zeitplan.tex} \input{components/zeitplan.tex}
\end{document} \end{document}
......
#pragma once
#include <random>
namespace lib
{
class PerlinGenerator
{
private:
uint32_t width;
uint32_t height;
std::default_random_engine engine;
std::uniform_real_distribution<float> rnd;
// std::vector<> grid;
double perlin(double x, double y) const;
public:
PerlinGenerator(uint32_t w, uint32_t h, uint32_t seed);
uint32_t operator()(uint32_t x, uint32_t y) const;
};
} // namespace lib
...@@ -9,10 +9,25 @@ ...@@ -9,10 +9,25 @@
namespace lib namespace lib
{ {
/**
* @brief forwards declaration für CgContext.
*/
class CgContext; class CgContext;
/**
* @brief Kapselt alle Vulkan-spezifischen Einstellungen einer Textur.
*/
struct TextureCreateInfo struct TextureCreateInfo
{ {
/**
* @brief Initialisiert eine neue Instanz der TextureCreateInfo-Klasse.
*
* @param queueFamilyIndices Eine Auflistung von Indizes, die angibt, von welchen Queues die Textur
* genutzt werden darf.
* @param format Das interne Format der Textur.
* @param usage Die Nutzungsmodi der Textur.
* @param layout Das Layout der Textur.
*/
inline TextureCreateInfo(std::vector<uint32_t> queueFamilyIndices = {}, inline TextureCreateInfo(std::vector<uint32_t> queueFamilyIndices = {},
vk::Format format = vk::Format{}, vk::Format format = vk::Format{},
vk::ImageUsageFlags usage = vk::ImageUsageFlagBits{}, vk::ImageUsageFlags usage = vk::ImageUsageFlagBits{},
...@@ -24,9 +39,22 @@ namespace lib ...@@ -24,9 +39,22 @@ namespace lib
{ {
} }
/**
* @brief @param queueFamilyIndices Eine Auflistung von Indizes, die angibt, von welchen Queues die
* Textur genutzt werden darf.
*/
std::vector<uint32_t> queueFamilyIndices; std::vector<uint32_t> queueFamilyIndices;
/**
* @brief @param format Das interne Format der Textur.
*/
vk::Format format; vk::Format format;
/**
* @brief @param usage Die Nutzungsmodi der Textur.
*/
vk::ImageUsageFlags usage; vk::ImageUsageFlags usage;
/**
* @brief @param layout Das Layout der Textur.
*/
vk::ImageLayout layout; vk::ImageLayout layout;
}; };
......
...@@ -88,7 +88,7 @@ bool lib::CgContext::TryCreateRasterizerPipeline() ...@@ -88,7 +88,7 @@ bool lib::CgContext::TryCreateRasterizerPipeline()
rasterizationStateCreateInfo.rasterizerDiscardEnable = false; rasterizationStateCreateInfo.rasterizerDiscardEnable = false;
rasterizationStateCreateInfo.polygonMode = vk::PolygonMode::eFill; rasterizationStateCreateInfo.polygonMode = vk::PolygonMode::eFill;
rasterizationStateCreateInfo.lineWidth = 1.f; rasterizationStateCreateInfo.lineWidth = 1.f;
rasterizationStateCreateInfo.frontFace = vk::FrontFace::eCounterClockwise; rasterizationStateCreateInfo.frontFace = vk::FrontFace::eClockwise;
rasterizationStateCreateInfo.cullMode = vk::CullModeFlagBits::eBack; rasterizationStateCreateInfo.cullMode = vk::CullModeFlagBits::eBack;
rasterizationStateCreateInfo.depthBiasEnable = false; rasterizationStateCreateInfo.depthBiasEnable = false;
...@@ -175,12 +175,12 @@ void lib::CgContext::CreateRasterizationDescriptorSets() ...@@ -175,12 +175,12 @@ void lib::CgContext::CreateRasterizationDescriptorSets()
frame.rasterizationDescriptorSet = *setsIt++; frame.rasterizationDescriptorSet = *setsIt++;
vk::DescriptorImageInfo rtImageInfo; vk::DescriptorImageInfo rtImageInfo;
rtImageInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; rtImageInfo.imageLayout = vk::ImageLayout::eGeneral;
// rtImageInfo.imageView = frame.raytracingTexture->GetView(); rtImageInfo.imageView = frame.raytracingTexture->GetView();
// rtImageInfo.sampler = frame.raytracingTexture->GetSampler(); rtImageInfo.sampler = frame.raytracingTexture->GetSampler();
rtImageInfo.imageView = this->dummyTexture->GetView(); // rtImageInfo.imageView = this->dummyTexture->GetView();
rtImageInfo.sampler = this->dummyTexture->GetSampler(); // rtImageInfo.sampler = this->dummyTexture->GetSampler();
vk::WriteDescriptorSet rtImageWrite; vk::WriteDescriptorSet rtImageWrite;
rtImageWrite.descriptorCount = 1; rtImageWrite.descriptorCount = 1;
...@@ -237,7 +237,7 @@ void lib::CgContext::CreateRasterizationRenderPass() ...@@ -237,7 +237,7 @@ void lib::CgContext::CreateRasterizationRenderPass()
{ {
vk::AttachmentDescription colorAttachment; vk::AttachmentDescription colorAttachment;
colorAttachment.initialLayout = vk::ImageLayout::eUndefined; colorAttachment.initialLayout = vk::ImageLayout::eUndefined;
colorAttachment.finalLayout = vk::ImageLayout::ePresentSrcKHR; colorAttachment.finalLayout = vk::ImageLayout::eColorAttachmentOptimal;
colorAttachment.loadOp = vk::AttachmentLoadOp::eDontCare; colorAttachment.loadOp = vk::AttachmentLoadOp::eDontCare;
colorAttachment.storeOp = vk::AttachmentStoreOp::eStore; colorAttachment.storeOp = vk::AttachmentStoreOp::eStore;
colorAttachment.format = this->swapChainImageFormat; colorAttachment.format = this->swapChainImageFormat;
......
...@@ -740,61 +740,59 @@ void lib::CgContext::UpdateCommandBuffer(uint32_t imageIndex) ...@@ -740,61 +740,59 @@ void lib::CgContext::UpdateCommandBuffer(uint32_t imageIndex)
frame.commandBuffer.begin(beginInfo); frame.commandBuffer.begin(beginInfo);
// if (this->IsOk()) if (this->IsOk())
// { {
// frame.commandBuffer.bindPipeline(vk::PipelineBindPoint::eRayTracingNV, this->raytracingStep.pipeline); frame.commandBuffer.bindPipeline(vk::PipelineBindPoint::eRayTracingNV, this->raytracingStep.pipeline);
// frame.commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eRayTracingNV, frame.commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eRayTracingNV,
// this->raytracingStep.pipelineLayout, this->raytracingStep.pipelineLayout,
// 0, frame.raytracingDescriptorSet, 0, frame.raytracingDescriptorSet,
// {}); {});
// TransitionImageLayout(frame.commandBuffer, TransitionImageLayout(frame.commandBuffer,
// frame.raytracingTexture->GetHandle(), this->swapChainImageFormat, frame.raytracingTexture->GetHandle(), this->swapChainImageFormat,
// vk::ImageLayout::eUndefined, vk::ImageLayout::eGeneral, vk::ImageLayout::eUndefined, vk::ImageLayout::eGeneral,
// vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe,
// vk::PipelineStageFlagBits::eRayTracingShaderNV); vk::PipelineStageFlagBits::eRayTracingShaderNV);
// frame.ubo->ScheduleTransfer(frame.commandBuffer); frame.ubo->ScheduleTransfer(frame.commandBuffer);
// frame.commandBuffer.pushConstants(this->raytracingStep.pipelineLayout, frame.commandBuffer.pushConstants(this->raytracingStep.pipelineLayout,
// vk::ShaderStageFlagBits::eRaygenNV | vk::ShaderStageFlagBits::eClosestHitNV, vk::ShaderStageFlagBits::eRaygenNV | vk::ShaderStageFlagBits::eClosestHitNV,
// 0, sizeof(this->pushConstant), 0, sizeof(this->pushConstant),
// &this->pushConstant); &this->pushConstant);
// auto sbtEntrySize = this->physicalDeviceInfo.GetRaytracingProperties().shaderGroupBaseAlignment; auto sbtEntrySize = this->physicalDeviceInfo.GetRaytracingProperties().shaderGroupBaseAlignment;
// frame.commandBuffer.traceRaysNV(this->shaderBindingTableBuffer->GetBufferHandle(), this->shaderOffsets.rayGen * sbtEntrySize, frame.commandBuffer.traceRaysNV(this->shaderBindingTableBuffer->GetBufferHandle(), this->shaderOffsets.rayGen * sbtEntrySize,
// this->shaderBindingTableBuffer->GetBufferHandle(), this->shaderOffsets.miss * sbtEntrySize, sbtEntrySize, this->shaderBindingTableBuffer->GetBufferHandle(), this->shaderOffsets.miss * sbtEntrySize, sbtEntrySize,
// this->shaderBindingTableBuffer->GetBufferHandle(), this->shaderOffsets.hitGroup * sbtEntrySize, sbtEntrySize, this->shaderBindingTableBuffer->GetBufferHandle(), this->shaderOffsets.hitGroup * sbtEntrySize, sbtEntrySize,
// this->shaderBindingTableBuffer->GetBufferHandle(), 0, 0, this->shaderBindingTableBuffer->GetBufferHandle(), 0, 0,
// this->swapChainExtent.width, this->swapChainExtent.height, 1); this->swapChainExtent.width, this->swapChainExtent.height, 1);
// } }
// TransitionImageLayout(frame.commandBuffer,
// frame.raytracingTexture->GetHandle(), this->swapChainImageFormat,
// vk::ImageLayout::eGeneral, vk::ImageLayout::eShaderReadOnlyOptimal,
// vk::PipelineStageFlagBits::eRayTracingShaderNV, vk::PipelineStageFlagBits::eAllGraphics);
TransitionImageLayout(frame.commandBuffer,
frame.swapChainImage, this->swapChainImageFormat,
vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal,
vk::PipelineStageFlagBits::eRayTracingShaderNV, vk::PipelineStageFlagBits::eAllGraphics);
if (this->IsOk()) if (this->IsOk())
{ {
// vk::RenderPassBeginInfo ppBeginInfo; vk::RenderPassBeginInfo ppBeginInfo;
// ppBeginInfo.renderPass = this->rasterizationStep.renderPass; ppBeginInfo.renderPass = this->rasterizationStep.renderPass;
// ppBeginInfo.framebuffer = frame.swapChainFramebufferForRasterizationRenderPass; ppBeginInfo.framebuffer = frame.swapChainFramebufferForRasterizationRenderPass;
// ppBeginInfo.renderArea.offset = {0, 0}; ppBeginInfo.renderArea.offset = {0, 0};
// ppBeginInfo.renderArea.extent = this->swapChainExtent; ppBeginInfo.renderArea.extent = this->swapChainExtent;
// frame.commandBuffer.beginRenderPass(ppBeginInfo, vk::SubpassContents::eInline); frame.commandBuffer.beginRenderPass(ppBeginInfo, vk::SubpassContents::eInline);
// frame.commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, this->rasterizationStep.pipeline); frame.commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, this->rasterizationStep.pipeline);
// frame.commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, frame.commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics,
// this->rasterizationStep.pipelineLayout, this->rasterizationStep.pipelineLayout,
// 0, frame.rasterizationDescriptorSet, {}); 0, frame.rasterizationDescriptorSet, {});
// frame.commandBuffer.draw(3, 1, 0, 0); frame.commandBuffer.draw(3, 1, 0, 0);
// frame.commandBuffer.endRenderPass(); frame.commandBuffer.endRenderPass();
}
else
{
TransitionImageLayout(frame.commandBuffer,
frame.swapChainImage, this->swapChainImageFormat,
vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal,
vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eFragmentShader);
} }
if (this->imGui.show) if (this->imGui.show)
......
#include "Util/PerlinGenerator.hpp"
#include "glm/glm.hpp"
#include <cmath>
#include <array>
namespace
{
double interpolate(double a, double b, double weight)
{
// TODO kann optimiert werden
auto trueWeight = 6.0 * std::pow(weight, 5.0) - 15.0 * std::pow(weight, 4.0) + 10.0 * std::pow(weight, 3.0);
return trueWeight * a + (1 - trueWeight) * b;
}
} // namespace
double lib::PerlinGenerator::perlin(double x, double y) const
{
// glm::vec2 point{std::fmod(x, 1.f), std::fmod(y, 1.f)};
// std::array<glm::vec2, 4> gradients;
// for (auto &gradient : gradients)
// {
// gradient.x = this->rnd(this->engine);
// gradient.y = this->rnd(this->engine);
// }
// static constexpr std::array<glm::vec2, 4> corners = {
// glm::vec2{0.f, 0.f},
// glm::vec2{0.f, 1.f},
// glm::vec2{1.f, 1.f},
// glm::vec2{1.f, 0.f},
// };
// std::array<float, 4> dotValues;
// for (size_t i = 0; i < dotValues.size(); i++)
// {
// dotValues[i] = glm::dot(point - corners[i], gradients[i]);
// }
// return interpolate(interpolate(dotValues[0], dotValues[1], point.x),
// interpolate(dotValues[2], dotValues[3], point.x),
// point.y);
return 0.0;
}
lib::PerlinGenerator::PerlinGenerator(uint32_t w, uint32_t h, uint32_t seed)
: width(w),
height(h),
engine(seed),
rnd()
{
}
uint32_t lib::PerlinGenerator::operator()(uint32_t x, uint32_t y) const
{
auto perlin = this->perlin(static_cast<double>(x) / this->width,
static_cast<double>(y) / this->height);
auto value = static_cast<uint8_t>(perlin * 255);
return uint32_t{0xff} |
static_cast<uint32_t>(value) << 8 |
static_cast<uint32_t>(value) << 16 |
static_cast<uint32_t>(value) << 24;
}
\ No newline at end of file