Просмотр исходного кода

More work on the documentation

BearishSun 8 лет назад
Родитель
Сommit
0e8f4b8b57

+ 3 - 3
Documentation/Manuals/Native/User/simpleMaterial.md

@@ -8,7 +8,7 @@ A shader is a set of GPU programs and render states that tell the GPU how is mes
 We will delay further discussion of shaders and GPU programs to a later chapter.
 
 # Material creation
-To create a material use the @ref bs::Material::create "Material::create" method, which expects a **Shader** as a parameter.
+To create a material use the @ref bs::Material::create "Material::create()" method, which expects a **Shader** as a parameter.
 
 ~~~~~~~~~~~~~{.cpp}
 // Get one of the built-in shaders
@@ -35,7 +35,7 @@ material->setTexture("gAlbedoTex", texture);
 
 After the texture has been set, anything rendered with that material will now have that particular texture applied. Different shaders will accept different parameters of different types. You can find out parameter names and types by looking at the shader source (discussed later).
 
-In this particular example we have a parameter named "gAlbedoTex" that accepts a **Texture** resource. We set such a parameter by calling @ref bs::Material::setTexture "Material::setTexture". There are other parameter types like floats, ints, colors, as well as multi-dimensional types like vectors and matrices which can be set by calling @ref bs::Material::setFloat "Material::setFloat", @ref bs::Material::setColor "Material::setColor", @ref bs::Material::setVec4 "Material::setVec4" and similar.
+In this particular example we have a parameter named "gAlbedoTex" that accepts a **Texture** resource. We set such a parameter by calling @ref bs::Material::setTexture "Material::setTexture()". There are other parameter types like floats, ints, colors, as well as multi-dimensional types like vectors and matrices which can be set by calling @ref bs::Material::setFloat "Material::setFloat()", @ref bs::Material::setColor "Material::setColor()", @ref bs::Material::setVec4 "Material::setVec4()" and similar.
 
 ~~~~~~~~~~~~~{.cpp}
 // Assuming our material has some more parameters, for purposes of the example
@@ -46,7 +46,7 @@ material->setMat4("someTransform", Matrix4::IDENTITY);
 ~~~~~~~~~~~~~
 
 ## Sampler states
-Sampler states are a special type of parameters that can be set by calling @ref bs::Material::setSamplerState "Material::setSamplerState". These states are used to control how is a texture read in a shader - for example they control what type of filtering to use, how to handle out of range texture coordinates and similar. Sampler states are created by calling @ref bs::SamplerState::create "SamplerState::create", while previously filling out the @ref bs::SAMPLER_STATE_DESC "SAMPLER_STATE_DESC" structure.
+Sampler states are a special type of parameters that can be set by calling @ref bs::Material::setSamplerState "Material::setSamplerState()". These states are used to control how is a texture read in a shader - for example they control what type of filtering to use, how to handle out of range texture coordinates and similar. Sampler states are created by calling @ref bs::SamplerState::create "SamplerState::create()", while previously filling out the @ref bs::SAMPLER_STATE_DESC "SAMPLER_STATE_DESC" structure.
 
 In most cases you don't need to set sampler states as the default one should be adequate. Shaders can also read textures without samplers by directly accessing their pixels, but this is not wanted for normal rendering as it ruins image quality due to the lack of filtering and it may not be as performance efficient. 
 

+ 222 - 0
Documentation/Manuals/Native/advMaterials.md

