Open colinbouvry opened 2 years ago
There's a section in the Main compute shader c++ file that looks like this:
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
/*
* Here's where you define one or more of the input parameters for your shader.
* Some examples:
*/
// SHADER_PARAMETER(uint32, MyUint32) // On the shader side: uint32 MyUint32;
// SHADER_PARAMETER(FVector3f, MyVector) // On the shader side: float3 MyVector;
// SHADER_PARAMETER_TEXTURE(Texture2D, MyTexture) // On the shader side: Texture2D<float4> MyTexture; (float4 should be whatever you expect each pixel in the texture to be, in this case float4(R,G,B,A) for 4 channels)
// SHADER_PARAMETER_SAMPLER(SamplerState, MyTextureSampler) // On the shader side: SamplerState MySampler; // CPP side: TStaticSamplerState<ESamplerFilter::SF_Bilinear>::GetRHI();
// SHADER_PARAMETER_ARRAY(float, MyFloatArray, [3]) // On the shader side: float MyFloatArray[3];
// SHADER_PARAMETER_UAV(RWTexture2D<FVector4f>, MyTextureUAV) // On the shader side: RWTexture2D<float4> MyTextureUAV;
// SHADER_PARAMETER_UAV(RWStructuredBuffer<FMyCustomStruct>, MyCustomStructs) // On the shader side: RWStructuredBuffer<FMyCustomStruct> MyCustomStructs;
// SHADER_PARAMETER_UAV(RWBuffer<FMyCustomStruct>, MyCustomStructs) // On the shader side: RWBuffer<FMyCustomStruct> MyCustomStructs;
// SHADER_PARAMETER_SRV(StructuredBuffer<FMyCustomStruct>, MyCustomStructs) // On the shader side: StructuredBuffer<FMyCustomStruct> MyCustomStructs;
// SHADER_PARAMETER_SRV(Buffer<FMyCustomStruct>, MyCustomStructs) // On the shader side: Buffer<FMyCustomStruct> MyCustomStructs;
// SHADER_PARAMETER_SRV(Texture2D<FVector4f>, MyReadOnlyTexture) // On the shader side: Texture2D<float4> MyReadOnlyTexture;
// SHADER_PARAMETER_STRUCT_REF(FMyCustomStruct, MyCustomStruct)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, RenderTarget)
With that, you should be able to add whatever parameters you need. Here's an (untested) example with the list you provided above:
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_TEXTURE(Texture2D, readTex) // On the shader side: Texture2D<float4> readTex; (float4 should be whatever you expect each pixel in the texture to be, in this case float4(R,G,B,A) for 4 channels)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, writeTex) // On the shader side: RWTexture2D<float4> writeTex; (float4 should be whatever you expect each pixel in the texture to be, in this case float4(R,G,B,A) for 4 channels)
SHADER_PARAMETER(int32, range) // On the shader side: int32 range;
SHADER_PARAMETER(uint32, threshold) // On the shader side: uint32 threshold;
SHADER_PARAMETER(uint32, nstates) // On the shader side: uint32 nstates;
SHADER_PARAMETER(bool, moore) // On the shader side: bool moore;
SHADER_PARAMETER(int32, rez) // On the shader side: int32 rez;
SHADER_PARAMETER_ARRAY(FVector4f, colors, [21]) // On the shader side: float4 colors[21];
END_SHADER_PARAMETER_STRUCT()
There's also another section in the same file a little way down that sets the PassParameters
:
PassParameters->range = 123;
PassParameters->moore = true;
// ...
Thanks
I don't understand how I put
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int range = 1;
and link to shader to have input from the box ?
I just want to link blueprint node input to uniform params on compute shader Any idea ?
There's a line in the public compute shader header file that defines this:
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", Category = "ComputeShader", WorldContext = "WorldContextObject"))
static U...Library_AsyncExecution* ExecuteBaseMaterialComputeShader(UObject* WorldContextObject, AActor* SceneContext, UMaterialInterface* Material, ...) {
To pass a variable from BP into a uniform in your shader, you'll need to:
...Library_AsyncExecution
actionF...DispatchParams
struct at the top of the fileBEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
section of the main cpp filePassParameters->...
) equal to the F...DispatchParams
in the dispatch part of the main cpp file.The basemat
example includes a Position
parameter which you can trace through each of the steps above to get a solid understanding of how each piece moves Position
from the BP call into the shader.
Thanks I have not : static U...Library_AsyncExecution ExecuteBaseMaterialComputeShader(UObject WorldContextObject, AActor SceneContext, UMaterialInterface Material, ...) { I understand nothing ! Why is it too complex ?
The basemat example has a Position
parameter that you can do a find/replace for in the code:
It starts out in the ExampleComputeShader.h file on line 101-102
:
We receive it as a parameter from BP
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", Category = "ComputeShader", WorldContext = "WorldContextObject"))
static UExampleComputeShaderLibrary_AsyncExecution* ExecuteBaseMaterialComputeShader(UObject* WorldContextObject, AActor* SceneContext, UMaterialInterface* Material, FVector2D Position) {
We then stuff it into the Action struct on line 105
Action->Position = static_cast<FVector2f>(Position);
Now that we have that position field we can go over to the ExampleComputeShader.cpp file and look at how it's dispatched
The shader parameter is defined on line 55
:
SHADER_PARAMETER(FVector2f, Position)
I just discovered that I'm not actually passing the Position param into the shader. We'll need to add that ourselves now:
Add this code just under line 139
PassParameters->OutputColor = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(OutputBuffer, PF_A32B32G32R32F));
PassParameters->Position = Params.Position; // <- Add this line here
Finally, this parameter is received in the ExampleComputeShader.usf file on line 4
:
float2 Position;
Hopefully, this makes more sense.
Following the same pattern, you can add your own uniforms and pass them from BP.
Hello
// texture Texture2D readTex;
RWTexture2D writeTex;
// uniform params
int range;
uint threshold;
uint nstates;
bool moore;
int rez;
float4 colors[21];
Do you have idea to add this feature ?
Thanks