效果地址:https://www.shadertoy.com/view/MsGczV
首先让我们只用一个custom节点连接材质,
打开HLSL查看器,复制代码到文本,搜索CustomExpression
可以看到这里就是节点的代码,然后我们可以进行操作,比如修改成
MaterialFloat3 CustomExpression0(FMaterialPixelParameters Parameters)
{
return 1;
}
float MyFunction(float a)
{
return a;
}
再把代码添加给custom节点,也是可以编译通过的
接下来复制shadertoy的代码并修改后放入custom节点
第一部分:
return 1;
}
#define Pi 3.14159265359
#define mix lerp
struct Gear
{
float t; // Time
float gearR; // Gear radius
float teethH; // Teeth height
float teethR; // Teeth "roundness"
float teethCount; // Teeth count
float diskR; // Inner or outer border radius
float3 color; // Color
};
float GearFunction(float2 uv, Gear g)
{
float r = length(uv);
float a = atan2(uv.y, uv.x);
// Gear polar function:
// A sine squashed by a logistic function gives a convincing
// gear shape!
float p = g.gearR-0.5*g.teethH +
g.teethH/(1.0+exp(g.teethR*sin(g.t + g.teethCount*a)));
float gear = r - p;
float disk = r - g.diskR;
return g.gearR > g.diskR ? max(-disk, gear) : max(disk, -gear);
}
float GearDe(float2 uv, Gear g)
{
// IQ's f/|Grad(f)| distance estimator:
float f = GearFunction(uv, g);
float2 eps = float2(0.0001, 0);
float2 grad = float2(
GearFunction(uv + eps.xy, g) - GearFunction(uv - eps.xy, g),
GearFunction(uv + eps.yx, g) - GearFunction(uv - eps.yx, g)) / (2.0*eps.x);
return (f)/length(grad);
}
float GearShadow(float2 uv, Gear g)
{
float r = length(uv + float2(0.1,0));
float de = r - g.diskR + 0.0*(g.diskR - g.gearR);
float eps = 0.4*g.diskR;
return smoothstep(eps, 0., abs(de));
}
void DrawGear(inout float3 color, float2 uv, Gear g, float eps)
{
float d = smoothstep(eps, -eps, GearDe(uv, g));
float s = 1.0 - 0.7*GearShadow(uv, g);
color = mix(s*color, g.color, d);
}
float aa()
{
return 0;
第二部分
float t = 0.5*iTime;
//float uv = 2.0*(fragCoord - 0.5*iResolution.xy)/iResolution.y;
//float eps = 2.0/iResolution.y;
//float2 uv = UV .xy * ScreenResolution.xy;
// Scene parameters;
float3 base;
base = float3(0.95, 0.7, 0.2);
const float count = 8.0;
Gear outer;
//outer = Gear(0.0, 0.8, 0.08, 4.0, 32.0, 0.9, base);
outer.t=0.0;
outer.gearR=0.8;
outer.teethH=0.08;
outer.teethR=4.0;
outer.teethCount=32.0;
outer.diskR=0.9;
outer.color=base;
Gear inner;
//inner = Gear(0.0, 0.4, 0.08, 4.0, 16.0, 0.3, base);
inner.t=0.0;
inner.gearR=0.4;
inner.teethH=0.08;
inner.teethR=4.0;
inner.teethCount=16.0;
inner.diskR=0.3;
inner.color=base;
// Draw inner gears back to front:
float3 color = float3(0.0,0.0,0.0);
for(float i=0.0; i<count; i++)
{
t += 2.0*Pi/count;
inner.t = 16.0*t;
inner.color = base*(0.35 + 0.6*i/(count-1.0));
DrawGear(color, uv+0.4*float2(cos(t),sin(t)), inner, eps);
}
// Draw outer gear:
DrawGear(color, uv, outer, eps);
return float4(color,1.0);
然后传入未定义的参数,这里需要添加一个参数(随便命名)把第一部分的代码传入,使编译可以通过
可以看到大致出现了
但是方向不对,这是因为UE的UV坐标在左上角,shadertoy的在左下角,我们 调整UV即可
最终完成。
如果需要把shader的usf文件放外部的情况,就需要在模块的StartupModule() 里面添加如下代码把shader的文件的路径添加(不知道在哪里的同学可以直接创建一个插件)
void FMyCustomShaderModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
FString PluginShaderDir = FPaths::Combine(FPaths::ProjectPluginsDir(), TEXT("MyCustomShader/Shaders"));
AddShaderSourceDirectoryMapping(TEXT("/Plugin/MyCustomShader"), PluginShaderDir);
}
然后在custom里添加就可以了
PS:调用函数的时候可以把函数放在struct RMfunction{};里,然后实例化RMfunction RM;就可调用里面的函数RM.function();Ctrl+Shift+.或者命令行recompileshaders changed可以重构shader
参考:https://docs.microsoft.com/zh-tw/windows/uwp/gaming/glsl-to-hlsl-reference