From e9440b970ecf28763c822353569834510771e889 Mon Sep 17 00:00:00 2001 From: Martin Valigursky Date: Thu, 23 Jul 2026 15:57:42 +0100 Subject: [PATCH 1/3] Add Render Targets manual page Adds a foundational "Render Targets" page under Advanced Rendering covering creation, rendering a scene into a target, excluding the display surface via layers, the RenderTarget origin option for cross-API orientation, choosing a renderable/HDR format, resizing, MSAA and cleanup, with the render-to-texture example embedded. Also links the new page from the Multiple Render Targets and Multiple Cameras pages, and adds the origin option to the MRT render target snippet. --- .../multiple-render-targets.md | 3 +- .../advanced-rendering/render-targets.md | 153 ++++++++++++++++++ .../graphics/cameras/multiple-cameras.md | 2 +- sidebars.js | 1 + 4 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 docs/user-manual/graphics/advanced-rendering/render-targets.md diff --git a/docs/user-manual/graphics/advanced-rendering/multiple-render-targets.md b/docs/user-manual/graphics/advanced-rendering/multiple-render-targets.md index 57f58be8717..9f3d520f4f9 100644 --- a/docs/user-manual/graphics/advanced-rendering/multiple-render-targets.md +++ b/docs/user-manual/graphics/advanced-rendering/multiple-render-targets.md @@ -3,7 +3,7 @@ title: Multiple Render Targets description: Configure multiple render targets, shared attachments rules, and shader output to several color buffers at once. --- -The multiple render targets feature allows you to simultaneously render to multiple textures. This manual page explores implementation, configuration, and an example use case of multiple render targets. +The multiple render targets feature allows you to simultaneously render to multiple textures. This manual page explores implementation, configuration, and an example use case of multiple render targets. It builds on the concepts covered in [Render Targets](./render-targets.md). MRT is supported on every device PlayCanvas runs on (WebGL2 and WebGPU). To detect the number of color attachments you can use on the current device, check [`GraphicsDevice.maxColorAttachments`](https://api.playcanvas.com/engine/classes/GraphicsDevice.html#maxcolorattachments). Typically, 8 attachments are supported. @@ -41,6 +41,7 @@ const renderTarget = new pc.RenderTarget({ name: 'MRT', colorBuffers: [texture0, texture1, texture2], depth: true, + origin: pc.RENDERTARGET_ORIGIN_TOP, samples: 2 }); ``` diff --git a/docs/user-manual/graphics/advanced-rendering/render-targets.md b/docs/user-manual/graphics/advanced-rendering/render-targets.md new file mode 100644 index 00000000000..7d19436c0b0 --- /dev/null +++ b/docs/user-manual/graphics/advanced-rendering/render-targets.md @@ -0,0 +1,153 @@ +--- +title: Render Targets +description: Render a scene into an offscreen texture instead of the screen, then use the result in your scene - covering creation, layer setup, orientation, formats, resizing and MSAA. +--- + +A [render target](https://api.playcanvas.com/engine/classes/RenderTarget.html) is a rectangular rendering surface you can render into instead of the screen. It wraps one or more renderable color textures, along with an optional depth (and stencil) buffer. Once a camera has rendered into it, the color texture holds the result and can be used anywhere a normal texture can - most commonly applied to a material to display it in the scene, or fed into further processing. + +This underpins effects such as in-world screens, security monitors, mirrors and portals, reflection and refraction, and custom multi-pass pipelines. + +## Creating a render target + +First create the color [texture](https://api.playcanvas.com/engine/classes/Texture.html) to render into. It must use a renderable, uncompressed format (see [Choosing a format](#choosing-a-format) below): + +```javascript +const texture = new pc.Texture(app.graphicsDevice, { + name: 'RT-color', + width: 512, + height: 256, + format: pc.PIXELFORMAT_SRGBA8, + mipmaps: true, + minFilter: pc.FILTER_LINEAR, + magFilter: pc.FILTER_LINEAR, + addressU: pc.ADDRESS_CLAMP_TO_EDGE, + addressV: pc.ADDRESS_CLAMP_TO_EDGE +}); +``` + +Then wrap it in a render target. Request a depth buffer if the scene you render needs depth testing, and set `samples` for hardware anti-aliasing (see [Anti-aliasing](#anti-aliasing)): + +```javascript +const renderTarget = new pc.RenderTarget({ + name: 'RT', + colorBuffer: texture, + depth: true, + origin: pc.RENDERTARGET_ORIGIN_TOP +}); +``` + +The [`origin`](#orientation) option is explained below. + +## Rendering the scene into it + +Assign the render target to a camera's [`renderTarget`](https://api.playcanvas.com/engine/classes/CameraComponent.html#rendertarget) property. That camera then renders into the texture instead of the screen. Give it a negative `priority` so it renders before the main camera each frame, ensuring the texture is up to date when the main camera uses it: + +```javascript +const textureCamera = new pc.Entity('TextureCamera'); +textureCamera.addComponent('camera', { + // rendered before the main camera (default priority 0) + priority: -1, + renderTarget +}); +app.root.addChild(textureCamera); +``` + +A render target can also be filled by means other than a camera - for example a fullscreen shader pass or a compute shader - but rendering a scene with a camera is the most common case. + +## Excluding the display surface with layers + +When the render target's texture is displayed on an object within the same scene, that object must **not** be rendered into the render target itself - otherwise the surface would try to render the texture it is currently producing, feeding back on itself. + +The clean way to arrange this is with [layers](../layers/index.md). A camera only renders the layers listed in its `layers` array, so placing the display object in a layer the texture camera does not list excludes it. The [render-to-texture example](#example) below uses three layers and two cameras: + +- **World** - the scene content. Listed by both cameras, so it renders into the texture and to the screen. +- **Excluded** - the object that displays the texture (and anything else that should appear on screen only). Listed by the main camera only. +- **Skybox** - listed by both cameras. + +```javascript +// a layer for objects that must not render into the texture +const excludedLayer = new pc.Layer({ name: 'Excluded' }); +app.scene.layers.insert(excludedLayer, 1); + +const worldLayer = app.scene.layers.getLayerByName('World'); +const skyboxLayer = app.scene.layers.getLayerByName('Skybox'); + +// texture camera renders the scene, but NOT the Excluded layer +textureCamera.camera.layers = [worldLayer.id, skyboxLayer.id]; + +// main camera renders everything, including the display surface in the Excluded layer +mainCamera.camera.layers = [worldLayer.id, excludedLayer.id, skyboxLayer.id]; +``` + +## Using the result + +The render target's color texture is available as [`renderTarget.colorBuffer`](https://api.playcanvas.com/engine/classes/RenderTarget.html#colorbuffer) (it is the same texture you created). Apply it to a material like any other texture - for instance as the emissive map of the plane that acts as the display surface: + +```javascript +const material = new pc.StandardMaterial(); +material.emissiveMap = renderTarget.colorBuffer; +material.emissive = pc.Color.WHITE; +material.update(); +``` + +## Orientation + +WebGL2 and WebGPU natively store a rendered image with the opposite vertical row order. If you leave the orientation unspecified and then sample the render target as a regular texture (with mesh UVs), the result appears vertically mirrored between the two APIs. The `origin` option pins the stored orientation so the render target looks identical everywhere. It can be: + +- [`RENDERTARGET_ORIGIN_TOP`](https://api.playcanvas.com/engine/variables/RENDERTARGET_ORIGIN_TOP.html) - row 0 is the top of the rendered image, on all graphics APIs, matching how image textures are stored. **Use this for any render target you sample as a regular texture** (a material map, or a cube map face). Recommended for most content - write the sampling code as if the texture were a loaded image. +- [`RENDERTARGET_ORIGIN_BOTTOM`](https://api.playcanvas.com/engine/variables/RENDERTARGET_ORIGIN_BOTTOM.html) - row 0 is the bottom of the rendered image, on all graphics APIs, replicating WebGL2's native layout. Use this to keep consuming code written against WebGL conventions working unchanged - shaders deriving UVs from projected (NDC) coordinates, or texture atlases addressing cells by viewport rectangles. +- [`RENDERTARGET_ORIGIN_NATIVE`](https://api.playcanvas.com/engine/variables/RENDERTARGET_ORIGIN_NATIVE.html) - the image is stored in the graphics API's native orientation, so the row order differs between WebGL2 and WebGPU. This is the default. It is only appropriate for orientation-agnostic consumers, such as screen-space sampling using coordinates derived from the fragment position. + +In short: if you display a render target on a surface in your scene, use `RENDERTARGET_ORIGIN_TOP`. + +## Choosing a format + +The color texture must use a renderable, uncompressed format: + +- **`PIXELFORMAT_RGBA8`** (or its sRGB variant `PIXELFORMAT_SRGBA8`) is the standard choice, renderable everywhere. +- **`PIXELFORMAT_RGB10A2`** offers 10 bits per RGB channel with 2-bit alpha - higher precision than `RGBA8` at the same memory cost, renderable on both WebGL2 and WebGPU. +- **HDR formats** (float `PIXELFORMAT_RGBA32F`, half-float `PIXELFORMAT_RGBA16F`, small-float `PIXELFORMAT_111110F`) are renderable subject to device support. Rather than picking one directly, query [`GraphicsDevice.getRenderableHdrFormat`](https://api.playcanvas.com/engine/classes/GraphicsDevice.html#getrenderablehdrformat), which returns the first supported option. Support varies: on WebGPU float and half-float are always renderable; on WebGL2 half-float is widely available (including many mobile iOS devices) while full float rendering requires [`GraphicsDevice.textureFloatRenderable`](https://api.playcanvas.com/engine/classes/GraphicsDevice.html#texturefloatrenderable). +- **`PIXELFORMAT_RGB9E5`** is a compact HDR format that can be sampled but **cannot** be used as a render target color buffer. + +See the [`Texture`](https://api.playcanvas.com/engine/classes/Texture.html) API reference for the full list and the detailed HDR support rules. + +For depth testing during rendering, request a depth buffer with `depth: true` when creating the render target (as shown above). Use `stencil: true` as well if you need a stencil buffer. + +## Resizing + +To change a render target's resolution - for example to keep it matched to the output size when the window resizes - call [`renderTarget.resize(width, height)`](https://api.playcanvas.com/engine/classes/RenderTarget.html#resize). This resizes the underlying color and depth buffers; their previous contents are not preserved. + +## Anti-aliasing + +Set `samples` greater than 1 to render the target with hardware multi-sample anti-aliasing (MSAA). The multi-sampled result is automatically resolved into the single-sampled color texture you created, which is the one you sample from: + +```javascript +const renderTarget = new pc.RenderTarget({ + colorBuffer: texture, + depth: true, + origin: pc.RENDERTARGET_ORIGIN_TOP, + samples: 4 +}); +``` + +## Cleaning up + +A render target does not own its textures, so destroy them separately when you are done. Destroy the color texture (and depth buffer texture, if you created one explicitly), then the render target: + +```javascript +renderTarget.colorBuffer.destroy(); +renderTarget.destroy(); +``` + +## Example + +The following example renders a scene into a texture from a second camera and displays it on a plane in the world. It uses the three-layer setup described above to keep the display plane out of the render target, and switches the texture camera between perspective and orthographic projection every few seconds. + + + +## Related pages + +- [Multiple Render Targets](./multiple-render-targets.md) - render to several color buffers at once from a single pass. +- [Multiple Cameras](../cameras/multiple-cameras.md) - composing views and assigning render targets to cameras. +- [Layers](../layers/index.md) - controlling which objects each camera renders. +- [Post Effects](../posteffects/index.md) - built-in and custom post-processing built on render targets. diff --git a/docs/user-manual/graphics/cameras/multiple-cameras.md b/docs/user-manual/graphics/cameras/multiple-cameras.md index 0a6205a18ae..4935e3bdd94 100644 --- a/docs/user-manual/graphics/cameras/multiple-cameras.md +++ b/docs/user-manual/graphics/cameras/multiple-cameras.md @@ -91,7 +91,7 @@ overlay.camera.clearDepthBuffer = true; // don't depth-test against the main vi ## Render Targets {#render-targets} -Instead of the screen, a camera can render into an offscreen texture by assigning a [RenderTarget](https://api.playcanvas.com/engine/classes/RenderTarget.html) to its `renderTarget` property. The resulting texture can then be applied to a material — for in-world screens, mirrors and portals — or processed further. See the engine's render-to-texture example: +Instead of the screen, a camera can render into an offscreen texture by assigning a [RenderTarget](https://api.playcanvas.com/engine/classes/RenderTarget.html) to its `renderTarget` property. The resulting texture can then be applied to a material — for in-world screens, mirrors and portals — or processed further. See the [Render Targets](/user-manual/graphics/advanced-rendering/render-targets/) page for the full details, and the engine's render-to-texture example: diff --git a/sidebars.js b/sidebars.js index c07aafbad91..0c59b9a9101 100644 --- a/sidebars.js +++ b/sidebars.js @@ -854,6 +854,7 @@ const sidebars = { 'user-manual/graphics/advanced-rendering/batching', 'user-manual/graphics/advanced-rendering/hardware-instancing', 'user-manual/graphics/advanced-rendering/multi-draw', + 'user-manual/graphics/advanced-rendering/render-targets', 'user-manual/graphics/advanced-rendering/multiple-render-targets', 'user-manual/graphics/advanced-rendering/indirect-drawing', 'user-manual/graphics/advanced-rendering/html-in-canvas', From 38562646523412e799a9cbc054b97531a3906548 Mon Sep 17 00:00:00 2001 From: Martin Valigursky Date: Thu, 23 Jul 2026 16:02:59 +0100 Subject: [PATCH 2/3] Add Japanese translation of the Render Targets page Translates the new Render Targets manual page into Japanese, and mirrors the companion edits (origin option in the MRT snippet and cross-links) in the Japanese Multiple Render Targets and Multiple Cameras pages. --- .../multiple-render-targets.md | 3 +- .../advanced-rendering/render-targets.md | 153 ++++++++++++++++++ .../graphics/cameras/multiple-cameras.md | 2 +- 3 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/multiple-render-targets.md b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/multiple-render-targets.md index 82a9566ebc7..80e1e509b9d 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/multiple-render-targets.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/multiple-render-targets.md @@ -3,7 +3,7 @@ title: 複数のレンダーターゲット description: 複数レンダーターゲットの設定、共有アタッチメントのルール、複数のカラーバッファへのシェーダー出力です。 --- -複数のレンダーターゲット機能を使用すると、複数のテクスチャに同時にレンダリングできます。このマニュアルページでは、複数のレンダーターゲットの実装、設定、および使用例について説明します。 +複数のレンダーターゲット機能を使用すると、複数のテクスチャに同時にレンダリングできます。このマニュアルページでは、複数のレンダーターゲットの実装、設定、および使用例について説明します。このページは [レンダーターゲット](./render-targets.md) で扱う概念を基礎としています。 MRTは、PlayCanvasが動作するすべてのデバイス(WebGL2およびWebGPU)でサポートされています。現在のデバイスで使用できるカラーアタッチメントの数を検出するには、[`GraphicsDevice.maxColorAttachments`](https://api.playcanvas.com/engine/classes/GraphicsDevice.html#maxcolorattachments)を確認してください。通常、8つのアタッチメントがサポートされています。 @@ -41,6 +41,7 @@ const renderTarget = new pc.RenderTarget({ name: 'MRT', colorBuffers: [texture0, texture1, texture2], depth: true, + origin: pc.RENDERTARGET_ORIGIN_TOP, samples: 2 }); ``` diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md new file mode 100644 index 00000000000..06f85b9a7e5 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md @@ -0,0 +1,153 @@ +--- +title: レンダーターゲット +description: 画面の代わりにオフスクリーンテクスチャへシーンをレンダリングし、その結果をシーン内で使用する方法を、作成・レイヤー構成・向き・フォーマット・リサイズ・MSAAとともに解説します。 +--- + +[レンダーターゲット](https://api.playcanvas.com/engine/classes/RenderTarget.html)は、画面の代わりにレンダリング先として使用できる矩形のレンダリング面です。1つ以上のレンダリング可能なカラーテクスチャと、オプションの深度(およびステンシル)バッファをラップします。カメラがレンダーターゲットにレンダリングすると、そのカラーテクスチャに結果が保持され、通常のテクスチャと同じように使用できます。もっとも一般的には、マテリアルに適用してシーン内に表示したり、さらに加工したりします。 + +これは、ゲーム内スクリーン、監視モニター、鏡やポータル、反射や屈折、カスタムのマルチパスパイプラインといった表現の基盤となります。 + +## レンダーターゲットの作成 {#creating-a-render-target} + +まず、レンダリング先となるカラー[テクスチャ](https://api.playcanvas.com/engine/classes/Texture.html)を作成します。テクスチャは、レンダリング可能で非圧縮のフォーマットを使用する必要があります(後述の[フォーマットの選択](#choosing-a-format)を参照)。 + +```javascript +const texture = new pc.Texture(app.graphicsDevice, { + name: 'RT-color', + width: 512, + height: 256, + format: pc.PIXELFORMAT_SRGBA8, + mipmaps: true, + minFilter: pc.FILTER_LINEAR, + magFilter: pc.FILTER_LINEAR, + addressU: pc.ADDRESS_CLAMP_TO_EDGE, + addressV: pc.ADDRESS_CLAMP_TO_EDGE +}); +``` + +次に、それをレンダーターゲットでラップします。レンダリングするシーンで深度テストが必要な場合は深度バッファを要求し、ハードウェアアンチエイリアスには `samples` を設定します([アンチエイリアス](#anti-aliasing)を参照)。 + +```javascript +const renderTarget = new pc.RenderTarget({ + name: 'RT', + colorBuffer: texture, + depth: true, + origin: pc.RENDERTARGET_ORIGIN_TOP +}); +``` + +[`origin`](#orientation) オプションについては後述します。 + +## シーンをレンダリングする {#rendering-the-scene-into-it} + +レンダーターゲットをカメラの [`renderTarget`](https://api.playcanvas.com/engine/classes/CameraComponent.html#rendertarget) プロパティに割り当てます。そのカメラは画面ではなくテクスチャにレンダリングするようになります。負の `priority` を設定して、メインカメラよりも前に毎フレームレンダリングされるようにし、メインカメラがテクスチャを使用する時点で内容が最新になるようにします。 + +```javascript +const textureCamera = new pc.Entity('TextureCamera'); +textureCamera.addComponent('camera', { + // メインカメラ(デフォルトの優先度0)より前にレンダリングされます + priority: -1, + renderTarget +}); +app.root.addChild(textureCamera); +``` + +レンダーターゲットは、カメラ以外の手段でも埋めることができます。たとえば全画面シェーダーパスやコンピュートシェーダーなどですが、カメラでシーンをレンダリングするのがもっとも一般的なケースです。 + +## 表示面をレイヤーで除外する {#excluding-the-display-surface-with-layers} + +レンダーターゲットのテクスチャを同じシーン内のオブジェクトに表示する場合、そのオブジェクト自体はレンダーターゲットにレンダリングしては**いけません**。さもないと、その面が現在生成中のテクスチャをレンダリングしようとし、自分自身にフィードバックしてしまいます。 + +これをきれいに実現する方法が[レイヤー](../layers/index.md)です。カメラは自身の `layers` 配列に列挙されたレイヤーのみをレンダリングするため、表示オブジェクトをテクスチャカメラが列挙していないレイヤーに配置すれば除外できます。以下の[レンダーテクスチャのサンプル](#example)では、3つのレイヤーと2つのカメラを使用しています。 + +- **World** - シーンの内容。両方のカメラが列挙するため、テクスチャと画面の両方にレンダリングされます。 +- **Excluded** - テクスチャを表示するオブジェクト(および画面にのみ表示すべきもの)。メインカメラのみが列挙します。 +- **Skybox** - 両方のカメラが列挙します。 + +```javascript +// テクスチャにレンダリングしてはいけないオブジェクト用のレイヤー +const excludedLayer = new pc.Layer({ name: 'Excluded' }); +app.scene.layers.insert(excludedLayer, 1); + +const worldLayer = app.scene.layers.getLayerByName('World'); +const skyboxLayer = app.scene.layers.getLayerByName('Skybox'); + +// テクスチャカメラはシーンをレンダリングするが、Excludedレイヤーはレンダリングしない +textureCamera.camera.layers = [worldLayer.id, skyboxLayer.id]; + +// メインカメラは、Excludedレイヤーの表示面を含めてすべてをレンダリングする +mainCamera.camera.layers = [worldLayer.id, excludedLayer.id, skyboxLayer.id]; +``` + +## 結果を使用する {#using-the-result} + +レンダーターゲットのカラーテクスチャは [`renderTarget.colorBuffer`](https://api.playcanvas.com/engine/classes/RenderTarget.html#colorbuffer) として利用できます(作成したテクスチャと同じものです)。他のテクスチャと同じようにマテリアルに適用できます。たとえば、表示面として機能する平面のエミッシブマップとして使用します。 + +```javascript +const material = new pc.StandardMaterial(); +material.emissiveMap = renderTarget.colorBuffer; +material.emissive = pc.Color.WHITE; +material.update(); +``` + +## 向き {#orientation} + +WebGL2とWebGPUは、レンダリングされた画像を垂直方向に逆の行順でネイティブに格納します。向きを指定しないままレンダーターゲットを通常のテクスチャとして(メッシュのUVで)サンプリングすると、2つのAPI間で結果が上下反転して見えます。`origin` オプションは、格納される向きを固定し、レンダーターゲットがどこでも同一に見えるようにします。次のいずれかを指定できます。 + +- [`RENDERTARGET_ORIGIN_TOP`](https://api.playcanvas.com/engine/variables/RENDERTARGET_ORIGIN_TOP.html) - すべてのグラフィックスAPIで、行0がレンダリングされた画像の上端になります。これは画像テクスチャの格納方法と一致します。**通常のテクスチャとしてサンプリングするレンダーターゲット(マテリアルマップやキューブマップの面)には、これを使用してください。** ほとんどのコンテンツで推奨されます。サンプリングするコードは、読み込んだ画像を扱うつもりで書いてください。 +- [`RENDERTARGET_ORIGIN_BOTTOM`](https://api.playcanvas.com/engine/variables/RENDERTARGET_ORIGIN_BOTTOM.html) - すべてのグラフィックスAPIで、行0がレンダリングされた画像の下端になり、WebGL2のネイティブなレイアウトを再現します。WebGLの規約に沿って書かれた既存のコード(投影(NDC)座標からUVを導出するシェーダーや、ビューポート矩形でセルをアドレッシングするテクスチャアトラスなど)をそのまま動作させたい場合に使用します。 +- [`RENDERTARGET_ORIGIN_NATIVE`](https://api.playcanvas.com/engine/variables/RENDERTARGET_ORIGIN_NATIVE.html) - 画像はグラフィックスAPIのネイティブな向きで格納されるため、行順はWebGL2とWebGPUで異なります。これがデフォルトです。フラグメント位置から導出した座標を使う画面空間サンプリングなど、向きに依存しない用途にのみ適しています。 + +要するに、レンダーターゲットをシーン内の面に表示する場合は `RENDERTARGET_ORIGIN_TOP` を使用してください。 + +## フォーマットの選択 {#choosing-a-format} + +カラーテクスチャは、レンダリング可能で非圧縮のフォーマットを使用する必要があります。 + +- **`PIXELFORMAT_RGBA8`**(またはそのsRGBバリアントである `PIXELFORMAT_SRGBA8`)が標準的な選択肢で、どこでもレンダリング可能です。 +- **`PIXELFORMAT_RGB10A2`** はRGB各チャンネル10ビットと2ビットのアルファを提供し、`RGBA8` と同じメモリコストでより高い精度が得られます。WebGL2とWebGPUの両方でレンダリング可能です。 +- **HDRフォーマット**(float の `PIXELFORMAT_RGBA32F`、half-float の `PIXELFORMAT_RGBA16F`、small-float の `PIXELFORMAT_111110F`)は、デバイスのサポート状況に応じてレンダリング可能です。直接1つを選ぶ代わりに、[`GraphicsDevice.getRenderableHdrFormat`](https://api.playcanvas.com/engine/classes/GraphicsDevice.html#getrenderablehdrformat) をクエリすると、サポートされている最初の選択肢が返されます。サポート状況は異なります。WebGPUではfloatとhalf-floatは常にレンダリング可能です。WebGL2ではhalf-floatは広く利用可能(多くのモバイルiOSデバイスを含む)ですが、完全なfloatのレンダリングには [`GraphicsDevice.textureFloatRenderable`](https://api.playcanvas.com/engine/classes/GraphicsDevice.html#texturefloatrenderable) が必要です。 +- **`PIXELFORMAT_RGB9E5`** はコンパクトなHDRフォーマットで、サンプリングは可能ですが、レンダーターゲットのカラーバッファとしては**使用できません**。 + +フォーマットの完全な一覧と詳細なHDRサポート規則については、[`Texture`](https://api.playcanvas.com/engine/classes/Texture.html) APIリファレンスを参照してください。 + +レンダリング中の深度テストには、レンダーターゲットの作成時に `depth: true` で深度バッファを要求します(上記のとおり)。ステンシルバッファが必要な場合は `stencil: true` も指定します。 + +## リサイズ {#resizing} + +レンダーターゲットの解像度を変更するには(たとえばウィンドウのリサイズ時に出力サイズと一致させ続けるため)、[`renderTarget.resize(width, height)`](https://api.playcanvas.com/engine/classes/RenderTarget.html#resize) を呼び出します。これは基になるカラーバッファと深度バッファをリサイズします。それまでの内容は保持されません。 + +## アンチエイリアス {#anti-aliasing} + +`samples` を1より大きく設定すると、ハードウェアのマルチサンプルアンチエイリアス(MSAA)でターゲットをレンダリングします。マルチサンプルの結果は、作成した単一サンプルのカラーテクスチャ(サンプリング対象となるもの)へ自動的に解決されます。 + +```javascript +const renderTarget = new pc.RenderTarget({ + colorBuffer: texture, + depth: true, + origin: pc.RENDERTARGET_ORIGIN_TOP, + samples: 4 +}); +``` + +## クリーンアップ {#cleaning-up} + +レンダーターゲットはテクスチャを所有しないため、使い終わったらそれらを個別に破棄します。カラーテクスチャ(および明示的に作成した場合は深度バッファのテクスチャ)を破棄してから、レンダーターゲットを破棄します。 + +```javascript +renderTarget.colorBuffer.destroy(); +renderTarget.destroy(); +``` + +## 例 {#example} + +次の例は、2つ目のカメラからシーンをテクスチャにレンダリングし、それをワールド内の平面に表示します。上記の3レイヤー構成を使って表示用の平面をレンダーターゲットから除外し、数秒ごとにテクスチャカメラを透視投影と平行投影で切り替えます。 + + + +## 関連ページ {#related-pages} + +- [複数のレンダーターゲット](./multiple-render-targets.md) - 1つのパスから複数のカラーバッファへ同時にレンダリングします。 +- [複数のカメラ](../cameras/multiple-cameras.md) - ビューの合成とカメラへのレンダーターゲットの割り当てです。 +- [レイヤー](../layers/index.md) - 各カメラがどのオブジェクトをレンダリングするかを制御します。 +- [ポストエフェクト](../posteffects/index.md) - レンダーターゲットの上に構築された、組み込みおよびカスタムの後処理です。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/cameras/multiple-cameras.md b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/cameras/multiple-cameras.md index f7db18f8de1..c389b82579d 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/cameras/multiple-cameras.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/cameras/multiple-cameras.md @@ -91,7 +91,7 @@ overlay.camera.clearDepthBuffer = true; // メインビューと深度テスト ## レンダーターゲット {#render-targets} -カメラは画面の代わりに、`renderTarget` プロパティに [RenderTarget](https://api.playcanvas.com/engine/classes/RenderTarget.html) を割り当てることで、オフスクリーンテクスチャにレンダリングできます。生成されたテクスチャはマテリアルに適用して、ゲーム内のスクリーン、鏡、ポータルなどに使ったり、さらに加工したりできます。エンジンのレンダーテクスチャのサンプルを参照してください: +カメラは画面の代わりに、`renderTarget` プロパティに [RenderTarget](https://api.playcanvas.com/engine/classes/RenderTarget.html) を割り当てることで、オフスクリーンテクスチャにレンダリングできます。生成されたテクスチャはマテリアルに適用して、ゲーム内のスクリーン、鏡、ポータルなどに使ったり、さらに加工したりできます。詳しくは [レンダーターゲット](/user-manual/graphics/advanced-rendering/render-targets/) のページを参照してください。エンジンのレンダーテクスチャのサンプルも参照してください: From e6da3343302806e6494d1e9cc016cb5a49abcb34 Mon Sep 17 00:00:00 2001 From: Martin Valigursky Date: Wed, 26 Aug 2026 11:47:32 +0100 Subject: [PATCH 3/3] Document explicit multisampled render targets and custom resolves --- .../advanced-rendering/render-targets.md | 38 +++++++++++++++++++ .../advanced-rendering/render-targets.md | 38 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/docs/user-manual/graphics/advanced-rendering/render-targets.md b/docs/user-manual/graphics/advanced-rendering/render-targets.md index 7d19436c0b0..cbf12a92ec9 100644 --- a/docs/user-manual/graphics/advanced-rendering/render-targets.md +++ b/docs/user-manual/graphics/advanced-rendering/render-targets.md @@ -130,6 +130,44 @@ const renderTarget = new pc.RenderTarget({ }); ``` +For control over how the samples are resolved - or to read them individually in a shader - see [Explicit multisampled render targets](#explicit-multisampled-render-targets-and-custom-resolves) below. + +## Explicit multisampled render targets and custom resolves + +:::note + +The features in this section require Engine 2.22 or later, and are WebGPU only. + +::: + +The automatic resolve above averages the samples with a fixed hardware "box" filter. Techniques that need a different resolve - a tonemapped color resolve, a min/max depth resolve, or reading the individual samples in a shader - create the multisampled textures explicitly (a [`Texture`](https://api.playcanvas.com/engine/classes/Texture.html) with `samples` greater than 1) and use them directly as the render target's buffers: + +```javascript +// multisampled textures - the render target renders directly into their samples +const msColor = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_RGBA16F, samples: 4 }); +const msDepth = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_DEPTH, samples: 4 }); + +// optional single-sampled resolve targets +const resolvedColor = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_RGBA16F, mipmaps: false }); +const resolvedDepth = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_R32F, mipmaps: false }); + +const renderTarget = new pc.RenderTarget({ + colorBuffer: msColor, + resolveBuffer: resolvedColor, // hardware resolve at the end of a render pass + depthBuffer: msDepth, + depthResolveBuffer: resolvedDepth // shader-based resolve, controlled by depthResolveMode +}); +``` + +- **Color**: when a `resolveBuffer` is provided, the color samples are hardware-resolved into it at the end of a render pass, like the automatic path. When it is omitted, the samples are stored instead, and a later pass reads them individually with `textureLoad` on a `texture_multisampled_2d` - a custom resolve. This is also the only way to use MSAA with formats the hardware cannot resolve, such as integer formats. With multiple render targets, each attachment has its own optional resolve texture (`resolveBuffers`). +- **Depth**: depth has no hardware resolve on WebGPU. A multisampled `depthBuffer` can be read per sample as a `texture_depth_multisampled_2d`, or resolved into the `depthResolveBuffer` by an engine-provided shader whose operation is selected with [`depthResolveMode`](https://api.playcanvas.com/engine/classes/RenderTarget.html#depthresolvemode) - `DEPTHRESOLVE_MIN` (the default, selecting the nearest surface), `DEPTHRESOLVE_MAX` or `DEPTHRESOLVE_SAMPLE0`. The same mode also controls the depth resolve used by the scene depth map and by depth copies. + +Two examples demonstrate these techniques - a custom tonemapped color resolve compared side by side against the hardware resolve, and per-sample depth fog compared against fog computed from a resolved depth: + + + + + ## Cleaning up A render target does not own its textures, so destroy them separately when you are done. Destroy the color texture (and depth buffer texture, if you created one explicitly), then the render target: diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md index 06f85b9a7e5..7aafa56eb99 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/user-manual/graphics/advanced-rendering/render-targets.md @@ -130,6 +130,44 @@ const renderTarget = new pc.RenderTarget({ }); ``` +サンプルの解決方法を制御したり、シェーダーでサンプルを個別に読み取ったりするには、下記の[明示的なマルチサンプルレンダーターゲット](#explicit-multisampled-render-targets-and-custom-resolves)を参照してください。 + +## 明示的なマルチサンプルレンダーターゲットとカスタム解決 {#explicit-multisampled-render-targets-and-custom-resolves} + +:::note + +このセクションの機能は Engine 2.22 以降が必要で、WebGPU 専用です。 + +::: + +上記の自動解決は、固定のハードウェア「ボックス」フィルターでサンプルを平均します。異なる解決が必要なテクニック(トーンマップされたカラー解決、min/max のデプス解決、シェーダーでの個別サンプルの読み取りなど)では、マルチサンプルテクスチャ(`samples` を1より大きく設定した [`Texture`](https://api.playcanvas.com/engine/classes/Texture.html))を明示的に作成し、レンダーターゲットのバッファとして直接使用します。 + +```javascript +// マルチサンプルテクスチャ - レンダーターゲットはそのサンプルへ直接レンダリングします +const msColor = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_RGBA16F, samples: 4 }); +const msDepth = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_DEPTH, samples: 4 }); + +// 任意の単一サンプル解決ターゲット +const resolvedColor = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_RGBA16F, mipmaps: false }); +const resolvedDepth = new pc.Texture(app.graphicsDevice, { width, height, format: pc.PIXELFORMAT_R32F, mipmaps: false }); + +const renderTarget = new pc.RenderTarget({ + colorBuffer: msColor, + resolveBuffer: resolvedColor, // レンダーパス終了時のハードウェア解決 + depthBuffer: msDepth, + depthResolveBuffer: resolvedDepth // depthResolveMode で制御されるシェーダーベースの解決 +}); +``` + +- **カラー**: `resolveBuffer` を指定すると、自動パスと同様に、レンダーパス終了時にカラーサンプルがハードウェア解決されます。省略すると、サンプルはそのまま保存され、後続のパスが `texture_multisampled_2d` に対する `textureLoad` で個別に読み取れます(カスタム解決)。整数フォーマットなど、ハードウェアが解決できないフォーマットで MSAA を使う唯一の方法でもあります。複数レンダーターゲットでは、各アタッチメントごとに任意の解決テクスチャ(`resolveBuffers`)を持てます。 +- **デプス**: WebGPU にはデプスのハードウェア解決がありません。マルチサンプルの `depthBuffer` は `texture_depth_multisampled_2d` としてサンプルごとに読み取るか、エンジン提供のシェーダーで `depthResolveBuffer` へ解決できます。解決の演算は [`depthResolveMode`](https://api.playcanvas.com/engine/classes/RenderTarget.html#depthresolvemode) で選択します - `DEPTHRESOLVE_MIN`(デフォルト。最も近いサーフェスを選択)、`DEPTHRESOLVE_MAX`、`DEPTHRESOLVE_SAMPLE0`。同じモードは、シーンデプスマップやデプスコピーで使われるデプス解決も制御します。 + +これらのテクニックを示す2つの例があります - ハードウェア解決と並べて比較するカスタムのトーンマップカラー解決、および解決済みデプスによるフォグと比較するサンプルごとのデプスフォグです。 + + + + + ## クリーンアップ {#cleaning-up} レンダーターゲットはテクスチャを所有しないため、使い終わったらそれらを個別に破棄します。カラーテクスチャ(および明示的に作成した場合は深度バッファのテクスチャ)を破棄してから、レンダーターゲットを破棄します。