-
Notifications
You must be signed in to change notification settings - Fork 128
Injecting custom shaders
This adds new CustomShader sections to the d3dx.ini which can be used to load custom shaders (of any type).
These shaders can be called from any other section that implements a command list, such as a ShaderOverride (to run a custom shader before or after another shader), Present (e.g. to implement a custom overlay or debug visualisation), or other CustomShaders (could be useful to chain together a number of related shaders that all have a common vertex shader).
When they are called they will save any currently bound shaders and bind their own (note - they currently don't unbind shaders that they don't replace - keep that in mind if trying to inject at a point where hull, domain or geometry shaders may be in use). They will restore the original shaders after they have run.
The type of draw/dispatch call should be specified in the CustomShader section to actually draw the shader (in fact these can be called from any command list if one was so inclined). All draw calls except indirect are supported.
Resources (e.g. render targets or UAVs to pass between shaders) can be assigned via the arbitrary resource copying support, and custom resources can be created if enough detail is specified in their [Resource] section, or loaded from a file on disk. The biggest missing piece is the ability to set the vertex buffer layout - creating custom vertex buffers is possible, but of limited use without this, however Vertex shaders can manufacture their own coordinates from the SV_VertexID to make up for this.
We also will want to be able to control the output merger state for this to be most useful, which is covered here. 3DMigoto also supports depth/stencil, rasterizer and input topology overrides.
e.g.
[CustomShaderDebugOverlay]
vs = ShaderFixes/my_custom_vs.hlsl
ps = ShaderFixes/my_custom_ps.hlsl
ps-t100 = ResourceThatIAmDebugging
Draw = 6, 0
post ps-t100 = null
[CustomShaderInjectedCS]
cs = ShaderFixes/my_custom_cs.hlsl
Dispatch = 8, 4, 1
[ShaderOverrideFoo]
Hash = ...
run = CustomShaderInjectedCS
[Present]
run = CustomShaderDebugOverlay
my_custom_vs.hlsl
void main(
out float4 pos : SV_Position0,
out float2 texcoord : TEXCOORD0,
uint vertex : SV_VertexID)
{
// Not using vertex buffers so manufacture our own coordinates.
// You may have to adjust this depending on whether the game is using
// clockwise or counterclockwise for front-facing surfaces:
switch(vertex) {
case 0:
pos.xy = float2(-1, -1);
break;
case 1:
pos.xy = float2(1, -1);
break;
case 2:
pos.xy = float2(-1, 1);
break;
case 3:
pos.xy = float2(-1, 1);
break;
case 4:
pos.xy = float2(1, -1);
break;
case 5:
pos.xy = float2(1, 1);
break;
default:
pos.xy = float2(2, 2);
break;
};
pos.zw = float2(0, 1);
// Note to all our 3D shaderhackers - this is where halos come from:
texcoord = pos.xy / 2 + 0.5;
}
my_custom_ps.hlsl
void main(
float4 pixel_pos : SV_Position0,
float2 texcoord : TEXCOORD0,
out float4 result : SV_Target0)
{
// do your stuff here
result = float4(1,0,0,1);
}