Shadertoy导出到Unity

        ShaderToy是一个很棒的Shader网站Shadertoy BETA,里面有很多很好的效果可以参考。它提供了一个网页编辑工具,可以很方便的查看和保存shader。

        但是它也存在一些缺点:

                1. 没有调试功能,只能使用简单的假彩色调试

                2. 灵活性不足,比如没法实时调参数查看整效果,没法调整输出分辨率

                3. 没有顶点着色器功能,只适合用于全屏图像效果。

        而将着色器导入到Unity可以解决以上的问题:

                1. 可以使用Shader调试工具

                2. 将参数添加到材质中,可以在运行时实时调整效果

                3. 可以将shader直接应用于Plane、Quad和Billboard等平面场景。也可以用于非平面的mesh,但是此时是拿模型的UV作为渲染坐标的,不一定能跟模型贴合,可能需要调整UV。

        ShaderMan是一个将ShaderToy转换成CG/HLSL语言的工具,这一步可以直接得到转换后的Material和Shader,使用方法参考其介绍,到这一步已经可以将材质应用于物体查看效果。

        这个工具实测效果并不是很理想,转化后还是有大量的报错需要修复,但至少比直接手动移植少了一些工作量。

        有时候我们想要直接在Unity中屏幕中直接输出结果,而不是要放到Mesh上。需要重载屏幕输出,这个功能也可以用于调试只跟UV相关的shader,建议是放到后处理不影响其他流程,在SRP中实现如下:

if (overloadMaterialSettings.enabled && overloadMaterialSettings.overdrawMaterial != null)
{
    buffer.GetTemporaryRT(
        overloadTextureId, bufferSize.x, bufferSize.y,
        0, FilterMode.Bilinear,
        useHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default
    );

    buffer.SetRenderTarget(
        overloadTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store
    );
    buffer.Blit(null, overloadTextureId, overloadMaterialSettings.overdrawMaterial);
    Draw(overloadTextureId, BuiltinRenderTextureType.CameraTarget);
    ExecuteBuffer();
    buffer.ReleaseTemporaryRT(overloadTextureId);
}

        这里执行了两步,第一步使用Material渲染到一个中间贴图,第二步将中间贴图渲染到相机。使用ShaderToy的默认shader,在Untiy得到结果如下: 

         可以在左上角调整分辨率:

        也可以通过屏幕截图方式获取结果。

        但是还是有局限性,ShaderToy中有大量着色器是用RayMarching或者RayTracing编写的,都是基于一个假定的世界空间和相机位置,跟导出到Unity后的世界空间和相机没有任何关系,要在Unity中对应起来必须将这些步骤重写。还有大量使用SDF的实现,在Unity也没有用武之地,因为一般直接用实际Mesh来实现。

        总的来说,这种移植只适合于一些不和场景交互、不使用RayMarching和RayTracing简单的全屏效果,或者只是想利用Unity的调试功能。

猜你喜欢

转载自blog.csdn.net/paserity/article/details/129702950
今日推荐