Skip to content

Commit

Permalink
Falcor 5.0 (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
skallweitNV committed Apr 4, 2022
1 parent 942f56b commit 64fa81b
Show file tree
Hide file tree
Showing 455 changed files with 14,664 additions and 3,549 deletions.
48 changes: 40 additions & 8 deletions Build/deploycommon.bat
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,52 @@ set NvApiDir=%ExtDir%\nvapi
set NvApiTargetDir=%OutDir%\Shaders\NVAPI
if exist %NvApiDir% (
if not exist %NvApiTargetDir% mkdir %NvApiTargetDir% >nul
copy /y %NvApiDir%\nvHLSLExtns.h %NvApiTargetDir%
copy /y %NvApiDir%\nvHLSLExtnsInternal.h %NvApiTargetDir%
copy /y %NvApiDir%\nvShaderExtnEnums.h %NvApiTargetDir%
copy /y %NvApiDir%\nvHLSLExtns.h %NvApiTargetDir% >nul
copy /y %NvApiDir%\nvHLSLExtnsInternal.h %NvApiTargetDir% >nul
copy /y %NvApiDir%\nvShaderExtnEnums.h %NvApiTargetDir% >nul
)

rem Copy NRD
set NrdDir=%ExtDir%\nrd
set NrdTargetDir=%OutDir%\Shaders\nrd\Shaders
if exist %NrdDir% (
if not exist %NrdTargetDir% mkdir %NrdTargetDir% >nul
robocopy %NrdDir%\Shaders %NrdTargetDir% /s /r:0 >nul
if %IsDebug% EQU 0 (
robocopy %NrdDir%\Lib\Release %OutDir% *.dll /r:0 >nul
) else (
robocopy %NrdDir%\Lib\Debug %OutDir% *.dll /r:0 >nul
)
)

rem Copy RTXDI SDK shaders
set RtxdiSDKDir=%ExtDir%\rtxdi\rtxdi-sdk\include\rtxdi
set RtxdiSDKTargetDir=%OutDir%\Shaders\rtxdi
if exist %RtxdiSDKDir% (
if not exist %RtxdiSDKTargetDir% mkdir %RtxdiSDKTargetDir% >nul
copy /y %RtxdiSDKDir%\ResamplingFunctions.hlsli %RtxdiSDKTargetDir% >nul
copy /y %RtxdiSDKDir%\Reservoir.hlsli %RtxdiSDKTargetDir% >nul
copy /y %RtxdiSDKDir%\RtxdiHelpers.hlsli %RtxdiSDKTargetDir% >nul
copy /y %RtxdiSDKDir%\RtxdiMath.hlsli %RtxdiSDKTargetDir% >nul
copy /y %RtxdiSDKDir%\RtxdiParameters.h %RtxdiSDKTargetDir% >nul
copy /y %RtxdiSDKDir%\RtxdiTypes.h %RtxdiSDKTargetDir% >nul
)

rem Copy Agility SDK Runtime
set AgilitySDKDir=%ExtDir%\agility-sdk
set AgilitySDKTargetDir=%OutDir%\D3D12
if exist %AgilitySDKDir% (
if not exist %AgilitySDKTargetDir% mkdir %AgilitySDKTargetDir% >nul
copy /y %AgilitySDKDir%\build\native\bin\x64\D3D12Core.dll %AgilitySDKTargetDir%
copy /y %AgilitySDKDir%\build\native\bin\x64\d3d12SDKLayers.dll %AgilitySDKTargetDir%
copy /y %AgilitySDKDir%\build\native\bin\x64\D3D12Core.dll %AgilitySDKTargetDir% >nul
copy /y %AgilitySDKDir%\build\native\bin\x64\d3d12SDKLayers.dll %AgilitySDKTargetDir% >nul
)

rem Copy NanoVDB
set NanoVDBApiDir=%ExtDir%\nanovdb
set NanoVDBDir=%ExtDir%\nanovdb
set NanoVDBTargetDir=%OutDir%\Shaders\NanoVDB
if exist %NanoVDBApiDir% (
if exist %NanoVDBDir% (
if not exist %NanoVDBTargetDir% mkdir %NanoVDBTargetDir% >nul
copy /y %NanoVDBApiDir%\include\nanovdb\PNanoVDB.h %NanoVDBTargetDir%
copy /y %NanoVDBDir%\include\nanovdb\PNanoVDB.h %NanoVDBTargetDir% >nul
)

rem Copy USD files, making sure not to overwrite dlls provided by other components, or dlls that we don't need.
Expand All @@ -94,5 +120,11 @@ if %IsDebug% EQU 0 (
robocopy %ExtDir%\nvtt\lib\x64-v141\Debug %OutDir% nvtt.dll /r:0 >nul
)

rem Copy DLSS
set NGXDir=%ExtDir%\ngx
if exist %NGXDir% (
robocopy %NGXDir%\lib\Windows_x86_64\rel %OutDir% nvngx_dlss.dll /r:0 >nul
)

rem robocopy sets the error level to something that is not zero even if the copy operation was successful. Set the error level to zero
exit /b 0
2 changes: 1 addition & 1 deletion Docs/Development/Error-Handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Note that error reporting is a separate topic from error handling and is discuss

* Use asserts to check for logic errors in C++ code; errors that should never occur and are a result of programmer mistakes rather than runtime conditions.
* Use `static_assert()` to check for logic errors at compile time if possible, for example, type checking of template arguments, or checking struct sizes.
* Use `assert()` to check for logic errors at runtime.
* Use `FALCOR_ASSERT()` to check for logic errors at runtime.
* Use asserts generously. Even trivially correct code might be affected by changes elsewhere.
* Make a habit of running the application in Debug mode regularly to make sure that no asserts trigger.

Expand Down
148 changes: 148 additions & 0 deletions Docs/Usage/Materials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
### [Index](../index.md) | [Usage](./index.md) | Materials

--------

# Materials

Starting with Falcor 5.0 there is a new material system that allows creation and rendering of different materials
types at runtime. In previous versions, a fixed diffuse+GGX material model was assumed.

All materials and their resources are managed by the `MaterialSystem` C++ class and matching Slang module.
The material system is owned by `Scene` object and bound together with its other resources when rendering.

In order to access the material system in shader code, the following module must be imported:

```c++
import Scene.Shading;
```

## Data layout

For efficient access, each material is described by a data blob of fixed size (currently 128B).
The data blob consists of a header (see `MaterialHeader` declared in `Falcor/Scene/Material/MaterialData.slang`)
followed by a data payload. The header always exists and holds material type ID and auxiliary flags etc.

The format of the data payload is opaque and depends on the material type. If a material needs more data
than what fits in the payload, it can store additional sideband data in a buffer.

All resources (textures, samplers, buffers) are accessed via bindless resource IDs, where the actual GPU
resources are managed by `MaterialSystem` and the IDs are allocated when resources are added.
These bindless IDs are stored as part of the data payload, so that a material is self-contained and fully
desribed by its data blob.

## Material class (host side)

On the host side, all materials are derived from the `Material` base class declared in `Scene/Material/Material.h`.

In order to add a new material, a new class should be added that inherits from `Material` and implements
its pure virtual member functions. The most important ones are:

```c++
// Called once per frame to prepare the material for rendering.
Material::UpdateFlags Material::update(MaterialSystem* pOwner);

// Returns the material data blob.
MaterialDataBlob Material::getDataBlob() const;
```
The base class holds the `MaterialHeader` struct and the derived material class is responsible
for holding the data payload. The `getDataBlob()` returns the final data blob, which will be uploaded to the
GPU by the material system for access on the shader side.
## Python bindings
To allow creation of materials and setting of the parameters from Python scripts (including `.pyscene` files),
each material class is expected to export Python bindings.
These bindings are defined in the `FALCOR_SCRIPT_BINDING` block, usually placed at the bottom of the material's `.cpp` file.
Example usage:
```c++
glass = StandardMaterial("WindowGlass")
glass.roughness = 0
glass.metallic = 0
glass.indexOfRefraction = 1.52
glass.specularTransmission = 1
glass.doubleSided = True
glass.nestedPriority = 2
glass.volumeAbsorption = float3(2.0, 1.0, 1.5)
```

For more examples of how material's are created from Python, refer to the test scenes in `Media/TestScenes/`
(this directory is automatically fetched when the solution is built the first time).

## Material module (shader side)

On the shader side, each material class has a corresponding Slang module stored in `Falcor/Rendering/Materials/`.
These modules implement the `IMaterial` Slang interface (see `Rendering/Materials/IMaterial.slang`).

The main purpose of the material module is to:
1. hold the material data, and
2. hold the code for setting up a BSDF at a shading point.

The latter is referred to as "pattern generation", which may involve sampling textures, evaluating
procedural functions, and any other setup needed for shading.

The first data field in the material module has to be the material header. This should be followed by the
material payload as declared for the material type. For example, the standard material is declared:

```c++
struct StandardMaterial : IMaterial
{
MaterialHeader header;
BasicMaterialData data;
...
};
```

An instance of the material is created by calling the material system as follows:

```c++
IMaterial material = gScene.materials.getMaterial(materialID);
```

Internally, this function accesses the material header to fetch the material type, and then it calls
Slang's `createDynamicObject<..>` function to create an instance of the right type.
The opaque material data blob is cast to the data types used in the material module, so its fields are
directly accessible internally in the material module.

## BSDF module (shader side)

Each material module has an associated BSDF type, which implements the `IBSDF` Slang interface.
For example, `StandardMaterial` has an associated `StandardBSDF` type.

An instance of the BSDF type is created for a specific shading point in the scene, and it exposes
interfaces for evaluating and sampling the BSDF at that point.
The `IBSDF` interface also has functions for querying additional BSDF properties
at the shading point, such as albedo, emission, etc.

A BSDF instance is created by calling the following function on the material:

```c++
ShadingData sd = ... // struct describing the shading point
ITextureSampler lod = ... // method for texture level-of-detail computation

IBSDF bsdf = material.setupBSDF(gScene.materials, sd, lod);
```

Internally, the `setupBSDF` function accesses the material system to fetch/evaluate all resources needed at the
shading point. It returns an instance of the material's associated BSDF type,
which the caller can then use to evaluate or sample the BSDF at the shading point.

Since creating the material followed by instantiating the BSDF is very common,
there is a convenience function `getBSDF()` on `MaterialSystem` that does both operations in one step:

```c++
IBSDF bsdf = gScene.materials.getBSDF(sd, lod);
```

In the above interfaces, a `ShadingData` struct is needed to describe the shading point.
This is generated at a hit point by calling the `prepareShadingData()` function.
This function is responsible for setting up the shading frame (normal, tangent, bitangent)
including evaluating normal mapping and material opacity for alpha testing.

In addition to this, a `ITextureSampler` instance is needed to describe how textures should
be sampled (if there are any). The caller is responsible for deciding this based on which
method for texture LOD it is using (e.g. ray cones, ray differentials, fixed mip level, etc).
See available choices in `Scene/Material/TextureSampler.slang`).
15 changes: 13 additions & 2 deletions Docs/Usage/Scene-Formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@

# Scene Formats

Falcor uses [Assimp](https://github.com/assimp/assimp) as its core asset loader and can load all file formats Assimp supports by default.
## USD Scene Files

Starting with version 5.0 Falcor includes an experimental importer for Universal Scene Description (USD) files.

The `UsdPreviewSurface` material model is partially supported by mapping to Falcor's `StandardMaterial` at load time.

## FBX/GLTF Scene Files

Falcor uses [Assimp](https://github.com/assimp/assimp) as its asset loader for FBX and GLTF scenes. It can load all other file formats Assimp supports by default, but support may be more limited.

All loaded material data is mapped to Falcor's `StandardMaterial` at load time.

From assets, Falcor will import:
- Scene Graph
Expand Down Expand Up @@ -132,7 +142,8 @@ Each vertex has a _position_, _normal_ and _texCoord_ attribute. Triangles are d

#### Create Materials

Next we need to define at least one material to use for our meshes:
Next we need to define at least one material to use for our meshes.
For more examples, see [Materials](./Materials.md).

```python
# Create materials
Expand Down
17 changes: 8 additions & 9 deletions Docs/Usage/Scenes.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,7 @@ GraphicsVars::SharedPtr pProgramVars = GraphicsVars::create(pProgram->getReflect
### Rasterization

The output of the default vertex shader includes two parameters: `instanceID`, and `materialID` which can be used to look up data for the current mesh being rendered.
```c++
gScene.geometryInstances[vertexOut.instanceID];
gScene.materials[vertexOut.materialID];
```
See interfaces in `Scene/Scene.slang`.

For basic usage, it is not necessary to perform the lookups yourself. A helper function defined in `Scene/Raster.slang` can load and prepare data for you.

Expand All @@ -131,7 +128,8 @@ import Scene.Raster;
float4 main(VSOut vertexOut, float4 pixelCrd : SV_POSITION, uint triangleIndex : SV_PrimitiveID) : SV_TARGET
{
float3 viewDir = normalize(gScene.camera.getPosition() - vOut.posW);
ShadingData sd = prepareShadingData(vertexOut, triangleIndex, viewDir);
let lod = ImplicitLodTextureSampler();
ShadingData sd = prepareShadingData(vertexOut, triangleIndex, viewDir, lod);
...
}
```
Expand All @@ -146,10 +144,11 @@ import Scene.Raytracing;
[shader("closesthit")]
void primaryClosestHit(inout PrimaryRayData hitData, in BuiltInTriangleIntersectionAttributes attribs)
{
const uint globalInstanceID = getGlobalInstanceID();
const VertexData v = getVertexData(globalInstanceID, PrimitiveIndex(), attribs);
const uint materialID = gScene.getMaterialID(globalInstanceID);
ShadingData sd = prepareShadingData(v, materialID, gScene.materials[materialID], gScene.materialResources[materialID], -WorldRayDirection(), 0);
GeometryInstanceID instanceID = getGeometryInstanceID();
VertexData v = getVertexData(instanceID, PrimitiveIndex(), attribs);
const uint materialID = gScene.getMaterialID(instanceID);
let lod = ExplicitLodTextureSampler(0.f);
ShadingData sd = gScene.materials.prepareShadingData(v, materialID, -WorldRayDirection(), lod);
...
}
```
4 changes: 4 additions & 0 deletions Docs/Usage/Scripting.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ class falcor.**EnvMap**
| `rotation` | `float3` | Rotation angles in degrees (XYZ). |
| `intensity` | `float` | Intensity (scalar multiplier). |

| Static method | Description |
|----------------------------|---------------------------------------|
| `createFromFile(filename)` | Create a environment map from a file. |

#### Material

**DEPRECATED**: Use `StandardMaterial` instead.
Expand Down
3 changes: 2 additions & 1 deletion Docs/Usage/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
- [Scene Creation](./Scene-Creation.md)
- [Scenes](./Scenes.md)
- [Scene Formats](./Scene-Formats.md)
- [Materials](./Materials.md)
- [Scripting](./Scripting.md)
- [Render Passes](./Render-Passes.md)
- [Path Tracer](./Path-Tracer.md)
- [Custom Primitives](./Custom-Primitives.md)
- [Custom Primitives](./Custom-Primitives.md)
44 changes: 44 additions & 0 deletions Falcor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Visualization2D", "Source\S
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PathTracer", "Source\RenderPasses\PathTracer\PathTracer.vcxproj", "{99799BA5-6503-425C-BFCC-8B94E6A40D1D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ModulateIllumination", "Source\RenderPasses\ModulateIllumination\ModulateIllumination.vcxproj", "{4E192689-E377-4936-8A1B-94B08226FC83}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NRDPass", "Source\RenderPasses\NRDPass\NRDPass.vcxproj", "{25964C78-F3F0-4889-869F-ADFDACEF0482}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLSSPass", "Source\RenderPasses\DLSSPass\DLSSPass.vcxproj", "{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTXDIPass", "Source\RenderPasses\RTXDIPass\RTXDIPass.vcxproj", "{8F778354-93D9-4030-B55F-19137650780D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
DebugD3D12|x64 = DebugD3D12|x64
Expand Down Expand Up @@ -410,6 +418,38 @@ Global
{99799BA5-6503-425C-BFCC-8B94E6A40D1D}.ReleaseD3D12|x64.Build.0 = Release|x64
{99799BA5-6503-425C-BFCC-8B94E6A40D1D}.ReleaseGFX|x64.ActiveCfg = Release|x64
{99799BA5-6503-425C-BFCC-8B94E6A40D1D}.ReleaseGFX|x64.Build.0 = Release|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.DebugD3D12|x64.ActiveCfg = Debug|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.DebugD3D12|x64.Build.0 = Debug|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.DebugGFX|x64.ActiveCfg = Debug|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.DebugGFX|x64.Build.0 = Debug|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.ReleaseD3D12|x64.ActiveCfg = Release|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.ReleaseD3D12|x64.Build.0 = Release|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.ReleaseGFX|x64.ActiveCfg = Release|x64
{4E192689-E377-4936-8A1B-94B08226FC83}.ReleaseGFX|x64.Build.0 = Release|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.DebugD3D12|x64.ActiveCfg = Debug|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.DebugD3D12|x64.Build.0 = Debug|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.DebugGFX|x64.ActiveCfg = Debug|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.DebugGFX|x64.Build.0 = Debug|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.ReleaseD3D12|x64.ActiveCfg = Release|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.ReleaseD3D12|x64.Build.0 = Release|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.ReleaseGFX|x64.ActiveCfg = Release|x64
{25964C78-F3F0-4889-869F-ADFDACEF0482}.ReleaseGFX|x64.Build.0 = Release|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.DebugD3D12|x64.ActiveCfg = Debug|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.DebugD3D12|x64.Build.0 = Debug|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.DebugGFX|x64.ActiveCfg = Debug|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.DebugGFX|x64.Build.0 = Debug|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.ReleaseD3D12|x64.ActiveCfg = Release|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.ReleaseD3D12|x64.Build.0 = Release|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.ReleaseGFX|x64.ActiveCfg = Release|x64
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32}.ReleaseGFX|x64.Build.0 = Release|x64
{8F778354-93D9-4030-B55F-19137650780D}.DebugD3D12|x64.ActiveCfg = Debug|x64
{8F778354-93D9-4030-B55F-19137650780D}.DebugD3D12|x64.Build.0 = Debug|x64
{8F778354-93D9-4030-B55F-19137650780D}.DebugGFX|x64.ActiveCfg = Debug|x64
{8F778354-93D9-4030-B55F-19137650780D}.DebugGFX|x64.Build.0 = Debug|x64
{8F778354-93D9-4030-B55F-19137650780D}.ReleaseD3D12|x64.ActiveCfg = Release|x64
{8F778354-93D9-4030-B55F-19137650780D}.ReleaseD3D12|x64.Build.0 = Release|x64
{8F778354-93D9-4030-B55F-19137650780D}.ReleaseGFX|x64.ActiveCfg = Release|x64
{8F778354-93D9-4030-B55F-19137650780D}.ReleaseGFX|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -452,6 +492,10 @@ Global
{05555565-706C-4633-BF8A-B99F96F2B301} = {D16038A7-B031-4181-B4A1-2C416C02330C}
{99FB6CED-94F9-4A5E-8238-E694B39351C0} = {4B8EAC4B-FFDF-4CCA-A6FE-4505631E51EC}
{99799BA5-6503-425C-BFCC-8B94E6A40D1D} = {D16038A7-B031-4181-B4A1-2C416C02330C}
{4E192689-E377-4936-8A1B-94B08226FC83} = {D16038A7-B031-4181-B4A1-2C416C02330C}
{25964C78-F3F0-4889-869F-ADFDACEF0482} = {D16038A7-B031-4181-B4A1-2C416C02330C}
{0B2F90ED-3524-4F92-8A0B-F542D90F3A32} = {D16038A7-B031-4181-B4A1-2C416C02330C}
{8F778354-93D9-4030-B55F-19137650780D} = {D16038A7-B031-4181-B4A1-2C416C02330C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {357B2AE0-FE30-4AC6-8D41-B580232BC0DE}
Expand Down
Loading

0 comments on commit 64fa81b

Please sign in to comment.