Control ambient occlusion, sunlight and softshadows via cvars
This commit is contained in:
parent
697e7982a7
commit
4f86a0ba81
5 changed files with 65 additions and 31 deletions
|
|
@ -26,6 +26,9 @@ ADD_STAT(lightmapper)
|
|||
CVAR(Int, lm_background_updates, 8, CVAR_NOSAVE);
|
||||
CVAR(Int, lm_max_updates, 128, CVAR_NOSAVE);
|
||||
CVAR(Float, lm_scale, 1.0, CVAR_NOSAVE);
|
||||
CVAR(Bool, lm_ao, true, 0);
|
||||
CVAR(Bool, lm_softshadows, true, 0);
|
||||
CVAR(Bool, lm_sunlight, true, 0);
|
||||
|
||||
VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
|
||||
{
|
||||
|
|
@ -151,7 +154,7 @@ void VkLightmap::Render()
|
|||
VkDeviceSize offset = 0;
|
||||
cmdbuffer->bindVertexBuffers(0, 1, &fb->GetRaytrace()->GetVertexBuffer()->buffer, &offset);
|
||||
cmdbuffer->bindIndexBuffer(fb->GetRaytrace()->GetIndexBuffer()->buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipeline.get());
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipeline[GetRaytracePipelineIndex()].get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 0, raytrace.descriptorSet0.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 2, fb->GetDescriptorSetManager()->GetBindlessDescriptorSet());
|
||||
|
|
@ -522,6 +525,7 @@ void VkLightmap::CreateShaders()
|
|||
std::string prefix = "#version 460\r\n";
|
||||
std::string traceprefix = "#version 460\r\n";
|
||||
prefix += "#extension GL_GOOGLE_include_directive : enable\n";
|
||||
|
||||
traceprefix += "#extension GL_GOOGLE_include_directive : enable\n";
|
||||
traceprefix += "#extension GL_EXT_nonuniform_qualifier : enable\r\n";
|
||||
if (useRayQuery)
|
||||
|
|
@ -564,14 +568,25 @@ void VkLightmap::CreateShaders()
|
|||
.DebugName("VkLightmap.VertCopy")
|
||||
.Create("VkLightmap.VertCopy", fb->GetDevice());
|
||||
|
||||
shaders.fragRaytrace = ShaderBuilder()
|
||||
.Type(ShaderType::Fragment)
|
||||
.AddSource("VersionBlock", traceprefix)
|
||||
.AddSource("frag_raytrace.glsl", LoadPrivateShaderLump("shaders/lightmap/frag_raytrace.glsl").GetChars())
|
||||
.OnIncludeLocal(onIncludeLocal)
|
||||
.OnIncludeSystem(onIncludeSystem)
|
||||
.DebugName("VkLightmap.FragRaytrace")
|
||||
.Create("VkLightmap.FragRaytrace", fb->GetDevice());
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
std::string defines = traceprefix;
|
||||
if (i & 1)
|
||||
defines += "#define USE_SOFTSHADOWS\n";
|
||||
if (i & 2)
|
||||
defines += "#define USE_AO\n";
|
||||
if (i & 4)
|
||||
defines += "#define USE_SUNLIGHT\n";
|
||||
|
||||
shaders.fragRaytrace[i] = ShaderBuilder()
|
||||
.Type(ShaderType::Fragment)
|
||||
.AddSource("VersionBlock", defines)
|
||||
.AddSource("frag_raytrace.glsl", LoadPrivateShaderLump("shaders/lightmap/frag_raytrace.glsl").GetChars())
|
||||
.OnIncludeLocal(onIncludeLocal)
|
||||
.OnIncludeSystem(onIncludeSystem)
|
||||
.DebugName("VkLightmap.FragRaytrace")
|
||||
.Create("VkLightmap.FragRaytrace", fb->GetDevice());
|
||||
}
|
||||
|
||||
shaders.fragResolve = ShaderBuilder()
|
||||
.Type(ShaderType::Fragment)
|
||||
|
|
@ -610,6 +625,18 @@ void VkLightmap::CreateShaders()
|
|||
.Create("VkLightmap.FragCopy", fb->GetDevice());
|
||||
}
|
||||
|
||||
int VkLightmap::GetRaytracePipelineIndex()
|
||||
{
|
||||
int index = 0;
|
||||
if (lm_softshadows && useRayQuery)
|
||||
index |= 1;
|
||||
if (lm_ao && useRayQuery)
|
||||
index |= 2;
|
||||
if (lm_sunlight && mesh->SunColor != FVector3(0.0f, 0.0f, 0.0f))
|
||||
index |= 4;
|
||||
return index;
|
||||
}
|
||||
|
||||
FString VkLightmap::LoadPrivateShaderLump(const char* lumpname)
|
||||
{
|
||||
int lump = fileSystem.CheckNumForFullName(lumpname, 0);
|
||||
|
|
@ -712,20 +739,23 @@ void VkLightmap::CreateRaytracePipeline()
|
|||
.DebugName("raytrace.renderPass")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
raytrace.pipeline = GraphicsPipelineBuilder()
|
||||
.Layout(raytrace.pipelineLayout.get())
|
||||
.RenderPass(raytrace.renderPass.get())
|
||||
.AddVertexShader(shaders.vertRaytrace.get())
|
||||
.AddFragmentShader(shaders.fragRaytrace.get())
|
||||
.AddVertexBufferBinding(0, sizeof(SurfaceVertex))
|
||||
.AddVertexAttribute(0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0)
|
||||
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
||||
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)
|
||||
.RasterizationSamples(VK_SAMPLE_COUNT_4_BIT)
|
||||
.Viewport(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
.Scissor(0, 0, 4096, 4096)
|
||||
.DebugName("raytrace.pipeline")
|
||||
.Create(fb->GetDevice());
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
raytrace.pipeline[i] = GraphicsPipelineBuilder()
|
||||
.Layout(raytrace.pipelineLayout.get())
|
||||
.RenderPass(raytrace.renderPass.get())
|
||||
.AddVertexShader(shaders.vertRaytrace.get())
|
||||
.AddFragmentShader(shaders.fragRaytrace[i].get())
|
||||
.AddVertexBufferBinding(0, sizeof(SurfaceVertex))
|
||||
.AddVertexAttribute(0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0)
|
||||
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
||||
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)
|
||||
.RasterizationSamples(VK_SAMPLE_COUNT_4_BIT)
|
||||
.Viewport(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
.Scissor(0, 0, 4096, 4096)
|
||||
.DebugName("raytrace.pipeline")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
raytrace.descriptorPool0 = DescriptorPoolBuilder()
|
||||
.AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1)
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ private:
|
|||
void CreateDrawIndexedBuffer();
|
||||
void CreateBakeImage();
|
||||
|
||||
int GetRaytracePipelineIndex();
|
||||
|
||||
static FString LoadPrivateShaderLump(const char* lumpname);
|
||||
static FString LoadPublicShaderLump(const char* lumpname);
|
||||
static ShaderIncludeResult OnInclude(FString headerName, FString includerName, size_t depth, bool system);
|
||||
|
|
@ -205,7 +207,7 @@ private:
|
|||
std::unique_ptr<VulkanShader> vertRaytrace;
|
||||
std::unique_ptr<VulkanShader> vertScreenquad;
|
||||
std::unique_ptr<VulkanShader> vertCopy;
|
||||
std::unique_ptr<VulkanShader> fragRaytrace;
|
||||
std::unique_ptr<VulkanShader> fragRaytrace[8];
|
||||
std::unique_ptr<VulkanShader> fragResolve;
|
||||
std::unique_ptr<VulkanShader> fragBlur[2];
|
||||
std::unique_ptr<VulkanShader> fragCopy;
|
||||
|
|
@ -216,7 +218,7 @@ private:
|
|||
std::unique_ptr<VulkanDescriptorSetLayout> descriptorSetLayout0;
|
||||
std::unique_ptr<VulkanDescriptorSetLayout> descriptorSetLayout1;
|
||||
std::unique_ptr<VulkanPipelineLayout> pipelineLayout;
|
||||
std::unique_ptr<VulkanPipeline> pipeline;
|
||||
std::unique_ptr<VulkanPipeline> pipeline[8];
|
||||
std::unique_ptr<VulkanRenderPass> renderPass;
|
||||
std::unique_ptr<VulkanDescriptorPool> descriptorPool0;
|
||||
std::unique_ptr<VulkanDescriptorPool> descriptorPool1;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
#define USE_SOFTSHADOWS
|
||||
|
||||
#include <shaders/lightmap/binding_lightmapper.glsl>
|
||||
#include <shaders/lightmap/binding_raytrace.glsl>
|
||||
#include <shaders/lightmap/binding_textures.glsl>
|
||||
|
|
@ -30,15 +28,19 @@ void main()
|
|||
vec3 normal = surfaces[SurfaceIndex].Normal;
|
||||
vec3 origin = worldpos + normal * 0.1;
|
||||
|
||||
#if defined(USE_SUNLIGHT)
|
||||
vec3 incoming = TraceSunLight(origin);
|
||||
#else
|
||||
vec3 incoming = vec3(0.0);
|
||||
#endif
|
||||
|
||||
for (uint j = LightStart; j < LightEnd; j++)
|
||||
{
|
||||
incoming += TraceLight(origin, normal, lights[j], SurfaceIndex);
|
||||
}
|
||||
|
||||
#if defined(USE_RAYQUERY) // The non-rtx version of TraceFirstHitTriangle is too slow to do AO without the shader getting killed ;(
|
||||
//incoming.rgb *= TraceAmbientOcclusion(origin, normal);
|
||||
#if defined(USE_AO)
|
||||
incoming.rgb *= TraceAmbientOcclusion(origin, normal);
|
||||
#endif
|
||||
|
||||
fragcolor = vec4(incoming, 1.0);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ vec3 TraceLight(vec3 origin, vec3 normal, LightInfo light, int surfaceIndex)
|
|||
vec3 ydir = cross(dir, xdir);
|
||||
|
||||
float lightsize = 10;
|
||||
int step_count = 16;
|
||||
int step_count = 10;
|
||||
for (int i = 0; i < step_count; i++)
|
||||
{
|
||||
vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * lightsize;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ vec3 TraceSunLight(vec3 origin)
|
|||
vec3 ydir = cross(dir, xdir);
|
||||
|
||||
float lightsize = 100;
|
||||
int step_count = 16;
|
||||
int step_count = 10;
|
||||
for (int i = 0; i < step_count; i++)
|
||||
{
|
||||
vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * lightsize;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue