2020-08-11 12:07:21 -04:00
# include "scenecapture.hpp"
# include "gfx_commandbuffer.hpp"
# include "scene.hpp"
# include "gfx.hpp"
# include "engine.hpp"
# include "renderer.hpp"
# include "shadowpass.hpp"
2020-08-15 20:09:16 -04:00
# include "materialcompiler.hpp"
2020-08-11 12:07:21 -04:00
# include "frustum.hpp"
2020-09-20 23:31:03 -04:00
# include "asset.hpp"
2020-08-11 12:07:21 -04:00
struct PushConstant {
Matrix4x4 m , v ;
} ;
struct SceneMaterial {
2021-05-12 09:56:44 -04:00
prism : : float4 color , info ;
2020-08-11 12:07:21 -04:00
} ;
struct SceneLight {
2021-05-12 09:56:44 -04:00
prism : : float4 positionType ;
prism : : float4 directionPower ;
prism : : float4 colorSize ;
prism : : float4 shadowsEnable ;
2020-08-11 12:07:21 -04:00
} ;
struct SceneProbe {
2021-05-12 09:56:44 -04:00
prism : : float4 position , size ;
2020-08-11 12:07:21 -04:00
} ;
struct SceneInformation {
2021-05-12 09:56:44 -04:00
prism : : float4 options ;
prism : : float4 camPos ;
2020-08-11 12:07:21 -04:00
Matrix4x4 vp , lightspace ;
Matrix4x4 spotLightSpaces [ max_spot_shadows ] ;
SceneMaterial materials [ max_scene_materials ] ;
SceneLight lights [ max_scene_lights ] ;
SceneProbe probes [ max_environment_probes ] ;
int numLights ;
int p [ 3 ] ;
} ;
2021-02-15 17:59:54 -05:00
struct SkyPushConstant {
Matrix4x4 view ;
2021-05-12 09:56:44 -04:00
prism : : float4 sun_position_fov ;
2021-02-15 17:59:54 -05:00
float aspect ;
} ;
struct FilterPushConstant {
Matrix4x4 mvp ;
float roughness ;
float buffer [ 15 ] ;
} ;
2020-08-11 12:07:21 -04:00
const int mipLevels = 5 ;
const std : : array < Matrix4x4 , 6 > sceneTransforms = {
2021-05-12 09:56:44 -04:00
prism : : look_at ( prism : : float3 ( 0 ) , prism : : float3 ( - 1.0 , 0.0 , 0.0 ) , prism : : float3 ( 0.0 , - 1.0 , 0.0 ) ) , // right
prism : : look_at ( prism : : float3 ( 0 ) , prism : : float3 ( 1.0 , 0.0 , 0.0 ) , prism : : float3 ( 0.0 , - 1.0 , 0.0 ) ) , // left
prism : : look_at ( prism : : float3 ( 0 ) , prism : : float3 ( 0.0 , - 1.0 , 0.0 ) , prism : : float3 ( 0.0 , 0.0 , - 1.0 ) ) , // top
prism : : look_at ( prism : : float3 ( 0 ) , prism : : float3 ( 0.0 , 1.0 , 0.0 ) , prism : : float3 ( 0.0 , 0.0 , 1.0 ) ) , // bottom
prism : : look_at ( prism : : float3 ( 0 ) , prism : : float3 ( 0.0 , 0.0 , 1.0 ) , prism : : float3 ( 0.0 , - 1.0 , 0.0 ) ) , // back
prism : : look_at ( prism : : float3 ( 0 ) , prism : : float3 ( 0.0 , 0.0 , - 1.0 ) , prism : : float3 ( 0.0 , - 1.0 , 0.0 ) ) // front
2020-08-17 10:56:15 -04:00
} ;
2020-08-11 12:07:21 -04:00
inline AssetPtr < Mesh > cubeMesh ;
SceneCapture : : SceneCapture ( GFX * gfx ) {
2021-05-12 08:50:02 -04:00
cubeMesh = assetm - > get < Mesh > ( prism : : app_domain / " models/cube.model " ) ;
2020-08-11 12:07:21 -04:00
// render pass
GFXRenderPassCreateInfo renderPassInfo = { } ;
2020-09-23 10:17:24 -04:00
renderPassInfo . label = " Scene Capture Cube " ;
2020-08-11 12:07:21 -04:00
renderPassInfo . attachments . push_back ( GFXPixelFormat : : R8G8B8A8_UNORM ) ;
renderPassInfo . attachments . push_back ( GFXPixelFormat : : DEPTH_32F ) ;
2021-02-15 19:01:17 -05:00
renderPassInfo . will_use_in_shader = true ;
2020-08-11 12:07:21 -04:00
renderPass = gfx - > create_render_pass ( renderPassInfo ) ;
GFXTextureCreateInfo textureInfo = { } ;
2021-02-04 08:21:40 -05:00
textureInfo . label = " Scene Capture Color " ;
2020-08-11 12:07:21 -04:00
textureInfo . width = scene_cubemap_resolution ;
textureInfo . height = scene_cubemap_resolution ;
textureInfo . format = GFXPixelFormat : : R8G8B8A8_UNORM ;
2021-05-11 19:16:54 -04:00
textureInfo . usage = GFXTextureUsage : : Attachment | GFXTextureUsage : : TransferSrc | GFXTextureUsage : : Sampled ;
2022-03-06 22:45:08 -05:00
2020-08-11 12:07:21 -04:00
offscreenTexture = gfx - > create_texture ( textureInfo ) ;
GFXTextureCreateInfo depthTextureInfo = { } ;
2021-02-04 08:21:40 -05:00
depthTextureInfo . label = " Scene Capture Depth " ;
2020-08-11 12:07:21 -04:00
depthTextureInfo . width = scene_cubemap_resolution ;
depthTextureInfo . height = scene_cubemap_resolution ;
depthTextureInfo . format = GFXPixelFormat : : DEPTH_32F ;
depthTextureInfo . usage = GFXTextureUsage : : Attachment ;
2022-03-06 22:45:08 -05:00
2020-08-11 12:07:21 -04:00
offscreenDepth = gfx - > create_texture ( depthTextureInfo ) ;
GFXFramebufferCreateInfo info ;
info . attachments = { offscreenTexture , offscreenDepth } ;
info . render_pass = renderPass ;
offscreenFramebuffer = gfx - > create_framebuffer ( info ) ;
GFXTextureCreateInfo cubeTextureInfo = { } ;
2021-02-04 08:21:40 -05:00
cubeTextureInfo . label = " Scene Capture Cubemap " ;
2020-08-11 12:07:21 -04:00
cubeTextureInfo . type = GFXTextureType : : Cubemap ;
cubeTextureInfo . width = scene_cubemap_resolution ;
cubeTextureInfo . height = scene_cubemap_resolution ;
cubeTextureInfo . format = GFXPixelFormat : : R8G8B8A8_UNORM ;
2021-06-01 11:10:58 -04:00
cubeTextureInfo . usage = GFXTextureUsage : : Sampled | GFXTextureUsage : : TransferDst | GFXTextureUsage : : TransferSrc ; // dst used for cubemap copy, src used for mipmap gen
2020-08-11 12:07:21 -04:00
cubeTextureInfo . mip_count = mipLevels ;
environmentCube = gfx - > create_texture ( cubeTextureInfo ) ;
2022-03-10 10:20:50 -05:00
sceneBuffer = gfx - > create_buffer ( nullptr , sizeof ( SceneInformation ) , true , GFXBufferUsage : : Storage ) ;
2020-08-11 12:07:21 -04:00
createSkyResources ( ) ;
createIrradianceResources ( ) ;
createPrefilterResources ( ) ;
}
void SceneCapture : : create_scene_resources ( Scene & scene ) {
auto gfx = engine - > get_gfx ( ) ;
if ( gfx - > supports_feature ( GFXFeature : : CubemapArray ) ) {
GFXTextureCreateInfo cubeTextureInfo = { } ;
2021-02-04 08:21:40 -05:00
cubeTextureInfo . label = " Irriadiance Cubemap " ;
2020-08-11 12:07:21 -04:00
cubeTextureInfo . type = GFXTextureType : : CubemapArray ;
cubeTextureInfo . width = irradiance_cubemap_resolution ;
cubeTextureInfo . height = irradiance_cubemap_resolution ;
cubeTextureInfo . format = GFXPixelFormat : : R8G8B8A8_UNORM ;
2021-05-12 10:29:29 -04:00
cubeTextureInfo . usage = GFXTextureUsage : : Sampled | GFXTextureUsage : : TransferDst ;
2020-08-11 12:07:21 -04:00
cubeTextureInfo . array_length = max_environment_probes ;
scene . irradianceCubeArray = gfx - > create_texture ( cubeTextureInfo ) ;
cubeTextureInfo = { } ;
2021-02-04 08:21:40 -05:00
cubeTextureInfo . label = " Prefiltered Cubemap " ;
2020-08-11 12:07:21 -04:00
cubeTextureInfo . type = GFXTextureType : : CubemapArray ;
cubeTextureInfo . width = scene_cubemap_resolution ;
cubeTextureInfo . height = scene_cubemap_resolution ;
cubeTextureInfo . format = GFXPixelFormat : : R8G8B8A8_UNORM ;
2021-05-12 10:29:29 -04:00
cubeTextureInfo . usage = GFXTextureUsage : : Sampled | GFXTextureUsage : : TransferDst ;
2020-08-11 12:07:21 -04:00
cubeTextureInfo . array_length = max_environment_probes ;
cubeTextureInfo . mip_count = mipLevels ;
scene . prefilteredCubeArray = gfx - > create_texture ( cubeTextureInfo ) ;
}
}
void SceneCapture : : render ( GFXCommandBuffer * command_buffer , Scene * scene ) {
2021-05-12 10:33:38 -04:00
if ( scene - > probe_refresh_timer > 0 ) {
scene - > probe_refresh_timer - - ;
return ;
}
2020-08-11 12:07:21 -04:00
int last_probe = 0 ;
auto probes = scene - > get_all < EnvironmentProbe > ( ) ;
for ( auto [ obj , probe ] : probes ) {
if ( last_probe > max_environment_probes )
return ;
2021-05-11 15:57:14 -04:00
if ( scene - > environment_dirty [ last_probe ] ) {
2020-08-11 12:07:21 -04:00
std : : map < Material * , int > material_indices ;
int numMaterialsInBuffer = 0 ;
2021-05-12 09:56:44 -04:00
const prism : : float3 lightPos = scene - > get < Transform > ( obj ) . get_world_position ( ) ;
2020-08-11 12:07:21 -04:00
2021-05-12 09:56:44 -04:00
const Matrix4x4 projection = prism : : infinite_perspective ( radians ( 90.0f ) , 1.0f , 0.1f ) ;
const Matrix4x4 model = prism : : translate ( Matrix4x4 ( ) , prism : : float3 ( - lightPos . x , - lightPos . y , - lightPos . z ) ) ;
2020-08-11 12:07:21 -04:00
SceneInformation sceneInfo = { } ;
sceneInfo . lightspace = scene - > lightSpace ;
sceneInfo . numLights = 0 ;
sceneInfo . camPos = lightPos ;
sceneInfo . vp = projection ;
for ( const auto [ obj , light ] : scene - > get_all < Light > ( ) ) {
SceneLight sl ;
2021-05-12 09:56:44 -04:00
sl . positionType = prism : : float4 ( scene - > get < Transform > ( obj ) . get_world_position ( ) , ( int ) light . type ) ;
prism : : float3 front = prism : : float3 ( 0.0f , 0.0f , 1.0f ) * scene - > get < Transform > ( obj ) . rotation ;
2020-08-11 12:07:21 -04:00
2021-05-12 09:56:44 -04:00
sl . directionPower = prism : : float4 ( - front , light . power ) ;
sl . colorSize = prism : : float4 ( utility : : from_srgb_to_linear ( light . color ) , radians ( light . spot_size ) ) ;
sl . shadowsEnable = prism : : float4 ( light . enable_shadows , radians ( light . size ) , 0 , 0 ) ;
2020-08-11 12:07:21 -04:00
sceneInfo . lights [ sceneInfo . numLights + + ] = sl ;
}
for ( int i = 0 ; i < max_spot_shadows ; i + + )
sceneInfo . spotLightSpaces [ i ] = scene - > spotLightSpaces [ i ] ;
const auto & meshes = scene - > get_all < Renderable > ( ) ;
for ( const auto [ obj , mesh ] : meshes ) {
if ( ! mesh . mesh )
continue ;
if ( mesh . materials . empty ( ) )
continue ;
for ( const auto & material : mesh . materials ) {
if ( ! material )
continue ;
if ( material - > static_pipeline = = nullptr | | material - > skinned_pipeline = = nullptr )
engine - > get_renderer ( ) - > create_mesh_pipeline ( * material . handle ) ;
if ( ! material_indices . count ( material . handle ) ) {
material_indices [ material . handle ] = numMaterialsInBuffer + + ;
}
}
}
const auto render_face = [ this , command_buffer , scene , & meshes , & model , & probe = probe ] ( int face ) {
const auto frustum = normalize_frustum ( extract_frustum ( sceneTransforms [ face ] ) ) ;
GFXRenderPassBeginInfo info = { } ;
info . framebuffer = offscreenFramebuffer ;
info . render_pass = renderPass ;
info . render_area . extent = { scene_cubemap_resolution , scene_cubemap_resolution } ;
command_buffer - > set_render_pass ( info ) ;
Viewport viewport = { } ;
viewport . width = scene_cubemap_resolution ;
viewport . height = scene_cubemap_resolution ;
command_buffer - > set_viewport ( viewport ) ;
if ( probe . is_sized ) {
for ( const auto [ obj , mesh ] : meshes ) {
if ( ! mesh . mesh )
continue ;
if ( mesh . materials . empty ( ) )
continue ;
PushConstant pc ;
pc . m = scene - > get < Transform > ( obj ) . model ;
pc . v = sceneTransforms [ face ] * model ;
command_buffer - > set_vertex_buffer ( mesh . mesh - > position_buffer , 0 , position_buffer_index ) ;
command_buffer - > set_vertex_buffer ( mesh . mesh - > normal_buffer , 0 , normal_buffer_index ) ;
command_buffer - > set_vertex_buffer ( mesh . mesh - > texture_coord_buffer , 0 , texcoord_buffer_index ) ;
command_buffer - > set_vertex_buffer ( mesh . mesh - > tangent_buffer , 0 , tangent_buffer_index ) ;
command_buffer - > set_vertex_buffer ( mesh . mesh - > bitangent_buffer , 0 , bitangent_buffer_index ) ;
command_buffer - > set_index_buffer ( mesh . mesh - > index_buffer , IndexType : : UINT32 ) ;
if ( mesh . mesh - > bones . empty ( ) ) {
for ( auto & part : mesh . mesh - > parts ) {
const int material_index = part . material_override = = - 1 ? 0 : part . material_override ;
if ( material_index > = mesh . materials . size ( ) )
continue ;
if ( mesh . materials [ material_index ] . handle = = nullptr | | mesh . materials [ material_index ] - > static_pipeline = = nullptr )
continue ;
2020-08-17 10:11:58 -04:00
if ( render_options . enable_frustum_culling & & ! test_aabb_frustum ( frustum , get_aabb_for_part ( scene - > get < Transform > ( obj ) , part ) ) )
2020-08-11 12:07:21 -04:00
continue ;
2020-09-22 16:09:25 -04:00
command_buffer - > set_graphics_pipeline ( mesh . materials [ material_index ] - > capture_pipeline ) ;
2020-08-11 12:07:21 -04:00
2020-09-30 19:18:17 -04:00
command_buffer - > bind_shader_buffer ( sceneBuffer , 0 , 1 , sizeof ( SceneInformation ) ) ;
command_buffer - > bind_texture ( scene - > depthTexture , 2 ) ;
command_buffer - > bind_texture ( scene - > pointLightArray , 3 ) ;
command_buffer - > bind_texture ( scene - > spotLightArray , 6 ) ;
2020-08-11 12:07:21 -04:00
command_buffer - > set_push_constant ( & pc , sizeof ( PushConstant ) ) ;
for ( auto & [ index , texture ] : mesh . materials [ material_index ] - > bound_textures ) {
2021-04-20 13:53:38 -04:00
GFXTexture * texture_to_bind = engine - > get_renderer ( ) - > dummy_texture ;
2020-08-11 12:07:21 -04:00
if ( texture )
texture_to_bind = texture - > handle ;
command_buffer - > bind_texture ( texture_to_bind , index ) ;
}
2020-09-23 09:53:45 -04:00
command_buffer - > draw_indexed ( part . index_count , part . index_offset , part . vertex_offset , 0 ) ;
2020-08-11 12:07:21 -04:00
}
}
}
}
// render sky
2021-02-15 19:01:17 -05:00
SkyPushConstant pc ;
2020-08-11 12:07:21 -04:00
2020-08-19 17:15:00 -04:00
pc . view = sceneTransforms [ face ] ;
2020-08-14 23:32:02 -04:00
pc . aspect = 1.0f ;
2020-08-11 12:07:21 -04:00
for ( auto & [ obj , light ] : scene - > get_all < Light > ( ) ) {
if ( light . type = = Light : : Type : : Sun )
2021-05-12 09:56:44 -04:00
pc . sun_position_fov = prism : : float4 ( scene - > get < Transform > ( obj ) . get_world_position ( ) , radians ( 90.0f ) ) ;
2020-08-11 12:07:21 -04:00
}
2020-09-22 16:09:25 -04:00
command_buffer - > set_graphics_pipeline ( skyPipeline ) ;
2020-08-11 12:07:21 -04:00
command_buffer - > set_push_constant ( & pc , sizeof ( SkyPushConstant ) ) ;
command_buffer - > draw ( 0 , 4 , 0 , 1 ) ;
2021-02-15 17:59:54 -05:00
command_buffer - > end_render_pass ( ) ;
2020-08-11 12:07:21 -04:00
command_buffer - > copy_texture ( offscreenTexture , scene_cubemap_resolution , scene_cubemap_resolution , environmentCube , face , 0 , 0 ) ;
} ;
engine - > get_gfx ( ) - > copy_buffer ( sceneBuffer , & sceneInfo , 0 , sizeof ( SceneInformation ) ) ;
for ( int face = 0 ; face < 6 ; face + + )
render_face ( face ) ;
command_buffer - > generate_mipmaps ( environmentCube , mipLevels ) ;
// calculate irradiance
const auto convulute_face = [ this , scene , command_buffer , & last_probe , projection ] ( int face ) {
GFXRenderPassBeginInfo info = { } ;
info . framebuffer = irradianceFramebuffer ;
info . render_pass = irradianceRenderPass ;
info . render_area . extent = { irradiance_cubemap_resolution , irradiance_cubemap_resolution } ;
command_buffer - > set_render_pass ( info ) ;
Viewport viewport = { } ;
viewport . width = irradiance_cubemap_resolution ;
viewport . height = irradiance_cubemap_resolution ;
command_buffer - > set_viewport ( viewport ) ;
Matrix4x4 mvp = projection * sceneTransforms [ face ] ;
command_buffer - > set_vertex_buffer ( cubeMesh - > position_buffer , 0 , 0 ) ;
command_buffer - > set_index_buffer ( cubeMesh - > index_buffer , IndexType : : UINT32 ) ;
2020-09-22 16:09:25 -04:00
command_buffer - > set_graphics_pipeline ( irradiancePipeline ) ;
2020-08-11 12:07:21 -04:00
command_buffer - > bind_texture ( environmentCube , 2 ) ;
command_buffer - > set_push_constant ( & mvp , sizeof ( Matrix4x4 ) ) ;
2020-09-23 09:53:45 -04:00
command_buffer - > draw_indexed ( cubeMesh - > num_indices , 0 , 0 , 0 ) ;
2021-02-15 17:59:54 -05:00
command_buffer - > end_render_pass ( ) ;
2021-05-11 15:57:14 -04:00
command_buffer - > copy_texture ( irradianceOffscreenTexture ,
irradiance_cubemap_resolution ,
irradiance_cubemap_resolution ,
scene - > irradianceCubeArray ,
face , // slice
last_probe , // layer
0 ) ; // level
2020-08-11 12:07:21 -04:00
} ;
for ( int face = 0 ; face < 6 ; face + + )
convulute_face ( face ) ;
// prefilter
const auto prefilter_face = [ this , scene , command_buffer , & last_probe , projection ] ( int face , int mip ) {
GFXRenderPassBeginInfo info = { } ;
info . framebuffer = prefilteredFramebuffer ;
info . render_pass = irradianceRenderPass ;
const uint32_t resolution = scene_cubemap_resolution * std : : pow ( 0.5 , mip ) ;
info . render_area . extent = { resolution , resolution } ;
command_buffer - > set_render_pass ( info ) ;
Viewport viewport = { } ;
viewport . width = resolution ;
viewport . height = resolution ;
command_buffer - > set_viewport ( viewport ) ;
command_buffer - > set_vertex_buffer ( cubeMesh - > position_buffer , 0 , 0 ) ;
command_buffer - > set_index_buffer ( cubeMesh - > index_buffer , IndexType : : UINT32 ) ;
2021-02-15 17:59:54 -05:00
FilterPushConstant pc ;
2020-08-11 12:07:21 -04:00
pc . mvp = projection * sceneTransforms [ face ] ;
pc . roughness = ( ( float ) mip ) / ( float ) ( mipLevels - 1 ) ;
2020-09-22 16:09:25 -04:00
command_buffer - > set_graphics_pipeline ( prefilterPipeline ) ;
2020-08-11 12:07:21 -04:00
command_buffer - > bind_texture ( environmentCube , 2 ) ;
command_buffer - > set_push_constant ( & pc , sizeof ( PushConstant ) ) ;
2020-09-23 09:53:45 -04:00
command_buffer - > draw_indexed ( cubeMesh - > num_indices , 0 , 0 , 0 ) ;
2020-08-11 12:07:21 -04:00
2021-02-15 17:59:54 -05:00
command_buffer - > end_render_pass ( ) ;
2021-05-11 15:57:14 -04:00
command_buffer - > copy_texture ( prefilteredOffscreenTexture ,
resolution , resolution ,
scene - > prefilteredCubeArray , face , last_probe , mip ) ;
2020-08-11 12:07:21 -04:00
} ;
for ( int mip = 0 ; mip < mipLevels ; mip + + ) {
for ( int i = 0 ; i < 6 ; i + + )
prefilter_face ( i , mip ) ;
}
scene - > environment_dirty [ last_probe ] = false ;
}
last_probe + + ;
}
}
void SceneCapture : : createSkyResources ( ) {
GFXGraphicsPipelineCreateInfo pipelineInfo = { } ;
2021-02-05 19:17:13 -05:00
pipelineInfo . label = " Sky Scene Capture " ;
2020-08-11 12:07:21 -04:00
pipelineInfo . render_pass = renderPass ;
2021-05-12 09:05:56 -04:00
pipelineInfo . shaders . vertex_src = ShaderSource ( prism : : path ( " sky.vert " ) ) ;
pipelineInfo . shaders . fragment_src = ShaderSource ( prism : : path ( " sky.frag " ) ) ;
2020-08-11 12:07:21 -04:00
pipelineInfo . shader_input . bindings = {
{ 1 , GFXBindingType : : PushConstant }
} ;
pipelineInfo . shader_input . push_constants = {
2021-02-15 17:59:54 -05:00
{ sizeof ( SkyPushConstant ) , 0 }
2020-08-11 12:07:21 -04:00
} ;
pipelineInfo . depth . depth_mode = GFXDepthMode : : LessOrEqual ;
skyPipeline = engine - > get_gfx ( ) - > create_graphics_pipeline ( pipelineInfo ) ;
}
void SceneCapture : : createIrradianceResources ( ) {
GFX * gfx = engine - > get_gfx ( ) ;
GFXTextureCreateInfo textureInfo = { } ;
2021-02-04 08:21:40 -05:00
textureInfo . label = " Irradiance Offscreen " ;
2020-08-11 12:07:21 -04:00
textureInfo . width = irradiance_cubemap_resolution ;
textureInfo . height = irradiance_cubemap_resolution ;
textureInfo . format = GFXPixelFormat : : R8G8B8A8_UNORM ;
2021-05-11 19:16:54 -04:00
textureInfo . usage = GFXTextureUsage : : Attachment | GFXTextureUsage : : TransferSrc ;
2022-03-06 22:45:08 -05:00
2020-08-11 12:07:21 -04:00
irradianceOffscreenTexture = gfx - > create_texture ( textureInfo ) ;
GFXRenderPassCreateInfo renderPassInfo = { } ;
2020-09-23 10:17:24 -04:00
renderPassInfo . label = " Irradiance " ;
2020-08-11 12:07:21 -04:00
renderPassInfo . attachments . push_back ( GFXPixelFormat : : R8G8B8A8_UNORM ) ;
2021-02-15 19:01:17 -05:00
renderPassInfo . will_use_in_shader = true ;
2020-09-23 11:54:59 -04:00
2020-08-11 12:07:21 -04:00
irradianceRenderPass = gfx - > create_render_pass ( renderPassInfo ) ;
2020-09-23 11:54:59 -04:00
GFXFramebufferCreateInfo info ;
info . attachments = { irradianceOffscreenTexture } ;
info . render_pass = irradianceRenderPass ;
2020-08-11 12:07:21 -04:00
2020-09-23 11:54:59 -04:00
irradianceFramebuffer = gfx - > create_framebuffer ( info ) ;
2020-08-11 12:07:21 -04:00
GFXGraphicsPipelineCreateInfo pipelineInfo = { } ;
pipelineInfo . label = " Irradiance Convolution " ;
2021-05-12 09:05:56 -04:00
pipelineInfo . shaders . vertex_src = ShaderSource ( prism : : path ( " irradiance.vert " ) ) ;
pipelineInfo . shaders . fragment_src = ShaderSource ( prism : : path ( " irradiance.frag " ) ) ;
2020-08-11 12:07:21 -04:00
GFXVertexInput input ;
2021-05-12 09:56:44 -04:00
input . stride = sizeof ( prism : : float3 ) ;
2020-08-11 12:07:21 -04:00
pipelineInfo . vertex_input . inputs . push_back ( input ) ;
GFXVertexAttribute positionAttribute ;
positionAttribute . format = GFXVertexFormat : : FLOAT3 ;
pipelineInfo . vertex_input . attributes . push_back ( positionAttribute ) ;
pipelineInfo . shader_input . push_constants = {
{ sizeof ( Matrix4x4 ) , 0 }
} ;
pipelineInfo . shader_input . bindings = {
{ 1 , GFXBindingType : : PushConstant } ,
2022-03-06 22:45:08 -05:00
{ 2 , GFXBindingType : : SampledImage }
2020-08-11 12:07:21 -04:00
} ;
pipelineInfo . render_pass = irradianceRenderPass ;
irradiancePipeline = gfx - > create_graphics_pipeline ( pipelineInfo ) ;
}
void SceneCapture : : createPrefilterResources ( ) {
GFX * gfx = engine - > get_gfx ( ) ;
GFXTextureCreateInfo textureInfo = { } ;
2021-02-04 08:21:40 -05:00
textureInfo . label = " Prefiltered Offscreen " ;
2020-08-11 12:07:21 -04:00
textureInfo . width = scene_cubemap_resolution ;
textureInfo . height = scene_cubemap_resolution ;
textureInfo . format = GFXPixelFormat : : R8G8B8A8_UNORM ;
2021-05-11 19:16:54 -04:00
textureInfo . usage = GFXTextureUsage : : Attachment | GFXTextureUsage : : TransferSrc ;
2022-03-06 22:45:08 -05:00
2020-08-11 12:07:21 -04:00
prefilteredOffscreenTexture = gfx - > create_texture ( textureInfo ) ;
GFXFramebufferCreateInfo info ;
info . attachments = { prefilteredOffscreenTexture } ;
info . render_pass = irradianceRenderPass ;
prefilteredFramebuffer = gfx - > create_framebuffer ( info ) ;
GFXShaderConstant size_constant = { } ;
size_constant . type = GFXShaderConstant : : Type : : Integer ;
size_constant . value = scene_cubemap_resolution ;
GFXGraphicsPipelineCreateInfo pipelineInfo = { } ;
pipelineInfo . label = " Prefilter " ;
2021-05-12 09:05:56 -04:00
pipelineInfo . shaders . vertex_src = ShaderSource ( prism : : path ( " filter.vert " ) ) ;
pipelineInfo . shaders . fragment_src = ShaderSource ( prism : : path ( " filter.frag " ) ) ;
2020-08-11 12:07:21 -04:00
pipelineInfo . shaders . fragment_constants = { size_constant } ;
GFXVertexInput input ;
2021-05-12 09:56:44 -04:00
input . stride = sizeof ( prism : : float3 ) ;
2020-08-11 12:07:21 -04:00
pipelineInfo . vertex_input . inputs . push_back ( input ) ;
GFXVertexAttribute positionAttribute ;
positionAttribute . format = GFXVertexFormat : : FLOAT3 ;
pipelineInfo . vertex_input . attributes . push_back ( positionAttribute ) ;
pipelineInfo . shader_input . push_constants = {
2021-02-15 17:59:54 -05:00
{ sizeof ( FilterPushConstant ) , 0 }
2020-08-11 12:07:21 -04:00
} ;
pipelineInfo . shader_input . bindings = {
{ 1 , GFXBindingType : : PushConstant } ,
2022-03-06 22:45:08 -05:00
{ 2 , GFXBindingType : : SampledImage }
2020-08-11 12:07:21 -04:00
} ;
pipelineInfo . render_pass = irradianceRenderPass ;
prefilterPipeline = gfx - > create_graphics_pipeline ( pipelineInfo ) ;
}