Any plans to use cbuffer instead of #defines?
- OtisInf
- Topic Author
Today, the shaders used in reshade are using #defines to define the parameter values they're operate with stored in .cfg files. When you want to create the perfect screenshot, this often requires one to tinker with the values in .cfg files, save the file, reshade picks up the change, recompiles the HLSL, and you see the effect of the change you made. This has the following downsides:
- it's slow, as changing a parameter could take 2-3 seconds at least to see the effect
- and more importantly: it works with files and recompiling of shaders, this means there's no real-time UI possible.
So this got me thinking: why not do the following? Use a cbuffer / constant buffer instead: using variables in a cbuffer struct, the HLSL compiler will compile that into a tight buffer which is updatable in real-time. The shaders no longer use the #defined constants in their code but the (albeit global) variables in the cbuffer.
The big advantage of this is that a real-time UI to change the values and immediately see the effect of that change is no longer hard: the UI (e.g. created with ImGui github.com/ocornut/imgui ) can offer controls to the user which, when their values are changed, immediately update the cbuffer which is then pushed to the shaders again, and the effect of the change is seen immediately.
This is the same system ENB uses: it saves the values used at runtime in separate, simple ini files. You could, for backwards compatibility, use the current cfg files as initial values for the variables, so people can download presets as-is, but don't have to alter the cfg files anymore, they can do that through the UI.
Am I delusional or is this a possibility? Thanks for listening.
Please Log in or Create an account to join the conversation.
- Ganossa
Please Log in or Create an account to join the conversation.
- OtisInf
- Topic Author
float GetFocalDepth(float2 focalpoint)
{
float depthsum = 0;
float fcRadius = 0.00;
[unroll]
for(int r=0;r<6;r++)
{
float t = (float)r;
t *= 3.1415*2/6;
float2 coord = float2(cos(t),sin(t));
coord.y *= ScreenSize.z;
coord *= fcRadius; // A
float depth = GetLinearDepth(tex2Dlod(RFX_depthColor,float4(coord+focalpoint,0,0)).x);
depthsum+=depth;
}
depthsum = depthsum/6;
#if(DOF_MANUALFOCUS == 1)
depthsum = DOF_MANUALFOCUSDEPTH; // B
#endif
return depthsum;
}
(hint: at line A, you're multiplying with 0, as fcRadius is never updated, at line B you're overwriting the work you've done above the code, which can be made more optimal by including the loop in the #ifdef so it's only done when manual focus depth is 0 )
Please Log in or Create an account to join the conversation.
- crosire
Please Log in or Create an account to join the conversation.
- Ganossa
@Crosire, any change to the loaded files will re-compile the shader currently? So even though they are internally cbuffer variables, they would still cause the re-compilations, is that correct or would you need to define the actual values in that experimental GUI that you mentioned?
Please Log in or Create an account to join the conversation.
- crosire
Of course. Uniforms are there to be changed at runtime, not to be changed in the source code.LuciferHawk wrote: @Crosire, any change to the loaded files will re-compile the shader currently? So even though they are internally cbuffer variables, they would still cause the re-compilations, is that correct or would you need to define the actual values in that experimental GUI that you mentioned?
When ReShade compiles a shader it stores a list of all uniforms it came across, creates a constant buffer and populates it with those uniforms. Later the GUI I'm talking about loops over all uniforms, adds some slider or similar to the in-game overlay and waits for user input. If the user changes one of those sliders, ReShade knows which offset in the constant buffer that value is stored at and replaces it in GPU memory.
Uniforms should be used carefully and only when useful. Example: Changing between different DOF types, which changes the actual code is something one would do with preprocessor macros, because it reduces the amount of code that needs to be executed. Something like the DOF near and far plane constants however could be implemented with uniforms, because those are simple variable values without any payload attached to them.
Please Log in or Create an account to join the conversation.
- OtisInf
- Topic Author
Please Log in or Create an account to join the conversation.
- Ganossa
If its supposed to be how you are saying, then (currently!) I am missing some step here in the plan Where (and maybe also When) will the settings for uniforms ultimately be stored persistently if not in the setting files so the user does not have to set them up each time he runs a game or to share presets?
Unless there is a clause for preset uniforms in the re-compilation on file change and another language extension to change/set this value, I see it not really being an alternative to preprocessor defines. (But maybe it was just too early in its actual development to answer those question that however need to be answered in the end I believe )
Please Log in or Create an account to join the conversation.
- crosire
They do have a default value:LuciferHawk wrote: Where (and maybe also When) will the settings for uniforms ultimately be stored persistently if not in the setting files so the user does not have to set them up each time he runs a game or to share presets?
uniform float myValue = 1337.0f;
Constant (is evaluated by the compiler):
static const float myValue = 1337.0f;
#define myValue 1337.0f
Please Log in or Create an account to join the conversation.