├── UI ├── Font.dds └── dxutcontrols.dds ├── doc └── logo.png ├── data ├── marker.png ├── noise.dds ├── real_static_scene.png ├── skydome │ └── sunny_day.jpg ├── tracked │ ├── plane.mtl │ ├── happy.mtl │ └── plane.obj ├── box.obj ├── camera_parameters.xml ├── cornellbox │ └── cornellbox.mtl ├── demo_gi_mr.xml └── demo_gi.xml ├── cmake ├── cpack │ ├── banner.png │ ├── dialog.png │ ├── license.txt │ └── Package.cmake ├── FindWMF.cmake ├── FindKinectSDK.cmake ├── FindAssimp.cmake ├── FindDXUT.cmake ├── FindOpenCV.cmake └── FindD3D.cmake ├── src ├── dune │ ├── logger.h │ ├── dune.h │ ├── math_tools.h │ ├── common_tools.h │ ├── unicode.h │ ├── exception.h │ ├── camera.cpp │ ├── record_tools.h │ ├── camera.h │ ├── serializer_tools.h │ ├── shader_resource.cpp │ ├── postprocess.cpp │ ├── sdk_mesh.h │ ├── serializer.cpp │ ├── shader_resource.h │ ├── composite_mesh.h │ ├── texture.h │ ├── texture_cache.h │ ├── common_tools.cpp │ ├── gbuffer.h │ ├── render_target.h │ ├── shader_tools.h │ ├── summed_area_tables.h │ ├── serializer.h │ ├── video_gbuffer.h │ ├── light.h │ ├── composite_mesh.cpp │ ├── postprocess.h │ ├── math_tools.cpp │ ├── simple_mesh.h │ ├── cbuffer.h │ ├── render_target.cpp │ ├── mesh.cpp │ ├── gbuffer.cpp │ ├── light.cpp │ ├── tracker.h │ └── kinect_gbuffer.h ├── idc.h ├── common_dxut.h ├── skydome.h ├── ext │ └── dds │ │ └── PlatformHelpers.h ├── pppipe.h ├── common_dxut.cpp └── main_gi.cpp ├── shader ├── pp_dof.hlsl ├── fs_triangle.hlsl ├── pp_film_grain.hlsl ├── overlay.hlsl ├── lpv_normalize.hlsl ├── tonemapping.hlsl ├── common.h ├── pp_fxaa.hlsl ├── pp_bloom.hlsl ├── pp_crt.hlsl ├── pp_ssao.hlsl ├── lpv_tools.hlsl ├── fuse_buffers.hlsl ├── deferred_vct.hlsl ├── postprocessing.hlsl ├── d3d_mesh_skydome.hlsl ├── deferred.hlsl ├── lpv_rendervol.hlsl ├── deferred_dlpv_kinect.hlsl ├── deferred_lpv.hlsl ├── pp_godrays.hlsl ├── pp_blur.hlsl ├── deferred_dvct_kinect.hlsl └── brdf.hlsl └── LICENSE /UI/Font.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/UI/Font.dds -------------------------------------------------------------------------------- /doc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/doc/logo.png -------------------------------------------------------------------------------- /data/marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/data/marker.png -------------------------------------------------------------------------------- /data/noise.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/data/noise.dds -------------------------------------------------------------------------------- /UI/dxutcontrols.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/UI/dxutcontrols.dds -------------------------------------------------------------------------------- /cmake/cpack/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/cmake/cpack/banner.png -------------------------------------------------------------------------------- /cmake/cpack/dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/cmake/cpack/dialog.png -------------------------------------------------------------------------------- /data/real_static_scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/data/real_static_scene.png -------------------------------------------------------------------------------- /data/skydome/sunny_day.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefranke/dirtchamber/HEAD/data/skydome/sunny_day.jpg -------------------------------------------------------------------------------- /cmake/FindWMF.cmake: -------------------------------------------------------------------------------- 1 | # Find WMF 2 | 3 | set(WMF_LIBRARIES "mf.lib;mfplat.lib;mfuuid.lib;Mfreadwrite.lib;shlwapi.lib" CACHE STRING "") 4 | -------------------------------------------------------------------------------- /data/tracked/plane.mtl: -------------------------------------------------------------------------------- 1 | newmtl plane 2 | Ns 92.156863 3 | Ka 0.800000 0.800000 0.800000 4 | Kd 0.8 0.8 0.8 5 | Ks 0 0 0 6 | Ni 1.000000 7 | d 1.000000 8 | illum 2 -------------------------------------------------------------------------------- /data/tracked/happy.mtl: -------------------------------------------------------------------------------- 1 | newmtl virtualobject 2 | Ns 92.156863 3 | Ka 0.000000 0.000000 0.000000 4 | #Kd 1.0 0.71 0.29 5 | Kd 1.0 0.2 0.1 6 | Ks 0.500000 0.500000 0.500000 7 | Ni 1.000000 8 | d 1.000000 9 | illum 2 10 | -------------------------------------------------------------------------------- /data/tracked/plane.obj: -------------------------------------------------------------------------------- 1 | mtllib plane.mtl 2 | 3 | o Plane 4 | v -2.500000 0.000000 -2.500000 5 | v -2.500000 -0.000000 2.500000 6 | v 2.500000 -0.000000 2.500000 7 | v 2.500000 0.000000 -2.500000 8 | 9 | usemtl plane 10 | s off 11 | f 4 3 2 1 12 | -------------------------------------------------------------------------------- /data/box.obj: -------------------------------------------------------------------------------- 1 | # Vertices: 8 2 | # Points: 0 3 | # Lines: 0 4 | # Faces: 6 5 | # Materials: 1 6 | 7 | o 1 8 | 9 | # Vertex list 10 | 11 | v -0.1 -0.1 0.1 12 | v -0.1 -0.1 -0.1 13 | v -0.1 0.1 -0.1 14 | v -0.1 0.1 0.1 15 | v 0.1 -0.1 0.1 16 | v 0.1 -0.1 -0.1 17 | v 0.1 0.1 -0.1 18 | v 0.1 0.1 0.1 19 | 20 | # Point/Line/Face list 21 | 22 | usemtl Default 23 | f 4 3 2 1 24 | f 2 6 5 1 25 | f 3 7 6 2 26 | f 8 7 3 4 27 | f 5 8 4 1 28 | f 6 7 8 5 29 | 30 | # End of file 31 | -------------------------------------------------------------------------------- /data/camera_parameters.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 5 6 |
f
7 | -4.1802327176423804e-001 5.0715244063187526e-001 0. 0. -5.7843597214487474e-001 8 |
9 | 10 | 11 | 3 12 | 3 13 |
f
14 | 15 | 6.5746697944293521e+002 0. 3.1950000000000000e+002 16 | 0. 6.5746697944293521e+002 2.3950000000000000e+002 17 | 0. 0. 1. 18 | 19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /cmake/FindKinectSDK.cmake: -------------------------------------------------------------------------------- 1 | # Find the Microsoft Kinect SDK 2 | 3 | include(FindPackageHandleStandardArgs) 4 | 5 | if (CMAKE_CL_64) 6 | set(LIBPATH "amd64;lib/amd64") 7 | else() 8 | set(LIBPATH "x86;lib/x86") 9 | endif() 10 | 11 | find_library(KinectSDK_LIBRARY 12 | NAMES Kinect10 13 | PATHS $ENV{KINECTSDK10_DIR}/lib 14 | PATH_SUFFIXES ${LIBPATH}) 15 | 16 | find_path(KinectSDK_INCLUDE_DIR 17 | NAMES NuiApi.h 18 | PATHS $ENV{KINECTSDK10_DIR}/inc 19 | PATH_SUFFIXES inc) 20 | 21 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(KinectSDK 22 | DEFAULT_MSG 23 | KinectSDK_LIBRARY 24 | KinectSDK_INCLUDE_DIR) 25 | -------------------------------------------------------------------------------- /src/dune/logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_LOGGER 10 | #define DUNE_LOGGER 11 | 12 | #include "unicode.h" 13 | 14 | namespace dune 15 | { 16 | namespace logger 17 | { 18 | /*! \brief Initialize the logging mechanism for dune. All cout/clog/cerr commands will reroute their output into a file identified by filename. */ 19 | void init(const tstring& filename); 20 | 21 | /*! \brief Show all warnings up to the call of this function collected by the logger with a popup. */ 22 | void show_warnings(); 23 | }; 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /shader/pp_dof.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocessing.hlsl" 8 | 9 | float blur_factor(in float depth) 10 | { 11 | return smoothstep(0, dof_focal_plane, abs(depth)); 12 | } 13 | 14 | float4 ps_depth_of_field(in PS_INPUT inp) : SV_Target 15 | { 16 | float4 blurred = frontbuffer_blurred.Sample(StandardFilter, inp.tex_coord); 17 | float4 full = frontbuffer.Sample(StandardFilter, inp.tex_coord); 18 | float depth = rt_lineardepth.Sample(StandardFilter, inp.tex_coord).x; 19 | 20 | if (!dof_enabled) 21 | return full; 22 | 23 | // TODO: a should be 0 or 1, but gets interpolated in between somewhere 24 | if (full.a < 0.5) 25 | return full; 26 | 27 | return lerp(full, blurred, saturate(blur_factor(depth))); 28 | } 29 | -------------------------------------------------------------------------------- /cmake/FindAssimp.cmake: -------------------------------------------------------------------------------- 1 | # Find the Open Asset Import Library 2 | 3 | include(FindPackageHandleStandardArgs) 4 | 5 | find_path(Assimp_INCLUDE_DIR 6 | NAMES assimp.h) 7 | 8 | find_file(Assimp_BINARY_RELEASE 9 | NAMES assimp.dll 10 | PATHS ${Assimp_INCLUDE_DIR}/../bin) 11 | 12 | find_library(Assimp_LIBRARY_RELEASE 13 | NAMES assimp 14 | PATHS ${Assimp_INCLUDE_DIR}/../lib) 15 | 16 | find_library(Assimp_LIBRARY_DEBUG 17 | NAMES assimpD 18 | PATHS ${Assimp_INCLUDE_DIR}/../lib) 19 | 20 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Assimp 21 | DEFAULT_MSG 22 | Assimp_INCLUDE_DIR 23 | Assimp_LIBRARY_RELEASE 24 | Assimp_LIBRARY_DEBUG) 25 | 26 | if(ASSIMP_FOUND) 27 | set(Assimp_LIBRARY optimized ${Assimp_LIBRARY_RELEASE} debug ${Assimp_LIBRARY_DEBUG} CACHE STRING "") 28 | mark_as_advanced(Assimp_LIBRARY_RELEASE Assimp_LIBRARY_DEBUG Assimp_BINARY_RELEASE) 29 | endif() -------------------------------------------------------------------------------- /shader/fs_triangle.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | struct PS_INPUT 8 | { 9 | float4 position : SV_POSITION; 10 | float2 tex_coord : TEXCOORD0; 11 | float3 view_ray : TEXCOORD1; 12 | }; 13 | 14 | cbuffer camera_vs : register(b0) 15 | { 16 | float4x4 vp : packoffset(c0); 17 | float4x4 vp_inv : packoffset(c4); 18 | float3 camera_pos : packoffset(c8); 19 | float pad0 : packoffset(c8.w); 20 | } 21 | 22 | // Note: could do way easier with SV_VertexID, but stupid HLSL debugger won't have it 23 | PS_INPUT vs_fs_triangle(in float3 pos : POSITION) 24 | { 25 | PS_INPUT outp; 26 | 27 | float4 position = float4(pos, 1.f); 28 | 29 | outp.position = position; 30 | outp.tex_coord = position.xy * float2(0.5, -0.5) + 0.5; 31 | outp.view_ray = mul(vp_inv, position).xyz; 32 | 33 | return outp; 34 | } 35 | -------------------------------------------------------------------------------- /shader/pp_film_grain.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocessing.hlsl" 8 | 9 | float grain(in float2 tc, in float3 value) 10 | { 11 | const float intensity = 0.2; 12 | 13 | float l = luminance(value); 14 | 15 | // add noise 16 | float x = tc.x * tc.y * time * 1000.0; 17 | x = fmod(x, 13.0) * fmod(x, 123.0); 18 | float dx = fmod(x, 0.01); 19 | 20 | float y = clamp(0.1 + dx * 100.0, 0.0, 1.0) * intensity; 21 | float r = 0.5 * intensity - y; 22 | 23 | return 1.0 + r; 24 | } 25 | 26 | float4 ps_film_grain(in PS_INPUT inp) : SV_Target 27 | { 28 | float4 value = frontbuffer.Sample(StandardFilter, inp.tex_coord); 29 | 30 | if (!film_grain_enabled || value.a < 0.5) 31 | return value; 32 | else 33 | { 34 | float g = grain(inp.tex_coord, value.rgb); 35 | float3 ggg = float3(g, g, g); 36 | return float4(value.rgb * ggg, value.a); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /data/cornellbox/cornellbox.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'cornellbox.blend' 2 | # Material Count: 5 3 | newmtl bluewall 4 | Ns 96.078431 5 | Ka 0.000000 0.000000 0.000000 6 | Kd 0.383844 0.505843 0.687189 7 | Ks 0.000000 0.000000 0.000000 8 | Ni 1.000000 9 | d 1.000000 10 | illum 1 11 | 12 | 13 | newmtl whitewall 14 | Ns 96.078431 15 | Ka 0.000000 0.000000 0.000000 16 | Kd 0.800000 0.800000 0.800000 17 | Ks 0.000000 0.000000 0.000000 18 | Ni 1.000000 19 | d 1.000000 20 | illum 1 21 | 22 | 23 | newmtl redwall 24 | Ns 96.078431 25 | Ka 0.000000 0.000000 0.000000 26 | Kd 0.800000 0.265540 0.232816 27 | Ks 0.000000 0.000000 0.000000 28 | Ni 1.000000 29 | d 1.000000 30 | illum 1 31 | 32 | 33 | newmtl yellow_box 34 | Ns 96.078431 35 | Ka 0.000000 0.000000 0.000000 36 | Kd 0.800000 0.800000 0.000000 37 | Ks 0.000000 0.000000 0.000000 38 | Ni 1.000000 39 | d 1.000000 40 | illum 1 41 | 42 | 43 | newmtl whitelight 44 | Ns 96.078431 45 | Ka 0.000000 0.000000 0.000000 46 | Kd 0.800000 0.800000 0.800000 47 | Ks 0.000000 0.000000 0.000000 48 | Ni 1.000000 49 | d 1.000000 50 | illum 1 51 | 52 | 53 | -------------------------------------------------------------------------------- /cmake/cpack/license.txt: -------------------------------------------------------------------------------- 1 | The Dirtchamber 2 | 3 | Copyright (c) 2014 Tobias Alexander Franke 4 | http://www.tobias-franke.eu 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/dune/dune.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * The Dune D3D library - Tobias Alexander Franke 2011 4 | * For copyright and license see LICENSE 5 | * http://www.tobias-franke.eu 6 | * 7 | * "God created Arrakis to train the faithful." 8 | * 9 | */ 10 | 11 | /*! \file */ 12 | 13 | /// Direct3D helper library 14 | namespace dune {} 15 | 16 | #include "assimp_mesh.h" 17 | #include "exception.h" 18 | #include "camera.h" 19 | #include "cbuffer.h" 20 | #include "common_tools.h" 21 | #include "composite_mesh.h" 22 | #include "deferred_renderer.h" 23 | #include "d3d_tools.h" 24 | #include "gbuffer.h" 25 | #include "light.h" 26 | #include "light_propagation_volume.h" 27 | #include "logger.h" 28 | #include "math_tools.h" 29 | #include "mesh.h" 30 | #include "postprocess.h" 31 | #include "record_tools.h" 32 | #include "render_target.h" 33 | #include "sdk_mesh.h" 34 | #include "shader_resource.h" 35 | #include "shader_tools.h" 36 | #include "sparse_voxel_octree.h" 37 | #include "serializer.h" 38 | #include "serializer_tools.h" 39 | #include "texture.h" 40 | #include "texture_cache.h" 41 | #include "unicode.h" 42 | 43 | #include "kinect_gbuffer.h" 44 | #include "tracker.h" 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The Dirtchamber 2 | 3 | Copyright (c) 2014 Tobias Alexander Franke 4 | http://www.tobias-franke.eu 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/dune/math_tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_MATH_TOOLS 10 | #define DUNE_MATH_TOOLS 11 | 12 | #include 13 | 14 | namespace dune 15 | { 16 | const float PI = 3.1415926f; 17 | const float DEG_TO_RAD = PI/180.f; 18 | 19 | /*! \brief Get a number of the Halton sequence. */ 20 | float halton(int index, int base); 21 | 22 | /*! \brief Get a number-pair of the Hammersley sequence. */ 23 | DirectX::XMFLOAT2 hammersley2d(unsigned int i, unsigned int N); 24 | 25 | DirectX::XMMATRIX make_projection(float z_near, float z_far); 26 | 27 | /*! \brief Approximate functions namespace. */ 28 | namespace approx 29 | { 30 | inline double sin(double x); 31 | inline double exp(double x); 32 | } 33 | 34 | /*! \brief Helper functions to convert PBRT matrix operations. */ 35 | namespace pbrt 36 | { 37 | DirectX::XMMATRIX translate(float x, float y, float z); 38 | DirectX::XMMATRIX rotate(float angle, float x, float y, float z); 39 | } 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/dune/common_tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_COMMON_TOOLS 10 | #define DUNE_COMMON_TOOLS 11 | 12 | #include "unicode.h" 13 | #include 14 | 15 | namespace dune 16 | { 17 | /*! \brief Extract a path from a given pattern, e.g. "C:/foo" from "C:/foo/\*.bar". */ 18 | tstring extract_path(const tstring& pattern); 19 | 20 | /*! \brief Returns true if the supplied path p was a relative URI. */ 21 | bool path_is_relative(const tstring& p); 22 | 23 | /*! \brief Returns an absolute path of the current execution directory. */ 24 | tstring absolute_path(); 25 | 26 | /*! \brief Return an absolute URI to a URI relative to the execution directory. Thus function is used in every loader. */ 27 | tstring make_absolute_path(const tstring& relative_filename); 28 | 29 | /*! \brief Return a vector of strings from a given argument string. A default file will be pushed to the vector if args was empty. */ 30 | std::vector files_from_args(const tstring& args, const tstring& default_file = L""); 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/dune/unicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_UNICODE 10 | #define DUNE_UNICODE 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace dune 18 | { 19 | #ifdef UNICODE 20 | 21 | typedef std::wstring tstring; 22 | typedef std::wifstream tifstream; 23 | typedef std::wofstream tofstream; 24 | typedef std::wstringstream tstringstream; 25 | #define tcerr std::wcerr 26 | #define tclog std::wclog 27 | #define tcout std::wcout 28 | 29 | tstring to_tstring(const std::string& str); 30 | std::string to_string(const tstring& str); 31 | 32 | #else 33 | 34 | typedef std::string tstring; 35 | typedef std::ifstream tifstream; 36 | typedef std::ofstream tofstream; 37 | typedef std::stringstream tstringstream; 38 | #define tcerr std::cerr 39 | #define tclog std::clog 40 | #define tcout std::cout 41 | 42 | tstring to_tstring(const std::wstring& str); 43 | std::wstring to_string(const tstring& str); 44 | 45 | #endif 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/dune/exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_EXCEPTION 10 | #define DUNE_EXCEPTION 11 | 12 | #include 13 | 14 | #include "unicode.h" 15 | 16 | namespace dune 17 | { 18 | /*! 19 | * \brief Exception class. 20 | * 21 | * A wrapper class for std::exception which adds support 22 | * for multibyte character messages. Call msg() instead of what() 23 | * to get a tstring of the exception. 24 | */ 25 | class exception : public std::exception 26 | { 27 | protected: 28 | tstring msg_; 29 | 30 | public: 31 | exception(tstring msg) 32 | { 33 | msg_ = msg; 34 | } 35 | 36 | virtual const char* what() const 37 | { 38 | return to_string(msg_).c_str(); 39 | } 40 | 41 | /*! \brief Return exception message as tstring. */ 42 | virtual const tstring& msg() const 43 | { 44 | return msg_; 45 | } 46 | 47 | virtual ~exception() throw() 48 | { 49 | } 50 | }; 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/dune/camera.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "camera.h" 8 | 9 | namespace dune 10 | { 11 | void camera::create(ID3D11Device* device) 12 | { 13 | cb_param_.create(device); 14 | } 15 | 16 | void camera::destroy() 17 | { 18 | cb_param_.destroy(); 19 | } 20 | 21 | void camera::update(float z_far) 22 | { 23 | DirectX::XMMATRIX view = GetViewMatrix(); 24 | DirectX::XMMATRIX proj = GetProjMatrix(); 25 | 26 | DirectX::XMStoreFloat4x4(¶meters().data().vp, view * proj); 27 | 28 | DirectX::XMFLOAT4X4 temp; 29 | DirectX::XMStoreFloat4x4(&temp, view); 30 | 31 | temp._41 = 0; 32 | temp._42 = 0; 33 | temp._43 = 0; 34 | 35 | DirectX::XMMATRIX no_translate = DirectX::XMLoadFloat4x4(&temp); 36 | 37 | DirectX::XMMATRIX vpp = no_translate * proj; 38 | 39 | DirectX::XMStoreFloat4x4(¶meters().data().vp_inv, DirectX::XMMatrixInverse(nullptr, vpp)); 40 | 41 | DirectX::XMStoreFloat3(¶meters().data().camera_pos, GetEyePt()); 42 | parameters().data().z_far = z_far; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /shader/overlay.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | SamplerState ShadowFilter : register(s2); 8 | 9 | struct PS_OVERLAY_INPUT 10 | { 11 | float4 position : SV_POSITION; 12 | float2 tex_coord : TEXCOORD0; 13 | }; 14 | 15 | Texture2D overlay_tex : register(t10); 16 | 17 | float2 calc_tex_coord(in float2 tex_coord) 18 | { 19 | float s = 0.3; 20 | 21 | if (tex_coord.x >= s || 22 | tex_coord.x < 0.0 || 23 | tex_coord.y >= s || 24 | tex_coord.x < 0.0) 25 | discard; 26 | 27 | return tex_coord * (1.0/s); 28 | } 29 | 30 | float4 ps_overlay(in PS_OVERLAY_INPUT In) : SV_Target 31 | { 32 | float2 ntex = calc_tex_coord(In.tex_coord); 33 | 34 | float4 over = abs(overlay_tex.Sample(ShadowFilter, ntex)); 35 | 36 | if (over.x > 1.0 || over.y > 1.0 || over.z > 1.0) 37 | over/=1000; 38 | 39 | return over; 40 | } 41 | 42 | float4 ps_overlay_depth(in PS_OVERLAY_INPUT In) : SV_TARGET 43 | { 44 | float2 ntex = calc_tex_coord(In.tex_coord); 45 | 46 | float d = 1.0 - overlay_tex.Sample(ShadowFilter, ntex).r; 47 | 48 | return float4(d,d,d,1); 49 | } 50 | -------------------------------------------------------------------------------- /data/demo_gi_mr.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0 5 | 0 6 | 1 7 | 8 | 9 | 0 10 | 0 11 | 0 12 | 13 | 14 | 15 | false 16 | 21 17 | 18 | 4 19 | 20 | 21 | 22 | 23 | 0.50256 24 | -0.712761 25 | 0.489291 26 | 27 | 28 | 1.63 29 | 1.63 30 | 1.63 31 | 32 | 33 | -20.9553 34 | 86.8186 35 | 314.676 36 | 37 | 38 | 39 | 40 | true 41 | 0.8 42 | 1.5 43 | 44 | 45 | false 46 | 47 | 48 | 0.74 49 | true 50 | 844 51 | 52 | 53 | false 54 | 0.05 55 | 0.4 56 | 57 | 58 | true 59 | 60 | 61 | true 62 | 63 | 64 | false 65 | 0.0005 66 | 67 | 68 | true 69 | 0.33 70 | 71 | 72 | -------------------------------------------------------------------------------- /cmake/FindDXUT.cmake: -------------------------------------------------------------------------------- 1 | # Find DXUT 2 | 3 | include(FindPackageHandleStandardArgs) 4 | 5 | if (CMAKE_CL_64) 6 | set(DXUTARCH "x64") 7 | else() 8 | set(DXUTARCH "Win32") 9 | endif() 10 | 11 | find_path(DXUT_SDK_PATH 12 | NAMES Core/DXUT.h) 13 | 14 | find_library(DXUT_LIBRARY_RELEASE 15 | NAMES DXUT 16 | PATHS ${DXUT_SDK_PATH}/Core/Bin/*/${DXUTARCH}/Release) 17 | 18 | find_library(DXUT_LIBRARY_DEBUG 19 | NAMES DXUT 20 | PATHS ${DXUT_SDK_PATH}/Core/Bin/*/${DXUTARCH}/Debug) 21 | 22 | find_library(DXUT_Opt_LIBRARY_RELEASE 23 | NAMES DXUTOpt 24 | PATHS ${DXUT_SDK_PATH}/Optional/Bin/*/${DXUTARCH}/Release) 25 | 26 | find_library(DXUT_Opt_LIBRARY_DEBUG 27 | NAMES DXUTOpt 28 | PATHS ${DXUT_SDK_PATH}/Optional/Bin/*/${DXUTARCH}/Debug) 29 | 30 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(DXUT 31 | DEFAULT_MSG 32 | DXUT_LIBRARY_RELEASE 33 | DXUT_Opt_LIBRARY_RELEASE 34 | DXUT_SDK_PATH) 35 | 36 | if(DXUT_FOUND) 37 | mark_as_advanced(DXUT_SDK_PATH DXUT_LIBRARY_RELEAE DXUT_LIBRARY_DEBUG DXUT_Opt_LIBRARY_RELEASE DXUT_Opt_LIBRARY_DEBUG) 38 | set(DXUT_INCLUDE_DIRS 39 | ${DXUT_SDK_PATH}/Core 40 | ${DXUT_SDK_PATH}/Optional 41 | CACHE STRING "") 42 | 43 | set(DXUT_LIBRARIES 44 | optimized ${DXUT_LIBRARY_RELEASE} optimized ${DXUT_Opt_LIBRARY_RELEASE} 45 | debug ${DXUT_LIBRARY_DEBUG} debug ${DXUT_Opt_LIBRARY_DEBUG} 46 | CACHE STRING "") 47 | endif() -------------------------------------------------------------------------------- /shader/lpv_normalize.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | struct PS_LPV_NORMALIZE 8 | { 9 | float4 coeff_r : SV_Target0; 10 | float4 coeff_g : SV_Target1; 11 | float4 coeff_b : SV_Target2; 12 | }; 13 | 14 | struct GS_LPV_PROPAGATE 15 | { 16 | float4 pos : SV_Position; 17 | float3 tex : TEXCOORD; 18 | uint rtindex : SV_RenderTargetArrayIndex; 19 | }; 20 | 21 | Texture2DArray lpv_sh_r : register(t7); 22 | Texture2DArray lpv_sh_g : register(t8); 23 | Texture2DArray lpv_sh_b : register(t9); 24 | Texture2DArray lpv_inject_counter : register(t10); 25 | 26 | PS_LPV_NORMALIZE ps_lpv_normalize(in GS_LPV_PROPAGATE input) 27 | { 28 | PS_LPV_NORMALIZE output; 29 | 30 | int4 lpv_pos = int4(input.pos.x, input.pos.y, input.tex.z, 0); 31 | 32 | float num_lights = abs(lpv_inject_counter.Load(lpv_pos).r); 33 | 34 | float scale = 1.0; 35 | 36 | if (num_lights > 0) 37 | scale = 1.0/num_lights; 38 | 39 | float4 r = lpv_sh_r.Load(lpv_pos); 40 | float4 g = lpv_sh_g.Load(lpv_pos); 41 | float4 b = lpv_sh_b.Load(lpv_pos); 42 | 43 | output.coeff_r = r * scale; 44 | output.coeff_g = g * scale; 45 | output.coeff_b = b * scale; 46 | 47 | return output; 48 | } 49 | -------------------------------------------------------------------------------- /src/idc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see copying.txt 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #pragma once 10 | 11 | /*! \brief IDs for DXUT GUI elements. */ 12 | enum 13 | { 14 | IDC_TARGETS, 15 | IDC_TOGGLE_FULLSCREEN, 16 | IDC_SETTINGS, 17 | IDC_FPS_COUNTER, 18 | 19 | IDC_FLUX_SCALE, 20 | 21 | IDC_LIGHT_DIRECTION, 22 | IDC_LIGHT_POS_X, 23 | IDC_LIGHT_POS_Y, 24 | IDC_LIGHT_POS_Z, 25 | IDC_LIGHT_WARMTH, 26 | 27 | IDC_NUM_VPLS, 28 | IDC_NUM_VPLS_INFO, 29 | IDC_GI_SCALE, 30 | IDC_GI_DEBUG1, 31 | IDC_GI_DEBUG2, 32 | IDC_GI_PARAMETER1, 33 | IDC_GI_PARAMETER2, 34 | IDC_GI_PARAMETER3, 35 | IDC_GI_INFO1, 36 | IDC_GI_INFO2, 37 | IDC_GI_INFO3, 38 | 39 | IDC_SSAO_ENABLED, 40 | IDC_SSAO_SCALE, 41 | 42 | IDC_FXAA_ENABLED, 43 | 44 | IDC_BLOOM_ENABLED, 45 | IDC_BLOOM_SIGMA, 46 | IDC_BLOOM_TRESHOLD, 47 | 48 | IDC_GODRAYS_ENABLED, 49 | IDC_GODRAYS_TAU, 50 | 51 | IDC_DOF_ENABLED, 52 | IDC_DOF_FOCAL_PLANE, 53 | IDC_DOF_COC_SCALE, 54 | 55 | IDC_EXPOSURE_ADAPT, 56 | IDC_EXPOSURE_KEY, 57 | IDC_EXPOSURE_SPEED, 58 | 59 | IDC_TRACK_TRANSX, 60 | IDC_TRACK_TRANSY, 61 | IDC_TRACK_TRANSZ, 62 | IDC_TRACK_SCALE, 63 | IDC_TRACK_ANIMATE, 64 | 65 | IDC_ZFAR, 66 | IDC_ZNEAR, 67 | 68 | IDC_CRT_ENABLED, 69 | IDC_FILM_GRAIN_ENABLED, 70 | 71 | // HAS TO BE LAST! 72 | IDC_DEBUG_INFO, 73 | }; 74 | -------------------------------------------------------------------------------- /src/dune/record_tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2017 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_RECORD_TOOLS 10 | #define DUNE_RECORD_TOOLS 11 | 12 | #include "unicode.h" 13 | 14 | #include 15 | 16 | namespace dune 17 | { 18 | class gbuffer; 19 | } 20 | 21 | namespace dune 22 | { 23 | class video_recorder 24 | { 25 | protected: 26 | UINT width_, 27 | height_, 28 | fps_; 29 | ID3D11Texture2D* ffmpeg_texture_; 30 | FILE* ffmpeg_; 31 | tstring path_; 32 | 33 | public: 34 | video_recorder(); 35 | virtual ~video_recorder(); 36 | 37 | void create(ID3D11Device* device, UINT width, UINT height, UINT fps, const tstring& path = L"../../data"); 38 | void destroy(); 39 | 40 | void start_recording(); 41 | void stop_recording(); 42 | void add_frame(ID3D11DeviceContext* context, ID3D11RenderTargetView* rtv); 43 | void add_frame(ID3D11DeviceContext* context, ID3D11Resource* resource); 44 | }; 45 | 46 | void dump_rtv(ID3D11Device* device, ID3D11DeviceContext* context, UINT width, UINT height, DXGI_FORMAT format, ID3D11RenderTargetView* rtv, const tstring& name); 47 | void dump_gbuffer(ID3D11Device* device, ID3D11DeviceContext* context, gbuffer& g, const tstring& name); 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/dune/camera.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_CAMERA 10 | #define DUNE_CAMERA 11 | 12 | #undef NOMINMAX 13 | #include 14 | #include 15 | 16 | #include "cbuffer.h" 17 | 18 | namespace dune 19 | { 20 | /*! 21 | * \brief A simple perspective camera. 22 | * 23 | * This class derives from CFirstPersonCamera in DXUT and simply handles 24 | * a constant buffer for the camera parameters. 25 | */ 26 | class camera : public CFirstPersonCamera 27 | { 28 | public: 29 | struct param 30 | { 31 | DirectX::XMFLOAT4X4 vp; 32 | DirectX::XMFLOAT4X4 vp_inv; 33 | DirectX::XMFLOAT3 camera_pos; 34 | FLOAT z_far; 35 | }; 36 | 37 | protected: 38 | typedef cbuffer cb_param; 39 | cb_param cb_param_; 40 | 41 | public: 42 | void create(ID3D11Device* device); 43 | void destroy(); 44 | 45 | //!@{ 46 | /*! \brief Return local cbuffer parameters. */ 47 | cb_param& parameters() { return cb_param_; } 48 | const cb_param& parameters() const { return cb_param_; } 49 | //!@} 50 | 51 | /*! \brief Update the constant buffer from the current values of the camera and a supplied Z-far. */ 52 | void update(float z_far); 53 | }; 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/dune/serializer_tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_SERIALIZER_TOOLS 10 | #define DUNE_SERIALIZER_TOOLS 11 | 12 | #include "serializer.h" 13 | 14 | namespace dune 15 | { 16 | class camera; 17 | class directional_light; 18 | class light_propagation_volume; 19 | class sparse_voxel_octree; 20 | } 21 | 22 | namespace dune 23 | { 24 | //!@{ 25 | /*! \brief Read/write camera parameters from/to a serializer. */ 26 | serializer& operator<<(serializer& s, const camera& c); 27 | const serializer& operator>>(const serializer& s, camera& c); 28 | //!@} 29 | 30 | //!@{ 31 | /*! \brief Read/write directional_light parameters from/to a serializer. */ 32 | serializer& operator<<(serializer& s, const directional_light& l); 33 | const serializer& operator>>(const serializer& s, directional_light& l); 34 | //!@} 35 | 36 | //!@{ 37 | /*! \brief Read/write light_propagation_volume parameters from/to a serializer. */ 38 | serializer& operator<<(serializer& s, const light_propagation_volume& lpv); 39 | const serializer& operator>>(const serializer& s, light_propagation_volume& lpv); 40 | //!@} 41 | 42 | //!@{ 43 | /*! \brief Read/write sparse_voxel_octree parameters from/to a serializer. */ 44 | serializer& operator<<(serializer& s, const sparse_voxel_octree& svo); 45 | const serializer& operator>>(const serializer& s, sparse_voxel_octree& svo); 46 | //!@} 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /shader/tonemapping.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #ifndef TONEMAPPING_HLSL 8 | #define TONEMAPPING_HLSL 9 | 10 | #define TONEMAP_GAMMA 1.0 11 | 12 | // Reinhard Tonemapper 13 | float4 tonemap_reinhard(in float3 color) 14 | { 15 | color *= 16; 16 | color = color/(1+color); 17 | float3 ret = pow(color, TONEMAP_GAMMA); // gamma 18 | return float4(ret,1); 19 | } 20 | 21 | // Uncharted 2 Tonemapper 22 | float3 tonemap_uncharted2(in float3 x) 23 | { 24 | float A = 0.15; 25 | float B = 0.50; 26 | float C = 0.10; 27 | float D = 0.20; 28 | float E = 0.02; 29 | float F = 0.30; 30 | 31 | return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; 32 | } 33 | 34 | float3 tonemap_uc2(in float3 color) 35 | { 36 | float W = 11.2; 37 | 38 | color *= 16; // Hardcoded Exposure Adjustment 39 | 40 | float exposure_bias = 2.0f; 41 | float3 curr = tonemap_uncharted2(exposure_bias*color); 42 | 43 | float3 white_scale = 1.0f/tonemap_uncharted2(W); 44 | float3 ccolor = curr*white_scale; 45 | 46 | float3 ret = pow(abs(ccolor), TONEMAP_GAMMA); // gamma 47 | 48 | return ret; 49 | } 50 | 51 | // Filmic tonemapper 52 | float3 tonemap_filmic(in float3 color) 53 | { 54 | color = max(0, color - 0.004f); 55 | color = (color * (6.2f * color + 0.5f)) / (color * (6.2f * color + 1.7f)+ 0.06f); 56 | 57 | // result has 1/2.2 baked in 58 | return pow(color, TONEMAP_GAMMA); 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /data/demo_gi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -0.0624965 5 | 9.99092 6 | -34.3683 7 | 8 | 9 | -0.0624965 10 | 9.99092 11 | -35.3683 12 | 13 | 14 | 15 | false 16 | 17 | 4 18 | 19 | 20 | 3.824 21 | 32 22 | 23 | 21 24 | 25 | 26 | 27 | 0 28 | -1 29 | 0 30 | 31 | 32 | 1 33 | 1 34 | 1 35 | 36 | 37 | 9.53674e-007 38 | 20.0297 39 | -9.53674e-007 40 | 41 | 42 | 43 | 44 | true 45 | 0.5 46 | 0.5 47 | 48 | 49 | false 50 | 51 | 52 | 0.8 53 | false 54 | 2000 55 | 56 | 57 | false 58 | 0.05 59 | 0.4 60 | 61 | 62 | true 63 | 64 | 65 | true 66 | 67 | 68 | false 69 | 0.0005 70 | 71 | 72 | true 73 | 0.1 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/dune/shader_resource.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "shader_resource.h" 8 | 9 | #include "unicode.h" 10 | #include "d3d_tools.h" 11 | 12 | namespace dune 13 | { 14 | void shader_resource::to_vs(ID3D11DeviceContext* context, UINT slot) 15 | { 16 | tcerr << name.c_str() << L" has no to_vs implementation" << std::endl; 17 | } 18 | 19 | void shader_resource::to_gs(ID3D11DeviceContext* context, UINT slot) 20 | { 21 | tcerr << name.c_str() << L" has no to_gs implementation" << std::endl; 22 | } 23 | 24 | void shader_resource::to_ps(ID3D11DeviceContext* context, UINT slot) 25 | { 26 | tcerr << name.c_str() << L" has no to_ps implementation" << std::endl; 27 | } 28 | 29 | void shader_resource::to_cs(ID3D11DeviceContext* context, UINT slot) 30 | { 31 | tcerr << name.c_str() << L" has no to_cs implementation" << std::endl; 32 | } 33 | 34 | void sampler_state::create(ID3D11Device* device, const D3D11_SAMPLER_DESC& desc) 35 | { 36 | assert_hr(device->CreateSamplerState(&desc, &state)); 37 | } 38 | 39 | void sampler_state::destroy() 40 | { 41 | safe_release(state); 42 | } 43 | 44 | void sampler_state::to_vs(ID3D11DeviceContext* context, UINT slot) 45 | { 46 | context->VSSetSamplers(slot, 1, &state); 47 | } 48 | 49 | void sampler_state::to_ps(ID3D11DeviceContext* context, UINT slot) 50 | { 51 | context->PSSetSamplers(slot, 1, &state); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /cmake/cpack/Package.cmake: -------------------------------------------------------------------------------- 1 | set(DIRTCHAMBER_BINARY_DIR "bin/release") 2 | 3 | # install redist package 4 | set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${DIRTCHAMBER_BINARY_DIR}) 5 | include(InstallRequiredSystemLibraries) 6 | 7 | # common config 8 | set(CPACK_PACKAGE_NAME "Dirtchamber") 9 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Dirtchamber") 10 | set(CPACK_PACKAGE_VENDOR "Tobias Alexander Franke") 11 | set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/Readme.md") 12 | set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/Readme.md") 13 | set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_SOURCE_DIR}/Readme.md") 14 | set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/cmake/cpack/license.txt") 15 | set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/doc/logo.png") 16 | set(CPACK_PACKAGE_VERSION_MAJOR "1") 17 | set(CPACK_PACKAGE_VERSION_MINOR "0") 18 | set(CPACK_PACKAGE_VERSION_PATCH "0") 19 | set(CPACK_PACKAGE_INSTALL_DIRECTORY "Dirtchamber") 20 | 21 | set(CPACK_PACKAGE_EXECUTABLES vct "Voxel Cone Tracer" 22 | lpv "Light Propagation Volume Renderer") 23 | 24 | if(OPENCV_FOUND) 25 | set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} 26 | delta_vct "DVCT Viewer" 27 | delta_lpv "DLPV Viewer") 28 | endif() 29 | 30 | # WiX 31 | set(CPACK_WIX_UPGRADE_GUID "00B776BF-6115-489E-85CD-49AF8559A7F8") 32 | set(CPACK_WIX_UI_BANNER "${CMAKE_SOURCE_DIR}/cmake/cpack/banner.png") 33 | set(CPACK_WIX_UI_DIALOG "${CMAKE_SOURCE_DIR}/cmake/cpack/dialog.png") 34 | set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "http://www.tobias-franke.eu/projects/dirtchamber") 35 | set(CPACK_WIX_PROPERTY_ARPHELPLINK "http://tobias-franke.eu/projects/dirtchamber/doc") 36 | 37 | include(CPack) -------------------------------------------------------------------------------- /cmake/FindOpenCV.cmake: -------------------------------------------------------------------------------- 1 | # Find OpenCV 2 | 3 | include(FindPackageHandleStandardArgs) 4 | 5 | find_path(OpenCV_DIR 6 | include/opencv2/opencv.hpp) 7 | 8 | if(OpenCV_DIR) 9 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH};${OpenCV_DIR}) 10 | include(OpenCVConfig-version) 11 | include(OpenCVConfig) 12 | 13 | mark_as_advanced(OpenCV_FOUND) 14 | 15 | find_path(OpenCV_INCLUDE_DIR 16 | NAMES opencv2/opencv.hpp 17 | PATHS ${OpenCV_DIR}/include) 18 | 19 | set(FVER "${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}") 20 | 21 | foreach(lib ${OpenCV_LIB_COMPONENTS}) 22 | string(SUBSTRING ${lib} 7 -1 slib) 23 | 24 | find_library(OpenCV_${slib}_LIBRARY_RELEASE 25 | NAMES opencv_${slib}${FVER} 26 | PATHS ${OpenCV_LIB_DIR}) 27 | 28 | mark_as_advanced(OpenCV_${slib}_LIBRARY_RELEASE) 29 | 30 | find_library(OpenCV_${slib}_LIBRARY_DEBUG 31 | NAMES opencv_${slib}${FVER}d 32 | PATHS ${OpenCV_LIB_DIR}) 33 | 34 | mark_as_advanced(OpenCV_${slib}_LIBRARY_DEBUG) 35 | 36 | set(OpenCV_${slib}_LIBRARY 37 | optimized ${OpenCV_${slib}_LIBRARY_RELEASE} 38 | #debug ${OpenCV_${slib}_LIBRARY_DEBUG} # don't add debug 39 | CACHE FILE "OpenCV ${slib} component") 40 | 41 | mark_as_advanced(OpenCV_${slib}_LIBRARY) 42 | 43 | set(OpenCV_LIBRARIES 44 | ${OpenCV_LIBRARIES};${OpenCV_${slib}_LIBRARY} 45 | CACHE STRING "All OpenCV libraries") 46 | endforeach(lib) 47 | 48 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenCV 49 | DEFAULT_MSG 50 | OpenCV_INCLUDE_DIR 51 | OpenCV_LIBRARIES) 52 | endif() -------------------------------------------------------------------------------- /src/common_dxut.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef COMMON_DXUT 10 | #define COMMON_DXUT 11 | 12 | #include "common_renderer.h" 13 | 14 | #include 15 | 16 | extern dc::common_renderer* the_renderer; 17 | extern ID3D11Device* the_device; 18 | extern ID3D11DeviceContext* the_context; 19 | 20 | namespace dc 21 | { 22 | //!@{ 23 | /*! 24 | * \brief Default implementation of DXUT callbacks common to all render samples. 25 | * 26 | * All render samples share common DXUT function callbacks which use identical code. They all refer to a 27 | * common_renderer pointer the_renderer which represents the main implementation and which must be set when initializing 28 | * the sample 29 | */ 30 | void CALLBACK on_releasing_swap_chain(void* pUserContext); 31 | bool CALLBACK on_modify_device(DXUTDeviceSettings* settings, void* user_context); 32 | HRESULT CALLBACK on_resize(ID3D11Device* pd3dDevice, IDXGISwapChain *pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext); 33 | void CALLBACK on_frame_move(double fTime, float fElapsedTime, void* pUserContext); 34 | LRESULT CALLBACK on_msg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing, void *pUserContext); 35 | void CALLBACK on_destroy_device(void* pUserContext); 36 | void CALLBACK on_keyboard(UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext); 37 | void CALLBACK on_render(ID3D11Device* device, ID3D11DeviceContext* context, double fTime, float fElapsedTime, void* pUserContext); 38 | void CALLBACK on_gui_event(UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext); 39 | //!@} 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/dune/postprocess.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocess.h" 8 | #include "d3d_tools.h" 9 | 10 | namespace dune 11 | { 12 | postprocessor::postprocessor() : 13 | buffers_start_slot_(-1), 14 | fs_triangle_(), 15 | frontbuffer_(), 16 | enabled_(false) 17 | { 18 | } 19 | 20 | void postprocessor::set_shader(ID3D11Device* device, ID3DBlob* input_binary, ID3D11VertexShader* fs_triangle, UINT buffers_start_slot) 21 | { 22 | fs_triangle_.set_shader(device, input_binary, fs_triangle, nullptr); 23 | 24 | buffers_start_slot_ = buffers_start_slot; 25 | 26 | do_set_shader(device); 27 | } 28 | 29 | void postprocessor::create(ID3D11Device* device, DXGI_SURFACE_DESC desc) 30 | { 31 | disable(); 32 | 33 | fs_triangle_.push_back(DirectX::XMFLOAT3(-1.f, -3.f, 1.f)); 34 | fs_triangle_.push_back(DirectX::XMFLOAT3(-1.f, 1.f, 1.f)); 35 | fs_triangle_.push_back(DirectX::XMFLOAT3(3.f, 1.f, 1.f)); 36 | 37 | fs_triangle_.create(device, L"full_screen_tri"); 38 | frontbuffer_.create(device, desc, 0); 39 | do_create(device); 40 | 41 | enable(); 42 | } 43 | 44 | void postprocessor::render(ID3D11DeviceContext* context, ID3D11RenderTargetView* backbuffer) 45 | { 46 | 47 | } 48 | 49 | void postprocessor::destroy() 50 | { 51 | do_destroy(); 52 | frontbuffer_.destroy(); 53 | fs_triangle_.destroy(); 54 | buffers_start_slot_ = -1; 55 | } 56 | 57 | void postprocessor::resize(UINT width, UINT height) 58 | { 59 | frontbuffer_.resize(width, height); 60 | do_resize(width, height); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /cmake/FindD3D.cmake: -------------------------------------------------------------------------------- 1 | # Find Microsoft Direct3D 11 in the Windows SDK 2 | 3 | include(FindPackageHandleStandardArgs) 4 | 5 | # find d3d 6 | if (CMAKE_CL_64) 7 | set(LIBPATH "x64") 8 | else() 9 | set(LIBPATH "x86") 10 | endif() 11 | 12 | set(WINDOWS_SDK_VERSION "8.1" CACHE STRING "Specify Windows SDK version") 13 | 14 | set(DXSDK_HKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v${WINDOWS_SDK_VERSION};InstallationFolder]") 15 | 16 | get_filename_component(DXSDK_DIR ${DXSDK_HKEY} ABSOLUTE) 17 | 18 | set(DXSDK_LIB_DIR "${DXSDK_DIR}/Lib/*/um/${LIBPATH}") 19 | set(DXSDK_INC_DIR "${DXSDK_DIR}/Include") 20 | 21 | find_path(D3D_INCLUDE_DIR 22 | NAMES D3D11.h 23 | PATHS ${DXSDK_INC_DIR}/um 24 | PATH_SUFFIXES Include/um) 25 | 26 | find_path(WINDOWS_SDK_INCLUDE_DIR 27 | NAMES winapifamily.h 28 | PATHS ${DXSDK_INC_DIR}/shared 29 | PATH_SUFFIXES Include/shared) 30 | 31 | find_library(WINDOWS_SDK_USP10_LIBRARY 32 | NAMES USP10 33 | PATHS ${DXSDK_LIB_DIR} 34 | PATH_SUFFIXES ${LIBPATH}) 35 | 36 | find_library(D3D_D3D11_LIBRARY 37 | NAMES d3d11 38 | PATHS ${DXSDK_LIB_DIR} 39 | PATH_SUFFIXES ${LIBPATH}) 40 | 41 | find_library(D3D_D3D10_LIBRARY 42 | NAMES d3d10 43 | PATHS ${DXSDK_LIB_DIR} 44 | PATH_SUFFIXES ${LIBPATH}) 45 | 46 | find_library(D3D_D3D9_LIBRARY 47 | NAMES d3d9 48 | PATHS ${DXSDK_LIB_DIR} 49 | PATH_SUFFIXES ${LIBPATH}) 50 | 51 | find_library(D3D_D3DCompiler_LIBRARY 52 | NAMES d3dcompiler 53 | PATHS ${DXSDK_LIB_DIR} 54 | PATH_SUFFIXES ${LIBPATH}) 55 | 56 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(D3D 57 | DEFAULT_MSG 58 | D3D_INCLUDE_DIR 59 | D3D_D3D11_LIBRARY 60 | D3D_D3D10_LIBRARY 61 | D3D_D3D9_LIBRARY 62 | D3D_D3DCompiler_LIBRARY) 63 | 64 | if(D3D_FOUND) 65 | mark_as_advanced( 66 | D3D_D3D11_LIBRARY 67 | D3D_D3D10_LIBRARY 68 | D3D_D3D9_LIBRARY 69 | D3D_D3DCompiler_LIBRARY) 70 | endif() 71 | -------------------------------------------------------------------------------- /src/dune/sdk_mesh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_SDK_MESH 10 | #define DUNE_SDK_MESH 11 | 12 | #include 13 | 14 | #include "mesh.h" 15 | #include "cbuffer.h" 16 | 17 | class CDXUTSDKMesh; 18 | 19 | namespace dune { 20 | 21 | const D3D11_INPUT_ELEMENT_DESC sdkmesh_vertex_desc[] = 22 | { 23 | { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 24 | { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 25 | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 26 | { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 27 | 0 28 | }; 29 | 30 | /*! \brief A d3d_mesh created with the SDKMesh DXUT loader. */ 31 | class sdk_mesh : public d3d_mesh 32 | { 33 | protected: 34 | std::shared_ptr sdk_mesh_; 35 | 36 | struct cbs_mesh_data_ps 37 | { 38 | DirectX::XMFLOAT4 diffuse_color; 39 | BOOL has_diffuse_tex; 40 | BOOL has_normal_tex; 41 | BOOL has_specular_tex; 42 | BOOL has_alpha_tex; 43 | }; 44 | 45 | struct cbs_mesh_data_vs 46 | { 47 | DirectX::XMFLOAT4X4 world; 48 | }; 49 | 50 | cbuffer cb_mesh_data_ps_; 51 | cbuffer cb_mesh_data_vs_; 52 | 53 | protected: 54 | virtual void reset(); 55 | virtual const D3D11_INPUT_ELEMENT_DESC* vertex_desc() { return sdkmesh_vertex_desc; } 56 | void load_texture(ID3D11Device* device, ID3D11Resource* texture, ID3D11ShaderResourceView* srv, void* context); 57 | 58 | public: 59 | size_t num_vertices(); 60 | size_t num_faces(); 61 | 62 | void create(ID3D11Device* device, LPCTSTR file); 63 | virtual void render(ID3D11DeviceContext* context, DirectX::XMFLOAT4X4* to_clip); 64 | }; 65 | 66 | } 67 | 68 | #endif // SDK_MESH 69 | -------------------------------------------------------------------------------- /src/dune/serializer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "serializer.h" 8 | 9 | #include 10 | #include 11 | 12 | #ifdef UNICODE 13 | typedef boost::property_tree::wptree tptree; 14 | #else 15 | typedef boost::property_tree::ptree tptree; 16 | #endif 17 | 18 | typedef boost::property_tree::xml_writer_settings txml_writer_settings; 19 | 20 | namespace dune 21 | { 22 | namespace detail 23 | { 24 | void to_properties(tstring path, const tptree& pt, std::map& properties) 25 | { 26 | for (const auto& i : pt) 27 | { 28 | tstring subpath = path; 29 | 30 | if (subpath != L"") 31 | subpath += L"."; 32 | 33 | subpath += i.first; 34 | 35 | if (!i.second.empty()) 36 | { 37 | to_properties(subpath, i.second, properties); 38 | } 39 | else 40 | properties[subpath] = i.second.data(); 41 | } 42 | } 43 | 44 | void from_properties(const std::map& properties, tptree& pt) 45 | { 46 | for (const auto& i : properties) 47 | pt.add(i.first, i.second); 48 | } 49 | } 50 | 51 | void serializer::load(const tstring& filename) 52 | { 53 | tptree pt; 54 | boost::property_tree::read_xml(dune::to_string(filename), pt); 55 | 56 | detail::to_properties(L"", pt, properties_); 57 | } 58 | 59 | void serializer::save(const tstring& filename) 60 | { 61 | tptree pt; 62 | detail::from_properties(properties_, pt); 63 | 64 | txml_writer_settings settings(L'\t', 1); 65 | boost::property_tree::write_xml(dune::to_string(filename), pt, std::locale(), settings); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/dune/shader_resource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_SHADER_RESOURCE 10 | #define DUNE_SHADER_RESOURCE 11 | 12 | #include 13 | #include "unicode.h" 14 | 15 | namespace dune 16 | { 17 | /*! 18 | * \brief A shader resource wrapper. 19 | * 20 | * This basic interface defines a resource which can be anything that can be uploaded to a GPU. 21 | * Each shader_resource has an identifying name, a function to destroy it and free all its resources 22 | * and several functions to upload it to a typed shader into a specified register. 23 | */ 24 | struct shader_resource 25 | { 26 | tstring name; 27 | 28 | /*! \brief Upload the shader resource to register slot of a vertex shader. */ 29 | virtual void to_vs(ID3D11DeviceContext* context, UINT slot); 30 | 31 | /*! \brief Upload the shader resource to register slot of a geometry shader. */ 32 | virtual void to_gs(ID3D11DeviceContext* context, UINT slot); 33 | 34 | /*! \brief Upload the shader resource to register slot of a pixel shader. */ 35 | virtual void to_ps(ID3D11DeviceContext* context, UINT slot); 36 | 37 | /*! \brief Upload the shader resource to register slot of a compute shader. */ 38 | virtual void to_cs(ID3D11DeviceContext* context, UINT slot); 39 | 40 | /*! \brief Destroy the shader_resource and free all memory. */ 41 | virtual void destroy() = 0; 42 | }; 43 | 44 | /*! 45 | * \brief A wrapper class for a sampler state. 46 | * 47 | * Manages an ID3D11SamplerState. 48 | */ 49 | struct sampler_state : public shader_resource 50 | { 51 | ID3D11SamplerState* state; 52 | 53 | void create(ID3D11Device* device, const D3D11_SAMPLER_DESC& desc); 54 | void destroy(); 55 | 56 | void to_vs(ID3D11DeviceContext* context, UINT slot); 57 | void to_ps(ID3D11DeviceContext* context, UINT slot); 58 | }; 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /shader/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #ifndef COMMON_SHADER_H 8 | #define COMMON_SHADER_H 9 | 10 | #define SLOT_SVO_PARAMETERS_VS_GS_PS 7 11 | #define SVO_SIZE 256 12 | #define SVO_MIPS 8 13 | 14 | #define SLOT_TEX_SVO_RSM_MU_START 12 15 | #define SLOT_TEX_SVO_RSM_RHO_START 6 16 | 17 | #define SLOT_TEX_SVO_V_START 7 18 | #define SLOT_TEX_SVO_V_DELTA 8 19 | #define SLOT_TEX_SVO_V_MU 9 20 | #define SLOT_TEX_SVO_V_NORMAL 7 21 | 22 | #define SLOT_TEX_LPV_INJECT_RSM_START 6 23 | #define SLOT_TEX_LPV_PROPAGATE_START 7 24 | #define SLOT_TEX_LPV_DEFERRED_START 7 25 | 26 | #define SLOT_TEX_DEFERRED_START 2 27 | #define SLOT_TEX_DEFERRED_KINECT_START 0 28 | 29 | #define SLOT_TEX_DEF_RSM_LINEARDEPTH 6 30 | #define SLOT_TEX_POSTPROCESSING_START 10 31 | #define SLOT_TEX_DIFFUSE 0 32 | #define SLOT_TEX_NORMAL 1 33 | #define SLOT_TEX_SPECULAR 2 34 | #define SLOT_TEX_ALPHA 3 35 | #define SLOT_TEX_OVERLAY 10 36 | #define SLOT_TEX_NOISE 14 37 | 38 | #define SLOT_ONETIME_VS 2 39 | #define SLOT_CAMERA_VS 0 40 | 41 | #define SLOT_ONETIME_PS 6 42 | #define SLOT_CAMERA_PS 1 43 | 44 | #define SLOT_ONETIME_GS 2 45 | #define SLOT_CAMERA_GS 0 46 | 47 | #define SLOT_GI_PARAMETERS_PS 3 48 | #define SLOT_POSTPROCESSING_PS 4 49 | #define SLOT_PER_FRAME_PS 5 50 | #define SLOT_LIGHT_PS 2 51 | #define SLOT_LPV_PARAMETERS_VS_PS 7 52 | 53 | #define USE_LPV 54 | #define GAMMA 2.2 55 | #define SHADOW_BIAS 0.015 56 | #define LPV_SIZE 32 57 | #define M_PI 3.14159265358 58 | #define PCF_SAMPLES 64 59 | #define SSAO_SAMPLES 8 60 | #define MAX_VPLS 512 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /shader/pp_fxaa.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocessing.hlsl" 8 | 9 | #define FXAA_PC 1 10 | #define FXAA_HLSL_4 1 11 | #define FXAA_QUALITY__PRESET 12 12 | #define FXAA_GREEN_AS_LUMA 1 13 | 14 | #include "Fxaa3_11.h" 15 | 16 | float4 ps_fxaa(in PS_INPUT inp) : SV_TARGET 17 | { 18 | if (!fxaa_enabled) 19 | return frontbuffer.Sample(StandardFilter, inp.tex_coord); 20 | 21 | float4 unused = float4(0,0,0,0); 22 | 23 | FxaaFloat2 pos = inp.tex_coord; 24 | FxaaFloat4 fxaaConsolePosPos = unused; 25 | FxaaTex tex = { StandardFilter, frontbuffer }; 26 | FxaaTex fxaaConsole360TexExpBiasNegOne = { StandardFilter, frontbuffer }; 27 | FxaaTex fxaaConsole360TexExpBiasNegTwo = { StandardFilter, frontbuffer }; 28 | 29 | float w,h; 30 | frontbuffer.GetDimensions(w,h); 31 | 32 | FxaaFloat2 fxaaQualityRcpFrame = float2(1.0/w, 1.0/h); 33 | 34 | FxaaFloat4 fxaaConsoleRcpFrameOpt = unused; 35 | FxaaFloat4 fxaaConsoleRcpFrameOpt2 = unused; 36 | FxaaFloat4 fxaaConsole360RcpFrameOpt2 = unused; 37 | FxaaFloat fxaaQualitySubpix = 0.75; 38 | FxaaFloat fxaaQualityEdgeThreshold = 0.166; 39 | FxaaFloat fxaaQualityEdgeThresholdMin = 0.0833; 40 | FxaaFloat fxaaConsoleEdgeSharpness = 8.0; 41 | FxaaFloat fxaaConsoleEdgeThreshold = 0.125; 42 | FxaaFloat fxaaConsoleEdgeThresholdMin = 0.05; 43 | FxaaFloat4 fxaaConsole360ConstDir = unused; 44 | 45 | return FxaaPixelShader( 46 | pos, 47 | fxaaConsolePosPos, 48 | tex, 49 | fxaaConsole360TexExpBiasNegOne, 50 | fxaaConsole360TexExpBiasNegTwo, 51 | fxaaQualityRcpFrame, 52 | fxaaConsoleRcpFrameOpt, 53 | fxaaConsoleRcpFrameOpt2, 54 | fxaaConsole360RcpFrameOpt2, 55 | fxaaQualitySubpix, 56 | fxaaQualityEdgeThreshold, 57 | fxaaQualityEdgeThresholdMin, 58 | fxaaConsoleEdgeSharpness, 59 | fxaaConsoleEdgeThreshold, 60 | fxaaConsoleEdgeThresholdMin, 61 | fxaaConsole360ConstDir 62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /src/dune/composite_mesh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_COMPOSITE_MESH 10 | #define DUNE_COMPOSITE_MESH 11 | 12 | #include "mesh.h" 13 | 14 | #include 15 | #include 16 | 17 | namespace dune 18 | { 19 | /*! 20 | * \brief A mesh composed from other meshes. 21 | * 22 | * A composite_mesh object is simply a collection of other d3d_mesh objects. 23 | * It can be used to group up objects together or simply have one representative 24 | * for many loaded meshes. 25 | * 26 | * This is not a scenegraph node! 27 | */ 28 | class composite_mesh : public d3d_mesh 29 | { 30 | protected: 31 | typedef std::shared_ptr mesh_ptr; 32 | std::vector meshes_; 33 | 34 | public: 35 | size_t num_vertices(); 36 | size_t num_faces(); 37 | 38 | virtual void set_world(const DirectX::XMFLOAT4X4& world); 39 | 40 | void set_shader(ID3D11Device* device, ID3DBlob* input_binary, ID3D11VertexShader* vs, ID3D11PixelShader* ps); 41 | 42 | virtual void set_shader_slots(INT diffuse_tex = -1, INT specular_tex = -1, INT normal_tex = -1); 43 | 44 | void create(ID3D11Device* device, const tstring& file); 45 | 46 | /*! 47 | * \brief Create a composite_mesh from a filename pattern. 48 | * 49 | * Calling this function will search a directory for a pattern and load all 50 | * hits into as separate meshes to group them up in a composite_mesh. 51 | * 52 | * \param device The Direct3D device. 53 | * \param pattern A string representing a file pattern, e.g. C:/models/\*.obj. 54 | * 55 | */ 56 | void create_from_dir(ID3D11Device* device, const tstring& pattern); 57 | 58 | /*! \brief Add a new mesh m to the composite_mesh. */ 59 | void push_back(mesh_ptr& m); 60 | void render(ID3D11DeviceContext* context, DirectX::XMFLOAT4X4* to_clip = nullptr); 61 | 62 | /*! \brief Returns the mesh at index i. */ 63 | mesh_ptr operator[](size_t i); 64 | 65 | /*! \brief Returns the number of submeshes. */ 66 | inline size_t size() { return meshes_.size(); } 67 | 68 | virtual void destroy(); 69 | }; 70 | } 71 | 72 | #endif // COMPOSITE_MESH 73 | -------------------------------------------------------------------------------- /shader/pp_bloom.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocessing.hlsl" 8 | #include "tonemapping.hlsl" 9 | 10 | float average_luminance() 11 | { 12 | return rt_adapted_luminance.Load(uint3(0,0,0)).x; 13 | } 14 | 15 | float ps_adapt_exposure(in PS_INPUT inp) : SV_Target 16 | { 17 | //get medium brightness of scene 18 | float curr_lum = luminance(frontbuffer.SampleLevel(StandardFilter, float2(0.5, 0.5), 10).rgb); 19 | float last_lum = rt_adapted_luminance.Load(uint3(0, 0, 0)).x; 20 | 21 | float v = last_lum + (curr_lum - last_lum) * (1 - exp(-time_delta * exposure_speed)); 22 | 23 | if (!exposure_adapt) 24 | v = 0.5; 25 | 26 | return v; 27 | } 28 | 29 | // Determines the color based on exposure settings 30 | float3 calc_exposed_color(in float3 color, in float average_lum, in float threshold, out float exposure) 31 | { 32 | // Use geometric mean 33 | average_lum = max(average_lum, 0.001f); 34 | float keyValue = exposure_key; 35 | float linear_exposure = (exposure_key / average_lum); 36 | exposure = log2(max(linear_exposure, 0.0001f)); 37 | exposure -= threshold; 38 | return exp2(exposure) * color; 39 | } 40 | 41 | // Applies exposure and tone mapping to the specific color, and applies 42 | // the threshold to the exposure value. 43 | float3 tone_map(in float4 color, in float average_lum, in float threshold, out float exposure) 44 | { 45 | color.rgb = calc_exposed_color(color.rgb, average_lum, threshold, exposure); 46 | color.rgb = tonemap_uc2(color.rgb); 47 | 48 | return color.rgb; 49 | } 50 | 51 | float4 ps_bloom(in PS_INPUT inp) : SV_TARGET 52 | { 53 | float4 color = frontbuffer.SampleLevel(StandardFilter, inp.tex_coord, 0); 54 | float avg_lum = average_luminance(); 55 | 56 | float exposure = 0; 57 | color.rgb = tone_map(color.rgba, avg_lum, 0, exposure); 58 | 59 | float4 bloom = bloom_buffer.Sample(ShadowFilter, inp.tex_coord); 60 | 61 | if (bloom_enabled) 62 | return float4((color + bloom).rgb, color.a); 63 | else 64 | return color; 65 | } 66 | 67 | float4 ps_bloom_treshold(in PS_INPUT inp) : SV_TARGET 68 | { 69 | float4 color = frontbuffer.Sample(StandardFilter, inp.tex_coord); 70 | 71 | float avg_lum = average_luminance(); 72 | float exposure = 0; 73 | color.rgb = calc_exposed_color(color.rgb, avg_lum, bloom_treshold, exposure); 74 | 75 | if (dot(color.rgb, 0.333f) <= 0.01f) 76 | color = 0.f; 77 | 78 | return float4(color.rgb, 1); 79 | } 80 | -------------------------------------------------------------------------------- /shader/pp_crt.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | // Reference: https://www.shadertoy.com/view/MsXGD4 8 | 9 | #include "postprocessing.hlsl" 10 | 11 | float4 scanline(in float2 coord, in float4 screen) 12 | { 13 | screen.rgb -= sin((coord.y * 0.7 - (time * 19.0))) * 0.002; 14 | screen.rgb -= sin((coord.y * 0.02 + (time * 6.0))) * 0.005; 15 | return screen; 16 | } 17 | 18 | float4 texture_chromatic_distort(in float2 coord) 19 | { 20 | float4 frag; 21 | frag.r = frontbuffer.SampleLevel(StandardFilter, float2(coord.x - 0.003 * sin(time), coord.y), 0.0).r; 22 | frag.g = frontbuffer.SampleLevel(StandardFilter, float2(coord.x, coord.y), 0.0).g; 23 | frag.b = frontbuffer.SampleLevel(StandardFilter, float2(coord.x + 0.003 * sin(time), coord.y), 0.0).b; 24 | frag.a = frontbuffer.SampleLevel(StandardFilter, float2(coord.x, coord.y), 0.0).a; 25 | return frag; 26 | } 27 | 28 | float2 crt_distort(in float2 coord, in float bend) 29 | { 30 | // put in symmetrical coords 31 | coord = (coord - 0.5) * 2.0; 32 | 33 | // deform coords 34 | coord.x *= 1.0 + pow(abs(abs(coord.y) / bend), 2.0); 35 | coord.y *= 1.0 + pow(abs(abs(coord.x) / bend), 2.0); 36 | 37 | // transform back to 0.0 - 1.0 space 38 | coord = (coord / 2.0) + 0.5; 39 | 40 | return coord; 41 | } 42 | 43 | float vignette(in float2 uv) 44 | { 45 | uv = (uv - 0.5) * 0.98; 46 | return clamp(pow(abs(cos(uv.x * M_PI)), 1.2) * pow(abs(cos(uv.y * M_PI)), 1.2) * 50.0, 0.0, 1.0); 47 | } 48 | 49 | float noise(in float2 uv) 50 | { 51 | float a = noise_tex.SampleLevel(StandardFilter, float3(uv + time*6.0, 0.0), 0.0).r; 52 | float b = noise_tex.SampleLevel(StandardFilter, float3(uv + time*4.0, 0.5), 0.0).r; 53 | 54 | return clamp(a + b, 0.94, 1.0); 55 | } 56 | 57 | float4 ps_crt(in PS_INPUT inp) : SV_Target 58 | { 59 | if (!crt_enabled) 60 | return frontbuffer.Sample(StandardFilter, inp.tex_coord); 61 | 62 | float2 uv = inp.tex_coord.xy; 63 | float2 crt_uv = crt_distort(uv, 3.2); 64 | 65 | float4 color = texture_chromatic_distort(crt_uv); 66 | 67 | float2 dim; 68 | frontbuffer.GetDimensions(dim.x, dim.y); 69 | 70 | float2 screen_space = crt_uv * dim; 71 | color = scanline(screen_space, color); 72 | 73 | color = lerp(vignette(crt_uv) * color, color, 0.2); 74 | 75 | float n = noise(crt_uv*2); 76 | 77 | if (any(clamp(crt_uv, float2(0,0), float2(1,1)) - crt_uv)) 78 | return float4(0,0,0,1); 79 | else 80 | return color * n; 81 | } 82 | -------------------------------------------------------------------------------- /shader/pp_ssao.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocessing.hlsl" 8 | 9 | float ssao(in PS_INPUT inp) 10 | { 11 | float2 tc = inp.tex_coord; 12 | float depth = rt_lineardepth.Sample(StandardFilter, tc).r; 13 | float3 pos = camera_pos + (normalize(inp.view_ray.xyz) * depth); 14 | float3 normal = rt_normals.Sample(StandardFilter, tc).rgb * 2.0 - 1.0; 15 | 16 | if (ssao_scale == 0.0) 17 | return 1.0; 18 | 19 | float w, h; 20 | rt_lineardepth.GetDimensions(w, h); 21 | 22 | const float2 scale = float2(1.0/w, 1.0/h); 23 | 24 | float ret = 0.0; 25 | 26 | float2 samples[24] = { 27 | float2(1,1), 28 | float2(-1,1), 29 | float2(1,-1), 30 | float2(-1,-1), 31 | float2(1,0), 32 | float2(-1,0), 33 | float2(0,-1), 34 | float2(0,-1), 35 | 36 | float2(2, 1), 37 | float2(-2, 1), 38 | float2(2, -1), 39 | float2(-2, -1), 40 | float2(2, 0), 41 | float2(-2, 0), 42 | float2(0, -2), 43 | float2(0, -2), 44 | 45 | float2(1, 2), 46 | float2(-1, 2), 47 | float2(1, -2), 48 | float2(-1, -2), 49 | 50 | float2(2, 2), 51 | float2(-2, 2), 52 | float2(2, -2), 53 | float2(-2, -2), 54 | }; 55 | 56 | [unroll] 57 | for (int i = 0; i < 24; ++i) 58 | { 59 | // TODO: Needs distance scaling 60 | float2 ntc = tc + samples[i] * scale * 2 * abs(simple_noise(tc)); 61 | 62 | float4 occvr = to_ray(ntc, vp_inv); 63 | 64 | float occdepth = rt_lineardepth.Sample(StandardFilter, ntc.xy).r; 65 | 66 | // bilateral filter 67 | if (abs(occdepth - depth) > 0.1) 68 | continue; 69 | 70 | float3 occnorm = rt_normals.Sample(StandardFilter, ntc.xy).xyz * 2.0 - 1.0; 71 | float3 occpos = camera_pos + (normalize(occvr).xyz * occdepth); 72 | 73 | float3 diff = occpos - pos; 74 | float3 v = normalize(diff); 75 | float ddiff = length(diff); 76 | 77 | if (dot(occnorm, normal) < 0.95) 78 | ret += ssao_scale * saturate(dot(normal, v)) * (1.0 / (1.0 + ddiff)); 79 | } 80 | 81 | return 1.0 - saturate(ret/SSAO_SAMPLES); 82 | } 83 | 84 | float4 ps_ssao(in PS_INPUT inp) : SV_TARGET 85 | { 86 | float4 color = frontbuffer.Sample(StandardFilter, inp.tex_coord, 0); 87 | 88 | if (ssao_enabled && color.a > 0) 89 | return color * ssao(inp); 90 | else 91 | return color; 92 | } 93 | -------------------------------------------------------------------------------- /shader/lpv_tools.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #ifndef LPV_TOOLS_HLSL 8 | #define LPV_TOOLS_HLSL 9 | 10 | #include "common.h" 11 | 12 | SamplerState LPVFilter : register(s1); 13 | 14 | Texture2DArray lpv_r : register(t7); 15 | Texture2DArray lpv_g : register(t8); 16 | Texture2DArray lpv_b : register(t9); 17 | 18 | cbuffer lpv_parameters : register(b7) 19 | { 20 | float4x4 world_to_lpv : packoffset(c0); 21 | uint lpv_size : packoffset(c4.x); 22 | float3 pad : packoffset(c4.y); 23 | } 24 | 25 | void lpv_trilinear_lookup(in float3 lpv_pos, inout float4 sh_r_val, inout float4 sh_g_val, inout float4 sh_b_val, 26 | in Texture2DArray lpvr, in Texture2DArray lpvg, in Texture2DArray lpvb, in int lpv_size, in SamplerState LPVFilter) 27 | { 28 | float3 tc = float3(lpv_pos.x, lpv_pos.y, lpv_pos.z * lpv_size); 29 | 30 | int zl = floor(tc.z); 31 | int zh = min(zl + 1, lpv_size - 1); 32 | 33 | float inv_zh = tc.z - zl; 34 | float inv_zl = 1.0f - inv_zh; 35 | 36 | float3 tc_l = float3(tc.x, tc.y, zl); 37 | float3 tc_h = float3(tc.x, tc.y, zh); 38 | 39 | sh_r_val = inv_zl * lpvr.SampleLevel(LPVFilter, tc_l, 0) + inv_zh * lpvr.SampleLevel(LPVFilter, tc_h, 0); 40 | sh_g_val = inv_zl * lpvg.SampleLevel(LPVFilter, tc_l, 0) + inv_zh * lpvg.SampleLevel(LPVFilter, tc_h, 0); 41 | sh_b_val = inv_zl * lpvb.SampleLevel(LPVFilter, tc_l, 0) + inv_zh * lpvb.SampleLevel(LPVFilter, tc_h, 0); 42 | } 43 | 44 | float4 gi_from_lpv(in float3 pos, in float3 N) 45 | { 46 | float4 indirect = float4(0.0, 0.0, 0.0, 1.0); 47 | 48 | float4 normal_sh = sh_clamped_cos_coeff(-N); 49 | 50 | float4 shcoeff_red = float4(0,0,0,0); 51 | float4 shcoeff_green = float4(0,0,0,0); 52 | float4 shcoeff_blue = float4(0,0,0,0); 53 | 54 | float3 lpv_pos = mul(world_to_lpv, float4(pos, 1)).xyz; 55 | float3 lpv_normal = normalize(mul(world_to_lpv, float4(N, 0))).xyz; 56 | 57 | // bias 58 | lpv_pos.z -= 0.5/LPV_SIZE; 59 | 60 | // ignore stuff outside the volume 61 | if (lpv_pos.x < 0 || lpv_pos.x > 1 || 62 | lpv_pos.y < 0 || lpv_pos.y > 1 || 63 | lpv_pos.z < 0 || lpv_pos.z > 1) 64 | return 0.f; 65 | 66 | lpv_trilinear_lookup(lpv_pos, shcoeff_red, shcoeff_green, shcoeff_blue, lpv_r, lpv_g, lpv_b, LPV_SIZE, LPVFilter); 67 | 68 | indirect.r = dot(shcoeff_red, normal_sh)/M_PI; 69 | indirect.g = dot(shcoeff_green, normal_sh)/M_PI; 70 | indirect.b = dot(shcoeff_blue, normal_sh)/M_PI; 71 | 72 | return indirect; 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/dune/texture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_TEXTURE 10 | #define DUNE_TEXTURE 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "shader_resource.h" 17 | 18 | namespace dune 19 | { 20 | /*! 21 | * \brief Wrapper for a Direct3D texture object 22 | * 23 | * Wraps up a Direct3D texture object with its own shader resource view. 24 | */ 25 | class texture : public shader_resource 26 | { 27 | protected: 28 | ID3D11ShaderResourceView* srview_; 29 | ID3D11Texture2D* texture_; 30 | DirectX::XMFLOAT2 size_; 31 | 32 | protected: 33 | virtual void do_create(ID3D11Device* device, D3D11_TEXTURE2D_DESC desc, D3D11_SUBRESOURCE_DATA* subresource); 34 | 35 | public: 36 | texture(); 37 | virtual ~texture() {} 38 | 39 | /* \brief Returns the shader resource view (SRV). */ 40 | ID3D11ShaderResourceView* const srv() const { return srview_; } 41 | 42 | void to_vs(ID3D11DeviceContext* context, UINT slot); 43 | void to_ps(ID3D11DeviceContext* context, UINT slot); 44 | 45 | //!@{ 46 | /*! \brief Create an empty texture from given descriptor, other resource or single parameters. */ 47 | void create(ID3D11Device* device, D3D11_TEXTURE2D_DESC desc, D3D11_SUBRESOURCE_DATA* subresource = nullptr); 48 | void create(ID3D11Device* device, const DXGI_SURFACE_DESC& desc, UINT num_mipmaps = 1); 49 | void create(ID3D11Device* device, UINT width, UINT height, DXGI_FORMAT format, const DXGI_SAMPLE_DESC& msaa, UINT num_mipmaps = 1); 50 | //!@} 51 | 52 | virtual void destroy(); 53 | 54 | /*! 55 | * \brief Map the texture to a pointer. 56 | * 57 | * Maps the texture to a pointer. If the texture is CPU accessible, this pointer can be read from and/or written to. 58 | * 59 | * \param context A Direct3D context. 60 | * \return A pointer to the texture buffer. 61 | */ 62 | void* map(ID3D11DeviceContext* context); 63 | 64 | /* \brief Unmap a previously mapped texture. */ 65 | void unmap(ID3D11DeviceContext* context); 66 | 67 | /* \brief Returns the size of the texture as float2(width, height). */ 68 | DirectX::XMFLOAT2 size() const; 69 | 70 | /* \brief Returns a texture descriptor of the texture. */ 71 | D3D11_TEXTURE2D_DESC desc() const; 72 | 73 | /* \brief Returns a pointer to the actual resource behind the texture. */ 74 | ID3D11Texture2D* resource() const; 75 | }; 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /shader/fuse_buffers.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common.h" 8 | 9 | SamplerState StandardFilter : register(s0); 10 | 11 | struct PS_INPUT 12 | { 13 | float4 position : SV_POSITION; 14 | float2 tex_coord : TEXCOORD0; 15 | float3 view_ray : TEXCOORD1; 16 | }; 17 | 18 | struct PS_OUTPUT 19 | { 20 | float4 color : SV_Target0; 21 | float4 specular : SV_Target1; 22 | float4 normal : SV_Target2; 23 | float2 ldepth : SV_Target3; 24 | }; 25 | 26 | Texture2D rt_color : register(t0); 27 | Texture2D rt_specular : register(t1); 28 | Texture2D rt_normal : register(t2); 29 | Texture2D rt_lineardepth : register(t3); 30 | Texture2D rt_kinect_color : register(t4); 31 | Texture2D rt_kinect_depth : register(t5); 32 | Texture2D rt_tracked_scene : register(t10); 33 | 34 | cbuffer gi_parameters_ps : register(b3) 35 | { 36 | float vpl_scale : packoffset(c0.x); 37 | float lpv_flux_amplifier : packoffset(c0.y); 38 | uint num_vpls : packoffset(c0.z); 39 | bool debug_gi : packoffset(c0.w); 40 | float4x4 world_to_lpv : packoffset(c1); 41 | } 42 | 43 | PS_OUTPUT ps_fuse_buffers(in PS_INPUT inp) : SV_TARGET 44 | { 45 | PS_OUTPUT output; 46 | 47 | float2 vd = rt_lineardepth.Sample(StandardFilter, inp.tex_coord).rg; 48 | float virtual_depth = vd.r; 49 | 50 | float real_depth = rt_kinect_depth.Sample(StandardFilter, inp.tex_coord).r * 4 - 7; 51 | float2 rd = float2(real_depth, real_depth * real_depth); 52 | 53 | float4 virtual_color = rt_color.Sample(StandardFilter, inp.tex_coord); 54 | float4 real_color = rt_kinect_color.Sample(StandardFilter, inp.tex_coord); 55 | 56 | real_color = pow(real_color, GAMMA); 57 | 58 | output.color = real_color; 59 | 60 | #if 0 61 | output.ldepth = rd; 62 | output.normal = float4(0.0,1.0,0.0,0); 63 | #else 64 | output.ldepth = float2(0,0); 65 | output.normal = float4(0.0,0.0,0.0,0); 66 | #endif 67 | 68 | output.specular = float4(0,0,0,0); 69 | 70 | if (virtual_depth > 0) 71 | { 72 | float3 tracked = rt_tracked_scene.Sample(StandardFilter, inp.tex_coord).rgb; 73 | 74 | if (length(tracked) != 0 || debug_gi) 75 | output.color = real_color; 76 | else 77 | output.color = virtual_color; 78 | 79 | output.normal = rt_normal.Sample(StandardFilter, inp.tex_coord); 80 | 81 | output.ldepth = vd; 82 | output.specular = rt_specular.Sample(StandardFilter, inp.tex_coord); 83 | } 84 | 85 | return output; 86 | } 87 | -------------------------------------------------------------------------------- /src/dune/texture_cache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_TEXTURE_CACHE 10 | #define DUNE_TEXTURE_CACHE 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include "unicode.h" 18 | 19 | namespace dune 20 | { 21 | class texture; 22 | } 23 | 24 | namespace dune 25 | { 26 | /*! 27 | * \brief A texture cache. 28 | * 29 | * The texture_cache is a single instance which keeps track of all currently loaded texture resources. 30 | * By requesting texture objects from this class, multiple requests of the same file will be cached 31 | * instead of creating additional textures in memory. 32 | */ 33 | class texture_cache : boost::noncopyable 34 | { 35 | protected: 36 | static std::map texture_cache_; 37 | 38 | texture_cache() {}; 39 | 40 | public: 41 | /*! \brief The static instance of the texture_cache. */ 42 | static texture_cache& i(); 43 | 44 | /*! 45 | * \brief Add a new texture to the cache. 46 | * 47 | * Load a new texture and add it to the cache. If the texture has already been loaded, nothing happens. 48 | * 49 | * \param device The Direct3D device. 50 | * \param filename A string of the filename on the disk. 51 | */ 52 | void add_texture(ID3D11Device* device, const tstring& filename); 53 | 54 | /* 55 | * \ brief Request a shader resource view for a texture. 56 | * 57 | * Request a shader resource view for a texture identified by a filename. If the texture hasn't been loaded yet, 58 | * it will be automatically added to the cache. Otherwise, the already cached texture's SRV will be returned. 59 | * 60 | * \param filename A string of the filename on the disk. 61 | * \return An SRV. 62 | */ 63 | ID3D11ShaderResourceView* srv(const tstring& filename) const; 64 | 65 | void generate_mips(ID3D11DeviceContext* context); 66 | 67 | /*! \brief Destroy the texture_cache and free all resources. */ 68 | void destroy(); 69 | }; 70 | 71 | /*! 72 | * \brief The principal function to load a texture. 73 | * 74 | * This function is used to load textures of any type. The correct loader will be deduced from the filename. Optionally, 75 | * a shader resource view can be directly retrieved for the file. This function will automatically populate the texture_cache 76 | * instance. 77 | * 78 | * \param device The Direct3D device 79 | * \param filename A string of the filename on the disk 80 | * \param srv An optional pointer to an empty SRV pointer. If this is nullptr, the parameter is ignored. 81 | */ 82 | void load_texture(ID3D11Device* device, const tstring& filename, ID3D11ShaderResourceView** srv = nullptr); 83 | 84 | void load_texture(ID3D11Device* device, const tstring& filename, texture& t); 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /shader/deferred_vct.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "deferred.hlsl" 8 | #include "vct_tools.hlsl" 9 | 10 | cbuffer gi_parameters_ps : register(b3) 11 | { 12 | float gi_scale : packoffset(c0.x); 13 | float glossiness : packoffset(c0.y); 14 | uint num_vpls : packoffset(c0.z); 15 | bool debug_gi : packoffset(c0.w); 16 | } 17 | 18 | #ifndef DVCT 19 | float3 gi_from_vct(in float2 tc, in float3 P, in float3 N, in float3 V, in float3 diffuse, in float3 specular, in float roughness) 20 | { 21 | roughness += glossiness / 10.f; 22 | return diffuse_from_vct(tc, P, N, V).rgb * diffuse + 23 | specular_from_vct(P, N, V, roughness).rgb * specular; 24 | } 25 | 26 | float4 ps_vct(in PS_INPUT inp) : SV_Target 27 | { 28 | gbuffer gb = unpack_gbuffer(inp.tex_coord); 29 | 30 | // normal 31 | float3 N = normalize(gb.normal.xyz * 2.0 - 1.0); 32 | 33 | // view 34 | float3 V = -normalize(inp.view_ray.xyz); 35 | 36 | // DEBUG VOLUME 37 | #if 0 38 | float3 vP = mul(world_to_svo, float4(camera_pos, 1.0)).xyz; 39 | float3 vV = mul(world_to_svo, float4(-V, 0.0)).xyz; 40 | return trace_cone(vP, normalize(vV), 0.001, 50, 0.1); 41 | #endif 42 | 43 | // if shading_mode == 2, the color is actually emissive 44 | if (gb.shading_mode == 2) 45 | return gb.diffuse_albedo; 46 | 47 | // ignore parts with no normals 48 | if (dot(gb.normal, gb.normal) == 0) 49 | return gb.diffuse_albedo * float4(main_light.color.rgb, 1.0); 50 | 51 | // reconstruct position in world space 52 | float3 P = camera_pos + (-V * gb.depth); 53 | 54 | // light 55 | float3 Ll = main_light.position.xyz - P; 56 | float3 L = normalize(Ll); 57 | 58 | // lambert 59 | float NoL = saturate(dot(N, L)); 60 | 61 | // have no gloss maps, roughness is simply inverse spec color/smoothness 62 | float roughness = 1.0 - gb.specular_albedo.r; 63 | 64 | // calculate power of light and scale it to get the scene adequately lit 65 | float power = 100 * length(scene_dim_max - scene_dim_min); 66 | 67 | // calculate irradiance 68 | float3 Li = M_PI * (power * get_spotlight(L, N) * main_light.color.rgb) / pow(length(Ll),2); 69 | 70 | // shadow attenuation factor 71 | #if 1 72 | float attenuation = shadow_attenuation(P, Ll, rt_rsm_lineardepth, 0.0, 0.0); 73 | #else 74 | float attenuation = shadow_cone(P, L, N, 0.00002); 75 | #endif 76 | 77 | // brdf 78 | float3 f = brdf(L, V, N, gb.diffuse_albedo.rgb, gb.specular_albedo.rgb, roughness); 79 | 80 | // emissive 81 | float3 T0 = 0; 82 | 83 | // direct 84 | float3 T1 = f * Li * attenuation * NoL; 85 | 86 | // indirect 87 | float3 T2 = gi_from_vct(inp.tex_coord.xy, P, N, V, gb.diffuse_albedo.rgb, gb.specular_albedo.rgb, roughness); 88 | 89 | T2 *= gi_scale; 90 | 91 | if (debug_gi) 92 | return float4(T2, 1.0); 93 | 94 | return float4(max(T0 + T1 + T2, 0.0f), 1.0f); 95 | } 96 | #endif 97 | -------------------------------------------------------------------------------- /src/dune/common_tools.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common_tools.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace dune 17 | { 18 | std::vector files_from_args(const tstring& arg, const tstring& default_file) 19 | { 20 | std::vector files; 21 | 22 | if (arg != L"") 23 | { 24 | int argsc; 25 | LPWSTR *args = CommandLineToArgvW(arg.c_str(), &argsc); 26 | 27 | for (int i = 0; i < argsc; ++i) 28 | files.push_back(dune::make_absolute_path(args[i])); 29 | } 30 | 31 | if (files.empty() && default_file != L"") 32 | files.push_back(dune::make_absolute_path(default_file)); 33 | 34 | return files; 35 | } 36 | 37 | tstring extract_path(const tstring& pattern) 38 | { 39 | tstring path = pattern; 40 | 41 | std::replace(path.begin(), path.end(), L'\\', L'/'); 42 | tstring::size_type pos = path.find_last_of(L"/"); 43 | 44 | return path.substr(0, pos+1); 45 | } 46 | 47 | bool path_is_relative(const tstring& p) 48 | { 49 | return (p.find(L":\\") == tstring::npos) && 50 | (p.find(L":/") == tstring::npos); 51 | } 52 | 53 | tstring absolute_path() 54 | { 55 | // get executable path 56 | const size_t s = 512; 57 | TCHAR path[s]; 58 | if (GetModuleFileName(nullptr, path, s) == ERROR_INSUFFICIENT_BUFFER) 59 | { 60 | tcerr << L"Failed to determine execution path" << std::endl; 61 | return L""; 62 | } 63 | 64 | return extract_path(path); 65 | } 66 | 67 | tstring make_absolute_path(const tstring& relative_filename) 68 | { 69 | if (!path_is_relative(relative_filename)) 70 | return relative_filename; 71 | 72 | tstring full_filename = absolute_path(); 73 | full_filename += relative_filename; 74 | 75 | return full_filename; 76 | } 77 | 78 | std::wstring ansi_to_wide(const std::string& str) 79 | { 80 | std::wstring str2(str.length(), L' '); 81 | std::copy(str.begin(), str.end(), str2.begin()); 82 | return str2; 83 | } 84 | 85 | std::string wide_to_ansi(const std::wstring& str) 86 | { 87 | static std::wstring_convert> utf8_conv; 88 | return utf8_conv.to_bytes(str); 89 | } 90 | 91 | #ifdef UNICODE 92 | 93 | tstring to_tstring(const std::string& str) 94 | { 95 | return ansi_to_wide(str); 96 | } 97 | 98 | std::string to_string(const tstring& str) 99 | { 100 | return wide_to_ansi(str); 101 | } 102 | 103 | #else 104 | 105 | tstring to_tstring(const std::wstring& str) 106 | { 107 | return wide_to_ansi(str); 108 | } 109 | 110 | std::wstring to_string(const tstring& str) 111 | { 112 | return ansi_to_wide(str); 113 | } 114 | 115 | #endif 116 | } 117 | -------------------------------------------------------------------------------- /src/dune/gbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_GBUFFER 10 | #define DUNE_GBUFFER 11 | 12 | #include "render_target.h" 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace dune 20 | { 21 | /*! 22 | * \brief A geometry buffer (collection of render_target objects). 23 | * 24 | * This class is a map of named render_target objects. The name gbuffer is only there because it isn't used as 25 | * a simple collection anywhere in the Dirtchamber. Each gbuffer can hold 0-N targets which are either 26 | * added directly, or with helper functions called add_target or _add_depth. Resizing a gbuffer 27 | * resizes all targets in it, and it is assumed that targets are all of equal size (even though 28 | * they don't have to be). 29 | */ 30 | class gbuffer : public shader_resource 31 | { 32 | protected: 33 | typedef std::vector targets_vec; 34 | typedef std::vector srv_vec; 35 | 36 | srv_vec srvs_; 37 | targets_vec buffers_; 38 | ID3D11Device* device_; 39 | 40 | protected: 41 | //!@{ 42 | /*! \brief Return a named target. */ 43 | render_target* target(const tstring& name); 44 | const render_target* target(const tstring& name) const; 45 | //!@} 46 | 47 | /*! \brief Fill up a vector of ID3D11ShaderResourceView with the SRVs of all render_target objects in this gbuffer. */ 48 | void srvs(srv_vec& srv_array); 49 | 50 | public: 51 | gbuffer(); 52 | virtual ~gbuffer() {} 53 | 54 | void create(ID3D11Device* device, const tstring& name); 55 | virtual void destroy(); 56 | 57 | //!@{ 58 | /*! \brief Create a new render_target in the gbuffer. These functions basically forward parameters to the render_target's create function. */ 59 | void add_target(const tstring& name, render_target& target); 60 | void add_target(const tstring& name, const D3D11_TEXTURE2D_DESC& desc, bool cached = false); 61 | void add_target(const tstring& name, const DXGI_SURFACE_DESC& desc, UINT num_mipmaps = 1); 62 | void add_depth(const tstring& name, DXGI_SURFACE_DESC desc); 63 | //!@} 64 | 65 | /*! \brief Returns all render_target objects in this gbuffer. */ 66 | targets_vec& targets(); 67 | 68 | //!@{ 69 | /*! \brief Fetch a render_target with its name. */ 70 | render_target* operator[](const tstring& name); 71 | const render_target* operator[](const tstring& name) const; 72 | //!@} 73 | 74 | /*! \brief Resize all render_target objects in this gbuffer to a new width and height. */ 75 | void resize(UINT width, UINT height); 76 | 77 | void to_ps(ID3D11DeviceContext* context, UINT start_slot); 78 | void to_gs(ID3D11DeviceContext* context, UINT start_slot); 79 | void to_vs(ID3D11DeviceContext* context, UINT start_slot); 80 | }; 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/dune/render_target.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_RENDER_TARGET 10 | #define DUNE_RENDER_TARGET 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "texture.h" 17 | 18 | namespace dune 19 | { 20 | /*! 21 | * \brief A render target wrapper. 22 | * 23 | * A render target is a texture that can be "written" to from the outside, whether it be from 24 | * the GPU or the CPU. A render_target object can be created in several different manners 25 | * (from manual specification to supplying common descriptors) and provides functions 26 | * to query views later used to read from or render to it. Furthermore, depending on the 27 | * parameters supplied to create(), render_target objects can also be CPU mapped to read 28 | * or write from/to them. 29 | */ 30 | class render_target : public texture 31 | { 32 | protected: 33 | ID3D11Device* device_; 34 | ID3D11RenderTargetView* rtview_; 35 | ID3D11DepthStencilView* dsview_; 36 | 37 | bool cached_; 38 | std::vector cached_copy_; 39 | 40 | protected: 41 | virtual void do_create(ID3D11Device* device, D3D11_TEXTURE2D_DESC desc, D3D11_SUBRESOURCE_DATA* subresource); 42 | 43 | public: 44 | render_target(); 45 | virtual ~render_target() {} 46 | 47 | /* \brief Returns the render target view (RTV). */ 48 | ID3D11RenderTargetView* const rtv() const { return rtview_; } 49 | 50 | /* \brief Returns the depth stencil view (DSV). */ 51 | ID3D11DepthStencilView* const dsv() const { return dsview_; } 52 | 53 | /* 54 | * \brief Resize the render_target. 55 | * 56 | * Resizes the render_target. Because new views are generated, old views still bound to the GPU are invalid. After a resize, 57 | * all views need to be re-bound! 58 | * 59 | * \param width The new width of the render_target. 60 | * \param height The new height of the render_target. 61 | */ 62 | void resize(UINT width, UINT height); 63 | 64 | virtual void destroy(); 65 | 66 | /*! \brief If this texture is cached, this method will copy the CPU side cache to the render_target texture. */ 67 | void update(ID3D11DeviceContext* context); 68 | 69 | /*! \brief Copy a data array of num_bytes size into the internal CPU cache. */ 70 | void copy(const BYTE* data, size_t num_bytes); 71 | 72 | /*! \brief Returns a pointer to the internal CPU texture cache. */ 73 | template 74 | T data() 75 | { 76 | return reinterpret_cast(&cached_copy_[0]); 77 | } 78 | 79 | //!@{ 80 | /*! \brief Enable caching. If this is true, creating this object will copy the initial sub-resource to a cache. */ 81 | void enable_cached(bool c) { cached_ = c; } 82 | bool cached() { return cached_; } 83 | //!@} 84 | }; 85 | 86 | void load_static_target(ID3D11Device* device, const tstring& filename, render_target& t); 87 | } 88 | 89 | #endif // RENDER_TARGET 90 | -------------------------------------------------------------------------------- /src/skydome.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | /*! 15 | * \brief A simple skydome mesh. 16 | * 17 | * Load a skydome mesh, disable depth stencil and render it without transformation 18 | * and two sky-layers. 19 | */ 20 | class skydome : public dune::gilga_mesh 21 | { 22 | protected: 23 | ID3D11ShaderResourceView* envmap_; 24 | ID3D11ShaderResourceView* clouds_; 25 | 26 | ID3D11DepthStencilState* dss_disable_depth_test_; 27 | ID3D11DepthStencilState* dss_enable_depth_test_; 28 | 29 | // TODO: stencil depth test goes here! 30 | 31 | public: 32 | virtual void create(ID3D11Device* device, const dune::tstring& file) 33 | { 34 | dune::gilga_mesh::create(device, dune::make_absolute_path(file).c_str()); 35 | 36 | D3D11_DEPTH_STENCIL_DESC dsd; 37 | dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; 38 | dsd.DepthFunc = D3D11_COMPARISON_LESS; 39 | dsd.StencilEnable = true; 40 | dsd.StencilReadMask = 0xFF; 41 | dsd.StencilWriteMask = 0xFF; 42 | dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 43 | dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; 44 | dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 45 | dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; 46 | dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 47 | dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; 48 | dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 49 | dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; 50 | 51 | dsd.DepthEnable = FALSE; 52 | dune::assert_hr(device->CreateDepthStencilState(&dsd, &dss_disable_depth_test_)); 53 | 54 | dsd.DepthEnable = TRUE; 55 | dune::assert_hr(device->CreateDepthStencilState(&dsd, &dss_enable_depth_test_)); 56 | } 57 | 58 | virtual void destroy() 59 | { 60 | dune::gilga_mesh::destroy(); 61 | 62 | dune::safe_release(dss_disable_depth_test_); 63 | dune::safe_release(dss_enable_depth_test_); 64 | } 65 | 66 | virtual void render(ID3D11DeviceContext* context) 67 | { 68 | context->OMSetDepthStencilState(dss_disable_depth_test_, 0); 69 | dune::gilga_mesh::render(context, nullptr); 70 | context->OMSetDepthStencilState(dss_enable_depth_test_, 0); 71 | } 72 | 73 | /*! \brief Set the environment map (latlong format) to use for the sky. */ 74 | void set_envmap(ID3D11Device* device, const dune::tstring& file) 75 | { 76 | dune::load_texture(device, file, &envmap_); 77 | 78 | for (auto i = meshes_.begin(); i != meshes_.end(); ++i) 79 | i->diffuse_tex = envmap_; 80 | } 81 | 82 | /*! \brief Set an optional cloud map (latlong format) to use for the sky. */ 83 | void set_clouds(ID3D11Device* device, const dune::tstring& file) 84 | { 85 | dune::load_texture(device, file, &clouds_); 86 | 87 | for (auto i = meshes_.begin(); i != meshes_.end(); ++i) 88 | i->specular_tex = clouds_; 89 | } 90 | }; 91 | -------------------------------------------------------------------------------- /src/dune/shader_tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_SHADER_TOOLS 10 | #define DUNE_SHADER_TOOLS 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include "exception.h" 18 | 19 | namespace dune 20 | { 21 | namespace detail 22 | { 23 | void compile_shader(ID3D11Device* device, LPCTSTR filename, LPCSTR shadermodel, LPCSTR mainfunc, UINT shader_flags, D3D_SHADER_MACRO* defines, ID3DBlob** binary); 24 | void compile_shader(ID3D11Device* device, ID3DBlob* binary, ID3D11GeometryShader** gs); 25 | void compile_shader(ID3D11Device* device, ID3DBlob* binary, ID3D11PixelShader** ps); 26 | void compile_shader(ID3D11Device* device, ID3DBlob* binary, ID3D11VertexShader** vs); 27 | } 28 | 29 | /*! 30 | * \brief (Re-)Compile a shader. 31 | * 32 | * This function tries to compile a shader and returns the D3D shader object and a possible binary blob which contains layout information. 33 | * Includes in HLSL are handled automatically, and error handling is done via the Dirtchamber logging mechanism. First, the shader file 34 | * is loaded and compiled to a blob. If this didn't work, the blob is discarded and an error is written to the logger. Otherwise, the 35 | * blob is turned to a proper shader and whatever shader pointer was supplied is now cleaned up and exchanged with a new shader. 36 | * 37 | * If the shader file was not found, but a file cso/mainfunc.cso instead was found, this precompiled version will be loaded instead and no 38 | * error is logged. 39 | * 40 | * \param device The Direct3D device. 41 | * \param filename A shader filename. 42 | * \param shadermodel An identifier of the shader model used, e.g. vs_5_0. 43 | * \param mainfunc The shader entry point. 44 | * \param shader_flags Any shader flags such as D3DCOMPILE_ENABLE_STRICTNESS. 45 | * \param defines HLSL defines. 46 | * \param shader A pointer to an ID3D11*Shader, which can already hold a valid shader object which will be replaced. 47 | * \param binary An optional pointer to an ID3D11Blob, which will contain the blob of the shader if it compiles. 48 | */ 49 | template 50 | void compile_shader(ID3D11Device* device, LPCTSTR filename, LPCSTR shadermodel, LPCSTR mainfunc, UINT shader_flags, D3D_SHADER_MACRO* defines, T** shader, ID3DBlob** binary = nullptr) 51 | { 52 | ID3DBlob* blob = nullptr; 53 | 54 | try 55 | { 56 | detail::compile_shader(device, filename, shadermodel, mainfunc, shader_flags, defines, &blob); 57 | } 58 | catch (exception& e) 59 | { 60 | tcerr << e.msg() << std::endl; 61 | safe_release(blob); 62 | return; 63 | } 64 | 65 | safe_release(*shader); 66 | 67 | try 68 | { 69 | detail::compile_shader(device, blob, shader); 70 | } 71 | catch (exception& e) 72 | { 73 | safe_release(blob); 74 | throw e; 75 | } 76 | 77 | if (binary) 78 | *binary = blob; 79 | else 80 | safe_release(blob); 81 | } 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /shader/postprocessing.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common.h" 8 | #include "tools.hlsl" 9 | 10 | SamplerState StandardFilter : register(s0); 11 | SamplerState ShadowFilter : register(s1); 12 | 13 | struct PS_INPUT 14 | { 15 | float4 position : SV_POSITION; 16 | float2 tex_coord : TEXCOORD0; 17 | float3 view_ray : TEXCOORD1; 18 | }; 19 | 20 | cbuffer onetime_ps : register(b6) 21 | { 22 | float4 scene_dim_max : packoffset(c0); 23 | float4 scene_dim_min : packoffset(c1);; 24 | } 25 | 26 | cbuffer camera_ps : register(b1) 27 | { 28 | float4x4 vp : packoffset(c0); 29 | float4x4 vp_inv : packoffset(c4); 30 | float3 camera_pos : packoffset(c8); 31 | float z_far : packoffset(c8.w); 32 | } 33 | 34 | cbuffer light_ps : register(b2) 35 | { 36 | directional_light main_light : packoffset(c0); 37 | float4x4 light_vp : packoffset(c3); 38 | float4x4 light_vp_inv : packoffset(c7); 39 | float4x4 light_vp_tex : packoffset(c11); 40 | float flux_scale : packoffset(c15); 41 | } 42 | 43 | cbuffer postprocessing_parameters_ps : register(b4) 44 | { 45 | bool ssao_enabled : packoffset(c0.x); 46 | float ssao_scale : packoffset(c0.y); 47 | 48 | bool godrays_enabled : packoffset(c0.z); 49 | float godrays_tau : packoffset(c0.w); 50 | 51 | bool dof_enabled : packoffset(c1.x); 52 | float dof_focal_plane : packoffset(c1.y); 53 | float dof_coc_scale : packoffset(c1.z); 54 | 55 | bool bloom_enabled : packoffset(c1.w); 56 | float bloom_sigma : packoffset(c2.x); 57 | float bloom_treshold : packoffset(c2.y); 58 | 59 | bool fxaa_enabled : packoffset(c2.z); 60 | 61 | bool exposure_adapt : packoffset(c2.w); 62 | float exposure_key : packoffset(c3.x); 63 | float exposure_speed : packoffset(c3.y); 64 | 65 | bool crt_enabled : packoffset(c3.z); 66 | bool film_grain_enabled : packoffset(c3.w); 67 | } 68 | 69 | cbuffer per_frame_ps : register(b5) 70 | { 71 | float time : packoffset(c0.x); 72 | float time_delta : packoffset(c0.y); 73 | float2 pad0 : packoffset(c0.z); 74 | } 75 | 76 | Texture2D frontbuffer_full : register(t0); 77 | 78 | Texture2D rt_colors : register(t2); 79 | Texture2D rt_specular : register(t3); 80 | Texture2D rt_normals : register(t4); 81 | Texture2D rt_lineardepth : register(t5); 82 | 83 | Texture2D rt_rsm_lineardepth : register(t6); 84 | 85 | Texture2D frontbuffer : register(t10); 86 | Texture2D rt_adapted_luminance : register(t11); 87 | Texture2D bloom_buffer : register(t12); 88 | Texture2D frontbuffer_blurred : register(t13); 89 | 90 | Texture3D noise_tex : register(t14); 91 | -------------------------------------------------------------------------------- /src/dune/summed_area_tables.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_SUMMED_AREA_TABLES 10 | #define DUNE_SUMMED_AREA_TABLES 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace dune 19 | { 20 | template 21 | T luminance(const T& r, const T& g, const T& b) 22 | { 23 | T v = static_cast(0.2126*r + 0.7152*g + 0.0722*b); 24 | return v*v; 25 | } 26 | 27 | struct environment_light 28 | { 29 | float theta, phi; 30 | DirectX::XMFLOAT2 pos; 31 | DirectX::XMFLOAT3 flux; 32 | }; 33 | 34 | class summed_area_table 35 | { 36 | protected: 37 | int width_, height_; 38 | std::vector sat_; 39 | 40 | float I(int x, int y) const; 41 | 42 | public: 43 | //template 44 | void create_lum(const BYTE* rgb, size_t width, size_t height, int nc) 45 | { 46 | assert(nc > 2); 47 | 48 | width_ = static_cast(width); height_ = static_cast(height); 49 | 50 | sat_.clear(); 51 | sat_.resize(width_ * height_); 52 | 53 | for (int y = 0; y < height_; ++y) 54 | for (int x = 0; x < width_; ++x) 55 | { 56 | size_t i = y*width_ + x; 57 | 58 | float r = static_cast(rgb[i*nc + 0]); 59 | float g = static_cast(rgb[i*nc + 1]); 60 | float b = static_cast(rgb[i*nc + 2]); 61 | 62 | float ixy = luminance(r,g,b); 63 | 64 | sat_[i] = ixy + I(x-1, y) + I(x, y-1) - I(x-1, y-1); 65 | } 66 | } 67 | 68 | int width() const { return width_; } 69 | int height() const { return height_; } 70 | 71 | /*! 72 | * \brief Returns the sum of a region defined by A,B,C,D. 73 | * 74 | * A----B 75 | * | | sum = C+A-B-D 76 | * D----C 77 | * 78 | */ 79 | float sum(int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy) const; 80 | }; 81 | 82 | struct sat_region 83 | { 84 | int x_, y_, w_, h_; 85 | float sum_; 86 | const summed_area_table* sat_; 87 | 88 | void create(int x, int y, int w, int h, const summed_area_table* sat, float init_sum = -1); 89 | 90 | /*! \brief Split region horizontally into subregions A and B. */ 91 | void split_w(sat_region& A, sat_region& B) const; 92 | void split_w(sat_region& A) const; 93 | 94 | /*! \brief Split region vertically into subregions A and B. */ 95 | void split_h(sat_region& A, sat_region& B) const; 96 | void split_h(sat_region& A) const; 97 | 98 | DirectX::XMFLOAT2 centroid() const; 99 | }; 100 | 101 | void median_cut(const BYTE* rgba, size_t width, size_t height, size_t n, std::vector& regions, summed_area_table& img); 102 | void median_cut(const BYTE* rgba, size_t width, size_t height, size_t n, std::vector& lights); 103 | } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /shader/d3d_mesh_skydome.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common.h" 8 | 9 | SamplerState StandardFilter : register(s0); 10 | 11 | struct VS_MESH_INPUT 12 | { 13 | float3 pos : POSITION; 14 | float3 norm : NORMAL; 15 | float2 texcoord : TEXCOORD0; 16 | float3 tangent : TANGENT; 17 | }; 18 | 19 | struct VS_MESH_OUTPUT 20 | { 21 | float4 pos : SV_POSITION; 22 | float4 norm : NORMAL; 23 | float3 tangent : TANGENT; 24 | float2 texcoord : TEXCOORD0; 25 | float3 wpos : WPOS; 26 | }; 27 | 28 | struct PS_MESH_OUTPUT 29 | { 30 | float4 color : SV_Target0; 31 | float4 normal : SV_Target1; 32 | float2 ldepth : SV_Target2; 33 | float4 specular : SV_Target3; 34 | }; 35 | 36 | cbuffer camera_vs : register(b0) 37 | { 38 | float4x4 vp : packoffset(c0); 39 | float4x4 vp_inv : packoffset(c4); 40 | float3 camera_pos : packoffset(c8); 41 | float pad0 : packoffset(c8.w); 42 | } 43 | 44 | cbuffer meshdata_vs : register(b1) 45 | { 46 | float4x4 world : packoffset(c0); 47 | } 48 | 49 | cbuffer meshdata_ps : register(b0) 50 | { 51 | float4 diffuse_color : packoffset(c0); 52 | bool has_diffuse_tex : packoffset(c1.x); 53 | bool has_normal_tex : packoffset(c1.y); 54 | bool has_specular_tex : packoffset(c1.z); 55 | bool has_alpha_tex : packoffset(c1.w); 56 | } 57 | 58 | cbuffer per_frame_ps : register(b5) 59 | { 60 | float time : packoffset(c0.x); 61 | float time_delta : packoffset(c0.y); 62 | float2 pad1 : packoffset(c0.z); 63 | } 64 | 65 | Texture2D diffuse_tex : register(t0); 66 | Texture2D normal_tex : register(t1); 67 | Texture2D specular_tex : register(t2); 68 | Texture2D alpha_tex : register(t3); 69 | 70 | VS_MESH_OUTPUT vs_skydome(in VS_MESH_INPUT input) 71 | { 72 | VS_MESH_OUTPUT output; 73 | 74 | // compensate for camera movement 75 | float4 pos = float4(input.pos + camera_pos, 1); 76 | 77 | output.pos = mul(vp, mul(world, pos)); 78 | output.norm = float4(input.norm, 0); 79 | output.tangent = float3(0,0,0); 80 | output.texcoord = input.texcoord.xy; 81 | 82 | output.wpos = input.pos; 83 | 84 | return output; 85 | } 86 | 87 | PS_MESH_OUTPUT ps_skydome(in VS_MESH_OUTPUT input) 88 | { 89 | PS_MESH_OUTPUT output; 90 | 91 | float2 tc = input.texcoord; 92 | tc.x += time * 0.001; 93 | 94 | float4 sky = pow(abs(diffuse_tex.Sample(StandardFilter, tc)), GAMMA); 95 | float4 cloudy_sky = sky; 96 | 97 | if (has_specular_tex) 98 | { 99 | tc.x += time*0.005; 100 | 101 | float clouds = pow(abs(specular_tex.Sample(StandardFilter, tc).r), GAMMA); 102 | cloudy_sky = lerp(sky, clouds, 0.8); 103 | } 104 | 105 | output.color = lerp(cloudy_sky, sky, tc.y); 106 | output.color.a = 0; 107 | 108 | output.normal = float4(0,0,0,0); 109 | output.ldepth = float2(0,0); 110 | output.specular = float4(0,0,0,0); 111 | 112 | return output; 113 | } 114 | -------------------------------------------------------------------------------- /src/dune/serializer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_SERIALIZER 10 | #define DUNE_SERIALIZER 11 | 12 | #include "exception.h" 13 | 14 | #include 15 | #include 16 | 17 | #include "unicode.h" 18 | 19 | namespace dune 20 | { 21 | typedef int BOOL; 22 | 23 | /*! 24 | * \brief Serializer to read/write Dune objects from/into JSON/XML. 25 | * 26 | * This class manages a map of key-value pairs of tstring objects and can 27 | * read or write them to XML files. Keys can be structured into sub-keys by 28 | * dividing them with dots. For instance, the hierarchy 29 | * 30 | * > foo { bar { baz }, bar1 { baz } } 31 | * 32 | * can be expressed with the following keys 33 | * 34 | * > foo.bar.baz 35 | * 36 | * > foo.bar1.baz 37 | * 38 | * The serializer is used to save information about Dune objects into 39 | * files. This enables loading program configurations. 40 | */ 41 | class serializer 42 | { 43 | protected: 44 | std::map properties_; 45 | 46 | public: 47 | /*! \brief Save the current key-value's into a file specified by filename. */ 48 | void save(const tstring& filename); 49 | 50 | /*! \brief Load key-value pairs from a file specified by filename. */ 51 | void load(const tstring& filename); 52 | 53 | /*! 54 | * \brief Get a value from a specified key. 55 | * 56 | * Fetch a value from the storage and return it as type T. 57 | * 58 | * \tparam T The type of the parameter. 59 | * \param key The key specifying the value. 60 | * \return The requested value. 61 | * \throws exception The key does not exist. 62 | */ 63 | template 64 | T get(const tstring& key) const 65 | { 66 | auto i = properties_.find(key); 67 | 68 | if (i == properties_.end()) 69 | throw dune::exception(L"Unknown key: " + key); 70 | 71 | T value; 72 | tstringstream ss(i->second); 73 | 74 | ss >> std::boolalpha >> value; 75 | return value; 76 | } 77 | 78 | /*! 79 | * \brief Add a new key-value pair or overwrite an existing key with a new value. 80 | * 81 | * Add a value of type T to the storage. If the key already exists, the value 82 | * is simply replaced. 83 | * 84 | * \tparam T The type of the parameter. 85 | * \param key The key specifying the value. 86 | * \param value The value. 87 | */ 88 | template 89 | void put(const tstring& key, const T& value) 90 | { 91 | tstringstream ss; 92 | ss << value; 93 | properties_[key] = ss.str(); 94 | } 95 | 96 | // Special case for type BOOL 97 | template<> 98 | void put(const tstring& key, const BOOL& value) 99 | { 100 | tstringstream ss; 101 | 102 | // BOOL is actually int, meh 103 | if (value == 0) 104 | ss << std::boolalpha << false; 105 | else if (value == 1) 106 | ss << std::boolalpha << true; 107 | else 108 | ss << value; 109 | 110 | properties_[key] = ss.str(); 111 | } 112 | }; 113 | } 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /shader/deferred.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common.h" 8 | #include "tools.hlsl" 9 | #include "brdf.hlsl" 10 | 11 | SamplerState StandardFilter : register(s0); 12 | SamplerState ShadowFilter : register(s2); 13 | 14 | struct PS_INPUT 15 | { 16 | float4 position : SV_POSITION; 17 | float2 tex_coord : TEXCOORD0; 18 | float3 view_ray : TEXCOORD1; 19 | }; 20 | 21 | cbuffer camera_ps : register(b1) 22 | { 23 | float4x4 vp : packoffset(c0); 24 | float4x4 vp_inv : packoffset(c4); 25 | float3 camera_pos : packoffset(c8); 26 | float z_far : packoffset(c8.w); 27 | } 28 | 29 | cbuffer light_ps : register(b2) 30 | { 31 | directional_light main_light : packoffset(c0); 32 | float4x4 light_mvp : packoffset(c3); 33 | float4x4 light_vp_inv : packoffset(c7); 34 | float4x4 light_vp_tex : packoffset(c11); 35 | } 36 | 37 | cbuffer onetime_ps : register(b6) 38 | { 39 | float4 scene_dim_max : packoffset(c0); 40 | float4 scene_dim_min : packoffset(c1); 41 | } 42 | 43 | Texture2D rt_colors : register(t2); 44 | Texture2D rt_specular : register(t3); 45 | Texture2D rt_normals : register(t4); 46 | Texture2D rt_lineardepth : register(t5); 47 | Texture2D rt_rsm_lineardepth : register(t6); 48 | 49 | Texture3D noise_tex : register(t14); 50 | 51 | float shadow_attenuation(in float3 pos, in float3 Ll, in Texture2D linear_shadowmap, in float min_s = 0.0, in float min_o = 0.0) 52 | { 53 | float4 tct = mul(light_vp_tex, float4(pos, 1)); 54 | float2 tc = tct.xy/tct.w; 55 | 56 | if (tc.x >= 1 || tc.y >= 1 || tc.y < 0 || tc.x < 0) 57 | return min_o; 58 | 59 | float z = length(Ll) * (1.0 - SHADOW_BIAS); 60 | 61 | return min(1.0, vsm(tc, z, linear_shadowmap, ShadowFilter) + min_s); 62 | } 63 | 64 | float get_spotlight(in float3 L, in float3 N) 65 | { 66 | float3 from_light = -L; 67 | float3 spot_dir = normalize(main_light.normal.xyz); 68 | 69 | float falloff = 0.7; 70 | 71 | float alpha = dot(from_light, spot_dir); 72 | 73 | float attenuation_dist = 1.0; 74 | 75 | if (alpha < falloff) 76 | attenuation_dist = 1.0 - 10*abs(alpha - falloff); 77 | 78 | return sdot(N, -from_light) * saturate(attenuation_dist); 79 | } 80 | 81 | struct gbuffer 82 | { 83 | float4 diffuse_albedo; 84 | float4 specular_albedo; 85 | float4 normal; 86 | float depth; 87 | uint shading_mode; 88 | }; 89 | 90 | /* 91 | void unpack_gbuffer(out float4 diffuse_albedo, 92 | out float4 specular_albedo, 93 | out float3 normal 94 | out float depth 95 | out uint shading_mode)*/ 96 | gbuffer unpack_gbuffer(in float2 tc) 97 | { 98 | gbuffer gb; 99 | 100 | gb.diffuse_albedo = rt_colors.Sample(StandardFilter, tc).rgba; 101 | gb.specular_albedo = rt_specular.Sample(StandardFilter, tc).rgba; 102 | gb.normal = rt_normals.Sample(StandardFilter, tc).xyzw; 103 | gb.depth = rt_lineardepth.Sample(StandardFilter, tc).r; 104 | gb.shading_mode = round(gb.normal.a * 10); 105 | 106 | return gb; 107 | } 108 | -------------------------------------------------------------------------------- /shader/lpv_rendervol.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common.h" 8 | #include "tools.hlsl" 9 | 10 | struct VS_MESH_INPUT 11 | { 12 | float3 pos : POSITION; 13 | float3 norm : NORMAL; 14 | float2 texcoord : TEXCOORD0; 15 | float3 tangent : TANGENT; 16 | }; 17 | 18 | struct VS_MESH_OUTPUT 19 | { 20 | float4 pos : SV_POSITION; 21 | float4 norm : NORMAL; 22 | float3 tangent : TANGENT; 23 | float2 texcoord : TEXCOORD0; 24 | float3 ldepth : LINEARDEPTH; 25 | }; 26 | 27 | struct PS_MESH_OUTPUT 28 | { 29 | float4 color : SV_Target0; 30 | float4 normal : SV_Target1; 31 | float2 ldepth : SV_Target2; 32 | float4 specular : SV_Target3; 33 | }; 34 | 35 | Texture2DArray lpv_r : register(t7); 36 | Texture2DArray lpv_g : register(t8); 37 | Texture2DArray lpv_b : register(t9); 38 | 39 | cbuffer onetime_vs : register(b2) 40 | { 41 | float4 scene_dim_max : packoffset(c0); 42 | float4 scene_dim_min : packoffset(c1); 43 | } 44 | 45 | cbuffer debug : register(b7) 46 | { 47 | float3 lpv_pos : packoffset(c0.x); 48 | float pad0 : packoffset(c0.w); 49 | }; 50 | 51 | cbuffer camera_vs : register(b0) 52 | { 53 | float4x4 vp : packoffset(c0); 54 | float4x4 vp_inv : packoffset(c4); 55 | float3 camera_pos : packoffset(c8); 56 | float pad1 : packoffset(c8.w); 57 | } 58 | 59 | cbuffer meshdata_vs : register(b1) 60 | { 61 | float4x4 world : packoffset(c0); 62 | } 63 | 64 | VS_MESH_OUTPUT vs_rendervol(in VS_MESH_INPUT input) 65 | { 66 | VS_MESH_OUTPUT output; 67 | 68 | float3 smax = scene_dim_max.xyz; 69 | float3 smin = scene_dim_min.xyz; 70 | 71 | // TODO: FIX THIS, LPV HAS ITS OWN SIZE! 72 | float3 diag = smax - smin; 73 | 74 | float3 dir = diag/float(LPV_SIZE); 75 | 76 | float s = length(dir)*0.4; 77 | 78 | float3 lpv_pos1 = lpv_pos + float3(1,1,1); 79 | 80 | float3 npos = smin + input.pos*s + dir*lpv_pos1.xyz; 81 | 82 | output.pos = mul(vp, mul(world, float4(npos, 1))); 83 | output.norm = float4(input.norm, 0); 84 | output.tangent = input.tangent; 85 | output.texcoord = input.texcoord; 86 | output.ldepth = 1.0; 87 | 88 | return output; 89 | } 90 | 91 | float4 load(in Texture2DArray lpv, in float3 lpv_pos) 92 | { 93 | return lpv.Load(int4(lpv_pos.x, lpv_pos.y, lpv_pos.z, 0)); 94 | } 95 | 96 | PS_MESH_OUTPUT ps_rendervol(in VS_MESH_OUTPUT input) 97 | { 98 | PS_MESH_OUTPUT output; 99 | 100 | // query lpv for color 101 | float4 r = load(lpv_r, lpv_pos); 102 | float4 g = load(lpv_g, lpv_pos); 103 | float4 b = load(lpv_b, lpv_pos); 104 | 105 | float4 normal_lobe = sh_clamped_cos_coeff(float3(0.f, 0.f, -1.f)); 106 | 107 | float3 nrgb; 108 | nrgb.r = dot(r, normal_lobe); 109 | nrgb.g = dot(g, normal_lobe); 110 | nrgb.b = dot(b, normal_lobe); 111 | 112 | if (nrgb.r < 0 || nrgb.g < 0 || nrgb.b < 0) 113 | nrgb = float3(1.0, 0.0, 0.0); 114 | 115 | output.color.rgb = nrgb; 116 | output.color.a = 0.0f; 117 | 118 | if (length(output.color.rgb) < 0.05f) 119 | discard; 120 | 121 | output.ldepth = 1.0; 122 | output.specular = float4(0,0,0,0); 123 | output.normal = float4(0,0,0,0); 124 | 125 | return output; 126 | } 127 | -------------------------------------------------------------------------------- /src/dune/video_gbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_VIDEO_GBUFFER 10 | #define DUNE_VIDEO_GBUFFER 11 | 12 | #include "gbuffer.h" 13 | 14 | #include 15 | 16 | interface ISampleGrabberCB : public IUnknown 17 | { 18 | virtual STDMETHODIMP SampleCB( double SampleTime, IMediaSample *pSample ) = 0; 19 | virtual STDMETHODIMP BufferCB( double SampleTime, BYTE *pBuffer, long BufferLen ) = 0; 20 | }; 21 | 22 | interface ISampleGrabber : public IUnknown 23 | { 24 | virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot ) = 0; 25 | virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType ) = 0; 26 | virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType ) = 0; 27 | virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem ) = 0; 28 | virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( long *pBufferSize, long *pBuffer ) = 0; 29 | virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( IMediaSample **ppSample ) = 0; 30 | virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback, long WhichMethodToCallback ) = 0; 31 | }; 32 | 33 | static const IID IID_ISampleGrabber = { 0x6B652FFF, 0x11FE, 0x4fce, { 0x92, 0xAD, 0x02, 0x66, 0xB5, 0xD7, 0xC7, 0x8F } }; 34 | static const IID IID_ISampleGrabberCB = { 0x0579154A, 0x2B53, 0x4994, { 0xB0, 0xD0, 0xE7, 0x73, 0x14, 0x8E, 0xFF, 0x85 } }; 35 | static const CLSID CLSID_SampleGrabber = { 0xC1F400A0, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; 36 | static const CLSID CLSID_NullRenderer = { 0xC1F400A4, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; 37 | 38 | #define RT_VIDEO_COLOR L"color" 39 | 40 | namespace dune 41 | { 42 | class video_gbuffer : public gbuffer 43 | { 44 | protected: 45 | struct grabber_callback : public ISampleGrabberCB 46 | { 47 | video_gbuffer* caller; 48 | virtual HRESULT __stdcall SampleCB(double time, IMediaSample* sample); 49 | virtual HRESULT __stdcall BufferCB(double time, BYTE* buffer, long len); 50 | virtual HRESULT __stdcall QueryInterface( REFIID iid, LPVOID *ppv ); 51 | virtual ULONG __stdcall AddRef(); 52 | virtual ULONG __stdcall Release(); 53 | }; 54 | 55 | friend struct grabber_callback; 56 | 57 | CRITICAL_SECTION cs_; 58 | bool async_; 59 | ID3D11DeviceContext* context_; 60 | bool running_; 61 | std::vector temp_buffer_; 62 | 63 | IFilterGraph2* graph_; 64 | ICaptureGraphBuilder2* capture_; 65 | IMediaControl* control_; 66 | 67 | IBaseFilter* nullf_; 68 | IBaseFilter* sgf_; 69 | IBaseFilter* current_device_; 70 | ISampleGrabber* sg_; 71 | 72 | grabber_callback callback_; 73 | 74 | typedef void (*video_cb)(BYTE* buffer, size_t width, size_t height); 75 | video_cb external_callback_; 76 | 77 | bool has_new_buffer_; 78 | 79 | protected: 80 | HRESULT init_device(UINT32 index, size_t w, size_t h, bool async); 81 | 82 | public: 83 | video_gbuffer(); 84 | virtual ~video_gbuffer() {} 85 | 86 | virtual void create(ID3D11Device* device, UINT32 device_index, const tstring& name, UINT w = 640, UINT h = 480); 87 | void set_callback(video_cb cb); 88 | 89 | void destroy(); 90 | 91 | HRESULT start(ID3D11DeviceContext* context); 92 | void stop(); 93 | 94 | void update(); 95 | }; 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/dune/light.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_LIGHT 10 | #define DUNE_LIGHT 11 | 12 | #include 13 | 14 | #include "cbuffer.h" 15 | #include "gbuffer.h" 16 | 17 | namespace dune 18 | { 19 | /*! 20 | * \brief A simple directional light source with an RSM. 21 | * 22 | * This class is a wrapper for a directional light source rendering to 23 | * a Reflective Shadow Map (RSM). It manages a constant buffer with 24 | * information about the light source such as position or view projection 25 | * matrix for rendering, as well as the gbuffer object to render the 26 | * RSM to. 27 | */ 28 | class directional_light 29 | { 30 | public: 31 | struct param 32 | { 33 | DirectX::XMFLOAT4 position; 34 | DirectX::XMFLOAT4 direction; 35 | DirectX::XMFLOAT4 flux; 36 | DirectX::XMFLOAT4X4 vp; 37 | DirectX::XMFLOAT4X4 vp_inv; 38 | DirectX::XMFLOAT4X4 vp_tex; 39 | }; 40 | 41 | protected: 42 | gbuffer rsm_; 43 | 44 | typedef cbuffer cb_param; 45 | cb_param cb_param_; 46 | 47 | public: 48 | virtual void create(ID3D11Device* device); 49 | 50 | virtual void create(ID3D11Device* device, const tstring& name, 51 | const DXGI_SURFACE_DESC& colors, const DXGI_SURFACE_DESC& normals, const DXGI_SURFACE_DESC& depth); 52 | 53 | virtual void create(ID3D11Device* device, const tstring& name, 54 | const D3D11_TEXTURE2D_DESC& colors, const D3D11_TEXTURE2D_DESC& normals, const D3D11_TEXTURE2D_DESC& depth); 55 | 56 | virtual void destroy(); 57 | 58 | //!@{ 59 | /*! \brief Return local cbuffer parameters. */ 60 | cb_param& parameters() { return cb_param_; } 61 | const cb_param& parameters() const { return cb_param_; } 62 | //!@} 63 | 64 | /*! \brief Update the view-projection matrix in the parameter cbuffer for shadowmap/RSM rendering. */ 65 | void update(const DirectX::XMFLOAT4& upt, const DirectX::XMMATRIX& light_proj); 66 | 67 | gbuffer& rsm(); 68 | void prepare_render(ID3D11DeviceContext* context); 69 | }; 70 | 71 | /*! 72 | * \brief A differential directional light source. 73 | * 74 | * A differential directional light source contains two RSMs \\( \\mu \\) and \\( \\rho \\): 75 | * - \\( \\rho \\) is an RSM of a scene with an additional object 76 | * - \\( \\mu \\) is an RSM of the same scene without the additional object 77 | * 78 | * Having these two RSMs, the differential indirect bounce can be extracted 79 | * by subtracting \\( \\mu \\) from \\( \\rho \\). This class is used to initialize delta_light_propagation_volume 80 | * objects or delta_sparse_voxel_octree objects. 81 | */ 82 | class differential_directional_light : public directional_light 83 | { 84 | protected: 85 | gbuffer mu_; 86 | 87 | public: 88 | /*! \brief Return RSM \\( \\rho \\). */ 89 | gbuffer& rho() { return rsm(); } 90 | 91 | /*! \brief Return RSM \\( \\mu \\). */ 92 | gbuffer& mu() { return mu_; } 93 | 94 | virtual void create(ID3D11Device* device, const tstring& name, 95 | const D3D11_TEXTURE2D_DESC& colors, const D3D11_TEXTURE2D_DESC& normals, const D3D11_TEXTURE2D_DESC& depth); 96 | 97 | virtual void destroy(); 98 | }; 99 | 100 | /* 101 | class point_light : public shader_resource 102 | { 103 | }; 104 | 105 | class environment_light : public shader_resource 106 | { 107 | }; 108 | */ 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /src/dune/composite_mesh.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "composite_mesh.h" 8 | 9 | #include 10 | 11 | #include "d3d_tools.h" 12 | #include "unicode.h" 13 | #include "exception.h" 14 | #include "common_tools.h" 15 | 16 | namespace dune 17 | { 18 | void composite_mesh::set_world(const DirectX::XMFLOAT4X4& world) 19 | { 20 | world_ = world; 21 | std::for_each(meshes_.begin(), meshes_.end(), [&](mesh_ptr& m){ m->set_world(world); }); 22 | } 23 | 24 | void composite_mesh::set_shader(ID3D11Device* device, ID3DBlob* input_binary, ID3D11VertexShader* vs, ID3D11PixelShader* ps) 25 | { 26 | exchange(&vs_, vs); 27 | exchange(&ps_, ps); 28 | 29 | std::for_each(meshes_.begin(), meshes_.end(), [&](mesh_ptr& m){ m->set_shader(device, input_binary, vs, ps); }); 30 | } 31 | 32 | void composite_mesh::create(ID3D11Device* device, const tstring& file) 33 | { 34 | mesh_ptr m; 35 | 36 | vs_ = nullptr; 37 | ps_ = nullptr; 38 | 39 | load_model(device, file, m); 40 | 41 | if (meshes_.empty()) 42 | init_bb(m->bb_min()); 43 | else 44 | update_bb(m->bb_min()); 45 | 46 | update_bb(m->bb_max()); 47 | 48 | meshes_.push_back(m); 49 | } 50 | 51 | void composite_mesh::create_from_dir(ID3D11Device* device, const tstring& pattern) 52 | { 53 | tstring absolute_pattern = make_absolute_path(pattern); 54 | tstring path = extract_path(tstring(absolute_pattern)); 55 | 56 | std::vector files; 57 | 58 | WIN32_FIND_DATA data; 59 | 60 | HANDLE h = FindFirstFile(absolute_pattern.c_str(), &data); 61 | 62 | if (h != INVALID_HANDLE_VALUE) 63 | { 64 | files.push_back(data); 65 | 66 | while(FindNextFile(h, &data)) 67 | files.push_back(data); 68 | } 69 | 70 | if (files.empty()) 71 | throw exception(tstring(L"Couldn't find ") + pattern); 72 | 73 | for (auto i = files.begin(); i != files.end(); ++i) 74 | { 75 | tstring file = path + tstring(i->cFileName); 76 | create(device, file.c_str()); 77 | } 78 | } 79 | 80 | void composite_mesh::render(ID3D11DeviceContext* context, DirectX::XMFLOAT4X4* to_clip) 81 | { 82 | std::for_each(meshes_.begin(), meshes_.end(), [&](mesh_ptr& m){ m->render(context, to_clip); }); 83 | } 84 | 85 | void composite_mesh::destroy() 86 | { 87 | d3d_mesh::destroy(); 88 | 89 | std::for_each(meshes_.begin(), meshes_.end(), [&](mesh_ptr& m){ m->destroy(); }); 90 | meshes_.clear(); 91 | } 92 | 93 | size_t composite_mesh::num_vertices() 94 | { 95 | size_t n = 0; 96 | std::for_each(meshes_.begin(), meshes_.end(), [&n](mesh_ptr& m){ n += m->num_vertices(); }); 97 | return n; 98 | } 99 | 100 | size_t composite_mesh::num_faces() 101 | { 102 | size_t n = 0; 103 | std::for_each(meshes_.begin(), meshes_.end(), [&n](mesh_ptr& m){ n += m->num_faces(); }); 104 | return n; 105 | } 106 | 107 | void composite_mesh::push_back(mesh_ptr& m) 108 | { 109 | meshes_.push_back(m); 110 | } 111 | 112 | void composite_mesh::set_shader_slots(INT diffuse_tex, INT specular_tex, INT normal_tex) 113 | { 114 | std::for_each(meshes_.begin(), meshes_.end(), [&](mesh_ptr& m){ m->set_shader_slots(diffuse_tex, specular_tex, normal_tex); }); 115 | } 116 | 117 | composite_mesh::mesh_ptr composite_mesh::operator[](size_t i) 118 | { 119 | return meshes_[i]; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/dune/postprocess.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_POSTPROCESS 10 | #define DUNE_POSTPROCESS 11 | 12 | #include "render_target.h" 13 | #include "simple_mesh.h" 14 | 15 | #include 16 | #include 17 | 18 | namespace dune 19 | { 20 | /*! 21 | * \brief A base interface for a postprocessor pipeline. 22 | * 23 | * This class defines a base interface for a postprocessing pipeline. A postprocessing pipeline is activated 24 | * by a deferred_renderer after the deferred render pass. It receives the deferred output as initial image and 25 | * is expected to render its end result into a backbuffer render target view. Everything in between is 26 | * dependent on the pipeline and can introduce as many render steps as needed. 27 | */ 28 | class postprocessor 29 | { 30 | protected: 31 | INT buffers_start_slot_; 32 | simple_mesh fs_triangle_; 33 | 34 | render_target frontbuffer_; 35 | 36 | bool enabled_; 37 | 38 | /*! \brief Overwrite this method to add your own creation code. */ 39 | virtual void do_create(ID3D11Device* device) 40 | { 41 | } 42 | 43 | /*! \brief Overwrite this to destroy additional resources created. */ 44 | virtual void do_destroy() 45 | { 46 | } 47 | 48 | /*! \brief Overwrite this method to initializes further shader instances. */ 49 | virtual void do_set_shader(ID3D11Device* device) 50 | { 51 | } 52 | 53 | /*! \brief Overwrite this method to react to resizes. */ 54 | virtual void do_resize(UINT width, UINT height) 55 | { 56 | } 57 | 58 | public: 59 | postprocessor(); 60 | virtual ~postprocessor() {} 61 | 62 | void create(ID3D11Device* device, DXGI_SURFACE_DESC desc); 63 | 64 | /*! \brief Render the entire postprocess (i.e. all steps of the pipeline) and write the result to backbuffer. */ 65 | virtual void render(ID3D11DeviceContext* context, ID3D11RenderTargetView* backbuffer); 66 | 67 | /*! 68 | * \brief Set shader parameters for the postprocessing pipeline. 69 | * 70 | * The postprocessing pipeline needs several things in order to run: A fullscreen triangle with 71 | * the matching shader input_binary and a start slot at which point to expect the frontbuffer (i.e 72 | * the buffer into which the image just before postprocessing was rendered). 73 | * 74 | * \param device The Direct3D device. 75 | * \param input_binary The input layout of the shader for the fullscreen triangle. 76 | * \param fs_triangle A vertex shader for a fullscreen triangle. 77 | * \param buffers_start_slot The slot at which the shader expects the frontbuffer. 78 | */ 79 | void set_shader(ID3D11Device* device, ID3DBlob* input_binary, ID3D11VertexShader* fs_triangle, UINT buffers_start_slot); 80 | 81 | void destroy(); 82 | 83 | /*! \brief Resizes the frontbuffer into which a deferred renderer writes its image to. */ 84 | void resize(UINT width, UINT height); 85 | 86 | /*! \brief Render into this render_target for the postprocessor. */ 87 | inline render_target& frontbuffer() { return frontbuffer_; } 88 | 89 | /*! \brief Enable the postprocessing pipeline. */ 90 | inline void enable() { enabled_ = true; }; 91 | 92 | /*! \brief Disable the postprocessing pipeline. */ 93 | inline void disable() { enabled_ = false; }; 94 | 95 | /*! \brief Check whether or not the postprocessing pipeline is enabled. */ 96 | inline bool enabled() { return enabled_; } 97 | }; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /src/dune/math_tools.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "math_tools.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace dune 14 | { 15 | namespace detail 16 | { 17 | // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html 18 | static float radiacal_inverse_vdc(unsigned int bits) 19 | { 20 | bits = (bits << 16u) | (bits >> 16u); 21 | bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); 22 | bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); 23 | bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); 24 | bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); 25 | return float(bits) * 2.3283064365386963e-10; // / 0x100000000 26 | } 27 | } 28 | 29 | DirectX::XMFLOAT2 hammersley2d(unsigned int i, unsigned int N) 30 | { 31 | return DirectX::XMFLOAT2(float(i) / float(N), detail::radiacal_inverse_vdc(i)); 32 | } 33 | 34 | float halton(int index, int base) 35 | { 36 | float result = 0; 37 | float f = 1.f / base; 38 | int i = index; 39 | 40 | while (i > 0) 41 | { 42 | result = result + f * static_cast(i % base); 43 | i = static_cast(std::floor(static_cast(i)/ base)); 44 | f = f / base; 45 | } 46 | 47 | return result; 48 | } 49 | 50 | void convert_handness(DirectX::XMMATRIX& m) 51 | { 52 | DirectX::XMFLOAT4X4 mat; 53 | DirectX::XMStoreFloat4x4(&mat, m); 54 | 55 | for (size_t i = 0; i < 4; ++i) 56 | std::swap(mat.m[2][i], mat.m[1][i]); 57 | 58 | for (size_t i = 0; i < 4; ++i) 59 | std::swap(mat.m[i][2], mat.m[i][1]); 60 | 61 | m = DirectX::XMLoadFloat4x4(&mat); 62 | } 63 | 64 | DirectX::XMMATRIX make_projection(float z_near, float z_far) 65 | { 66 | float n = z_near; 67 | float f = z_far; 68 | 69 | float q = f/(f-n); 70 | 71 | return DirectX::XMMATRIX 72 | ( 73 | 1.f, 0.f, 0.f, 0.f, 74 | 0.f, 1.f, 0.f, 0.f, 75 | 0.f, 0.f, q, 1.f, 76 | 0.f, 0.f, -q*n, 0.f 77 | ); 78 | } 79 | 80 | namespace approx 81 | { 82 | inline double sin(double x) 83 | { 84 | return x - x * x * x * (0.1587164 + x * x * 0.00585375); 85 | } 86 | 87 | inline double exp(double x) 88 | { 89 | const double a0 = 1.000090756764725753887362987792025308996; 90 | const double a1 = 9.973086551667860566788019540269306006270e-1; 91 | const double a2 = 4.988332174505582284710918757571761729419e-1; 92 | const double a3 = 1.773462612793916519454714108029230813767e-1; 93 | const double a4 = 4.415666059995979611944324860870682575219e-2; 94 | 95 | return a0 + x * (a1 + x * (a2 + x * (a3 + x * a4))); 96 | } 97 | 98 | // http://www.johndcook.com/blog/2012/07/25/trick-for-computing-log1x/ 99 | template static inline T log1p(T x) throw() 100 | { 101 | volatile T y = 1 + x, z = y - 1; 102 | return z == 0 ? x : x * std::log(y) / z; 103 | } 104 | } 105 | 106 | namespace pbrt 107 | { 108 | DirectX::XMMATRIX translate(float x, float y, float z) 109 | { 110 | return DirectX::XMMatrixTranslation(x, -y/2.f, z); 111 | } 112 | 113 | DirectX::XMMATRIX rotate(float angle, float x, float y, float z) 114 | { 115 | DirectX::XMMATRIX rot; 116 | DirectX::XMVECTORF32 axis = { x, y, z, 0.f }; 117 | 118 | return DirectX::XMMatrixRotationAxis(axis, angle); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/ext/dds/PlatformHelpers.h: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // File: PlatformHelpers.h 3 | // 4 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 5 | // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 6 | // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 7 | // PARTICULAR PURPOSE. 8 | // 9 | // Copyright (c) Microsoft Corporation. All rights reserved. 10 | // 11 | // http://go.microsoft.com/fwlink/?LinkId=248929 12 | //-------------------------------------------------------------------------------------- 13 | 14 | #pragma once 15 | 16 | #pragma warning(disable : 4324 4481) 17 | 18 | #include 19 | 20 | #if defined(_DEBUG) || defined(PROFILE) 21 | #pragma comment(lib,"dxguid.lib") 22 | #endif 23 | 24 | namespace DirectX 25 | { 26 | // Helper utility converts D3D API failures into exceptions. 27 | inline void ThrowIfFailed(HRESULT hr) 28 | { 29 | if (FAILED(hr)) 30 | { 31 | throw std::exception(); 32 | } 33 | } 34 | 35 | 36 | // Helper sets a D3D resource name string (used by PIX and debug layer leak reporting). 37 | template 38 | inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char (&name)[TNameLength]) 39 | { 40 | #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) 41 | resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name); 42 | #else 43 | UNREFERENCED_PARAMETER(resource); 44 | UNREFERENCED_PARAMETER(name); 45 | #endif 46 | } 47 | 48 | 49 | // Helper for output debug tracing 50 | inline void DebugTrace( _In_z_ _Printf_format_string_ const char* format, ... ) 51 | { 52 | #ifdef _DEBUG 53 | va_list args; 54 | va_start( args, format ); 55 | 56 | char buff[1024]; 57 | vsprintf_s( buff, format, args ); 58 | OutputDebugStringA( buff ); 59 | #else 60 | UNREFERENCED_PARAMETER( format ); 61 | #endif 62 | } 63 | 64 | 65 | // Helper smart-pointers 66 | struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } }; 67 | 68 | typedef public std::unique_ptr ScopedHandle; 69 | 70 | inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; } 71 | 72 | template class ScopedObject : public Microsoft::WRL::ComPtr {}; 73 | } 74 | 75 | 76 | #if defined(_MSC_VER) && (_MSC_VER < 1610) 77 | 78 | // Emulate the C++0x mutex and lock_guard types when building with Visual Studio versions < 2012. 79 | namespace std 80 | { 81 | class mutex 82 | { 83 | public: 84 | mutex() { InitializeCriticalSection(&mCriticalSection); } 85 | ~mutex() { DeleteCriticalSection(&mCriticalSection); } 86 | 87 | void lock() { EnterCriticalSection(&mCriticalSection); } 88 | void unlock() { LeaveCriticalSection(&mCriticalSection); } 89 | bool try_lock() { return TryEnterCriticalSection(&mCriticalSection) != 0; } 90 | 91 | private: 92 | CRITICAL_SECTION mCriticalSection; 93 | 94 | mutex(mutex const&); 95 | mutex& operator= (mutex const&); 96 | }; 97 | 98 | 99 | template 100 | class lock_guard 101 | { 102 | public: 103 | typedef Mutex mutex_type; 104 | 105 | explicit lock_guard(mutex_type& mutex) 106 | : mMutex(mutex) 107 | { 108 | mMutex.lock(); 109 | } 110 | 111 | ~lock_guard() 112 | { 113 | mMutex.unlock(); 114 | } 115 | 116 | private: 117 | mutex_type& mMutex; 118 | 119 | lock_guard(lock_guard const&); 120 | lock_guard& operator= (lock_guard const&); 121 | }; 122 | } 123 | 124 | #else // _MSC_VER < 1610 125 | 126 | #include 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /shader/deferred_dlpv_kinect.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "deferred_lpv.hlsl" 8 | #include "tonemapping.hlsl" 9 | 10 | Texture2D rt_kinect_color : register(t0); 11 | Texture2D rt_kinect_ldepth : register(t1); 12 | 13 | float2 to_gbuffer(in float3 c) 14 | { 15 | float4 pc = mul(vp, float4(c, 1.0)); 16 | pc.xy /= pc.w; 17 | 18 | return to_tex(pc.xy); 19 | } 20 | 21 | bool is_real_surface(in float3 pos) 22 | { 23 | float2 tc = to_gbuffer(pos); 24 | 25 | // TODO: abuse specular as mask for now, replace me later 26 | float v = rt_specular.Sample(StandardFilter, tc).r; 27 | 28 | return (v < 0.1); 29 | } 30 | 31 | Texture2DArray lpv_rho_r : register(t11); 32 | Texture2DArray lpv_rho_g : register(t12); 33 | Texture2DArray lpv_rho_b : register(t13); 34 | 35 | float get_spotlight(in float3 P, in float3 L, in float3 N) 36 | { 37 | float3 spot_dir = normalize(main_light.normal.xyz); 38 | 39 | float falloff = 0.7; 40 | 41 | float alpha = dot(-L, spot_dir); 42 | 43 | float attenuation_dist = 1.0; 44 | 45 | if (alpha < falloff) 46 | attenuation_dist = 1.0 - 10 * abs(alpha - falloff); 47 | 48 | return 1; 49 | return sdot(L, N); 50 | return sdot(L, N) * saturate(attenuation_dist); 51 | } 52 | 53 | // returns rgba. a = 1 if pixel was processed normally, a = 0 if pixel wasn't processed at all or if it was phantom geometry 54 | float4 ps_ar_dlpv(in PS_INPUT inp) : SV_Target 55 | { 56 | float4 kinect_background = pow(rt_kinect_color.Sample(StandardFilter, inp.tex_coord).rgba, 2.2); 57 | float4 diffuse_albedo = rt_colors.Sample(StandardFilter, inp.tex_coord); 58 | float3 normal = rt_normals.Sample(StandardFilter, inp.tex_coord).xyz; 59 | float depth = rt_lineardepth.Sample(StandardFilter, inp.tex_coord).r; 60 | float4 specular_albedo = rt_specular.Sample(StandardFilter, inp.tex_coord); 61 | 62 | // ignore parts with no normals 63 | if (dot(normal, normal) == 0) 64 | return kinect_background; 65 | 66 | float3 Na = normal * 2.0 - 1.0; 67 | float3 N = normalize(Na); 68 | 69 | // view 70 | float3 V = -normalize(inp.view_ray.xyz); 71 | 72 | // reconstruct position in world space 73 | float3 P = camera_pos + (-V * depth); 74 | 75 | bool is_real = is_real_surface(P); 76 | 77 | // light 78 | float3 Ll = main_light.position.xyz - P; 79 | float3 L = normalize(Ll); 80 | 81 | // lambert 82 | float NoL = saturate(dot(N, L)); 83 | 84 | // have no gloss maps, roughness is simply inverse spec color 85 | float roughness = 1.0 - specular_albedo.r; 86 | 87 | // calculate power of light and scale it to get the scene adequately lit 88 | float power = 100 * length(scene_dim_max - scene_dim_min); 89 | 90 | // calculate irradiance 91 | float3 Li = M_PI * (power * get_spotlight(P, L, N) * main_light.color.rgb) / dot(Ll, Ll); 92 | 93 | // shadow attenuation factor 94 | float attenuation = 1; 95 | 96 | // brdf 97 | float3 f = brdf(L, V, N, diffuse_albedo.rgb, specular_albedo.rgb, 1); 98 | 99 | // emissive 100 | float3 T0 = 0; 101 | 102 | // direct 103 | float3 T1 = f * Li * attenuation * NoL; 104 | 105 | if (is_real) 106 | { 107 | T1 = kinect_background.rgb; 108 | f = brdf(L, V, N, diffuse_albedo.rgb, 0, 1); 109 | } 110 | 111 | // indirect bounce 112 | float4 indirect_delta; 113 | float4 indirect_rho; 114 | 115 | indirect_delta = gi_from_lpv(P, N); 116 | indirect_rho = gi_from_lpv(P, N); 117 | 118 | float3 T2 = 0; 119 | 120 | if (!is_real) 121 | { 122 | T2 += indirect_rho * gi_scale * diffuse_albedo.rgb / M_PI; 123 | } 124 | else 125 | { 126 | T2 += indirect_delta * gi_scale * diffuse_albedo; 127 | } 128 | 129 | if (debug_gi) 130 | return float4(abs(T2), 1.0f); 131 | 132 | return float4(max(T0 + T1 + T2, 0.0f), !is_real); 133 | } 134 | -------------------------------------------------------------------------------- /src/dune/simple_mesh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_SIMPLE_MESH 10 | #define DUNE_SIMPLE_MESH 11 | 12 | #include 13 | #include 14 | 15 | #include "d3d_tools.h" 16 | #include "mesh.h" 17 | 18 | namespace dune 19 | { 20 | /*! 21 | * \brief A very simple mesh class with position-only vertex attributes. 22 | * 23 | * This class represents a very simple implementation of a d3d_mesh. A simple_mesh only contains vertices with a position attribute. 24 | * Use this class if you want to specify simple geometry for which fixed attributes will be declared in a shader. An example usage 25 | * of this class is the fullscreen triangle used for a deferred renderer. 26 | * 27 | * \note Yes I know you can use SV_VertexID as well to generate a fullscreen triangle, but PIX didn't like it and since then I didn't care... 28 | * 29 | */ 30 | class simple_mesh : public d3d_mesh 31 | { 32 | protected: 33 | struct vertex 34 | { 35 | DirectX::XMFLOAT3 v; 36 | }; 37 | 38 | std::vector vertices_; 39 | 40 | ID3D11Buffer* mesh_data_; 41 | 42 | protected: 43 | virtual const D3D11_INPUT_ELEMENT_DESC* vertex_desc() 44 | { 45 | static D3D11_INPUT_ELEMENT_DESC l[] = 46 | { 47 | { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 48 | 0 49 | }; 50 | 51 | return l; 52 | } 53 | 54 | public: 55 | simple_mesh() : 56 | vertices_(), 57 | mesh_data_() 58 | { 59 | } 60 | 61 | virtual ~simple_mesh() {} 62 | 63 | /*! \brief Add a new vertex p to the mesh. */ 64 | void push_back(DirectX::XMFLOAT3& p) 65 | { 66 | vertex v = { p }; 67 | vertices_.push_back(v); 68 | } 69 | 70 | /*! 71 | * \brief Create a new simple_mesh. 72 | * 73 | * This function creates a new, empty simple_mesh. 74 | * 75 | * \param device The Direct3D device. 76 | * \param name Instead of a filename, a name is used to write the creating of a simple_mesh into a log. This parameter serves no other purpose. 77 | */ 78 | virtual void create(ID3D11Device* device, const tstring& name) 79 | { 80 | tclog << L"Creating: simple geometry " << name << L" with " << num_faces() << " faces" << std::endl; 81 | 82 | D3D11_BUFFER_DESC bd; 83 | ZeroMemory(&bd, sizeof(bd)); 84 | bd.Usage = D3D11_USAGE_DEFAULT; 85 | bd.ByteWidth = sizeof(vertex)* 3; 86 | bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 87 | bd.CPUAccessFlags = 0; 88 | 89 | D3D11_SUBRESOURCE_DATA InitData; 90 | ZeroMemory(&InitData, sizeof(InitData)); 91 | InitData.pSysMem = &vertices_[0]; 92 | 93 | assert_hr(device->CreateBuffer(&bd, &InitData, &mesh_data_)); 94 | } 95 | 96 | virtual void render(ID3D11DeviceContext* context, DirectX::XMFLOAT4X4* to_clip = nullptr) 97 | { 98 | context->VSSetShader(vs_, nullptr, 0); 99 | context->IASetInputLayout(vertex_layout_); 100 | context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 101 | 102 | static const UINT stride = sizeof(vertex); 103 | static const UINT offset = 0; 104 | 105 | context->IASetVertexBuffers(0, 1, &mesh_data_, &stride, &offset); 106 | 107 | context->Draw(static_cast(num_vertices()), 0); 108 | } 109 | 110 | virtual size_t num_vertices() 111 | { 112 | return vertices_.size(); 113 | } 114 | 115 | virtual size_t num_faces() 116 | { 117 | return num_vertices() / 3; 118 | } 119 | 120 | virtual void destroy() 121 | { 122 | safe_release(mesh_data_); 123 | vertices_.clear(); 124 | 125 | d3d_mesh::destroy(); 126 | } 127 | }; 128 | } 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /src/dune/cbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_CONSTANT_BUFFER 10 | #define DUNE_CONSTANT_BUFFER 11 | 12 | #include "shader_resource.h" 13 | #include "d3d_tools.h" 14 | 15 | namespace dune 16 | { 17 | /*! 18 | * \brief A wrapper for constant buffers. 19 | * 20 | * cbuffer is a wrapping class managing a constant buffer. It does so by taking a struct 21 | * of the constant buffer layout as parameter T, keeping a local copy which can always be 22 | * accessed and modified. A call to the member update() will copy the local version into 23 | * the mapped resource. Every call to upload the constant buffer to a shader will automatically 24 | * update it first. 25 | */ 26 | template 27 | class cbuffer : public shader_resource 28 | { 29 | protected: 30 | ID3D11Buffer* cb_; 31 | ID3D11DeviceContext* context_; 32 | D3D11_MAPPED_SUBRESOURCE mapped_res_; 33 | T local_; 34 | 35 | T* map(ID3D11DeviceContext* context) 36 | { 37 | context_ = context; 38 | context_->Map(cb_, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res_); 39 | return reinterpret_cast(mapped_res_.pData); 40 | } 41 | 42 | void unmap() 43 | { 44 | if (mapped_res_.pData) 45 | { 46 | context_->Unmap(cb_, 0); 47 | ZeroMemory(&mapped_res_, sizeof(D3D11_MAPPED_SUBRESOURCE)); 48 | } 49 | } 50 | 51 | public: 52 | cbuffer() : 53 | cb_(nullptr), 54 | context_(nullptr) 55 | { 56 | ZeroMemory(&mapped_res_, sizeof(D3D11_MAPPED_SUBRESOURCE)); 57 | ZeroMemory(&local_, sizeof(T)); 58 | } 59 | 60 | virtual ~cbuffer() {} 61 | 62 | T& data() 63 | { 64 | return local_; 65 | } 66 | 67 | /*! \brief Returns a reference to the local copy of the constant buffer. */ 68 | const T& data() const 69 | { 70 | return local_; 71 | } 72 | 73 | void create(ID3D11Device* device) 74 | { 75 | D3D11_BUFFER_DESC cbd; 76 | cbd.Usage = D3D11_USAGE_DYNAMIC; 77 | cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 78 | cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 79 | cbd.MiscFlags = 0; 80 | cbd.StructureByteStride = 0; 81 | 82 | cbd.ByteWidth = sizeof(T); 83 | assert_hr(device->CreateBuffer(&cbd, nullptr, &cb_)); 84 | } 85 | 86 | void to_vs(ID3D11DeviceContext* context, UINT start_slot) 87 | { 88 | update(context); 89 | context_->VSSetConstantBuffers(start_slot, 1, &cb_); 90 | } 91 | 92 | void to_gs(ID3D11DeviceContext* context, UINT start_slot) 93 | { 94 | update(context); 95 | context_->GSSetConstantBuffers(start_slot, 1, &cb_); 96 | } 97 | 98 | void to_ps(ID3D11DeviceContext* context, UINT start_slot) 99 | { 100 | update(context); 101 | context_->PSSetConstantBuffers(start_slot, 1, &cb_); 102 | } 103 | 104 | void to_cs(ID3D11DeviceContext* context, UINT start_slot) 105 | { 106 | update(context); 107 | context_->CSSetConstantBuffers(start_slot, 1, &cb_); 108 | } 109 | 110 | /*! \brief Copy over the local buffer into the mapped resource. */ 111 | void update(ID3D11DeviceContext* context) 112 | { 113 | T* mapped = map(context); 114 | { 115 | *mapped = local_; 116 | } 117 | unmap(); 118 | } 119 | 120 | void destroy() 121 | { 122 | if (cb_ != nullptr) 123 | { 124 | unmap(); 125 | cb_->Release(); 126 | } 127 | 128 | cb_ = nullptr; 129 | context_ = nullptr; 130 | ZeroMemory(&mapped_res_, sizeof(D3D11_MAPPED_SUBRESOURCE)); 131 | ZeroMemory(&local_, sizeof(T)); 132 | } 133 | }; 134 | } 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /src/dune/render_target.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "render_target.h" 8 | 9 | #include "d3d_tools.h" 10 | #include "exception.h" 11 | 12 | #include "texture_cache.h" 13 | 14 | namespace dune 15 | { 16 | render_target::render_target() : 17 | device_(nullptr), 18 | rtview_(nullptr), 19 | dsview_(nullptr), 20 | cached_(false), 21 | cached_copy_() 22 | { 23 | } 24 | 25 | void render_target::do_create(ID3D11Device* device, D3D11_TEXTURE2D_DESC desc, D3D11_SUBRESOURCE_DATA* subresource) 26 | { 27 | rtview_ = nullptr; 28 | dsview_ = nullptr; 29 | 30 | device_ = device; 31 | 32 | if (desc.Format == DXGI_FORMAT_R32_TYPELESS) 33 | desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; 34 | 35 | if (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) 36 | { 37 | tcout << "Target \"" << this->name.c_str() << "\" is technically not a render target but a depth stencil texture." << std::endl; 38 | 39 | texture::do_create(device, desc, subresource); 40 | 41 | D3D11_DEPTH_STENCIL_VIEW_DESC desc_dsv; 42 | ZeroMemory(&desc_dsv, sizeof(desc_dsv)); 43 | desc_dsv.Format = DXGI_FORMAT_D32_FLOAT; 44 | desc_dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 45 | desc_dsv.Flags = 0; 46 | desc_dsv.Texture2D.MipSlice = 0; 47 | 48 | assert_hr(device->CreateDepthStencilView(texture_, &desc_dsv, &dsview_)); 49 | } 50 | else if (desc.Usage == D3D11_USAGE_DYNAMIC) 51 | { 52 | // target is dynamic and being "rendered" to from the outside via map/unmap/update/data() 53 | texture::do_create(device, desc, subresource); 54 | } 55 | else 56 | { 57 | desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; 58 | texture::do_create(device, desc, subresource); 59 | assert_hr(device->CreateRenderTargetView(texture_, nullptr, &rtview_)); 60 | } 61 | 62 | if (cached_) 63 | { 64 | if (subresource) 65 | { 66 | size_t num_bytes = desc.Height * subresource->SysMemPitch; 67 | cached_copy_.resize(num_bytes); 68 | copy(reinterpret_cast(subresource->pSysMem), num_bytes); 69 | } 70 | else 71 | { 72 | // TODO: fixme 73 | cached_copy_.resize(desc.Width * desc.Height * 4); 74 | } 75 | } 76 | } 77 | 78 | void render_target::resize(UINT width, UINT height) 79 | { 80 | if (width == size_.x && 81 | height == size_.y) 82 | return; 83 | 84 | // get old format 85 | D3D11_TEXTURE2D_DESC desc; 86 | texture_->GetDesc(&desc); 87 | 88 | desc.Width = width; 89 | desc.Height = height; 90 | 91 | // save old device 92 | auto device = device_; 93 | 94 | destroy(); 95 | create(device, desc); 96 | } 97 | 98 | void render_target::destroy() 99 | { 100 | texture::destroy(); 101 | 102 | safe_release(rtview_); 103 | safe_release(dsview_); 104 | 105 | device_ = nullptr; 106 | cached_ = false; 107 | cached_copy_.clear(); 108 | } 109 | 110 | void render_target::copy(const BYTE* data, size_t num_bytes) 111 | { 112 | std::memcpy(&cached_copy_[0], data, num_bytes); 113 | } 114 | 115 | void render_target::update(ID3D11DeviceContext* context) 116 | { 117 | void* p = map(context); 118 | 119 | if (p) 120 | { 121 | BYTE* target = reinterpret_cast(p); 122 | std::memcpy(p, data(), cached_copy_.size()); 123 | unmap(context); 124 | } 125 | } 126 | 127 | void load_static_target(ID3D11Device* device, const tstring& filename, render_target& t) 128 | { 129 | t.enable_cached(true); 130 | load_texture(device, filename, t); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/dune/mesh.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "mesh.h" 8 | 9 | //#include "sdk_mesh.h" 10 | #include "assimp_mesh.h" 11 | #include "d3d_tools.h" 12 | #include "unicode.h" 13 | 14 | namespace dune 15 | { 16 | void load_model(ID3D11Device* device, const tstring& file, std::shared_ptr& ptr) 17 | { 18 | tstring path = file; 19 | 20 | // TODO 21 | /* 22 | bool is_sdkmesh = path.find(L".sdkmesh") != std::string::npos; 23 | 24 | if (is_sdkmesh) 25 | ptr.reset(new sdk_mesh()); 26 | else*/ 27 | ptr.reset(new gilga_mesh()); 28 | 29 | ptr->create(device, file); 30 | } 31 | 32 | d3d_mesh::d3d_mesh() : 33 | vs_(nullptr), 34 | ps_(nullptr), 35 | vertex_layout_(nullptr), 36 | diffuse_tex_slot_(-1), 37 | normal_tex_slot_(-1), 38 | specular_tex_slot_(-1) 39 | { 40 | } 41 | 42 | void d3d_mesh::destroy() 43 | { 44 | safe_release(vertex_layout_); 45 | safe_release(ps_); 46 | safe_release(vs_); 47 | diffuse_tex_slot_ = -1; 48 | specular_tex_slot_ = -1; 49 | normal_tex_slot_ = -1; 50 | } 51 | 52 | UINT count(const D3D11_INPUT_ELEMENT_DESC* desc) 53 | { 54 | UINT array_size = 0; 55 | while (desc->SemanticName != nullptr) { array_size++; desc++; } 56 | return array_size; 57 | } 58 | 59 | void d3d_mesh::set_shader(ID3D11Device* device, ID3DBlob* input_binary, ID3D11VertexShader* vs, ID3D11PixelShader* ps) 60 | { 61 | exchange(&vs_, vs); 62 | exchange(&ps_, ps); 63 | 64 | const D3D11_INPUT_ELEMENT_DESC* vd = vertex_desc(); 65 | 66 | UINT array_size = count(vd); 67 | 68 | safe_release(vertex_layout_); 69 | 70 | assert_hr(device->CreateInputLayout(vd, static_cast(array_size), input_binary->GetBufferPointer(), 71 | input_binary->GetBufferSize(), &vertex_layout_)); 72 | } 73 | 74 | bool is_visible(const aabb& bbox, const DirectX::XMFLOAT4X4& to_clip) 75 | { 76 | DirectX::XMFLOAT3 mi = bbox.bb_min(); 77 | DirectX::XMFLOAT3 ma = bbox.bb_max(); 78 | 79 | DirectX::XMFLOAT3 aabb[8] = 80 | { 81 | mi, ma, 82 | DirectX::XMFLOAT3(mi.x, ma.y, ma.z), 83 | DirectX::XMFLOAT3(mi.x, mi.y, ma.z), 84 | DirectX::XMFLOAT3(mi.x, ma.y, mi.z), 85 | DirectX::XMFLOAT3(ma.x, mi.y, mi.z), 86 | DirectX::XMFLOAT3(ma.x, mi.y, ma.z), 87 | DirectX::XMFLOAT3(ma.x, ma.y, mi.z), 88 | }; 89 | 90 | DirectX::XMVECTOR aabb_trans[8]; 91 | 92 | DirectX::XMMATRIX m_to_clip = DirectX::XMLoadFloat4x4(&to_clip); 93 | 94 | for (size_t i = 0; i < 8; ++i) 95 | aabb_trans[i] = DirectX::XMVector3Transform(DirectX::XMLoadFloat3(&aabb[i]), m_to_clip); 96 | 97 | bool inside; 98 | 99 | for (size_t i = 0; i < 6; ++i) 100 | { 101 | for (size_t k = 0; k < 3; ++k) 102 | { 103 | inside = false; 104 | 105 | for (size_t j = 0; j < 8; ++j) 106 | { 107 | if (DirectX::XMVectorGetByIndex(aabb_trans[j], k) > -DirectX::XMVectorGetW(aabb_trans[j])) 108 | { 109 | inside = true; 110 | break; 111 | } 112 | } 113 | 114 | if (!inside) break; 115 | 116 | inside = false; 117 | 118 | for (size_t j = 0; j < 8; ++j) 119 | { 120 | if (DirectX::XMVectorGetByIndex(aabb_trans[j], k) < DirectX::XMVectorGetW(aabb_trans[j])) 121 | { 122 | inside = true; 123 | break; 124 | } 125 | } 126 | 127 | if (!inside) break; 128 | } 129 | 130 | if (!inside) break; 131 | } 132 | 133 | return inside; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/dune/gbuffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "gbuffer.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "d3d_tools.h" 14 | 15 | namespace dune 16 | { 17 | gbuffer::gbuffer() : 18 | srvs_(), 19 | buffers_(), 20 | device_(nullptr) 21 | { 22 | } 23 | 24 | void gbuffer::destroy() 25 | { 26 | std::for_each(buffers_.begin(), buffers_.end(), [](targets_vec::value_type& i){ i.destroy(); }); 27 | buffers_.clear(); 28 | srvs_.clear(); 29 | device_ = nullptr; 30 | } 31 | 32 | render_target* gbuffer::operator[](const tstring& name) 33 | { 34 | return target(name); 35 | } 36 | 37 | const render_target* gbuffer::operator[](const tstring& name) const 38 | { 39 | return target(name); 40 | } 41 | 42 | gbuffer::targets_vec& gbuffer::targets() 43 | { 44 | return buffers_; 45 | } 46 | 47 | void gbuffer::resize(UINT width, UINT height) 48 | { 49 | srvs_.clear(); 50 | std::for_each(buffers_.begin(), buffers_.end(), [&width, &height, this](targets_vec::value_type& rt){ rt.resize(width, height); srvs_.push_back(rt.srv()); }); 51 | } 52 | 53 | render_target* gbuffer::target(const tstring& n) 54 | { 55 | assert(name != L""); 56 | 57 | const tstring full_name = name + L"_" + n; 58 | 59 | for (size_t i = 0; i < buffers_.size(); ++i) 60 | if (buffers_[i].name == full_name) 61 | return &buffers_[i]; 62 | 63 | return 0; 64 | } 65 | 66 | const render_target* gbuffer::target(const tstring& n) const 67 | { 68 | assert(name != L""); 69 | 70 | const tstring full_name = name + L"_" + n; 71 | 72 | for (size_t i = 0; i < buffers_.size(); ++i) 73 | if (buffers_[i].name == full_name) 74 | return &buffers_[i]; 75 | 76 | return 0; 77 | } 78 | 79 | void gbuffer::add_target(const tstring& n, render_target& t) 80 | { 81 | t.name = name + L"_" + n; 82 | buffers_.push_back(t); 83 | srvs_.push_back(t.srv()); 84 | } 85 | 86 | void gbuffer::add_target(const tstring& n, const DXGI_SURFACE_DESC& desc, UINT num_mipmaps) 87 | { 88 | assert(device_); 89 | 90 | render_target t; 91 | t.create(device_, desc, num_mipmaps); 92 | t.name = this->name + L"_" + n; 93 | 94 | srvs_.push_back(t.srv()); 95 | 96 | buffers_.push_back(t); 97 | } 98 | 99 | void gbuffer::add_target(const tstring& n, const D3D11_TEXTURE2D_DESC& desc, bool cached) 100 | { 101 | assert(device_); 102 | 103 | render_target t; 104 | t.enable_cached(cached); 105 | t.create(device_, desc); 106 | t.name = name + L"_" + n; 107 | 108 | srvs_.push_back(t.srv()); 109 | 110 | buffers_.push_back(t); 111 | } 112 | 113 | void gbuffer::add_depth(const tstring& name, DXGI_SURFACE_DESC desc) 114 | { 115 | desc.Format = DXGI_FORMAT_R32_TYPELESS; 116 | desc.SampleDesc.Count = 1; 117 | desc.SampleDesc.Quality = 0; 118 | 119 | assert(device_); 120 | 121 | add_target(name, desc); 122 | } 123 | 124 | void gbuffer::create(ID3D11Device* device, const tstring& n) 125 | { 126 | assert(device); 127 | 128 | device_ = device; 129 | name = n; 130 | 131 | buffers_.clear(); 132 | } 133 | 134 | void gbuffer::to_ps(ID3D11DeviceContext* context, UINT start_slot) 135 | { 136 | context->PSSetShaderResources(start_slot, static_cast(srvs_.size()), &srvs_[0]); 137 | } 138 | 139 | void gbuffer::to_gs(ID3D11DeviceContext* context, UINT start_slot) 140 | { 141 | context->GSSetShaderResources(start_slot, static_cast(srvs_.size()), &srvs_[0]); 142 | } 143 | 144 | void gbuffer::to_vs(ID3D11DeviceContext* context, UINT start_slot) 145 | { 146 | context->VSSetShaderResources(start_slot, static_cast(srvs_.size()), &srvs_[0]); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/dune/light.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "light.h" 8 | #include "d3d_tools.h" 9 | 10 | #include 11 | 12 | namespace dune 13 | { 14 | void directional_light::update(const DirectX::XMFLOAT4& upt, const DirectX::XMMATRIX& light_proj) 15 | { 16 | DirectX::XMVECTOR up = DirectX::XMLoadFloat4(&upt); 17 | DirectX::XMVECTOR eye = DirectX::XMLoadFloat4(¶meters().data().position); 18 | DirectX::XMVECTOR dir = DirectX::XMLoadFloat4(¶meters().data().direction); 19 | 20 | // guard against bogus directions 21 | if (parameters().data().direction.x + parameters().data().direction.y + parameters().data().direction.z == 0) 22 | return; 23 | 24 | DirectX::XMMATRIX light_view = DirectX::XMMatrixLookToLH(eye, dir, up); 25 | 26 | DirectX::XMMATRIX light_view_inv = DirectX::XMMatrixInverse(nullptr, light_view); 27 | 28 | DirectX::XMMATRIX vp = light_view * light_proj; 29 | DirectX::XMStoreFloat4x4(&cb_param_.data().vp, vp); 30 | 31 | DirectX::XMMATRIX vp_inv = DirectX::XMMatrixInverse(nullptr, vp); 32 | DirectX::XMStoreFloat4x4(&cb_param_.data().vp_inv, vp_inv); 33 | 34 | DirectX::XMMATRIX tex 35 | ( 36 | 0.5f, 0.0f, 0.0f, 0.0f, 37 | 0.0f, -0.5f, 0.0f, 0.0f, 38 | 0.f, 0.f, 0.5f, 0.0f, 39 | 0.5f, 0.5f, 0.5f, 1.0f 40 | ); 41 | 42 | DirectX::XMStoreFloat4x4(&cb_param_.data().vp_tex, vp * tex); 43 | } 44 | 45 | void directional_light::create(ID3D11Device* device) 46 | { 47 | assert(device); 48 | cb_param_.create(device); 49 | } 50 | 51 | void directional_light::create(ID3D11Device* device, const tstring& name, const DXGI_SURFACE_DESC& colors, const DXGI_SURFACE_DESC& normals, const DXGI_SURFACE_DESC& depth) 52 | { 53 | create(device); 54 | rsm_.create(device, name); 55 | 56 | // setup reflective shadow map 57 | rsm_.add_target(L"lineardepth", depth, 0); 58 | rsm_.add_target(L"colors", colors); 59 | rsm_.add_target(L"normals", normals); 60 | } 61 | 62 | void directional_light::create(ID3D11Device* device, const tstring& name, const D3D11_TEXTURE2D_DESC& colors, const D3D11_TEXTURE2D_DESC& normals, const D3D11_TEXTURE2D_DESC& depth) 63 | { 64 | create(device); 65 | rsm_.create(device, name); 66 | 67 | // setup reflective shadow map 68 | rsm_.add_target(L"lineardepth", depth); 69 | rsm_.add_target(L"colors", colors); 70 | rsm_.add_target(L"normals", normals); 71 | } 72 | 73 | void directional_light::prepare_render(ID3D11DeviceContext* context) 74 | { 75 | static float clear_color[4] = { 0.f, 0.f, 0.f, 0.f }; 76 | 77 | ID3D11RenderTargetView* rsm_views[] = { 78 | rsm_[L"colors"]->rtv(), 79 | rsm_[L"normals"]->rtv(), 80 | rsm_[L"lineardepth"]->rtv() 81 | }; 82 | 83 | clear_rtvs(context, rsm_views, 3, clear_color); 84 | 85 | DirectX::XMFLOAT2 size = rsm_[L"colors"]->size(); 86 | set_viewport(context, 87 | static_cast(size.x), 88 | static_cast(size.y)); 89 | } 90 | 91 | gbuffer& directional_light::rsm() 92 | { 93 | return rsm_; 94 | } 95 | 96 | void directional_light::destroy() 97 | { 98 | rsm_.destroy(); 99 | cb_param_.destroy(); 100 | } 101 | 102 | void differential_directional_light::create(ID3D11Device* device, const tstring& name, const D3D11_TEXTURE2D_DESC& colors, const D3D11_TEXTURE2D_DESC& normals, const D3D11_TEXTURE2D_DESC& depth) 103 | { 104 | directional_light::create(device, name + L"_rho", colors, normals, depth); 105 | 106 | // setup reflective shadow map 107 | mu_.create(device, name + L"_mu"); 108 | mu_.add_target(L"lineardepth", depth); 109 | mu_.add_target(L"colors", colors); 110 | mu_.add_target(L"normals", normals); 111 | } 112 | 113 | void differential_directional_light::destroy() 114 | { 115 | directional_light::destroy(); 116 | mu_.destroy(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /shader/deferred_lpv.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2011 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "deferred.hlsl" 8 | #include "lpv_tools.hlsl" 9 | #include "importance.hlsl" 10 | 11 | cbuffer gi_parameters_ps : register(b3) 12 | { 13 | float gi_scale : packoffset(c0.x); 14 | float lpv_flux_amplifier : packoffset(c0.y); 15 | uint num_vpls : packoffset(c0.z); 16 | bool debug_gi : packoffset(c0.w); 17 | } 18 | 19 | Texture2D env_map : register(t13); 20 | 21 | float4 ps_lpv(PS_INPUT inp) : SV_Target 22 | { 23 | gbuffer gb = unpack_gbuffer(inp.tex_coord); 24 | 25 | float3 Na = gb.normal.xyz * 2.0 - 1.0; 26 | float3 N = normalize(Na); 27 | 28 | // view 29 | float3 V = -normalize(inp.view_ray.xyz); 30 | 31 | // if diffuse_albedo has alpha = 0, the color is actually emissive 32 | if (gb.diffuse_albedo.a == 0.0) 33 | return gb.diffuse_albedo; 34 | 35 | // ignore parts with no normals 36 | if (dot(gb.normal, gb.normal) == 0) 37 | return gb.diffuse_albedo * float4(main_light.color.rgb, 1.0); 38 | 39 | if (gb.depth >= z_far) 40 | return float4(0.0, 0.0, 0.0, 0.0); 41 | 42 | // reconstruct position in world space 43 | float3 pos = camera_pos + (-V * gb.depth); 44 | 45 | // light 46 | float3 Ll = main_light.position.xyz - pos; 47 | float3 L = normalize(Ll); 48 | 49 | // lambert 50 | float NoL = dot(N, L); 51 | 52 | // reflected L 53 | float3 R = normalize(reflect(-L, N)); 54 | 55 | // half vector between L and V 56 | float3 H = normalize(L+V); 57 | 58 | // have no gloss maps, roughness is simply inverse spec color 59 | #if 1 60 | float roughness = 1.0 - gb.specular_albedo.r; 61 | #else 62 | float roughness = gb.specular_albedo.a; 63 | #endif 64 | 65 | // calculate power of light and scale it to get the scene adequately lit 66 | float power = 100 * length(scene_dim_max - scene_dim_min); 67 | 68 | // calculate irradiance 69 | float3 Li = M_PI * (power * get_spotlight(L, N) * main_light.color.rgb) / dot(Ll, Ll); 70 | 71 | // shadow attenuation factor 72 | float attenuation = shadow_attenuation(pos, Ll, rt_rsm_lineardepth, 0.0, 0.0); 73 | 74 | // brdf 75 | #if 1 76 | float alpha = roughness*roughness; 77 | 78 | float NoV = dot(N, V); 79 | float NoH = dot(N, H); 80 | float LoH = dot(L, H); 81 | 82 | // refractive index 83 | float n = 1.5; 84 | float f0 = pow((1 - n)/(1 + n), 2); 85 | 86 | float3 Rs; 87 | 88 | if (gb.shading_mode == 1) 89 | { 90 | // the fresnel term 91 | float F = F_schlick(f0, LoH); 92 | 93 | // the geometry term 94 | float G = G_UE4(alpha, NoV); 95 | 96 | // the NDF term 97 | float D = D_ggx(alpha, NoH); 98 | 99 | // specular term 100 | Rs = gb.specular_albedo.rgb/M_PI * 101 | (F * G * D)/ 102 | (4 * NoL * NoV); 103 | } 104 | else 105 | { 106 | roughness = gb.specular_albedo.a * (num_vpls - 1.0) / 512.0f; 107 | 108 | gb.specular_albedo.rgb = float3(F0_GOLD); 109 | #if 1 110 | Rs = specular_ibl_is(gb.specular_albedo.rgb, roughness, N, V, env_map, StandardFilter) * main_light.color.rgb; 111 | #else 112 | Rs = ibl_specular_blinn_phong_mip(gb.diffuse_albedo.rgb, gb.specular_albedo.rgb, roughness, N, V, env_map, StandardFilter) * main_light.color.rgb; 113 | #endif 114 | } 115 | 116 | // diffuse fresnel, can be cheaper as 1-f0 117 | float Fd = F_schlick(f0, NoL); 118 | 119 | float3 Rd = gb.diffuse_albedo.rgb/M_PI * (1.0f - Fd); 120 | 121 | float3 f = (Rd + Rs); 122 | #else 123 | float3 f = brdf(L, V, N, gb.diffuse_albedo.rgb, gb.specular_albedo.rgb, roughness); 124 | #endif 125 | 126 | // emissive 127 | float3 T0 = 0; 128 | 129 | // direct 130 | float3 T1 = f * Li * attenuation * NoL; 131 | 132 | // first bounce 133 | float3 indirect = gi_from_lpv(pos, N).rgb * gi_scale; 134 | 135 | if (debug_gi) 136 | return float4(indirect, 1); 137 | 138 | float3 T2 = indirect * gb.diffuse_albedo.rgb / M_PI; 139 | 140 | return float4(max(T0 + T1 + T2, 0.0f), 1.0f); 141 | } 142 | -------------------------------------------------------------------------------- /src/pppipe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef PPPIPE 10 | #define PPPIPE 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | /*! 17 | * \brief A default implementation of the postprocessor. 18 | * 19 | * This is a default implementation of the postprocessor class. The output of a deferred renderer 20 | * is rendered to the frontbuffer render_target of the postprocessor. Each postprocess effect is rendered 21 | * by swapping input and output of the previous shader, until the last shader writes its output to the 22 | * backbuffer provided to the postprocessor. 23 | * 24 | * This postprocessor implements SSAO, Godrays, Depth-of-Field, Bloom, FXAA, exposure adaptation, a CRT monitor 25 | * effect, TV grain and HDR rendering. 26 | */ 27 | class pppipe : public dune::postprocessor 28 | { 29 | public: 30 | struct parameters 31 | { 32 | BOOL ssao_enabled; 33 | float ssao_scale; 34 | 35 | BOOL godrays_enabled; 36 | float godrays_tau; 37 | 38 | BOOL dof_enabled; 39 | float dof_focal_plane; 40 | float dof_coc_scale; 41 | 42 | BOOL bloom_enabled; 43 | float bloom_sigma; 44 | float bloom_treshold; 45 | 46 | BOOL fxaa_enabled; 47 | 48 | BOOL exposure_adapt; 49 | float exposure_key; 50 | float exposure_speed; 51 | 52 | BOOL crt_enabled; 53 | BOOL film_grain_enabled; 54 | }; 55 | 56 | protected: 57 | typedef dune::cbuffer cb_pp_parameters; 58 | cb_pp_parameters cb_pp_parameters_; 59 | 60 | ID3D11PixelShader* ssao_; 61 | ID3D11PixelShader* bloom_; 62 | ID3D11PixelShader* godrays_; 63 | ID3D11PixelShader* godrays_merge_; 64 | ID3D11PixelShader* dof_; 65 | ID3D11PixelShader* adapt_exposure_; 66 | ID3D11PixelShader* fxaa_; 67 | ID3D11PixelShader* bloom_treshold_; 68 | ID3D11PixelShader* crt_; 69 | ID3D11PixelShader* film_grain_; 70 | 71 | ID3D11PixelShader* gauss_godrays_h_; 72 | ID3D11PixelShader* gauss_godrays_v_; 73 | ID3D11PixelShader* gauss_bloom_h_; 74 | ID3D11PixelShader* gauss_bloom_v_; 75 | ID3D11PixelShader* gauss_dof_h_; 76 | ID3D11PixelShader* gauss_dof_v_; 77 | ID3D11PixelShader* copy_; 78 | 79 | virtual void do_create(ID3D11Device* device); 80 | virtual void do_destroy(); 81 | virtual void do_set_shader(ID3D11Device* device); 82 | virtual void do_resize(UINT width, UINT height); 83 | 84 | dune::render_target blurred_[6]; 85 | dune::render_target bloom_full_; 86 | dune::render_target frontbuffer_blurred_; 87 | 88 | dune::render_target temporary_; 89 | dune::render_target rt_adapted_luminance_[2]; 90 | 91 | //!@{ 92 | /*! \brief Render depth of field and blur it. */ 93 | void dof(ID3D11DeviceContext* context, dune::render_target& in, dune::render_target& out); 94 | void dofblur(ID3D11DeviceContext* context, dune::render_target& in, dune::render_target& out); 95 | //!@} 96 | 97 | //!@{ 98 | /*! \brief Render bloom and blur it. */ 99 | void bloom(ID3D11DeviceContext* context, dune::render_target& frontbuffer); 100 | void bloomblur(ID3D11DeviceContext* context, dune::render_target& in, dune::render_target& out); 101 | //!@} 102 | 103 | /*! \brief Compute godrays on half size buffer. */ 104 | void godrays(ID3D11DeviceContext* context, dune::render_target& in, dune::render_target& out); 105 | 106 | /*! \brief Render the entire pipeline by switching back and forth between a two temporary buffers. */ 107 | void render(ID3D11DeviceContext* context, ID3D11PixelShader* ps, dune::render_target& in, ID3D11RenderTargetView* out); 108 | 109 | public: 110 | virtual void render(ID3D11DeviceContext* context, ID3D11RenderTargetView* backbuffer); 111 | 112 | //!@{ 113 | /*! \brief Return local cbuffer parameters. */ 114 | cb_pp_parameters& parameters() { return cb_pp_parameters_; } 115 | const cb_pp_parameters& parameters() const { return cb_pp_parameters_; } 116 | //!@} 117 | }; 118 | 119 | //!@{ 120 | /*! \brief Read/write postprocessor from/to a serializer. */ 121 | dune::serializer& operator<<(dune::serializer& s, const pppipe& p); 122 | const dune::serializer& operator>>(const dune::serializer& s, pppipe& p); 123 | //!@} 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /src/dune/tracker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_TRACKER 10 | #define DUNE_TRACKER 11 | 12 | #ifdef OPENCV 13 | 14 | #include "render_target.h" 15 | 16 | #include 17 | 18 | #include 19 | 20 | namespace dune 21 | { 22 | /*! 23 | * \brief A basic pattern. 24 | * 25 | * This class encodes a pattern loaded from disk (usually an image), which pre-rotates 26 | * the pattern for later tracking purposes. 27 | */ 28 | class pattern 29 | { 30 | protected: 31 | std::vector rotated_versions_; 32 | 33 | public: 34 | /*! 35 | * \brief Load a pattern from disk. 36 | * 37 | * Load a pattern from disk and create pre-rotated versions which are later accessed for tracking. 38 | * 39 | * \param filename The pattern's filename. 40 | */ 41 | void load(const tstring& filename); 42 | 43 | const cv::Mat& operator[](size_t i) const { return rotated_versions_[i]; } 44 | }; 45 | 46 | /*! 47 | * \brief Detected pattern information block. 48 | * 49 | * Once a pattern was detected, this structure contains information about the detection, such 50 | * as the index in the array of patterns which was supplied for detection, the orientation 51 | * that had the highest correlation as well as the correlation itself, and a transformation 52 | * matrix from camera to world space which can be used to transform a mesh to the position 53 | * and orientation of the pattern. 54 | */ 55 | struct detection_info 56 | { 57 | size_t index; 58 | int orientation; 59 | double correlation; 60 | 61 | DirectX::XMMATRIX transformation; 62 | }; 63 | 64 | /*! 65 | * \brief A simple pattern tracker written with OpenCV. 66 | * 67 | * This class implements a basic pattern tracker. Patterns are loaded and added to a vector of patterns 68 | * which are then detected in render_target frames. 69 | */ 70 | class tracker 71 | { 72 | public: 73 | float time_track_; 74 | 75 | protected: 76 | cv::Mat cam_intrinsic_; 77 | cv::Mat cam_distortion_; 78 | 79 | std::vector patterns_; 80 | std::vector detected_; 81 | 82 | public: 83 | void create(const tstring& camera_parameters_filename); 84 | void destroy(); 85 | 86 | /*! 87 | * \brief Track loaded patterns in a render_target frame. 88 | * 89 | * This method needs to be called whenever a new render_target is available where tracking should be performed. 90 | * For each loaded pattern, tracking information will be gathered that can be later accessed with the model_view_matrix() method. 91 | * 92 | * \param frame A render_target frame which has its data cached 93 | */ 94 | void track_frame(render_target& frame); 95 | 96 | /*! \brief Load a pattern filename from disk. Returns an ID for the pattern to later identify it. */ 97 | size_t load_pattern(const tstring& filename); 98 | 99 | /*! \brief Remove a loaded pattern identified by an ID. */ 100 | void remove_pattern(size_t id); 101 | 102 | /*! 103 | * \brief Retrieve a model-view matrix for a pattern id. 104 | * 105 | * This method will construct a model-view matrix necessary to correctly transform 3D geometry according to a 106 | * tracked pattern. Additionally, rescaling, transformation, and a rotation can be added beforehand. If the pattern 107 | * wasn't detected in a frame by the method track_frame, then the previously detected matrix will be returned. 108 | * 109 | * \param scale Scales the world before moving it to the pattern. 110 | * \param translation Translate the world before moving it to the pattern. 111 | * \param rotation Rotate the world before moving it to the pattern. 112 | * \param pattern_id The ID of the pattern, in case more than one is tracked simultanously. 113 | * \return The model-view matrix to move the world position to the pattern space. 114 | */ 115 | DirectX::XMFLOAT4X4 model_view_matrix(FLOAT scale, const DirectX::XMFLOAT3& translation, const DirectX::XMFLOAT4X4& rotation, UINT pattern_id = 0) const; 116 | }; 117 | } 118 | 119 | #endif 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /shader/pp_godrays.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocessing.hlsl" 8 | 9 | #define GODRAYS_MIST_SPEED 20 10 | #define GODRAYS_NUM_SAMPLES 60 11 | #define GODRAYS_NUM_SAMPLES_RCP 0.015625 12 | #define GODRAYS_DITHERING 50 13 | 14 | float shadowed(in float3 pos) 15 | { 16 | float4 tct = mul(light_vp_tex, float4(pos, 1)); 17 | float2 tc = tct.xy/tct.w; 18 | 19 | if (tc.x >= 1 || tc.y >= 1 || tc.y < 0 || tc.x < 0) 20 | return 0.0; 21 | 22 | float3 v = main_light.position.xyz - pos; 23 | 24 | float VoL = saturate(dot(normalize(-v), main_light.normal.xyz)); 25 | 26 | float z = length(v); 27 | z *= 1.0 - SHADOW_BIAS; 28 | 29 | return vsm(tc, z, rt_rsm_lineardepth, ShadowFilter) * VoL; 30 | } 31 | 32 | float P(in float3 x, in float3 view_dir) 33 | { 34 | float4 scene_delta = scene_dim_max - scene_dim_min; 35 | float sdiv = max(scene_delta.x, max(scene_delta.y, scene_delta.z)); 36 | 37 | float t = time * GODRAYS_MIST_SPEED; 38 | float3 xx = x + float3(0, t, 0); 39 | float3 tcv = xx / (sdiv/5); 40 | 41 | float v = noise_tex.Sample(StandardFilter, tcv).r; 42 | 43 | // Schlick phase function 44 | /* 45 | float k = -0.1; 46 | float costheta = 1; 47 | float p = (1 - k*k) / (4 * M_PI*(1 + k*costheta*costheta)); 48 | */ 49 | 50 | return v*v; 51 | } 52 | 53 | // Volumetric Fogging 2 54 | // http://www.humus.name/index.php?page=3D&ID=70 55 | float4 godrays_humus(in PS_INPUT inp) 56 | { 57 | float m = length(scene_dim_max - scene_dim_min); 58 | float s = rt_lineardepth.Sample(StandardFilter, inp.tex_coord).r; 59 | 60 | float3 view_dir = s * normalize(inp.view_ray.xyz) * GODRAYS_NUM_SAMPLES_RCP; 61 | 62 | float n = godrays_tau * length(view_dir); 63 | 64 | float a = 1.0; 65 | float b = 0.0; 66 | 67 | float3 pos = camera_pos; 68 | 69 | uint w,h; 70 | rt_lineardepth.GetDimensions(w, h); 71 | 72 | // dither shadow 73 | // THINK: maybe undo dithering if enough samples were fogged? 74 | float rf = noise_tex.Sample(StandardFilter, float3(inp.tex_coord*GODRAYS_DITHERING, 0)); 75 | float rando = 1.0 + (2.0 * rf - 1.0) * s / m; 76 | 77 | //[unroll(GODRAYS_NUM_SAMPLES)] 78 | for (int i = 0; i < GODRAYS_NUM_SAMPLES; i++) 79 | { 80 | pos += view_dir * rando; 81 | 82 | float v = shadowed(pos); 83 | float fog = P(pos, view_dir); 84 | 85 | float x = 1.0 - fog * n; 86 | a *= x; 87 | b = lerp(v, b, x); 88 | } 89 | 90 | return b; 91 | } 92 | 93 | float4 ps_godrays(in PS_INPUT inp) : SV_TARGET 94 | { 95 | float4 color = frontbuffer.Sample(StandardFilter, inp.tex_coord, 0); 96 | 97 | if (godrays_enabled) 98 | return color + godrays_humus(inp); 99 | else 100 | return color; 101 | } 102 | 103 | float4 ps_godrays_halfres(in PS_INPUT inp) : SV_TARGET 104 | { 105 | if (godrays_enabled) 106 | return godrays_humus(inp); 107 | else 108 | return float4(0, 0, 0, 0); 109 | } 110 | 111 | float4 bilateral_sample(in float2 tc) 112 | { 113 | float w, h; 114 | 115 | rt_lineardepth.GetDimensions(w, h); 116 | 117 | float center_tap = rt_lineardepth.SampleLevel(ShadowFilter, tc, 0).x; 118 | 119 | float2 dtc_rcp = float2(1.0 / w, 1.0 / h)*2; 120 | 121 | float min_depth_diff = 1.0; 122 | 123 | float2 nearest_sample = tc; 124 | 125 | for (int i = -1; i <= 1; ++i) 126 | for (int j = -1; j <= 1; ++j) 127 | { 128 | float2 stc = tc + float2(i, j)*dtc_rcp; 129 | float tap = rt_lineardepth.SampleLevel(ShadowFilter, stc, 1).x; 130 | 131 | float depth_diff = abs(center_tap - tap); 132 | 133 | if (depth_diff < min_depth_diff) 134 | { 135 | min_depth_diff = depth_diff; 136 | nearest_sample = stc; 137 | } 138 | } 139 | 140 | return frontbuffer_blurred.SampleLevel(StandardFilter, nearest_sample, 0); 141 | } 142 | 143 | float4 ps_godrays_merge(in PS_INPUT inp) : SV_TARGET 144 | { 145 | float4 color = frontbuffer.SampleLevel(StandardFilter, inp.tex_coord, 0); 146 | float4 godrays = frontbuffer_blurred.SampleLevel(StandardFilter, inp.tex_coord, 0); 147 | 148 | if (godrays_enabled) 149 | return float4((color + godrays).rgb, color.a); 150 | else 151 | return color; 152 | } 153 | -------------------------------------------------------------------------------- /shader/pp_blur.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "postprocessing.hlsl" 8 | 9 | // Performs a gaussian blur in one direction 10 | float4 gauss(in PS_INPUT input, in float2 tex_scale, in float sigma) 11 | { 12 | float4 color = 0; 13 | 14 | float w,h; 15 | frontbuffer.GetDimensions(w,h); 16 | 17 | for (int i = -6; i < 6; i++) 18 | { 19 | float weight = gauss_weight(i, sigma); 20 | 21 | // compute tap tc 22 | float2 tc = input.tex_coord; 23 | tc += (i / float2(w,h)) * tex_scale; 24 | 25 | // fetch tap 26 | float4 tap = frontbuffer.Sample(ShadowFilter, tc); 27 | color += tap * weight; 28 | } 29 | 30 | return color; 31 | } 32 | 33 | float4 bilateral_gauss_far(in PS_INPUT input, in float2 tex_scale, in float sigma) 34 | { 35 | float4 color = 0; 36 | 37 | float w,h; 38 | frontbuffer.GetDimensions(w,h); 39 | 40 | float4 center_tap_color = frontbuffer_full.Sample(StandardFilter, input.tex_coord); 41 | float center_tap_depth = rt_lineardepth.Sample(ShadowFilter, input.tex_coord).x; 42 | 43 | float dw,dh; 44 | rt_lineardepth.GetDimensions(dw,dh); 45 | 46 | float weightaccum = 0; 47 | 48 | for (int i = -6; i < 6; i++) 49 | { 50 | float weight = gauss_weight(i, sigma); 51 | 52 | // compute tap tc 53 | float2 tc = input.tex_coord; 54 | tc += (i / float2(w,h)) * tex_scale; 55 | 56 | float2 dtc = input.tex_coord; 57 | dtc += (i / float2(dw,dh)) * tex_scale; 58 | 59 | // fetch tap 60 | float4 tap = frontbuffer.Sample(ShadowFilter, tc); 61 | float dtap = rt_lineardepth.Sample(ShadowFilter, dtc).x; 62 | 63 | if (dtap >= center_tap_depth) 64 | color += tap * weight; 65 | else 66 | color += center_tap_color * weight; 67 | 68 | weightaccum += weight; 69 | } 70 | 71 | return float4(color.rgb, 1); 72 | } 73 | 74 | float4 bilateral_gauss_near(in PS_INPUT input, float2 tex_scale, float sigma) 75 | { 76 | float4 accum = 0; 77 | float accum_weight = 0; 78 | 79 | float w,h; 80 | frontbuffer.GetDimensions(w,h); 81 | 82 | float4 center_tap_color = frontbuffer.Sample(StandardFilter, input.tex_coord); 83 | float center_depth_tap = rt_lineardepth.Sample(ShadowFilter, input.tex_coord).x; 84 | 85 | float dw,dh; 86 | rt_lineardepth.GetDimensions(dw,dh); 87 | 88 | [unroll] 89 | for (int i = -6; i < 6; i++) 90 | { 91 | // compute tap tc 92 | float2 tc = input.tex_coord; 93 | tc += (i / float2(w,h)) * tex_scale; 94 | 95 | float2 dtc = input.tex_coord; 96 | dtc += (i / float2(dw,dh)) * tex_scale; 97 | 98 | // fetch tap 99 | float4 tap = frontbuffer.Sample(ShadowFilter, tc); 100 | float depth_tap = rt_lineardepth.Sample(ShadowFilter, dtc).x; 101 | 102 | float depth_diff = abs(depth_tap - center_depth_tap); 103 | float r2 = depth_diff * 100.0 / center_depth_tap; 104 | float g = exp(-r2 * r2); 105 | 106 | if (depth_diff == 0) 107 | g = 1; 108 | 109 | float weight = gauss_weight(i, sigma) * g; 110 | 111 | if (depth_tap < center_depth_tap) 112 | accum += tap * weight; 113 | else 114 | accum += center_tap_color * weight; 115 | 116 | accum_weight += weight; 117 | } 118 | 119 | return float4(accum.rgb/accum_weight, 1); 120 | } 121 | 122 | float4 ps_gauss_bloom_h(in PS_INPUT inp) : SV_TARGET 123 | { 124 | return gauss(inp, float2(0, 1), bloom_sigma); 125 | } 126 | 127 | float4 ps_gauss_bloom_v(in PS_INPUT inp) : SV_TARGET 128 | { 129 | return gauss(inp, float2(1, 0), bloom_sigma); 130 | } 131 | 132 | float4 ps_gauss_dof_h(in PS_INPUT inp) : SV_TARGET 133 | { 134 | return bilateral_gauss_far(inp, float2(0, 1), dof_coc_scale); 135 | } 136 | 137 | float4 ps_gauss_dof_v(in PS_INPUT inp) : SV_TARGET 138 | { 139 | return bilateral_gauss_far(inp, float2(1, 0), dof_coc_scale); 140 | } 141 | 142 | float4 ps_gauss_godrays_h(in PS_INPUT inp) : SV_TARGET 143 | { 144 | return bilateral_gauss_near(inp, float2(0, 1), 2.5); 145 | } 146 | 147 | float4 ps_gauss_godrays_v(in PS_INPUT inp) : SV_TARGET 148 | { 149 | return bilateral_gauss_near(inp, float2(1, 0), 2.5); 150 | } 151 | 152 | float4 ps_copy(in PS_INPUT inp) : SV_TARGET 153 | { 154 | return frontbuffer.SampleLevel(ShadowFilter, inp.tex_coord, 0); 155 | } 156 | -------------------------------------------------------------------------------- /shader/deferred_dvct_kinect.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2014 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #define DVCT 8 | #include "deferred_vct.hlsl" 9 | 10 | Texture2D rt_kinect_color : register(t0); 11 | Texture2D rt_kinect_ldepth : register(t1); 12 | 13 | float2 to_gbuffer(in float3 c) 14 | { 15 | float4 pc = mul(vp, float4(c, 1.0)); 16 | pc.xy /= pc.w; 17 | 18 | return to_tex(pc.xy); 19 | } 20 | 21 | bool is_real_surface(in float3 pos) 22 | { 23 | float2 tc = to_gbuffer(pos); 24 | 25 | // TODO: abuse specular as mask for now, replace me later 26 | float v = rt_specular.Sample(StandardFilter, tc).r; 27 | 28 | return (v < 0.1); 29 | } 30 | 31 | float4 ps_ar_dvct(in PS_INPUT inp) : SV_Target 32 | { 33 | float4 kinect_background = pow(rt_kinect_color.Sample(StandardFilter, inp.tex_coord).rgba, 2.2); 34 | float4 diffuse_albedo = rt_colors.Sample(StandardFilter, inp.tex_coord); 35 | float4 specular_albedo = rt_specular.Sample(StandardFilter, inp.tex_coord); 36 | float4 normal = rt_normals.Sample(StandardFilter, inp.tex_coord); 37 | float depth = rt_lineardepth.Sample(StandardFilter, inp.tex_coord).r; 38 | uint shading_mode = round(normal.a * 10); 39 | 40 | // ignore parts with no normals 41 | if (dot(normal.xyz, normal.xyz) == 0) 42 | return kinect_background; 43 | 44 | float3 Na = normal.xyz * 2.0 - 1.0; 45 | float3 N = normalize(Na); 46 | 47 | // view 48 | float3 V = -normalize(inp.view_ray.xyz); 49 | 50 | // if diffuse_albedo has alpha = 0, the color is actually emissive 51 | if (shading_mode == 2) 52 | return diffuse_albedo*100; 53 | 54 | // reconstruct position in world space 55 | float3 P = camera_pos + (-V * depth); 56 | 57 | bool is_real = is_real_surface(P); 58 | 59 | //#define DEBUG_NORMALS 60 | #ifdef DEBUG_NORMALS 61 | float3 vP = mul(world_to_svo, float4(camera_pos, 1.0)).xyz; 62 | float3 vV = mul(world_to_svo, float4(-V, 0.0)).xyz; 63 | 64 | float4 x = trace_cone(vP, normalize(vV), 0.0001, 50, true, 1); 65 | 66 | if (x.w > 0.f) 67 | return x; 68 | //return x / 2.5 / 2.0 + 0.5; 69 | else 70 | return kinect_background; 71 | #endif 72 | 73 | //#define DEBUG_VOLUME 74 | #ifdef DEBUG_VOLUME 75 | float3 vP = mul(world_to_svo, float4(P, 1.0)).xyz; 76 | 77 | int4 lpos = int4(vP * SVO_SIZE, 0); 78 | 79 | return normalize(normal_volume.Load(lpos)).rgba / 2.0 + 0.5; 80 | #endif 81 | 82 | // light 83 | float3 Ll = main_light.position.xyz - P; 84 | float3 L = normalize(Ll); 85 | 86 | // lambert 87 | float NoL = saturate(dot(N, L)); 88 | 89 | // have no gloss maps, roughness is simply inverse spec color 90 | float roughness = 1.0 - specular_albedo.r; 91 | 92 | // calculate power of light and scale it to get the scene adequately lit 93 | float power = 100 * length(scene_dim_max - scene_dim_min); 94 | 95 | // calculate irradiance 96 | float3 Li = M_PI * (power * get_spotlight(L, N) * main_light.color.rgb) / dot(Ll, Ll); 97 | 98 | // shadow attenuation factor 99 | float attenuation = shadow_cone(P, L, N, 0.0005); 100 | 101 | // brdf 102 | float3 f = brdf(L, V, N, diffuse_albedo.rgb, specular_albedo.rgb, 1); 103 | 104 | // emissive 105 | float3 T0 = 0; 106 | 107 | // direct 108 | float3 T1 = f * Li * attenuation * NoL; 109 | 110 | if (is_real) 111 | { 112 | // NOTE: this might look nice, but erradicates all real indirect bounces from the image as well 113 | // T1 = kinect_background * attenuation 114 | // Correct way: use regular background, compute antiradiance from shadowed light source only and add this to T1 115 | T1 = kinect_background.rgb; 116 | f = brdf(L, V, N, diffuse_albedo.rgb, 0, 1); 117 | T1 -= kinect_background.rgb * f * (1 - attenuation); 118 | } 119 | 120 | // indirect bounce number one 121 | float3 T2 = float3(0, 0, 0); 122 | 123 | // first bounce 124 | float4 diffuse_indirect = diffuse_from_vct(inp.tex_coord.xy, P, N, V, is_real); 125 | T2 += diffuse_indirect.rgb * gi_scale * diffuse_albedo.rgb / M_PI; 126 | 127 | if (is_real) 128 | { 129 | float4 specular_indirect = specular_from_vct(P, N, V, glossiness, is_real); 130 | T2 += specular_indirect.rgb * gi_scale; 131 | T1 *= pow(1 - specular_indirect.a, 10); 132 | } 133 | 134 | if (debug_gi) 135 | return float4(abs(T2), 1.0f); 136 | 137 | return float4(max(T0 + T1 + T2, 0.0f), !is_real); 138 | } 139 | -------------------------------------------------------------------------------- /shader/brdf.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common.h" 8 | 9 | #ifndef BRDF_HLSL 10 | #define BRDF_HLSL 11 | 12 | #define F0_WATER 0.02,0.02,0.02 13 | #define F0_PLASTIC 0.03,0.03,0.03 14 | #define F0_PLASTIC_HIGH 0.05,0.05,0.05 15 | #define F0_GLASS 0.08,0.08,0.08 16 | #define F0_DIAMOND 0.17,0.17,0.17 17 | #define F0_IRON 0.56,0.57,0.58 18 | #define F0_COPPER 0.95,0.64,0.54 19 | #define F0_GOLD 1.00,0.71,0.29 20 | #define F0_ALUMINIUM 0.91,0.92,0.92 21 | #define F0_SILVER 0.95,0.93,0.88 22 | 23 | float sqr(in float x) 24 | { 25 | return x * x; 26 | } 27 | 28 | // Schlick's approximation of the fresnel term 29 | float F_schlick(in float f0, in float LoH) 30 | { 31 | // only have specular if f0 isn't 0 32 | //float enable = float(dot(f0, 1.0f) > 0.0f); 33 | return (f0 + (1.0f - f0) * pow(1.0f - LoH, 5.0f)); 34 | } 35 | 36 | // Optimizied Schlick 37 | // http://seblagarde.wordpress.com/2011/08/17/hello-world/ 38 | float SphericalGaussianApprox(in float CosX, in float ModifiedSpecularPower) 39 | { 40 | return exp2(ModifiedSpecularPower * CosX - ModifiedSpecularPower); 41 | } 42 | 43 | #define OneOnLN2_x6 8.656170 // == 1/ln(2) * 6 (6 is SpecularPower of 5 + 1) 44 | 45 | float3 F_schlick_opt(in float3 SpecularColor, in float3 E, in float3 H) 46 | { 47 | // In this case SphericalGaussianApprox(1.0f - saturate(dot(E, H)), OneOnLN2_x6) is equal to exp2(-OneOnLN2_x6 * x) 48 | return SpecularColor + (1.0f - SpecularColor) * exp2(-OneOnLN2_x6 * saturate(dot(E, H))); 49 | } 50 | 51 | // Microfacet Models for Refraction through Rough Surfaces 52 | // Walter et al. 53 | // http://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.html 54 | // aka Towbridge-Reitz 55 | float D_ggx(in float alpha, in float NoH) 56 | { 57 | float a2 = alpha*alpha; 58 | float cos2 = NoH*NoH; 59 | 60 | return (1.0f/M_PI) * sqr(alpha/(cos2 * (a2 - 1) + 1)); 61 | 62 | /* 63 | // version from the paper, eq 33 64 | float CosSquared = NoH*NoH; 65 | float TanSquared = (1.0f - CosSquared)/CosSquared; 66 | return (1.0f/M_PI) * sqr(alpha/(CosSquared * (alpha*alpha + TanSquared))); 67 | */ 68 | } 69 | 70 | // Smith GGX with denominator 71 | // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html 72 | float G_smith_ggx(in float a, in float NoV, in float NoL) 73 | { 74 | float a2 = a*a; 75 | float G_V = NoV + sqrt((NoV - NoV * a2) * NoV + a2); 76 | float G_L = NoL + sqrt((NoL - NoL * a2) * NoL + a2); 77 | return rcp(G_V * G_L); 78 | } 79 | 80 | // Schlick GGX 81 | // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html 82 | float G_UE4(in float alpha, in float NoV) 83 | { 84 | float k = alpha/2; 85 | return NoV/(NoV * (1 - k) + k); 86 | } 87 | 88 | float G_implicit(in float NoV, in float NoL) 89 | { 90 | return NoL * NoV; 91 | } 92 | 93 | // Beckmann distribution 94 | float D_beckmann(in float m, in float t) 95 | { 96 | float M = m*m; 97 | float T = t*t; 98 | return exp((T-1)/(M*T)) / (M*T*T); 99 | } 100 | 101 | // Helper to convert roughness to Phong specular power 102 | float alpha_to_spec_pow(in float a) 103 | { 104 | return 2.0f / (a * a) - 2.0f; 105 | } 106 | 107 | // Helper to convert Phong specular power to alpha 108 | float spec_pow_to_alpha(in float s) 109 | { 110 | return sqrt(2.0f / (s + 2.0f)); 111 | } 112 | 113 | // Blinn Phong with conversion functions for roughness 114 | float D_blinn_phong(in float n, in float NoH) 115 | { 116 | float alpha = spec_pow_to_alpha(n); 117 | 118 | return (1.0f / (M_PI*alpha*alpha)) * pow(NoH, n); 119 | } 120 | 121 | // Cook-Torrance specular BRDF + diffuse 122 | float3 brdf(in float3 L, in float3 V, in float3 N, in float3 cdiff, in float3 cspec, in float roughness) 123 | { 124 | float alpha = roughness*roughness; 125 | 126 | float3 H = normalize(L+V); 127 | 128 | float NoL = dot(N, L); 129 | float NoV = dot(N, V); 130 | float NoH = dot(N, H); 131 | float LoH = dot(L, H); 132 | 133 | // refractive index 134 | float n = 1.5; 135 | float f0 = pow((1 - n)/(1 + n), 2); 136 | 137 | // the fresnel term 138 | float F = F_schlick(f0, LoH); 139 | 140 | // the geometry term 141 | float G = G_UE4(alpha, NoV); 142 | 143 | // the NDF term 144 | float D = D_ggx(alpha, NoH); 145 | 146 | // specular term 147 | float3 Rs = cspec/M_PI * 148 | (F * G * D)/ 149 | (4 * NoL * NoV); 150 | 151 | // diffuse fresnel, can be cheaper as 1-f0 152 | float Fd = F_schlick(f0, NoL); 153 | 154 | float3 Rd = cdiff/M_PI * (1.0f - Fd); 155 | 156 | return (Rd + Rs); 157 | } 158 | 159 | #endif 160 | -------------------------------------------------------------------------------- /src/common_dxut.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | #include "common_dxut.h" 8 | #include "common_gui.h" 9 | 10 | namespace dc 11 | { 12 | void CALLBACK on_releasing_swap_chain(void* pUserContext) 13 | { 14 | dc::gui::dlg_manager.OnD3D11ReleasingSwapChain(); 15 | } 16 | 17 | bool CALLBACK on_modify_device(DXUTDeviceSettings* settings, void* user_context) 18 | { 19 | #if defined(DEBUG) | defined(_DEBUG) 20 | settings->d3d11.CreateFlags = D3D11_CREATE_DEVICE_DEBUG; 21 | #endif 22 | 23 | return true; 24 | } 25 | 26 | void CALLBACK on_render(ID3D11Device* device, ID3D11DeviceContext* context, double fTime, float fElapsedTime, void* pUserContext) 27 | { 28 | static float clear_color[4] = { 0.0f, 0.f, 0.0f, 1.0f }; 29 | 30 | if (the_renderer) 31 | the_renderer->render(context, DXUTGetD3D11RenderTargetView(), DXUTGetD3D11DepthStencilView()); 32 | 33 | // render gui 34 | dc::gui::on_render(device, context, fTime, fElapsedTime, pUserContext); 35 | } 36 | 37 | HRESULT CALLBACK on_resize(ID3D11Device* pd3dDevice, IDXGISwapChain *pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext) 38 | { 39 | tclog << L"State: Resizing" << std::endl; 40 | 41 | if (the_renderer) 42 | the_renderer->resize(pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height); 43 | 44 | dc::gui::on_resize(pd3dDevice, pSwapChain, pBackBufferSurfaceDesc, pUserContext); 45 | 46 | return S_OK; 47 | } 48 | 49 | void CALLBACK on_frame_move(double fTime, float fElapsedTime, void* pUserContext) 50 | { 51 | if (the_renderer) 52 | the_renderer->update_frame(the_context, fTime, fElapsedTime); 53 | } 54 | 55 | LRESULT CALLBACK on_msg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing, void *pUserContext) 56 | { 57 | dc::gui::on_msg(hWnd, uMsg, wParam, lParam, pbNoFurtherProcessing, pUserContext); 58 | 59 | if (*pbNoFurtherProcessing) 60 | return 0; 61 | 62 | if (the_renderer) 63 | the_renderer->update_camera(the_context, hWnd, uMsg, wParam, lParam); 64 | 65 | return 0; 66 | } 67 | 68 | void CALLBACK on_destroy_device(void* pUserContext) 69 | { 70 | tclog << L"State: Destroy" << std::endl; 71 | 72 | if (the_renderer) 73 | the_renderer->destroy(); 74 | 75 | dc::gui::dlg_manager.OnD3D11DestroyDevice(); 76 | } 77 | 78 | void CALLBACK on_keyboard(UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext) 79 | { 80 | if (!the_renderer) 81 | return; 82 | 83 | static const auto save_stuff = [](dune::serializer& s){ the_renderer->save(s); }; 84 | static const auto load_stuff = [](dune::serializer& s){ the_renderer->load(the_context, s); }; 85 | 86 | if (nChar == 'C' && bKeyDown) 87 | { 88 | static bool enable = false; 89 | enable = !enable; 90 | 91 | if (enable) 92 | the_renderer->start_capture(the_device, DXUTGetWindowWidth(), DXUTGetWindowHeight(), 30); 93 | else 94 | the_renderer->stop_capture(); 95 | } 96 | 97 | if (nChar == 'R' && bKeyDown) 98 | the_renderer->reload_shader(the_device, the_context); 99 | 100 | if (nChar == 'O' && bKeyDown) 101 | dc::gui::toggle(); 102 | 103 | if (nChar == 'P' && bKeyDown) 104 | dc::gui::save_settings(save_stuff); 105 | } 106 | 107 | void CALLBACK on_gui_event(UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext) 108 | { 109 | if (!the_renderer) 110 | return; 111 | 112 | CDXUTDialog* current_tab = pControl->m_pDialog; 113 | 114 | if (current_tab == &dc::gui::hud_postp1 || 115 | current_tab == &dc::gui::hud_postp2) 116 | { 117 | dc::gui::get_parameters(the_renderer->postprocessor()); 118 | the_renderer->update_postprocessing_parameters(the_context); 119 | } 120 | 121 | switch (nControlID) 122 | { 123 | case IDC_TOGGLE_FULLSCREEN: 124 | DXUTToggleFullScreen(); 125 | break; 126 | 127 | case IDC_TARGETS: 128 | the_renderer->show_target(the_context, dc::gui::combo_render_targets->GetSelectedItem()->strText); 129 | break; 130 | 131 | case IDC_SETTINGS: 132 | dc::gui::select_hud(); 133 | break; 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main_gi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The Dirtchamber - Tobias Alexander Franke 2013 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #include "gi_renderer.h" 10 | 11 | gi_renderer renderer; 12 | 13 | void update_timings_gui() 14 | { 15 | dune::tstringstream ss; 16 | 17 | ss << L"RSM: " << renderer.time_rsm_ << L"ms\n" 18 | #ifdef LPV 19 | << L"Inject: " << renderer.volume().time_inject_ << L"ms\n" 20 | << L"Normalize: " << renderer.volume().time_normalize_ << L"ms\n" 21 | << L"Propagate: " << renderer.volume().time_propagate_ << L"ms\n" 22 | #else 23 | << L"Inject: " << renderer.volume().time_inject_ << L"ms\n" 24 | << L"Voxelize: " << renderer.volume().time_voxelize_ << L"ms\n" 25 | << L"Filtering: " << renderer.volume().time_mip_ << L"ms\n" 26 | #endif 27 | << L"Deferred: " << renderer.time_deferred_ << "ms\n" 28 | ; 29 | 30 | dc::gui::set_text(IDC_DEBUG_INFO + 0, ss.str().c_str()); 31 | } 32 | 33 | void CALLBACK on_keyboard(UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext) 34 | { 35 | dc::on_keyboard(nChar, bKeyDown, bAltDown, pUserContext); 36 | 37 | static const auto load_stuff = [](dune::serializer& s){ renderer.load(the_context, s); }; 38 | 39 | if (nChar == 'L' && bKeyDown) 40 | { 41 | if (dc::gui::load_settings(load_stuff)) 42 | { 43 | dc::gui::set_parameters(renderer.postprocessor()); 44 | dc::gui::set_parameters(renderer.volume()); 45 | dc::gui::set_parameters(renderer.main_light(), renderer.scene(), z_near, z_far); 46 | } 47 | } 48 | } 49 | 50 | HRESULT CALLBACK on_create_device(ID3D11Device* device, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext) 51 | { 52 | tclog << L"State: Create" << std::endl; 53 | 54 | the_device = device; 55 | the_context = DXUTGetD3D11DeviceContext(); 56 | 57 | dune::assert_hr(dc::gui::dlg_manager.OnD3D11CreateDevice(device, the_context)); 58 | 59 | renderer.create(device); 60 | the_renderer = &renderer; 61 | 62 | dc::gui::get_parameters(renderer.volume()); 63 | dc::gui::get_parameters(renderer.postprocessor()); 64 | dc::gui::get_parameters(renderer.main_light(), renderer.scene(), z_near, z_far); 65 | 66 | renderer.update_everything(the_context); 67 | 68 | return S_OK; 69 | } 70 | 71 | void CALLBACK on_render(ID3D11Device* device, ID3D11DeviceContext* context, double fTime, float fElapsedTime, void* pUserContext) 72 | { 73 | dc::on_render(device, context, fTime, fElapsedTime, pUserContext); 74 | 75 | update_timings_gui(); 76 | } 77 | 78 | void CALLBACK on_gui_event(UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext) 79 | { 80 | dc::on_gui_event(nEvent, nControlID, pControl, pUserContext); 81 | 82 | CDXUTDialog* current_tab = pControl->m_pDialog; 83 | 84 | if (current_tab == &dc::gui::hud_gi) 85 | { 86 | dc::gui::get_parameters(renderer.volume()); 87 | renderer.update_gi_parameters(the_context); 88 | } 89 | 90 | if (current_tab == &dc::gui::hud_light) 91 | { 92 | dc::gui::get_parameters(renderer.main_light(), renderer.scene(), z_near, z_far); 93 | renderer.update_light_parameters(the_context, renderer.main_light()); 94 | } 95 | } 96 | 97 | int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 98 | { 99 | #if defined(DEBUG) | defined(_DEBUG) 100 | _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 101 | #endif 102 | 103 | try 104 | { 105 | dune::logger::init(L"../../data/log.txt"); 106 | 107 | files_scene = dune::files_from_args(lpCmdLine, L"../../data/cornellbox/cornellbox.obj"); 108 | 109 | DXUTSetCallbackKeyboard(on_keyboard); 110 | DXUTSetCallbackD3D11DeviceCreated(on_create_device); 111 | DXUTSetCallbackD3D11FrameRender(on_render); 112 | DXUTSetCallbackD3D11DeviceDestroyed(dc::on_destroy_device); 113 | DXUTSetCallbackD3D11SwapChainResized(dc::on_resize); 114 | DXUTSetCallbackMsgProc(dc::on_msg); 115 | DXUTSetCallbackFrameMove(dc::on_frame_move); 116 | DXUTSetCallbackD3D11SwapChainReleasing(dc::on_releasing_swap_chain); 117 | DXUTSetCallbackDeviceChanging(dc::on_modify_device); 118 | 119 | dc::gui::init(on_gui_event); 120 | 121 | DXUTInit(true, true); 122 | DXUTCreateWindow(L"dirtchamber"); 123 | DXUTCreateDevice(D3D_FEATURE_LEVEL_11_0, true, 1280, 720); 124 | 125 | dc::gui::update(&renderer); 126 | 127 | DXUTMainLoop(); 128 | } 129 | catch (dune::exception& e) 130 | { 131 | tcerr << e.msg() << std::endl; 132 | dc::on_destroy_device(nullptr); 133 | } 134 | 135 | return DXUTGetExitCode(); 136 | } 137 | -------------------------------------------------------------------------------- /src/dune/kinect_gbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Dune D3D library - Tobias Alexander Franke 2012 3 | * For copyright and license see LICENSE 4 | * http://www.tobias-franke.eu 5 | */ 6 | 7 | /*! \file */ 8 | 9 | #ifndef DUNE_KINECT_GBUFFER 10 | #define DUNE_KINECT_GBUFFER 11 | 12 | #ifdef MICROSOFT_KINECT_SDK 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include "gbuffer.h" 20 | #include "unicode.h" 21 | 22 | #define RT_KINECT_DEPTH L"depth" 23 | #define RT_KINECT_COLOR L"color" 24 | 25 | namespace dune 26 | { 27 | /*! 28 | * \brief A GBuffer fed from a Kinect camera. 29 | * 30 | * The kinect_gbuffer is a regular Geometry Buffer which is fed from a Kinect camera. It has two targets 31 | * for depth and colors. When passing this buffer to a deferred renderer, it will not notice the difference 32 | * to a regular GBuffer and can therefore render for instance post-processing effects as usual. 33 | * 34 | * kinect_gbuffer objects work with a two step update model with pull mechanics. 35 | * A thread is spawned which copies images received from the Kinect into two internal render_target objects. 36 | * Once the render_target objects are written to, flags are raised to indicate this to other threads. 37 | * The application thread calls the update method to pull data over into the gbuffer 38 | * objects. This is necessary to be able to update buffers without managing two D3D context objects 39 | * in a multithreading environment, because GBuffers under normal circumstances can only be accessed 40 | * in the same thread as the renderer. 41 | */ 42 | class kinect_gbuffer : public gbuffer 43 | { 44 | protected: 45 | enum DATA_TYPE 46 | { 47 | DEPTH, 48 | COLOR 49 | }; 50 | 51 | HANDLE the_thread_; 52 | HANDLE color_event_; 53 | HANDLE depth_event_; 54 | HANDLE kill_event_; 55 | HANDLE color_stream_; 56 | HANDLE depth_stream_; 57 | 58 | INuiSensor *sensor_; 59 | 60 | bool align_streams_; 61 | 62 | CRITICAL_SECTION cs_color_, cs_depth_; 63 | 64 | protected: 65 | /*! \brief The thread which updates render_targets from the Kinect API. */ 66 | static DWORD WINAPI thread(LPVOID); 67 | 68 | /*! \brief Initializes a Kinect camera. */ 69 | void init(); 70 | 71 | /*! \brief Stops the Kinect thread and shuts down the Kinect. */ 72 | void shutdown(); 73 | 74 | /*! \brief Map and update the depth render_target GPU memory from the CPU copy. */ 75 | void update_depth(ID3D11DeviceContext* context); 76 | 77 | /*! \brief Map and update the color render_target GPU memory from the CPU copy. */ 78 | void update_color(ID3D11DeviceContext* context); 79 | 80 | size_t width_, height_; 81 | bool has_new_depth_, has_new_color_; 82 | 83 | // hide me: kinect_gbuffer cannot be created empty or resized. 84 | void create(ID3D11Device* device); 85 | void resize(size_t width, size_t height); 86 | 87 | /*! 88 | * \brief Copies over NUI_IMAGE_FRAMEs to render_targets. 89 | * 90 | * Calling this method with a type will copy over a NUI_IMAGE_FRAME to a render_target's CPU bound buffer. 91 | * 92 | * \param type The type of the buffer to copy: color or depth. 93 | */ 94 | void copy_buffer(DATA_TYPE type); 95 | 96 | /*! \brief Lock a buffer type. */ 97 | void lock(DATA_TYPE type); 98 | 99 | /*! \brief Unlock a buffer type. */ 100 | void unlock(DATA_TYPE type); 101 | 102 | public: 103 | kinect_gbuffer(); 104 | virtual ~kinect_gbuffer() {} 105 | 106 | virtual void create(ID3D11Device* device, const tstring& name, UINT w = 640, UINT h = 480, bool align_streams = true); 107 | void destroy(); 108 | 109 | /*! \brief Start an initialized Kinect camera. */ 110 | void start(); 111 | 112 | /*! \brief Stop a running Kinect camera. */ 113 | void stop(); 114 | 115 | /*! \brief Copy over all render_target CPU memory to the GPU. Call this method every before rendering. */ 116 | void update(ID3D11DeviceContext* context); 117 | 118 | /*! \brief Returns the depth render_target. */ 119 | render_target* depth() 120 | { return target(RT_KINECT_DEPTH); } 121 | 122 | /*! \brief Returns the color render_target. */ 123 | render_target* color() 124 | { return target(RT_KINECT_COLOR); } 125 | 126 | //!@{ 127 | /*! \brief Return the minimum and maximum depth range defined by the Kinect SDK. */ 128 | float depth_min() const; 129 | float depth_max() const; 130 | //!@} 131 | }; 132 | } 133 | 134 | #endif 135 | 136 | #endif 137 | --------------------------------------------------------------------------------