Skip to content
Ian Munsie edited this page Nov 16, 2015 · 1 revision

Arbitrary Resource Copying support was added in 3DMigoto 1.2.4

As of 1.2.5. it supports copying:

  • Constant Buffers (s-cb)
  • Vertex Buffers (vb)
  • Index Buffers (ib)
  • Stream Output Buffers (so)
  • Textures (s-t)
  • Render Targets (o)
  • Depth Targets (oD)
  • Unordered Access Views (ps-u / cs-u)

There are countless possibilities with this support, but here's a few practical examples to get you started.

Copy constant buffer 1 from the pixel shader to the vertex shader as constant buffer 13 (used in Mad Max to get access to the depth of a light to fix bloom):

[ShaderOverrideBloomVS]
; The vertex shader doesn't have access to the light depth, which we need to
; correct the bloom position accurately. The pixel shader does have the depth
; which it uses to calculate the bloom opacity. Bind the relevant constant
; buffer from the pixel shader to the vertex shader so we can get the correct
; depth and fix the position.
Hash=e9849e745227d124
vs-cb13 = ps-cb1

Copy a constant buffer from one shader to another, using an intermediate resource (used to fix specular highlights and environmental reflections in Unity 5 games):

; Define an intermediate resource to copy between different shaders. Custom
; resources like this start with "Resource":
[ResourceUnityPerCameraRare]

; Copy constant buffer 1 from the directional lighting shader into the
; intermediate resource:
[ShaderOverrideDirectional]
Hash = b78925705424e647
ResourceUnityPerCameraRare = vs-cb1

; Copy (actually reference) the intermediate resource into the physical
; lighting shader as constant buffer 13:
[ShaderOverridePhysical]
Hash = ca5cfc8e4d8b1ce5
vs-cb13 = ResourceUnityPerCameraRare

Copy the currently active depth buffer into a vertex shader (e.g. for automatically adjusting a crosshair depth) - this replaces the experimental depth_input feature, which has been removed:

[ShaderOverrideCrosshair]
Hash = 07e0f4c1eb997ee1
vs-t110 = oD

Copy a vertex buffer into the shader as a constant buffer (Might be able to look up the position of other vertices?):

[ShaderOverrideClippedLight]
Hash = 1234
vs-cb12 = vb0

Copy an active render target into the shader as a texture:

[ShaderOverrideClippedTransparency]
Hash = abcd
ps-t108 = o0

There's also keywords to control some advanced features. For example, 3DMigoto will try to guess whether it should do a full copy of a resource, or only a lightweight reference, but maybe you want to override this:

[ResourceTempStorage]
[ShaderOverrideFoo]
Hash = foo
; Assigning *to* a temporary resource defaults to copying, but maybe we
; actually want a reference either to get any updates the game makes to the
; original texture, or because we know the resource won't change before we need
; to use it:
ResourceTempStorage = reference ps-t0

[ShaderOverrideBar]
Hash = bar
; Assigning *from* a temporary resource defaults to reference, but perhaps the
; temporary resource doesn't have the right bind flags for what we are
; assigning it to, or we want it leave it assigned in this slot while
; preventing it from getting updated if the game changes the original:
ps-t110 = copy ResourceTempStorage

By default, if you try to copy something that wasn't bound, 3DMigoto will unbind the destination as well. But, perhaps the resource you are copying is only bound some of the time, and if it is not bound you want to leave whatever was previously bound in the destination alone:

[ShaderOverrideBaz]
Hash = baz
ps-t50 = o2 unless_null

Or, perhaps you just want to unbind something from the pipeline for some reason (like influencing driver heuristics?):

[ShaderOverrideRubbish]
Hash = rubbish
o0 = null

A demonstration of several new features in 3DMigoto 1.2.5 combined together:

  • The [Present] section is used to clear a temporary resource at the start of each frame (to prevent stale information being used if the copy source is unavailable in a frame. e.g. prevent the UI being adjusted from the depth buffer while in a menu)
  • The "post" keyword indicates that o0 should be copied after the draw call instead of before (to get the result of the draw operation)
  • max_copies_per_frame is used to limit the number of times the temporary resource can be written to to 1
  • unless_null is used to make sure that the temporary resource won't be cleared once it has been assigned (probably unnecessary in this specific scenario, but hey - demo)
[ResourceWBuffer]
max_copies_per_frame = 1

[Present]
ResourceWBuffer = null

[ShaderOverrideZToWBuffer]
Hash = ...
post ResourceWBuffer = o0 unless_null

[ShaderOverrideCrosshair]
Hash = ...
vs-t110 = ResourceWBuffer