Merge remote-tracking branch 'origin/master'
# Conflicts: # engine/gfx/CMakeLists.txt
This commit is contained in:
commit
2ce04b686d
28 changed files with 1585 additions and 30 deletions
|
@ -1 +1 @@
|
|||
{"color":{"asset_value":"textures/kamen.png","float_value":0.0,"name":"","type":2,"value":{"x":0.7341179847717285,"y":0.7305880188941956,"z":0.6741179823875427}},"normal":{"asset_value":"","float_value":0.0,"name":"","type":0,"value":{"x":0.0,"y":0.0,"z":0.0}},"version":3}
|
||||
{"color":{"asset_value":"textures/kamen.png","float_value":0.0,"name":"","type":2,"value":{"x":0.7341179847717285,"y":0.7305880188941956,"z":0.6741179823875427}},"normal":{"asset_value":"textures/kamen-normal.png","float_value":0.0,"name":"","type":2,"value":{"x":0.0,"y":0.0,"z":0.0}},"version":3}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"color":{"asset_value":"textures/mramor6x6.png","float_value":0.0,"name":"","type":2,"value":{"x":0.7341179847717285,"y":0.7094119787216187,"z":0.6741179823875427}},"normal":{"asset_value":"","float_value":0.0,"name":"","type":0,"value":{"x":0.0,"y":0.0,"z":0.0}},"version":3}
|
||||
{"color":{"asset_value":"textures/mramor6x6.png","float_value":0.0,"name":"","type":2,"value":{"x":0.7341179847717285,"y":0.7094119787216187,"z":0.6741179823875427}},"normal":{"asset_value":"textures/mrarmor-normal.png","float_value":0.0,"name":"","type":2,"value":{"x":0.0,"y":0.0,"z":0.0}},"version":3}
|
||||
|
|
BIN
data/textures/kamen-normal.png
Normal file
BIN
data/textures/kamen-normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 430 KiB |
BIN
data/textures/mrarmor-normal.png
Normal file
BIN
data/textures/mrarmor-normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -302,6 +302,7 @@ namespace prism {
|
|||
#endif
|
||||
|
||||
bool console_enabled = true;
|
||||
bool ui_enabled = true;
|
||||
|
||||
private:
|
||||
void setup_scene(Scene& scene);
|
||||
|
|
|
@ -449,6 +449,9 @@ void engine::process_key_down(const unsigned int keyCode) {
|
|||
|
||||
if(keyCode == platform::get_keycode(InputButton::C))
|
||||
console_enabled = !console_enabled;
|
||||
|
||||
if(keyCode == platform::get_keycode(InputButton::Backspace))
|
||||
ui_enabled = !ui_enabled;
|
||||
}
|
||||
|
||||
void engine::process_key_up(const unsigned int keyCode) {
|
||||
|
@ -620,12 +623,14 @@ void engine::update_animation(const Animation& anim, const float time) {
|
|||
|
||||
void engine::begin_frame(const float delta_time) {
|
||||
imgui->begin_frame(delta_time);
|
||||
|
||||
if(debug_enabled)
|
||||
draw_debug_ui();
|
||||
|
||||
if(console_enabled)
|
||||
draw_console();
|
||||
if(ui_enabled) {
|
||||
if (debug_enabled)
|
||||
draw_debug_ui();
|
||||
|
||||
if (console_enabled)
|
||||
draw_console();
|
||||
}
|
||||
|
||||
if(current_app != nullptr)
|
||||
current_app->begin_frame();
|
||||
|
|
|
@ -16,6 +16,20 @@ add_custom_target(GFXInterface SOURCES
|
|||
public/gfx_sampler.hpp)
|
||||
set_target_properties(GFXInterface PROPERTIES CMAKE_FOLDER "GFX")
|
||||
|
||||
add_subdirectory(dummy)
|
||||
|
||||
if(ENABLE_DX12)
|
||||
add_subdirectory(dx12)
|
||||
endif()
|
||||
|
||||
if(ENABLE_METAL)
|
||||
add_subdirectory(metal)
|
||||
endif()
|
||||
|
||||
if(ENABLE_VULKAN)
|
||||
add_subdirectory(vulkan)
|
||||
endif()
|
||||
|
||||
if(ENABLE_WEBGPU)
|
||||
add_subdirectory(webgpu)
|
||||
endif()
|
||||
|
|
3
engine/gfx/dx12/CMakeLists.txt
Executable file
3
engine/gfx/dx12/CMakeLists.txt
Executable file
|
@ -0,0 +1,3 @@
|
|||
add_library(GFXDX12 STATIC src/gfx_dummy.cpp)
|
||||
target_include_directories(GFXDX12 PUBLIC include)
|
||||
target_link_libraries(GFXDX12 PUBLIC GFX)
|
30
engine/gfx/dx12/include/gfx_dummy.hpp
Executable file
30
engine/gfx/dx12/include/gfx_dummy.hpp
Executable file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
||||
class GFXDummy : public GFX {
|
||||
public:
|
||||
bool initialize() override;
|
||||
void initializeView(void* native_handle, uint32_t width, uint32_t height) override;
|
||||
|
||||
// buffer operations
|
||||
GFXBuffer* createBuffer(void* data, GFXSize size, GFXBufferUsage usage) override;
|
||||
void copyBuffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) override;
|
||||
|
||||
// texture operations
|
||||
GFXTexture* createTexture(uint32_t width, uint32_t height, GFXPixelFormat format, GFXStorageMode storageMode, GFXTextureUsage usage) override;
|
||||
void copyTexture(GFXTexture* texture, void* data, GFXSize size) override;
|
||||
|
||||
// framebuffer operations
|
||||
GFXFramebuffer* createFramebuffer(GFXFramebufferCreateInfo& info) override;
|
||||
|
||||
// render pass operations
|
||||
GFXRenderPass* createRenderPass(GFXRenderPassCreateInfo& info) override;
|
||||
|
||||
// pipeline operations
|
||||
GFXPipeline* createPipeline(GFXPipelineCreateInfo& info) override;
|
||||
|
||||
void render(GFXCommandBuffer* command_buffer) override;
|
||||
|
||||
const char* getName() override;
|
||||
};
|
46
engine/gfx/dx12/src/gfx_dummy.cpp
Executable file
46
engine/gfx/dx12/src/gfx_dummy.cpp
Executable file
|
@ -0,0 +1,46 @@
|
|||
#include "gfx_dummy.hpp"
|
||||
|
||||
bool GFXDummy::initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void GFXDummy::initializeView(void* native_handle, uint32_t width, uint32_t height) {
|
||||
|
||||
}
|
||||
|
||||
GFXBuffer* GFXDummy::createBuffer(void* data, GFXSize size, GFXBufferUsage usage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GFXDummy::copyBuffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) {
|
||||
|
||||
}
|
||||
|
||||
GFXTexture* GFXDummy::createTexture(uint32_t width, uint32_t height, GFXPixelFormat format, GFXStorageMode storageMode, GFXTextureUsage usage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GFXDummy::copyTexture(GFXTexture* texture, void* data, GFXSize size) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
GFXFramebuffer* GFXDummy::createFramebuffer(GFXFramebufferCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GFXRenderPass* GFXDummy::createRenderPass(GFXRenderPassCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GFXPipeline* GFXDummy::createPipeline(GFXPipelineCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GFXDummy::render(GFXCommandBuffer* command_buffer) {
|
||||
|
||||
}
|
||||
|
||||
const char* GFXDummy::getName() {
|
||||
return "None";
|
||||
}
|
29
engine/gfx/metal/CMakeLists.txt
Executable file
29
engine/gfx/metal/CMakeLists.txt
Executable file
|
@ -0,0 +1,29 @@
|
|||
set(SRC
|
||||
include/gfx_metal.hpp
|
||||
|
||||
src/gfx_metal.mm
|
||||
src/gfx_metal_buffer.hpp
|
||||
src/gfx_metal_pipeline.hpp
|
||||
src/gfx_metal_texture.hpp
|
||||
src/gfx_metal_framebuffer.hpp
|
||||
src/gfx_metal_renderpass.hpp
|
||||
src/gfx_metal_sampler.hpp)
|
||||
|
||||
add_library(GFXMetal STATIC
|
||||
${SRC})
|
||||
|
||||
set_target_properties(GFXMetal PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
FRAMEWORK_VERSION OBJC
|
||||
PUBLIC_HEADER "${HEADERS}"
|
||||
)
|
||||
target_link_libraries(GFXMetal PUBLIC
|
||||
GFX
|
||||
Core
|
||||
Log
|
||||
"-framework Metal")
|
||||
target_include_directories(GFXMetal PUBLIC
|
||||
include
|
||||
PRIVATE
|
||||
src)
|
||||
set_engine_properties(GFXMetal)
|
70
engine/gfx/metal/include/gfx_metal.hpp
Executable file
70
engine/gfx/metal/include/gfx_metal.hpp
Executable file
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
#include <MetalKit/MetalKit.h>
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
||||
class GFXMetal : public GFX {
|
||||
public:
|
||||
bool is_supported() override;
|
||||
GFXContext required_context() override { return GFXContext::Metal; }
|
||||
ShaderLanguage accepted_shader_language() override { return ShaderLanguage::MSL; }
|
||||
const char* get_name() override;
|
||||
|
||||
bool supports_feature(const GFXFeature feature) override;
|
||||
|
||||
bool initialize(const GFXCreateInfo& createInfo) override;
|
||||
|
||||
void initialize_view(void* native_handle, const int identifier, const uint32_t width, const uint32_t height) override;
|
||||
void remove_view(const int identifier) override;
|
||||
|
||||
// buffer operations
|
||||
GFXBuffer* create_buffer(void* data, const GFXSize size, const bool dynamicData, const GFXBufferUsage usage) override;
|
||||
void copy_buffer(GFXBuffer* buffer, void* data, const GFXSize offset, const GFXSize size) override;
|
||||
|
||||
void* get_buffer_contents(GFXBuffer* buffer) override;
|
||||
|
||||
// texture operations
|
||||
GFXTexture* create_texture(const GFXTextureCreateInfo& info) override;
|
||||
void copy_texture(GFXTexture* texture, void* data, GFXSize size) override;
|
||||
void copy_texture(GFXTexture* from, GFXTexture* to) override;
|
||||
void copy_texture(GFXTexture* from, GFXBuffer* to) override;
|
||||
|
||||
// sampler opeations
|
||||
GFXSampler* create_sampler(const GFXSamplerCreateInfo& info) override;
|
||||
|
||||
// framebuffer operations
|
||||
GFXFramebuffer* create_framebuffer(const GFXFramebufferCreateInfo& info) override;
|
||||
|
||||
// render pass operations
|
||||
GFXRenderPass* create_render_pass(const GFXRenderPassCreateInfo& info) override;
|
||||
|
||||
// pipeline operations
|
||||
GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override;
|
||||
GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override;
|
||||
|
||||
GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use = false) override;
|
||||
|
||||
void submit(GFXCommandBuffer* command_buffer, const int window = -1) override;
|
||||
|
||||
private:
|
||||
struct NativeMTLView {
|
||||
int identifier = -1;
|
||||
CAMetalLayer* layer = nullptr;
|
||||
};
|
||||
|
||||
std::vector<NativeMTLView*> nativeViews;
|
||||
|
||||
NativeMTLView* getNativeView(int identifier) {
|
||||
for(auto& view : nativeViews) {
|
||||
if(view->identifier == identifier)
|
||||
return view;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
id<MTLDevice> device = nil;
|
||||
id<MTLCommandQueue> command_queue = nil;
|
||||
};
|
1115
engine/gfx/metal/src/gfx_metal.mm
Executable file
1115
engine/gfx/metal/src/gfx_metal.mm
Executable file
File diff suppressed because it is too large
Load diff
19
engine/gfx/metal/src/gfx_metal_buffer.hpp
Executable file
19
engine/gfx/metal/src/gfx_metal_buffer.hpp
Executable file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "gfx_buffer.hpp"
|
||||
|
||||
class GFXMetalBuffer : public GFXBuffer {
|
||||
public:
|
||||
id<MTLBuffer> handles[3] = {nil, nil, nil};
|
||||
bool dynamicData = false;
|
||||
|
||||
id<MTLBuffer> get(int frameIndex) {
|
||||
if(dynamicData) {
|
||||
return handles[frameIndex];
|
||||
} else {
|
||||
return handles[0];
|
||||
}
|
||||
}
|
||||
};
|
13
engine/gfx/metal/src/gfx_metal_framebuffer.hpp
Executable file
13
engine/gfx/metal/src/gfx_metal_framebuffer.hpp
Executable file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
#include <vector>
|
||||
|
||||
#include "gfx_framebuffer.hpp"
|
||||
|
||||
class GFXMetalTexture;
|
||||
|
||||
class GFXMetalFramebuffer : public GFXFramebuffer {
|
||||
public:
|
||||
std::vector<GFXMetalTexture*> attachments;
|
||||
};
|
32
engine/gfx/metal/src/gfx_metal_pipeline.hpp
Executable file
32
engine/gfx/metal/src/gfx_metal_pipeline.hpp
Executable file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "gfx_pipeline.hpp"
|
||||
|
||||
class GFXMetalPipeline : public GFXPipeline {
|
||||
public:
|
||||
std::string label;
|
||||
|
||||
id<MTLRenderPipelineState> handle = nil;
|
||||
id<MTLComputePipelineState> compute_handle = nil;
|
||||
|
||||
MTLSize threadGroupSize;
|
||||
|
||||
id<MTLDepthStencilState> depthStencil = nil;
|
||||
MTLPrimitiveType primitiveType;
|
||||
|
||||
MTLCullMode cullMode;
|
||||
GFXWindingMode winding_mode;
|
||||
|
||||
struct VertexStride {
|
||||
int location, stride;
|
||||
};
|
||||
|
||||
std::vector<VertexStride> vertexStrides;
|
||||
|
||||
int pushConstantSize = 0;
|
||||
int pushConstantIndex = 0;
|
||||
|
||||
bool renderWire = false;
|
||||
};
|
10
engine/gfx/metal/src/gfx_metal_renderpass.hpp
Executable file
10
engine/gfx/metal/src/gfx_metal_renderpass.hpp
Executable file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "gfx_renderpass.hpp"
|
||||
|
||||
class GFXMetalRenderPass : public GFXRenderPass {
|
||||
public:
|
||||
std::vector<MTLPixelFormat> attachments;
|
||||
};
|
10
engine/gfx/metal/src/gfx_metal_sampler.hpp
Executable file
10
engine/gfx/metal/src/gfx_metal_sampler.hpp
Executable file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "gfx_sampler.hpp"
|
||||
|
||||
class GFXMetalSampler : public GFXSampler {
|
||||
public:
|
||||
id<MTLSamplerState> handle = nil;
|
||||
};
|
16
engine/gfx/metal/src/gfx_metal_texture.hpp
Executable file
16
engine/gfx/metal/src/gfx_metal_texture.hpp
Executable file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "gfx_texture.hpp"
|
||||
|
||||
class GFXMetalTexture : public GFXTexture {
|
||||
public:
|
||||
id<MTLTexture> handle = nil;
|
||||
id<MTLSamplerState> sampler = nil;
|
||||
|
||||
int array_length = 1;
|
||||
bool is_cubemap = false;
|
||||
|
||||
MTLPixelFormat format;
|
||||
};
|
3
engine/gfx/webgpu/CMakeLists.txt
Executable file
3
engine/gfx/webgpu/CMakeLists.txt
Executable file
|
@ -0,0 +1,3 @@
|
|||
add_library(GFXWebGPU STATIC src/gfx_dummy.cpp)
|
||||
target_include_directories(GFXWebGPU PUBLIC include)
|
||||
target_link_libraries(GFXWebGPU PUBLIC GFX)
|
30
engine/gfx/webgpu/include/gfx_dummy.hpp
Executable file
30
engine/gfx/webgpu/include/gfx_dummy.hpp
Executable file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
||||
class GFXDummy : public GFX {
|
||||
public:
|
||||
bool initialize() override;
|
||||
void initializeView(void* native_handle, uint32_t width, uint32_t height) override;
|
||||
|
||||
// buffer operations
|
||||
GFXBuffer* createBuffer(void* data, GFXSize size, GFXBufferUsage usage) override;
|
||||
void copyBuffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) override;
|
||||
|
||||
// texture operations
|
||||
GFXTexture* createTexture(uint32_t width, uint32_t height, GFXPixelFormat format, GFXStorageMode storageMode, GFXTextureUsage usage) override;
|
||||
void copyTexture(GFXTexture* texture, void* data, GFXSize size) override;
|
||||
|
||||
// framebuffer operations
|
||||
GFXFramebuffer* createFramebuffer(GFXFramebufferCreateInfo& info) override;
|
||||
|
||||
// render pass operations
|
||||
GFXRenderPass* createRenderPass(GFXRenderPassCreateInfo& info) override;
|
||||
|
||||
// pipeline operations
|
||||
GFXPipeline* createPipeline(GFXPipelineCreateInfo& info) override;
|
||||
|
||||
void render(GFXCommandBuffer* command_buffer) override;
|
||||
|
||||
const char* getName() override;
|
||||
};
|
46
engine/gfx/webgpu/src/gfx_dummy.cpp
Executable file
46
engine/gfx/webgpu/src/gfx_dummy.cpp
Executable file
|
@ -0,0 +1,46 @@
|
|||
#include "gfx_dummy.hpp"
|
||||
|
||||
bool GFXDummy::initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void GFXDummy::initializeView(void* native_handle, uint32_t width, uint32_t height) {
|
||||
|
||||
}
|
||||
|
||||
GFXBuffer* GFXDummy::createBuffer(void* data, GFXSize size, GFXBufferUsage usage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GFXDummy::copyBuffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) {
|
||||
|
||||
}
|
||||
|
||||
GFXTexture* GFXDummy::createTexture(uint32_t width, uint32_t height, GFXPixelFormat format, GFXStorageMode storageMode, GFXTextureUsage usage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GFXDummy::copyTexture(GFXTexture* texture, void* data, GFXSize size) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
GFXFramebuffer* GFXDummy::createFramebuffer(GFXFramebufferCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GFXRenderPass* GFXDummy::createRenderPass(GFXRenderPassCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GFXPipeline* GFXDummy::createPipeline(GFXPipelineCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GFXDummy::render(GFXCommandBuffer* command_buffer) {
|
||||
|
||||
}
|
||||
|
||||
const char* GFXDummy::getName() {
|
||||
return "None";
|
||||
}
|
|
@ -215,7 +215,13 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
|
|||
|
||||
src += "layout(binding = " + std::to_string(sampler_index++) + ") uniform sampler2D colorTexture;\n";
|
||||
}
|
||||
|
||||
|
||||
if(material.normalProperty.type == DataType::AssetTexture) {
|
||||
material.bound_textures[sampler_index] = material.normalProperty.value_tex;
|
||||
|
||||
src += "layout(binding = " + std::to_string(sampler_index++) + ") uniform sampler2D normalTexture;\n";
|
||||
}
|
||||
|
||||
if(use_ibl) {
|
||||
src += "vec3 get_reflect(int i, vec3 final_normal) {\n \
|
||||
const vec3 direction = normalize(in_frag_pos - scene.camPos.xyz);\n \
|
||||
|
@ -292,7 +298,16 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
|
|||
src += "vec3 final_diffuse_color = from_srgb_to_linear(Color);\n";
|
||||
src += "float final_roughness = scene.materials[inMaterialIndex].info.y;\n";
|
||||
src += "float final_metallic = scene.materials[inMaterialIndex].info.x;\n";
|
||||
src += "vec3 final_normal = in_normal;\n";
|
||||
|
||||
if(material.normalProperty.type == DataType::AssetTexture) {
|
||||
prism::log("enabling normal mapping on material..");
|
||||
|
||||
src += "vec3 final_normal = texture(normalTexture, in_uv).rgb;\n";
|
||||
src += "final_normal = final_normal * 2.0 - 1.0;\n";
|
||||
src += "final_normal = in_tbn * final_normal;\n";
|
||||
} else {
|
||||
src += "vec3 final_normal = in_normal;\n";
|
||||
}
|
||||
|
||||
src +=
|
||||
"ComputedSurfaceInfo surface_info = compute_surface(final_diffuse_color.rgb, final_normal, final_metallic, final_roughness);\n \
|
||||
|
@ -312,7 +327,11 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
|
|||
break;\n \
|
||||
}\n \
|
||||
SurfaceBRDF surface_brdf = brdf(light_info.direction, surface_info);\n";
|
||||
|
||||
|
||||
if(render_options.enable_normal_mapping && material.normalProperty.type == DataType::AssetTexture && render_options.enable_normal_shadowing) {
|
||||
src += std::string("light_info.radiance *= calculate_normal_lighting(normalTexture, final_normal, light_info.direction);\n");
|
||||
}
|
||||
|
||||
src += "Lo += ((surface_brdf.specular + surface_brdf.diffuse) * light_info.radiance * surface_brdf.NdotL) * scene.lights[i].colorSize.rgb;\n \
|
||||
}\n";
|
||||
|
||||
|
|
|
@ -18,7 +18,10 @@ enum class ShaderStage {
|
|||
/// The shader language that the shader is written in.
|
||||
enum class ShaderLanguage {
|
||||
GLSL,
|
||||
SPIRV
|
||||
SPIRV,
|
||||
MSL,
|
||||
HLSL,
|
||||
WGSL // lol how do we even convert to this
|
||||
};
|
||||
|
||||
/// Compilation options when compiling shaders.
|
||||
|
|
|
@ -102,6 +102,15 @@ std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_la
|
|||
switch(to_language) {
|
||||
case ShaderLanguage::SPIRV:
|
||||
return ShaderSource(spirv);
|
||||
case ShaderLanguage::MSL:
|
||||
prism::log("Unimplemented shader language: MSL");
|
||||
return ShaderSource(spirv);
|
||||
case ShaderLanguage::HLSL:
|
||||
prism::log("Unimplemented shader language: HLSL");
|
||||
return ShaderSource(spirv);
|
||||
case ShaderLanguage::WGSL:
|
||||
prism::log("Unimplemented shader language: WGSL");
|
||||
return ShaderSource(spirv);
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
const float PI = 3.14159265359;
|
||||
const float EPSILON = 0.005;
|
||||
|
||||
const vec2 PoissionPCFDisk[16] = {
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
};
|
||||
|
||||
const vec2 PoissonOffsets[64] = {
|
||||
vec2(0.0617981, 0.07294159),
|
||||
vec2(0.6470215, 0.7474022),
|
||||
|
|
|
@ -66,7 +66,7 @@ struct ComputedLightInformation {
|
|||
float pcf_sun(const vec4 shadowCoords, const float uvRadius) {
|
||||
float sum = 0;
|
||||
for(int i = 0; i < 16; i++) {
|
||||
const float z = texture(sun_shadow, shadowCoords.xy + PoissonOffsets[i] * uvRadius).r;
|
||||
const float z = texture(sun_shadow, shadowCoords.xy + PoissionPCFDisk[i] * uvRadius).r;
|
||||
sum += (z < (shadowCoords.z - 0.005)) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,7 @@ void blocker_distance_sun(const vec3 shadowCoords, const float uvLightSize, inou
|
|||
blockers = 0;
|
||||
|
||||
for(int i = 0; i < numBlockerSearchSamples; i++) {
|
||||
const float z = texture(sun_shadow,
|
||||
shadowCoords.xy + PoissonOffsets[i] * searchWidth).r;
|
||||
const float z = texture(sun_shadow, shadowCoords.xy + PoissionPCFDisk[i] * searchWidth).r;
|
||||
if(z < shadowCoords.z) {
|
||||
blockerSum += z;
|
||||
blockers++;
|
||||
|
@ -105,11 +104,12 @@ void blocker_distance_sun(const vec3 shadowCoords, const float uvLightSize, inou
|
|||
float pcss_sun(const vec4 shadowCoords, float light_size_uv) {
|
||||
float average_blocker_depth = 0.0;
|
||||
int num_blockers = 0;
|
||||
|
||||
blocker_distance_sun(shadowCoords.xyz, light_size_uv, average_blocker_depth, num_blockers);
|
||||
if(num_blockers < 1)
|
||||
return 1.0;
|
||||
|
||||
const float penumbraWidth = penumbra_size(-shadowCoords.z, average_blocker_depth);
|
||||
const float penumbraWidth = penumbra_size(shadowCoords.z, average_blocker_depth);
|
||||
|
||||
const float uvRadius = penumbraWidth * light_size_uv * 0.1 / shadowCoords.z;
|
||||
return pcf_sun(shadowCoords, uvRadius);
|
||||
|
@ -145,7 +145,7 @@ ComputedLightInformation calculate_sun(Light light) {
|
|||
float pcf_spot(const vec4 shadowCoords, const int index, const float uvRadius) {
|
||||
float sum = 0;
|
||||
for(int i = 0; i < 16; i++) {
|
||||
const float z = texture(spot_shadow, vec3(shadowCoords.xy + PoissonOffsets[i] * uvRadius, index)).r;
|
||||
const float z = texture(spot_shadow, vec3(shadowCoords.xy + PoissionPCFDisk[i] * uvRadius, index)).r;
|
||||
sum += (z < (shadowCoords.z - 0.001)) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
|
@ -160,8 +160,7 @@ void blocker_distance_spot(const vec3 shadowCoords, const int index, const float
|
|||
blockers = 0;
|
||||
|
||||
for(int i = 0; i < numBlockerSearchSamples; i++) {
|
||||
const float z = texture(spot_shadow,
|
||||
vec3(shadowCoords.xy + PoissonOffsets[i] * searchWidth, index)).r;
|
||||
const float z = texture(spot_shadow, vec3(shadowCoords.xy + PoissionPCFDisk[i] * searchWidth, index)).r;
|
||||
if(z < shadowCoords.z) {
|
||||
blockerSum += z;
|
||||
blockers++;
|
||||
|
@ -174,6 +173,7 @@ void blocker_distance_spot(const vec3 shadowCoords, const int index, const float
|
|||
float pcss_spot(const vec4 shadowCoords, const int index, float light_size_uv) {
|
||||
float average_blocker_depth = 0.0;
|
||||
int num_blockers = 0;
|
||||
|
||||
blocker_distance_spot(shadowCoords.xyz, index, light_size_uv, average_blocker_depth, num_blockers);
|
||||
if(num_blockers < 1)
|
||||
return 1.0;
|
||||
|
@ -197,7 +197,7 @@ ComputedLightInformation calculate_spot(Light light) {
|
|||
const vec4 shadowCoord = fragPostSpotLightSpace[last_spot_light] / fragPostSpotLightSpace[last_spot_light].w;
|
||||
|
||||
#ifdef SHADOW_FILTER_NONE
|
||||
shadow = (texture(spot_shadow, vec3(shadowCoord.xy, last_spot_light)).r < shadowCoord.z) ? 0.0 : 1.0;
|
||||
shadow = (texture(spot_shadow, vec3(shadowCoord.xy, last_spot_light)).r < shadowCoord.z - 0.005) ? 0.0 : 1.0;
|
||||
#endif
|
||||
#ifdef SHADOW_FILTER_PCF
|
||||
shadow = pcf_spot(shadowCoord, last_spot_light, 0.01);
|
||||
|
@ -223,14 +223,23 @@ ComputedLightInformation calculate_spot(Light light) {
|
|||
|
||||
#ifdef POINT_SHADOWS_SUPPORTED
|
||||
|
||||
vec3 sampleOffsetDirections[20] = vec3[]
|
||||
(
|
||||
vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
||||
vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
|
||||
vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
|
||||
vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
|
||||
vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
|
||||
);
|
||||
|
||||
float pcf_point(const vec3 shadowCoords, const int index, const float uvRadius) {
|
||||
float sum = 0;
|
||||
for(int i = 0; i < 16; i++) {
|
||||
const float z = texture(point_shadow, vec4(shadowCoords.xyz + vec3(PoissonOffsets[i].xy, PoissonOffsets[i].x) * uvRadius, index)).r;
|
||||
for(int i = 0; i < 20; i++) {
|
||||
const float z = texture(point_shadow, vec4(shadowCoords.xyz + sampleOffsetDirections[i] * uvRadius, index)).r;
|
||||
sum += (z < length(shadowCoords) - 0.05) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
return sum / 16;
|
||||
return sum / 20;
|
||||
}
|
||||
|
||||
#ifdef SHADOW_FILTER_PCSS
|
||||
|
@ -240,9 +249,8 @@ void blocker_distance_point(const vec3 shadowCoords, const int index, const floa
|
|||
float blockerSum = 0.0;
|
||||
blockers = 0;
|
||||
|
||||
for(int i = 0; i < numBlockerSearchSamples; i++) {
|
||||
const float z = texture(point_shadow,
|
||||
vec4(shadowCoords + vec3(PoissonOffsets[i], PoissonOffsets[i].x) * searchWidth, index)).r;
|
||||
for(int i = 0; i < 20; i++) {
|
||||
const float z = texture(point_shadow, vec4(shadowCoords + sampleOffsetDirections[i] * 0.05, index)).r;
|
||||
if(z < length(shadowCoords)) {
|
||||
blockerSum += z;
|
||||
blockers++;
|
||||
|
@ -255,14 +263,15 @@ void blocker_distance_point(const vec3 shadowCoords, const int index, const floa
|
|||
float pcss_point(const vec3 shadowCoords, const int index, float light_size_uv) {
|
||||
float average_blocker_depth = 0.0;
|
||||
int num_blockers = 0;
|
||||
|
||||
blocker_distance_point(shadowCoords.xyz, index, light_size_uv, average_blocker_depth, num_blockers);
|
||||
if(num_blockers < 1)
|
||||
return 1.0;
|
||||
|
||||
const float dist = length(shadowCoords);
|
||||
const float penumbraWidth = penumbra_size(dist, average_blocker_depth);
|
||||
|
||||
const float depth = length(shadowCoords);
|
||||
const float penumbraWidth = penumbra_size(-depth, average_blocker_depth);
|
||||
|
||||
const float uvRadius = penumbraWidth * light_size_uv;
|
||||
const float uvRadius = penumbraWidth * light_size_uv / dist;
|
||||
return pcf_point(shadowCoords, index, uvRadius);
|
||||
}
|
||||
#endif
|
||||
|
@ -286,7 +295,7 @@ ComputedLightInformation calculate_point(Light light) {
|
|||
shadow = (dist <= sampledDist + 0.05) ? 1.0 : 0.0;
|
||||
#endif
|
||||
#ifdef SHADOW_FILTER_PCF
|
||||
shadow = pcf_point(lightVec, int(light.shadowsEnable.z), 1.0);
|
||||
shadow = pcf_point(lightVec, int(light.shadowsEnable.z), 0.05);
|
||||
#endif
|
||||
#ifdef SHADOW_FILTER_PCSS
|
||||
shadow = pcss_point(lightVec, int(light.shadowsEnable.z), light.shadowsEnable.y);
|
||||
|
|
|
@ -20,11 +20,13 @@ void ExampleApp::initialize_render() {
|
|||
|
||||
camera_obj = scene->add_object();
|
||||
auto& camera = scene->add<Camera>(camera_obj);
|
||||
camera.near = 0.1f;
|
||||
|
||||
auto sun_obj = scene->add_object();
|
||||
auto& sun = scene->add<Light>(sun_obj);
|
||||
sun.type = Light::Type::Point;
|
||||
sun.use_dynamic_shadows = true;
|
||||
sun.size = 25.0f;
|
||||
auto& sun_trans = scene->get<Transform>(sun_obj);
|
||||
sun_trans.position = {-2, 5, 1};
|
||||
|
||||
|
@ -33,6 +35,7 @@ void ExampleApp::initialize_render() {
|
|||
second_sun.type = Light::Type::Point;
|
||||
second_sun.color = {1, 0, 0};
|
||||
second_sun.use_dynamic_shadows = true;
|
||||
second_sun.size = 25.0f;
|
||||
scene->get<Transform>(second_sun_obj).position = {-14, 1, -1};
|
||||
|
||||
auto third_sun_obj = scene->add_object();
|
||||
|
@ -40,6 +43,7 @@ void ExampleApp::initialize_render() {
|
|||
third_sun.type = Light::Type::Point;
|
||||
third_sun.color = {0, 0, 1};
|
||||
third_sun.use_dynamic_shadows = true;
|
||||
third_sun.size = 25.0f;
|
||||
scene->get<Transform>(third_sun_obj).position = {3, 1, -1};
|
||||
|
||||
main_object = scene->add_object();
|
||||
|
|
Reference in a new issue