Skip to content

Commit

Permalink
Fix out-of-date tutorials (#336)
Browse files Browse the repository at this point in the history
* Fix expired API and paths

* Fix mogwai option flags

* Fix typos and add description for reflect()

* Fix unfollowing codes to coding conventions

* Fix heading level of reflect() description

* Fix incorrect description of object

replace 'array' with 'dictionary' and fix typo of 'perframeCB'.
  • Loading branch information
udemegane authored Jan 31, 2023
1 parent 703eb30 commit 430824f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 18 deletions.
5 changes: 4 additions & 1 deletion docs/tutorials/01-mogwai-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Run Mogwai from within Visual Studio (by pressing Ctrl+F5), or from the command
-h, --help Display this help menu.
-s[path], --script=[path] Python script file to run.
--deferred The script is loaded deferred.
-S[path], --scene=[path] Scene file (for example, a .pyscene
file) to open.
-l[path], --logfile=[path] File to write log into.
Expand All @@ -42,6 +43,8 @@ Run Mogwai from within Visual Studio (by pressing Ctrl+F5), or from the command
-d, --debug-shaders Generate shader debug info.
--enable-debug-layer Enable debug layer (enabled by default
in Debug build).
--precise Force all slang programs to run in
precise mode
```

Using `--silent` together with `--script` allows to run Mogwai for rendering in the background.
Expand All @@ -53,7 +56,7 @@ If you start it without specifying any options, Mogwai starts with a blank scree
With Mogwai up and running, we'll proceed to loading something. You can load two kinds of files: scripts (which usually contain some global settings and render graphs) and scenes.

### Loading a Script (.py)
Open the load script dialog by either going to `File -> Load Script` or hitting `Ctrl + O`. Navigate to the location of the script you wish to run and select it to load and run it. Alternatively, dragging-and-dropping a script into Mogwai will also work. Note that scripts intended for use with Mogwai must be written in Python. Full scripting documentation can be found [here](../Usage/Scripting.md).
Open the load script dialog by either going to `File -> Load Script` or hitting `Ctrl + O`. Navigate to the location of the script you wish to run and select it to load and run it. Alternatively, dragging-and-dropping a script into Mogwai will also work. Note that scripts intended for use with Mogwai must be written in Python. Full scripting documentation can be found [here](../usage/scripting.md).

Here, we'll load the Forward Renderer, located at `Source/Mogwai/Data/ForwardRenderer.py`.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/02-implementing-a-render-pass.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ You can adjust the description of the render pass library by adjusting the follo
const RenderPass::Info ExampleBlitPass::kInfo { "ExampleBlitPass", "Blits a texture into another texture." };
```
We will ignore further details regarding render passes and their implementation for the purposes of this tutorial. Additional information can be found [here](../Usage/Render-Passes.md).
We will ignore further details regarding render passes and their implementation for the purposes of this tutorial. Additional information can be found [here](../usage/render-passes.md).
2 changes: 1 addition & 1 deletion docs/tutorials/03-creating-and-editing-render-graphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Creating a render graph through scripting follows similar steps as creating it t
- `markOutput()` takes an optional `mask` parameter specifying which color channels to output for frame capture.
- Multiple calls to `markOutput()` with different masks can be made, frame capture will generate separate output files.

*For more information on the scripting API, you can find the documentation [here](../Usage/Scripting.md).*
*For more information on the scripting API, you can find the documentation [here](../usage/scripting.md).*

To create a render graph through scripting:
1. Create a function to contain the commands. This is not required, but recommended.
Expand Down
68 changes: 53 additions & 15 deletions docs/tutorials/04-writing-shaders.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Writing Shaders

Now that we've written a basic render pass and render graph, let's look at writing more complex passes that use shaders. Falcor uses the Slang shading language and compiler, and files should use one of the following extensions: `.slang`, `.slangh`, `.hlsl`, `.hlsli`. For more information on best practices for working with shaders in Falcor, please refer to the *Using Shaders and Data Files* section of the [Getting Started](../Getting-Started.md) page.
Now that we've written a basic render pass and render graph, let's look at writing more complex passes that use shaders. Falcor uses the Slang shading language and compiler, and files should use one of the following extensions: `.slang`, `.slangh`, `.hlsl`, `.hlsli`. For more information on best practices for working with shaders in Falcor, please refer to the *Using Shaders and Data Files* section of the [Getting Started](../getting-started.md) page.

For this tutorial, we'll create a pass that renders a scene as a wireframe of a particular color.

Expand Down Expand Up @@ -53,10 +53,10 @@ While `create()` does not need to do more than calling the constructor and retur

The constructor should look similar to this:
```c++
WireframePass::WireframePass()
WireframePass::WireframePass() : RenderPass(kInfo)
{
mpProgram = GraphicsProgram::createFromFile("RenderPasses/WireframePass/Wireframe.3d.slang", "vsMain", "psMain");

mpProgram = GraphicsProgram::createFromFile("RenderPasses/Wireframe/Wireframe.3d.slang", "vsMain",
"psMain");
RasterizerState::Desc wireframeDesc;
wireframeDesc.setFillMode(RasterizerState::FillMode::Wireframe);
wireframeDesc.setCullMode(RasterizerState::CullMode::None);
Expand All @@ -67,6 +67,16 @@ WireframePass::WireframePass()
mpGraphicsState->setRasterizerState(mpRasterState);
}
```
### `reflect()`
As in the Implementing a Render Pass tutorial, you simply set the Output for the Wireframe view.
```c++
RenderPassReflection WireframePass::reflect(const CompileData& compileData)
{
RenderPassReflection reflector;
reflector.addOutput("output", "Wireframe view texture");
return reflector;
}
```

### `setScene()`
Our first render pass had no need for a `Scene` object; however, this pass does and will need this function to set `mpScene`. We first need to set `mpScene` to the scene that's passed in then add all scene defines to `mpProgram`. We then create our `GraphicsVars` so that we can bind shader variables later in `execute()`. These are done like so:
Expand All @@ -93,38 +103,66 @@ pRenderContext->clearFbo(pTargetFbo.get(), clearColor, 1.0f, 0, FboAttachmentTyp
mpGraphicsState->setFbo(pTargetFbo);
```

#### Setting the Render State
We need to perform two operations here: indicate that we want to use a custom `RasterizerState` and bind all necessary values to our shader. We can indicate that we're using a custom `RasterizerState` by creating a `Scene::Renderflags` object and setting the flag `Scene::RenderFlags::UserRasterizerState`. Binding shader values is also fairly straightforward as Falcor allows you to set shader values in the `GraphicsVars` object in the same way as you would set values in an array. Our shader requires a single color value, `gColor`, which is located inside the `perFrameCB` constant buffer. This step should look like this:
#### Binding the shader
Binding shader values is also fairly straightforward as Falcor allows you to set shader values in the `GraphicsVars` object in the same way as you would set values in a dictionary. Our shader requires a single color value, `gColor`, which is located inside the `PerFrameCB` constant buffer. This step should look like this:
```c++
Scene::RenderFlags renderFlags = Scene::RenderFlags::UserRasterizerState;
mpVars["perFrameCB"]["gColor"] = float4(0, 1, 0, 1);
mpVars["PerFrameCB"]["gColor"] = float4(0, 1, 0, 1);
```

#### Rendering a Scene Using the Shader
With our scene, shader, and both the `GraphicsState` and `RasterizerState` set up, we can finally render our scene at the end of `execute()`. This is done through the `render()` method of `mpScene`, like so:
```c++
mpScene->rasterize(pRenderContext, mpGraphicsState.get(), mpGraphicsVars.get(), renderFlags);
mpScene->rasterize(pRenderContext, mpGraphicsState.get(), mpVars.get(), mpRasterState, mpRasterState);
```
Your `execute()` function should now look like this, with a check for `mpScene` so we avoid accessing the scene when it isn't set:
```c++
void WireframePass::execute(RenderContext* pRenderContext, const RenderData& renderData)
{
auto pTargetFbo = Fbo::create({ renderData.getTexture("output") });
auto pTargetFbo = Fbo::create({renderData.getTexture("output")});
const float4 clearColor(0, 0, 0, 1);
pRenderContext->clearFbo(pTargetFbo.get(), clearColor, 1.0f, 0, FboAttachmentType::All);
mpGraphicsState->setFbo(pTargetFbo);
if (mpScene)
{
// Set render state
Scene::RenderFlags renderFlags = Scene::RenderFlags::UserRasterizerState;
mpVars["PerFrameCB"]["gColor"] = float4(0, 1, 0, 1);
mpScene->rasterize(pRenderContext, mpGraphicsState.get(), mpVars.get(), renderFlags);
mpScene->rasterize(pRenderContext, mpGraphicsState.get(), mpVars.get(), mpRasterState, mpRasterState);
}
}
```

Using the Render Graph Editor, create a graph solely containing this pass then launch it in Mogwai. You should see a black screen as there is no scene currently loaded. Load a scene by going to `File -> Load Scene`, and you should now see the wireframe for the scene you selected. We used `media/Arcade/Arcade.pyscene`, which looks like this:
And you need to create CMakeLists.txt to include your C++ and Slang files in the build target.
```CMake
add_renderpass(WireframePass)
target_sources(WireframePass PRIVATE
WireframePass.cpp
WireframePass.h
WireframePass.3d.slang
)
target_copy_shaders(WireframePass RenderPasses/WireframePass)
target_source_group(WireframePass "RenderPasses")
```


Using the Render Graph Editor, create a graph solely containing this pass then launch it in Mogwai, or create a python script.
```python
from falcor import *

def render_graph_WireframePass():
g = RenderGraph('WireframePass')
loadRenderPassLibrary('WireframePass.dll')
Wireframe = createPass('WireframePass')
g.addPass(WireframePass, 'WireframePass')
g.markOutput('WireframePass.output')
return g

WireframePass = render_graph_WireframePass()
try: m.addGraph(WireframePass)
except NameError: None
```

You should see a green screen as there is no scene currently loaded. Load a scene by going to `File -> Load Scene`, and you should now see the wireframe for the scene you selected. We used `media/Arcade/Arcade.pyscene`, which looks like this:

![WireframePass](./images/wireframe-pass.png)

0 comments on commit 430824f

Please sign in to comment.