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的调试功能。