联系电话:18652913986
行业资讯位置:首页 > 行业资讯
Unreal|ShaderToy到Unreal
发表时间:2024-07-16     阅读次数:     字体:【
贴上shadertoy的相关代码:

    const int nParticles = 150;const float size = 0.001;const float softness = 150.0;const vec4 bgColor = vec4(0.0,0.0,0.0,1.0); float random (int i){ return fract(sin(float(i)*43.0)*4790.234);   } float softEdge(float edge, float amt){    return clamp(1.0 / (clamp(edge, 1.0/amt, 1.0)*amt), 0.,1.);} void mainImage( out vec4 fragColor, in vec2 fragCoord ){     vec2 uv = fragCoord/iResolution.xy;    vec2 tc = uv;    float aspect = iResolution.x / iResolution.y;   uv.x *= aspect;     fragColor = bgColor;     //vec4 tex = texture(iChannel0, tc);    float np = float(nParticles);    for(int i = 0; i        vec2 tc = uv;         float r = random(i);        float r2 = random(i+nParticles);        float r3 = random(i+nParticles*2);        tc.x -= sin(iTime*1.125 + r*30.0)*r;        tc.y -= cos(iTime*1.125 + r*40.0)*r2*0.5;         float l = length(tc - vec2(aspect*0.5, 0.5));// - r*size;        tc -= vec2(aspect*0.5, 0.5)*1.0;        tc = tc * 2.0 - 1.0;        tc *= 1.0;        tc = tc * 0.5 + 0.5;         vec4 orb = vec4(r, r2, r3, softEdge(l, softness));        orb.rgb *= 1.5; // boost it         fragColor = mix(fragColor, orb, orb.a);    }    //fragColor = mix(tex, fragColor, fragColor.a);}
    1
    逐行分析




    1.const int nParticles = 150;: 定义了粒子数量为150。

    2.const float size = 0.001;: 定义了粒子大小为0.001。

    3.const float softness = 150.0;: 定义了软边缘的强度为150.0。

    4.const vec4 bgColor = vec4(0.0,0.0,0.0,1.0);: 定义了背景颜色为黑色。

    5.float random(int i): 定义了一个生成伪随机数的函数,通过输入参数i生成不同的随机数。

    6.float softEdge(float edge, float amt): 定义了一个函数,用于计算软边缘效果的强度。

    7.void mainImage(out vec4 fragColor, in vec2 fragCoord): 主函数,负责计算每个像素的颜色。

    8.vec2 uv = fragCoord / iResolution.xy;: 计算了当前像素的归一化坐标。

    9.vec2 tc = uv;: 将uv坐标赋值给tc。

    10.float aspect = iResolution.x / iResolution.y; uv.x *= aspect;: 计算了屏幕的宽高比,以便在水平方向上拉伸或挤压纹理。

    11.fragColor = bgColor;: 将背景颜色赋给fragColor。

    12.for(int i = 0; i < nParticles; i++) { ... }: 循环迭代nParticles次,生成粒子效果。

    13.vec4 tex = texture(iChannel0, tc);: 这行代码被注释掉了,原本可能是用于从外部纹理中获取颜色信息的。

    14.在循环中,通过调用random函数生成随机数r、r2和r3,用于控制粒子的位置和外观。

    15.float l = length(tc - vec2(aspect*0.5, 0.5));: 计算了粒子距离屏幕中心的距离。

    16.tc -= vec2(aspect*0.5, 0.5)*1.0; tc = tc * 2.0 - 1.0; tc *= 1.0; tc = tc * 0.5 + 0.5;: 对tc进行了一系列归一化操作,将其范围限制在0到1之间。

    17.vec4 orb = vec4(r, r2, r3, softEdge(l, softness));: 创建了一个包含粒子颜色和透明度的vec4,透明度由softEdge函数计算得到。

    18.orb.rgb *= 1.5;: 增强了粒子的颜色。

    19.fragColor = mix(fragColor, orb, orb.a);: 使用混合函数将当前像素的颜色与粒子颜色进行混合。

    20.//fragColor = mix(tex, fragColor, fragColor.a);: 这行代码被注释掉了,原本应该是用于将外部纹理与粒子效果混合。

    2
    转化为HLSL





    由于unreal材质使用hlsl,而shadertoy使用glsl,所以需要将上面代码转化为hlsl。

    针对当前案例中的代码主要的转化点为:

    • 数据类型转换:GLSL中的vec2、vec4、float等类型需要转换为HLSL中的float2、float4、float等类型。

    • 内置变量的转换:GLSL中的内置变量如iResolution、iTime等需要转换为HLSL中对应的内置变量。

    • 函数定义与调用:GLSL中的函数定义和调用与HLSL中稍有不同,比如GLSL中的mix需要转化为HLSL中的lerp。

    所以经过转化以后的代码如下:

      //也可以继续用const来定义常量#define nParticles 150#define size 0.001#define softness 150.0   #define bgColor float4(0.0, 0.0, 0.0, 1.0) float random(int i) {    return frac(sin(float(i) * 43.0) * 4790.234);} float softEdge(float edge, float amt) {    return clamp(1.0 / (clamp(edge, 1.0 / amt, 1.0) * amt), 0.0, 1.0);} void mainImage(out float4 fragColor : SV_Target, in float2 fragCoord : VPos) {    float2 uv = fragCoord / iResolution.xy;    float2 tc = uv;    float aspect = iResolution.x / iResolution.y;    uv.x *= aspect;     fragColor = bgColor;     //float4 tex = tex2D(iChannel0, tc);    float np = nParticles;    for(int i = 0; i         float2 tc = uv;         float r = random(i);        float r2 = random(i + nParticles);        float r3 = random(i + nParticles * 2);        tc.x -= sin(iTime * 1.125 + r * 30.0) * r;        tc.y -= cos(iTime * 1.125 + r * 40.0) * r2 * 0.5;         float l = length(tc - float2(aspect * 0.5, 0.5));// - r * size;        tc -= float2(aspect * 0.5, 0.5) * 1.0;        tc = tc * 2.0 - 1.0;        tc *= 1.0;        tc = tc * 0.5 + 0.5;         float4 orb = float4(r, r2, r3, softEdge(l, softness));        orb.rgb *= 1.5; // boost it         fragColor = lerp(fragColor, orb, orb.a);    }    //fragColor = lerp(tex, fragColor, fragColor.a);}
      3
      写入Unreal


      要把上面代码写进unreal材质编辑器,就需要了解custom节点的一些使用方法。比如这里面除了主函数以外,还调用了一个随机数函数和一个软边函数,而一个custom本身就是一个函数,所以需要把调用的函数放在另外一个custom节点中。具体如下:

      图片
        return 0;}float random(int i) {    return frac(sin(float(i) * 43.0) * 4790.234);} float softEdge(float edge, float amt) {return clamp(1.0 / (clamp(edge, 1.0/amt, 1.0)*amt), 0.,1.);
        另起一个custom节点,放入主函数,并将常量等相关参数暴露在外方便设置
          for(int i = 0; i nParticles; i++) {        float2 tc = uv;         float r = random(i);        float r2 = random(i + nParticles);        float r3 = random(i + nParticles * 2);        tc.x -= sin(iTime * 1.125 + r * 30.0) * r;//时间暴露方便做速度调整           tc.y -= cos(iTime * 1.125 + r * 40.0) * r2 * 0.5;         float l = length(tc - float2( 0.5, 0.5));// - r * size;        tc -= float2( 0.5, 0.5) * 1.0;        tc = tc * 2.0 - 1.0;        tc *= 1.0;        tc = tc * 0.5 + 0.5;         float4 orb = float4(r, r2, r3, softEdge(l, softness));        orb.rgb *= 1.5; // boost it         fragColor = lerp(fragColor, orb, orb.a);    }return fragColor;

          实际放到custom的时候,用引擎uv进行了替换并暴露,相应的aspect 给到数值1,并且把下面的常量等作为参数进行暴露。

          图片



          文章转载自

          Thepoly

           
          上一篇:Blender载具装配插件
          下一篇:在虚幻引擎中创建一个详细的伦敦环境