@@ -0,0 +1,222 @@
+Advanced materials									{#advMaterials}
+===============
+[TOC]
+
+We have already talked about how to create materials, assign them parameters and bind them to a **Renderable** component. In this section we'll show an advanced way to assign material parameters, how to use materials for rendering directly (without using **Renderable** component) and how to create your own shaders without the use of BSL.
+
+# Material parameters {#advMaterials_a}
+Previously we have shown to how to set **Material** parameters by calling methods like @ref bs::Material::setTexture "Material::setTexture()", @ref bs::Material::setFloat "Material::setFloat()", @ref bs::Material::setColor "Material::setColor()", @ref bs::Material::setVec4 "Material::setVec4()" and similar.
+
+As an alternative you can also set materials through material handles. Once a material handle is retrieved it allows you to set material parameters much more efficiently than by calling the methods above directly. 
+
+To retrieve the handles call any of the following methods, depending on material parameter type:
+ - @ref bs::ct::Material::getParamTexture "ct::Material::getParamTexture()" - Outputs a @ref bs::TMaterialParamTexture<Core> "MaterialParamTexture" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamLoadStoreTexture "ct::Material::getParamLoadStoreTexture()" - Outputs a @ref bs::TMaterialParamLoadStoreTexture<Core> "MaterialParamLoadStoreTexture" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamBuffer "ct::Material::getParamBuffer()" - Outputs a @ref bs::TMaterialParamBuffer<Core> "MaterialParamBuffer" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamSamplerState "ct::Material::getParamSamplerState()" - Outputs a @ref bs::TMaterialParamSampState<Core> "MaterialParamSampState" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamFloat "ct::Material::getParamFloat()" - Outputs a @ref bs::TMaterialDataParam<T, Core> "MaterialParamFloat" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamVec2 "ct::Material::getParamVec2()" - Outputs a @ref bs::TMaterialDataParam<T, Core> "MaterialParamVec2" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamVec3 "ct::Material::getParamVec3()" - Outputs a @ref bs::TMaterialDataParam<T, Core> "MaterialParamVec3" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamVec4 "ct::Material::getParamVec4()" - Outputs a @ref bs::TMaterialDataParam<T, Core> "MaterialParamVec4" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamColor "ct::Material::getParamColor()" - Outputs a @ref bs::TMaterialDataParam<T, Core> "MaterialParamColor" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamMat3 "ct::Material::getParamMat3()" - Outputs a @ref bs::TMaterialDataParam<T, Core> "MaterialParamMat3" handle that can be used for reading & writing the parameter value.
+ - @ref bs::ct::Material::getParamMat4 "ct::Material::getParamMat4()" - Outputs a @ref bs::TMaterialDataParam<T, Core> "MaterialParamMat4" handle that can be used for reading & writing the parameter value.
+ 
+Handles provide **set()** and **get()** methods that can be used for writing and reading the parameter values. 
+ 
+~~~~~~~~~~~~~{.cpp}
+HMaterial material = ...;
+
+MaterialParamMat4 myMatParam;
+MaterialParamTexture myTextureParam;
+
+material->getParamMat4("vertProjMatrix", myMatParam);
+material->getParamTexture("mainTexture", myTextureParam);
+
+Matrix4 viewProjMat = ...;
+SPtr<Texture> someTexture = ...;
+
+myVectorParam.set(viewProjMat);
+myTextureParam.set(someTexture);
+~~~~~~~~~~~~~ 
+ 
+Material handles are very similar as **GpuParams** handles we talked about earlier. There are two major differences:
+ - **GpuParams** handles will only set the parameter value for a specific **GpuProgram**, while material handles will set the values for all **GpuProgram**%s that map to that handle.
+ - **GpuProgram** parameters are retrieved directly from program source code, while **Material** parameters need to be explicitly defined in the **Shader** (shown below). **Material** parameters always map to one or multiple **GpuProgram** parameters. 
+
+# Creating a shader manaully {#advMaterials_b}
+So far when we wanted to create a shader we would create a BSL file which would then be imported, creating a @ref bs::Shader "Shader". But you can also create shaders manually by explicitly providing HLSL/GLSL code for **GpuProgram**%s and non-programmable states. 
+
+Each shader definition contains two things:
+ - A list of parameters, with a mapping of each parameter to one or multiple variables in a GPU program
+ - One or multiple @ref bs::Technique "Technique"%s. Each technique is essentially a fully fledged shader of its own. Techniques are chosen by the renderer depending on the context. For example some techniques only support the DirectX backend, while others only the Vulkan backend.
+  - Each technique contains one or multiple @ref bs::Pass "Pass"%es. A pass is a set of GPU programs and non-programmable states. When rendering using a certain technique each pass will be executed one after another. This allows you to render objects that require more complex rendering that requires multiple separate steps - althrough in practice most techniques have only a single pass.
+
+To summarize, the relationship between materials, shaders, techniques and passes is:
+ - **Material** [contains one]-> **Shader** [contains one or multiple]-> **Technique** [contains one or multiple]-> **Pass**
+ 
+## Creating a pass {#advMaterials_b_a}
+A **Pass** can be created by filling out a @ref bs::PASS_DESC "PASS_DESC" descriptor and passing it to @ref bs::Pass::create "Pass::create()" method. **PASS_DESC** is fairly simple and it expects a set of GPU programs and non-programmable states.
+
+~~~~~~~~~~~~~{.cpp}
+SPtr<GpuProgram> vertexProg = ...;
+SPtr<GpuProgram> fragmentProg = ...;
+
+SPtr<BlendState> blendState = ...;
+
+// Create a pass with a vertex and fragment program, and a non-default blend state
+PASS_DESC desc;
+desc.vertexProgram = vertexProg;
+desc.fragmentProg = fragmentProg;
+desc.blendState = blendState;
+
+SPtr<Pass> pass = Pass::create(desc);
+~~~~~~~~~~~~~
+
+GPU programs and non-programmable states are created as described in the low-level rendering API manual.
+
+## Creating a technique {#advMaterials_b_b}
+Now that we know how to create a pass, we can use one or multiple passes to initialize a **Technique**. A technique is just a container for one or multiple passes.
+
+To create a technique call @ref bs::Technique::create "Technique::create()" and provide it with:
+ - Shading language name - This should be "HLSL" or "GLSL". The engine will not use this technique unless this language is supported by the current render API.
+ - Renderer name - In case you are using a non-default renderer, and the technique only works on it. Otherwise use the built-in variable `RendererAny`
+ - Array containing one or multiple passes
+ 
+For example:
+~~~~~~~~~~~~~{.cpp}
+SPtr<Pass> pass = ...;
+
+// Create a technique that uses HLSL and supports any renderer, with a single pass
+SPtr<Technique> technique = Technique::create("HLSL", RendererAny, { pass });
+~~~~~~~~~~~~~
+  
+## Creating a shader {#materials_b_c}
+Now that we have a technique we can create the shader by calling @ref bs::Shader::create "Shader::create()", which expects a list of techniques, name of the shader and a @ref bs::TSHADER_DESC<T> "SHADER_DESC" structure as input.
+	
+@ref bs::TSHADER_DESC<T> "SHADER_DESC" allows you to specify a set of optional parameters to control how the shader rendering works:
+  - @ref bs::TSHADER_DESC<T>::queueSortType "SHADER_DESC::queueSortType" - Controls how should objects rendered with this shader be sorted. Either front to back, back to front, or without sorting. This property can be used for the active renderer to properly render objects, as certain effects (like transparency) require their objects to be rendered in a specific order.
+  - @ref bs::TSHADER_DESC<T>::queuePriority "SHADER_DESC::queuePriority" - Controls at what point should objects rendered with this shader be rendered relative to other objects. Objects with higher priority will be rendered before ones with lower priority, and sorting due to **SHADER_DESC::queueSortType** will never sort outside of priority groups. This can allow you to render a certain type of objects before all others (e.g. all opaque objects should be rendered before transparent ones).
+  - @ref bs::TSHADER_DESC<T>::separablePasses "SHADER_DESC::separablePasses" - An optimization hint to the renderer that can improve performance when turned on. Only relevant if the shader has techniques with multiple passes. When true the renderer will not necessarily execute passes right after another, but might render other objects in-between passes. This can reduce state switching as multiple objects can be rendered with a single pass, but is only relevant for algorithms that can handle such a process (most can't).
+
+~~~~~~~~~~~~~{.cpp}
+SPtr<Technique> technique = ...;
+	
+SHADER_DESC desc;
+desc.queueSortType = QueueSortType::None;
+desc.queuePriority = 0;
+desc.separablePasses = false;
+
+SPtr<Shader> shader = Shader::create("MyShader", desc, { technique });
+~~~~~~~~~~~~~ 
+  
+## Shader parameters {#materials_b_d}
+Shader parameters allow you to change values of parameters in GPU programs through the **Material** interface. They are similar to GPU program parameters described earlier, but they set the values on all GPU programs on all passes in the active technique, instead of doing so only on a single GPU program. Additionally they also support renderer semantics (see below).
+
+To create the parameter interface you must populate the **SHADER_DESC** structure by calling one of the @ref bs::TSHADER_DESC<T>::addParameter "SHADER_DESC::addParameter()" overloads.
+
+Parameters come in two variants:
+ - Data - These are primitive types like float, int or bool. This includes their vector and array variants. Check @ref bs::GpuParamDataType "GpuParamDataType" for a list of all data parameter types.
+ - Object - These are object types like texture, buffer or sampler state. Check @ref bs::GpuParamObjectType "GpuParamObjectType" for a list of all object parameter types.
+
+For each parameter you must specify:
+ - Its name. This will be the name accessible through **Material**. It can be anything you like, as long as it is unique.
+ - Name of the GPU variable it maps to. This must be a variable defined in source code of one or multiple GPU programs used in the shader (across all techniques/passes).
+ - Type of the GPU variable, as described above.
+
+~~~~~~~~~~~~~{.cpp}
+// Extended example from above
+SPtr<Technique> technique = ...;
+	
+SHADER_DESC desc;
+desc.queueSortType = QueueSortType::None;
+desc.queuePriority = 0;
+desc.separablePasses = false;
+
+// Add a 4x4 transform matrix data parameter
+desc.addParameter("WorldTfrm", "WorldTfrm", GPDT_MATRIX_4X4);
+
+// Add a texture parameter
+desc.addParameter("AlbedoTex", "AlbedoTex", GPOT_TEXTURE2D);
+
+SPtr<Shader> shader = Shader::create("MyShader", desc, { technique });
+~~~~~~~~~~~~~
+
+### Advanced parameters {#materials_b_d_a}
+**SHADER_DESC::addParameter** also supports two additional arguments we didn't touch on in the previous section: renderer semantic and default value.
+
+Renderer semantic allows you to give the parameter a unique tag that can be recognized by the active renderer. The renderer can then use these semantics to automatically assign values to them while rendering. For example the "WVP" semantic might notify the renderer to populate this parameter with the world-view-projection matrix. This way the user is not responsible for setting such parameters manually. The actual semantics supported depend on the active renderer. If provided and renderer doesn't support a semantic, it will be ignored. We'll talk more on how to access semantics in the renderer manual.
+
+The parameter default value allows you to provide a value that will be used for initializing the parameter when a **Material** is initially constructed. For data parameters the default value is a provided as a raw block of memory, and for object parameters it can be a reference to a **Texture** or a **SamplerState**.
+
+~~~~~~~~~~~~~{.cpp}
+// An extended example from above with semantics and default values:
+SPtr<Technique> technique = ...;
+	
+SHADER_DESC desc;
+desc.queueSortType = QueueSortType::None;
+desc.queuePriority = 0;
+desc.separablePasses = false;
+
+// Add a 4x4 transform matrix data parameter with a "W" semantic and identity matrix as default
+desc.addParameter("WorldTfrm", "WorldTfrm", GPDT_MATRIX_4X4, "W", 1, 0, &Matrix4::Identity);
+
+// Add a texture parameter with an "Albedo" semantic and a white texture as default
+desc.addParameter("AlbedoTex", "AlbedoTex", GPOT_TEXTURE2D, Texture::White, "Albedo");
+
+HShader shader = Shader::create("MyShader", desc, { technique });
+~~~~~~~~~~~~~  
+  
+# Manually rendering using the material {#materials_c}
+In an earlier manual we have shown how to render using a **Material** by attaching it to a **Renderable** component and letting the renderer do the rest. You can however render using the material completely manually, using the low-level rendering API.
+
+Material is a **CoreObject** which means it also has a core-thread interface accessible through @ref bs::Material::getCore() "Material::getCore()". The interface is the same as the non-core interface we have described so far.
+
+## Binding material {#materials_c_a}
+**Material** cannot be bound directly to the low level rendering API. You must instead manually retrieve a pipeline state for one of its passes.
+
+You can retrieve a specific pass from a material by calling @ref bs::Material::getPass() "Material::getPass()". The method expects an index of a technique and an index of a pass. To get the number of supported techniques call @ref bs::Material::getNumTechniques() "Material::getNumTechniques()", and to get the number of passes for a specific technique call @ref bs::Material::getNumPasses() "Material::getNumPasses()" with a specific technique index.
+
+Once you have a **Pass** you can retrieve from it either a **GraphicsPipelineState** or a **ComputePipelineState** by calling @ref bs::Pass::getGraphicsPipelineState() "Pass::getGraphicsPipelineState()" and @ref bs::Pass::getComputePipelineState() "Pass::getComputePipelineState()", respectively. Those can then be bound for rendering as shown in the low level rendering API manual.
+
+~~~~~~~~~~~~~{.cpp}
+SPtr<Material> material = ...;
+
+int passIdx = 0;
+int techniqueIdx = 0;
+SPtr<Pass> pass = material->getPass(passIdx, techniqueIdx);
+
+RenderAPI& rapi = RenderAPI::instance();
+rapi.setGraphicsPipeline(pass->getGraphicsPipelineState());
+~~~~~~~~~~~~~
+
+Alternatively you can use the helper methods @ref bs::ct::RendererUtility::setPass "RendererUtility::setPass()" or @ref bs::ct::RendererUtility::setComputePass "RendererUtility::setComputePass()".
+
+## Binding material parameters {#materials_c_b}
+In order to bind material parameters we need to somehow get access to a **GpuParams** object from the material. This is done through an intermediate class @ref bs::GpuParamsSet "GpuParamsSet", created by a call to @ref bs::Material::createParamsSet() "Material::createParamsSet()", which as a parameter takes a technique index.
+
+**GpuParams** for a specific pass can then be retrieved by calling @ref bs::GpuParamsSet::getGpuParams() "GpuParamsSet::getGpuParams()" with the pass index. They can then be bound as described in the low level render API manual.
+
+~~~~~~~~~~~~~{.cpp}
+SPtr<Material> material = ...;
+
+int passIdx = 0;
+int techniqueIdx = 0;
+SPtr<GpuParamsSet> paramsSet = material->createParamsSet(techniqueIdx);
+
+RenderAPI& rapi = RenderAPI::instance();
+rapi.setGpuParams(paramsSet->getGpuParams(passIdx));
+~~~~~~~~~~~~~
+
+Note that creation of a **GpuParamsSet** object is expensive, and the intent is that it will be created once (or just a few times) per material. **GpuParamsSet** contains a completely separate storage from the **Material** it was created from, therefore whenever material parameters are updated you must transfer its contents into **GpuParams** by calling @ref bs::GpuParamsSet::update() "GpuParamsSet::update()".
+
+~~~~~~~~~~~~~{.cpp}
+SPtr<GpuParamsSet> paramsSet = material->createParamsSet(techniqueIdx);
+
+// ...update some parameters on the material...
+
+// Transfer the updated data
+paramsSet->update(material);
+~~~~~~~~~~~~~
+
+Once both the material's pipeline state and parameters are bound, you can then proceed to render as normally, as described in the low-level rendering manual.

+ 2 - 3
Documentation/Manuals/Native/manuals.md

@@ -96,7 +96,7 @@ A set of manuals covering advanced functionality intented for those wanting to e
  - [Flags](@ref flags)
  - [Any](@ref any) 
  - [Unit tests](@ref unitTests)
-- [Advanced material](@ref advMaterial)
+- [Advanced materials](@ref advMaterials)
 - [Threading](@ref threading)
 - [Plugins](@ref plugins)
 - **Renderer**
@@ -119,5 +119,4 @@ Name                                      | Description
 ------------------------------------------|-------------
 [BSLFX](@ref bsl)    	  		  		  | Provides a reference for the Banshee Shading Language syntax.
 [Custom GUI elements](@ref customGUI)     | Shows you how to create custom GUI elements, manually render text or modify GUI system in a general way.
-[Meshes](@ref meshes)                     | Shows you how to create, use and manipulate meshes.
-[Materials](@ref materials)				  | Shows you how to create and use materials and shaders.
+[Meshes](@ref meshes)                     | Shows you how to create, use and manipulate meshes.

+ 0 - 199
Documentation/Manuals/Native/materials.md

@@ -1,199 +0,0 @@
-Materials									{#materials}
-===============
-[TOC]
-
-TODO:
- - GpuParamsSet
- - MaterialParam%s
-
-A material controls how is an object rendered. In Banshee it is represented with @ref bs::Material "Material" and @ref bs::ct::Material "ct::Material" classes. Both of these provide almost equivalent functionality, but the former is for use on the simulation thread, and the latter is for use on the core thread. If you are confused by the dual nature of the objects, read the [core thread](@ref coreThread) manual. 
-
-We'll focus on the simulation thread @ref bs::Material "Material" throughout this manual, but aside from the `ct` namespace there are no major differences between the two interfaces.
-
-Internally material contains a set of GPU programs, render states and GPU program parameters. GPU programs and render states are immutable and are controlled by the @ref bs::Shader "Shader" assigned to the material. The parameters can be modified by the interface provided by the material, and this parameter access actually constitutes the bulk of the material's interface. Essentially materials can be thought of as shader "instances".
-
-Since shaders are such intrical parts of materials, we'll explain how to create them before continuing with the discussion about materials.
-
-# Shaders {#materials_a}
-A shader is a group of GPU programs and render states that fully control the rendering of an object. Shader also exposes a set of parameters the user can change in order to control the rendering further (e.g. by providing different textures or transforms for each object).
-
-To learn more about GPU programs and render states read the [GPU program](@ref gpuPrograms) and [render API](@ref renderAPI) manuals.
-
-A shader can actually contain multiple sets of GPU programs and render states. Such set is called a @ref bs::Technique "Technique", but only one technique can ever be active for rendering. Different techniques can be used for supporting different render API's or renderers (e.g. one technique for DirectX 11, other for OpenGL). Each shader can contain one or multiple techniques and the most appropriate technique will be chosen according to the active render API and renderer.
-
-Each technique contains one or multiple @ref bs::Pass "passes". Each pass contains a set of GPU programs and render states. When rendering using a certain technique each pass will be executed one after another. This allows you to render objects that require more complex rendering that requires multiple separate steps.
-
-To summarize, the relationship between materials, shaders, techniques and passes is:
- - Material [contains one]-> Shader [contains one or multiple]-> Technique [contains one or multiple]-> Pass
-
-## Pass {#materials_a_a}
-Before we can create a shader we must first know how to create a @ref bs::Pass "Pass". Pass can be created by filling out a @ref bs::PASS_DESC "PASS_DESC" descriptor and passing it to @ref bs::Pass::create "Pass::create". @ref bs::PASS_DESC "PASS_DESC" is fairly simple and it expects a set of GPU programs and render states. For example:
-~~~~~~~~~~~~~{.cpp}
-SPtr<GpuProgram> vertexProg = ...;
-SPtr<GpuProgram> fragmentProg = ...;
-
-SPtr<BlendState> blendState = ...;
-
-// Create a pass with a vertex and fragment program, and a non-default blend state
-PASS_DESC desc;
-desc.vertexProgram = vertexProg;
-desc.fragmentProg = fragmentProg;
-desc.blendState = blendState;
-
-SPtr<Pass> pass = Pass::create(desc);
-~~~~~~~~~~~~~
-
-[GPU program](@ref gpuPrograms) and [render API](@ref renderAPI) manuals teach you how to create GPU programs and render states. 
-
-## Technique {#materials_a_b}
-Now that we know how to create a pass, we can use one or multiple passes to initialize a @ref bs::Technique "Technique". A technique is just a container for passes for a specific render API and renderer.
-
-To create a technique call @ref bs::Technique::create "Technique::create" and provide it with:
- - One or multiple passes
- - Supported render API name: Use built-in `RenderAPIAny` to signal that the technique works on any API, or use the render API identifier to signal that it only works on a specific one. By default supported identifiers are: `"VulkanRenderAPI"`, `"D3D11RenderAPI"`, `"GLRenderAPI"`, but more can be added via plugins. In general those identifiers are returned from @ref bs::ct::RenderAPI::getName "ct::RenderAPI::getName". Most users should be okay by providing `RenderAPIAny`.
- - Supported renderer name: Use built-in `RendererAny` to signal that the technique works on any renderer, or use the renderer identifier to signal that it only works on a specific one. By default the only supported identifier is `"RenderBeast"`, but more can be added via plugins. In general those identifiers are returned from @ref bs::ct::Renderer::getName "ct::Renderer::getName". Most users should be okay by providing `RendererAny`.
- - An optional list of tags that allows renderer to pick which technique to use when rendering objects. Can be left empty in most cases.
-
-For example:
-~~~~~~~~~~~~~{.cpp}
-SPtr<Pass> pass = ...;
-
-// Create a technique that supports any render API or renderer, with a single pass
-SPtr<Technique> technique = Technique::create(RenderAPIAny, RendererAny, { pass });
-~~~~~~~~~~~~~
- 
-## Creating a shader {#materials_a_c}
-Now that we have a technique we can create our shader by calling @ref bs::Shader::create "Shader::create", which expects a list of techniques, name of the shader and @ref bs::TSHADER_DESC<T> "SHADER_DESC" as input.
-	
-@ref bs::TSHADER_DESC<T> "SHADER_DESC" allows you to specify a set of optional parameters to control how the shader rendering works:
-  - `queueSortType` - Controls how should objects rendered with this shader be sorted. Either front to back, back to front, or without sorting. This property can be used for the active renderer to properly render objects, as certain effects (like transparency) require their objects to be rendered in a specific order.
-  - `queuePriority` - Controls when should objects rendered with this shader be rendered relative to other objects. Objects with higher priority will be rendered before ones with lower priority, and sorting due to `queueSortType` will never sort outside of priority groups. This can allow you to render a certain type of objects before all others (e.g. all opaque objects should be rendered before transparent ones).
-  - `separablePasses` - An optimization hint to the renderer that can improve performance when turned on. Only relevant if the shader has techniques with multiple passes. When true the renderer will not necessarily execute passes right after another, but might render other objects in-between passes. This can reduce state switching as multiple objects can be rendered with a single pass, but is only relevant for algorithms that can handle such a process (most can't).
-  - `flags` - Allows you to provide custom flags to the renderer. Interpretation of this value depends on the renderer used and by default its value is ignored.
-	
-@ref bs::TSHADER_DESC<T> "SHADER_DESC" also expects you to provide a set of parameters accepted by the GPU programs used by the passes. We'll explain parameters later, but for now assume we're creating a shader with no parameters:
-~~~~~~~~~~~~~{.cpp}
-SPtr<Technique> technique = ...;
-	
-SHADER_DESC desc;
-desc.queueSortType = QueueSortType::None;
-desc.queuePriority = 0;
-desc.separablePasses = false;
-desc.flags = 0;
-
-SPtr<Shader> shader = Shader::create("MyShader", desc, { technique });
-~~~~~~~~~~~~~	
-	
-## Shader parameters {#materials_a_d}
-Shader parameters allow you to change values of parameters in GPU programs. They are similar to GPU program parameters described in the [GPU program](@ref gpuPrograms) manual, but they set the values on all GPU programs on all passes, instead of working only on a single GPU program. Additionally they also support renderer semantics (see below).
-
-Shader only defines the parameter interface (their name, type and description), but actual parameters can only be changed from a @ref bs::Material "Material", as we'll show later. To create the parameter interface you must populate the @ref bs::TSHADER_DESC<T> "SHADER_DESC" structure by calling one of the @ref bs::TSHADER_DESC<T>::addParameter "SHADER_DESC::addParameter" overloads.
-
-Parameters come in two variants:
- - Data - These are primitive types like float, int or bool. This includes their vector and array variants. Check @ref bs::GpuParamDataType "GpuParamDataType" for a list of all data parameter types.
- - Object - These are object types like texture, buffer or sampler state. Check @ref bs::GpuParamObjectType "GpuParamObjectType" for a list of all object parameter types.
-
-Each parameter must have a name and a GPU variable it maps to. The name can be anything you like (as long as its unique) and it will be used for accessing the parameter from the @ref bs::Material "Material". The GPU variable must be a name of the GPU variable defined in GPU program code. This is the name contained in @ref bs::GpuParamDesc "GpuParamDesc" which is returned from @ref bs::GpuProgram::getParamDesc "GpuProgram::getParamDesc". 
-
-You must also provide the type of the parameter. This way the system can know how to distinguish parameters in case multiple GPU programs have the same-named GPU variable but with different type. For data parameters you can also provide the size of the array (in case the GPU variable is an array), or the size of a single element (only needed for structs).
-
-An extended example from above:
-~~~~~~~~~~~~~{.cpp}
-SPtr<Technique> technique = ...;
-	
-SHADER_DESC desc;
-desc.queueSortType = QueueSortType::None;
-desc.queuePriority = 0;
-desc.separablePasses = false;
-desc.flags = 0;
-
-// Add a 4x4 transform matrix data parameter
-desc.addParameter("WorldTfrm", "WorldTfrm", GPDT_MATRIX_4X4);
-
-// Add a texture parameter
-desc.addParameter("AlbedoTex", "AlbedoTex", GPOT_TEXTURE2D);
-
-SPtr<Shader> shader = Shader::create("MyShader", desc, { technique });
-~~~~~~~~~~~~~
-
-### Advanced parameters {#materials_a_d_a}
-@ref bs::SHADER_DESC::addParameter "SHADER_DESC::addParameter" also supports two additional arguments we didn't touch on in the previous section: renderer semantic and default value.
-
-Renderer semantic allows you to give the parameter a unique name that can be recognized by the active renderer. The renderer can then use these semantics to automatically assign values to them while rendering. For example the "WVP" semantic might notify the renderer to populate this parameter with the world-view-projection matrix. This way the user is not responsible for setting such parameters manually.
-
-The list of supported semantics depends on the currently active renderer. The default renderer is still in the implementation phase and supports no semantics. Read more about semantics in the [renderer](@ref renderer) manual.
-
-The parameter default value allows you to provide a value that will be used for initializing the parameter when a @ref bs::Material "Material" is initially constructed. For data parameters the default value is a provided as a raw block of memory, and for object parameters it can be a reference to a @ref bs::Texture "Texture" or a @ref bs::SamplerState "SamplerState".
-
-An extended example from above with semantics and default values:
-~~~~~~~~~~~~~{.cpp}
-SPtr<Technique> technique = ...;
-	
-SHADER_DESC desc;
-desc.queueSortType = QueueSortType::None;
-desc.queuePriority = 0;
-desc.separablePasses = false;
-desc.flags = 0;
-
-// Add a 4x4 transform matrix data parameter with a "W" semantic and identity matrix as default
-desc.addParameter("WorldTfrm", "WorldTfrm", GPDT_MATRIX_4X4, "W", 1, 0, &Matrix4::Identity);
-
-// Add a texture parameter with an "Albedo" semantic and a white texture as default
-desc.addParameter("AlbedoTex", "AlbedoTex", GPOT_TEXTURE2D, Texture::White, "Albedo");
-
-HShader shader = Shader::create("MyShader", desc, { technique });
-~~~~~~~~~~~~~
-
-## Banshee Shading Language {#materials_a_d_b}
-Instead of creating shaders manually like we have described so far, Banshee provides a BSLFX language (Banshee Shading Language FX) that allows you to describe everything we talked about so far (GPU programs, states, parameter interface) in a single file which can then be imported into the engine like so:
-~~~~~~~~~~~~~{.cpp}
-HShader shader = gImporter().import<Shader>("myShader.bsl");
-~~~~~~~~~~~~~
-
-This is the preferred way of creating shaders, as its much simpler, concise and flexible. Learn about BSLFX syntax in the [BSLFX](@ref bslfx) manual.
-
-## Saving/loading {#materials_a_d_c}
-A shader is a @ref bs::Resource "Resource" and can be saved/loaded like any other. See the [resource](@ref resources) manual.
-
-# Creating a material {#materials_b}
-Now that we finally have a shader we can create our material by calling @ref bs::Material::create "Material::create" like so:
-~~~~~~~~~~~~~{.cpp}
-HShader shader = ...;
-HMaterial material = Material::create(shader);
-~~~~~~~~~~~~~
-
-This will select the most appropriate technique from the shader and initialize the material with it. Once initialized you can read and write parameters from/to the material, and use it for rendering.
-
-# Material parameters {#materials_c}
-Material allows you to read and write parameters in two different ways:
- - By calling various set/get methods like @ref bs::Material::getVec4 "Material::getVec4" or @ref bs::Material::setVec4 "Material::setVec4" which read and write the parameter value directly.
- - By retrieving parameter handle by calling @ref bs::Material::getParamVec4 "Material::getParamVec4" which returns a handle object @ref bs::TMaterialDataParam<T, false> "MaterialParamVec4". This object can then be used by calling its @ref bs::TMaterialDataParam<T, false>::get "MaterialParamVec4::get" and @ref bs::TMaterialDataParam<T, false>::set "MaterialParamVec4::set" methods similar to above.
- 
-We have shown an example for a 4D vector but similarly named methods exist for other parameter types. The second method of accessing the parameters is prefered as it allows you to save the handle to the parameter, which avoids a potentially expensive name lookup every time we need to access it.
-
-An example of writing a material value, both directly and with a handle:
-~~~~~~~~~~~~~{.cpp}
-HMaterial material = ...;
-
-// Set parameter directly
-material->setMat4("WorldTfrm", Matrix4::Identity);
-
-// Get handle and set value indirectly
-MaterialParamMat4 worldTfrmParam = material->getParamMat4("WorldTfrm");
-worldTfrmParam.set(Matrix4::Identity);
-
-// Set object parameter indirectly
-MaterialParamTexture albedoParam = material->getParamTexture("AlbedoTex");
-albedoParam.set(Texture::White);
-~~~~~~~~~~~~~
-# Rendering with material {#materials_d}
-From the simulation thread you cannot use material to render manually (you must instead use GPU programs and states manually as described by the [render API](@ref renderAPI) manual). You are instead expected to set the material on a @ref bs::Renderable "Renderable" object which will then be used for rendering automatically. Read the [renderer](@ref renderer) manual for more information.
-
-Core thread gives you more flexibility and you can use @ref bs::ct::RendererUtility::setPass "ct::RendererUtility::setPass" to bind a specific pass from a material to the pipeline, and @ref bs::ct::RendererUtility::setPassParams "ct::RendererUtility::setPassParams" to bind material parameters for a specific pass. 
-
-In order to retrieve a set of per-pass @ref bs::GpuParams "GpuParams" that can be used for binding directly to the pipeline, call @ref bs::Material::createParamsSet "Material::createParamsSet", followed by @ref bs::Material::updateParamsSet "Material::updateParamsSet". You are required to call @ref bs::Material::updateParamsSet "Material::updateParamsSet" whenever material parameters change, in order to transfer the new data to @ref bs::GpuParams "GpuParams".
-
-After pass and pass parameters are bound you can follow them with draw calls as described in the [render API](@ref renderAPI) manual to render objects manually. 
-
-# Saving/loading {#materials_e}
-A material is a @ref bs::Resource "Resource" and can be saved/loaded like any other. See the [resource](@ref resources) manual.

+ 3 - 0
Source/BansheeCore/Include/BsPass.h

@@ -135,7 +135,10 @@ namespace bs
 		const GpuProgramType& getDomainProgram() const { return mData.domainProgram; }
 		const GpuProgramType& getComputeProgram() const { return mData.computeProgram; }
 
+		/** Returns the graphics pipeline state describing this pass, or null if its a compute pass. */
 		const GraphicsPipelineStateType& getGraphicsPipelineState() const { return mGraphicsPipelineState; }
+
+		/** Returns the compute pipeline state describing this pass, or null if its a graphics pass. */
 		const ComputePipelineStateType& getComputePipelineState() const { return mComputePipelineState; }
 	protected:
 		TPass();