【Unity】ShaderToys——将大神们写的shader搬到unity中来吧

2023-10-31

      这篇文章翻译自国外的一篇文章(这里是原文链接),正在使用unity的你是否在shader toy上发现很多牛逼哄哄的shader却不知道如何使用,那么这篇文章就是帮助你来进行转换的。本文只是基础文章,那些对HLSL/CG/GLSL都很熟悉的大神相信已经会觉得太简单了。下面是索引和正文……


本文索引:

文章目录




      如果你正在试图涉猎shader编程这个领域,你可能或多或少听说过 shaderToy这个网站,这个网站上有很多令人惊奇的shader效果,而这些效果有可能只用了几行代码来实现,就好像官方示例程序中提供的效果那样振奋人心。下面是这个网站上其中两个很厉害的例子:
“Seascape” by TDM
“Seascape” by TDM
“Elevated” by iq
“Elevated” by iq

      这个网站上提供的效果示例不仅仅令人赞叹,通过查看他们的源代码,你还可以学习到很多东西。网站上提供了可以在线实时创建和预览效果的代码框,在你的浏览器中,你可以通过修改代码,修改变量和输入来查看效果的变换。
      网站上的代码只提供GLSL语言的支持,因为他们是通过在你的浏览器中运行WebGl来展现这些效果的。在本文中的这个例子是在unity5中实现的,但应该在其他版本的unity中也可以很好的运行。


# 一、 GLSL到HLSL的转换       理论上来说,应该是有将GLSL直接转换为HLSL的工具,但据我所知,至少目前我还没有发现这样的工具。因此,我只能手动将代码一行行转换过来。幸运的是,一般来说,一个shader文件的代码都不会很长,大部分也就一百来行吧,听起来可能只需要几分钟就可以完成这个过程。       微软已经发布过[一篇文章](https://msdn.microsoft.com/en-GB/library/windows/apps/dn166865.aspx?tduid=%289049037839cdab01df889087d9e11888%29%28256380%29%282459594%29%28TnL5HPStwNw-WALomT9mLFV8cHQZR8fELw%29%28%29)专门介绍了GLSL和HLSL之间的差别。Unity中也有一篇类似的很有用的文章在[这里](http://docs.unity3d.com/Manual/SL-PlatformDifferences.html)。而下面是我在转换shader的过程中经常用到的一些方法: - 将 iGlobalTime   shader 输入值转换为(用来驱动shader中动画的时间,类似C#中的Time.deltaTime(单位为秒)) _Time.y - 将 iResolution.xy (“视口的像素分辨率”)  转换为 _ScreenParams.xy - 将元素为 float2, mat2的向量 vec2 类型转换为 float2x2 等. - 将 vec3(1) 简写的构造器改写为所有分量都为1的 float3(1,1,1) - 将 Texture2D 改写为 Tex2D - 将 atan(x,y) 改写为 atan2(y,x) <- 注意参数的顺序! - 将 mix() 改写为 lerp() - 将 *= 改写为 mul() - 将纹理Texture2D查找函数的第三个参数(偏移量bias)移除 - mainImage(out vec4 fragColor, in vec2 fragCoord) 是一个片段着色器, 在unity中等同于 float4 mainImage(float2 fragCoord : SV_POSITION) : SV_Target - GLSL中纹理坐标Y方向的原点在顶部,而HLSL中纹理坐标Y方向的原点在底部,所以你需要使用这个公式 uv.y = 1 – uv.y 对每个点重新定义纹理坐标

      ShaderToys上的这些效果都没有用到顶点着色器函数,他们通过在像素着色器中计算屏幕上每个点对应的UV坐标来确定每个像素对应的颜色值。因此,shadertoy上的这些效果特别适合用来做全屏特效(或者,你可以将他们直接赋给一个面板或者四边形),只要是UV从0到1平铺开来的效果都会差不多。


# 二、 在Unity中实现它       写过shader的开发者应该清楚,在片段着色器(或者说顶点着色器)中对每个像素单独做计算是非常耗性能的。如果你想使你的shader以一个流畅运行的帧率来展现的话,一个比较通用的做法是将片段着色器中的像素缩小到一个合适的比率,再通过放大到屏幕比例的方式来减少计算量。以下是本文中要用到的CS代码通用框架:
using System;
using UnityEngine;

[ExecuteInEditMode]
public class ShaderToy : MonoBehaviour
{

    public int horizontalResolution = 320;
    public int verticalResolution = 240;
    public Shader shaderToy;
    private Material shaderToyMaterial = null;
    public Material material
    {
        get
        {
            shaderToyMaterial = CheckShaderAndCreateMaterial(shaderToy, shaderToyMaterial);
            return shaderToyMaterial;
        }
    }

    // Called by camera to apply image effect
    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        // To draw the shader at full resolution, use: 
        // Graphics.Blit (source, destination, material);

        // To draw the shader at scaled down resolution, use:
        RenderTexture scaled = RenderTexture.GetTemporary(horizontalResolution, verticalResolution);
        Graphics.Blit(source, scaled, material);
        Graphics.Blit(scaled, destination);
        RenderTexture.ReleaseTemporary(scaled);
    }

    protected Material CheckShaderAndCreateMaterial(Shader shader, Material material)
    {
        if (shader == null)
        {
            return null;
        }

        if (shader.isSupported && material && material.shader == shader)
            return material;

        if (!shader.isSupported)
        {
            return null;
        }
        else
        {
            material = new Material(shader);
            material.hideFlags = HideFlags.DontSave;
            if (material)
                return material;
            else
                return null;
        }
    }
}

下面是ShaderToy网站上的源码:

// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	vec2 uv = -1.0 + 2.0*fragCoord.xy / iResolution.xy;
	uv.x *=  iResolution.x / iResolution.y;

    // background	 
	vec3 color = vec3(0.8 + 0.2*uv.y);

    // bubbles	
	for( int i=0; i<40; i++ )
	{
        // bubble seeds
		float pha =      sin(float(i)*546.13+1.0)*0.5 + 0.5;
		float siz = pow( sin(float(i)*651.74+5.0)*0.5 + 0.5, 4.0 );
		float pox =      sin(float(i)*321.55+4.1) * iResolution.x / iResolution.y;

        // buble size, position and color
		float rad = 0.1 + 0.5*siz;
		vec2  pos = vec2( pox, -1.0-rad + (2.0+2.0*rad)*mod(pha+0.1*iGlobalTime*(0.2+0.8*siz),1.0));
		float dis = length( uv - pos );
		vec3  col = mix( vec3(0.94,0.3,0.0), vec3(0.1,0.4,0.8), 0.5+0.5*sin(float(i)*1.2+1.9));
		//    col+= 8.0*smoothstep( rad*0.95, rad, dis );
		
        // render
		float f = length(uv-pos)/rad;
		f = sqrt(clamp(1.0-f*f,0.0,1.0));
		color -= col.zyx *(1.0-smoothstep( rad*0.95, rad, dis )) * f;
	}

    // vigneting	
	color *= sqrt(1.5-0.5*length(uv));

	fragColor = vec4(color,1.0);
}

下面是转换过来在Unity中使用的Shader代码:

// See https://www.shadertoy.com/view/4dl3zn
// GLSL -> HLSL reference: https://msdn.microsoft.com/en-GB/library/windows/apps/dn166865.aspx

Shader "Custom/Bubbles" {

    SubShader {
    
        Pass {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            
            struct v2f{
                float4 position : SV_POSITION;
            };
            
            v2f vert(float4 v:POSITION) : SV_POSITION {
                v2f o;
                o.position = mul (UNITY_MATRIX_MVP, v);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target {
            
                float2 uv = -1.0 + 2.0*i.position.xy/ _ScreenParams.xy;
                uv.x *= _ScreenParams.x/ _ScreenParams.y ;
            
                // Background
                fixed4 outColour = fixed4(0.8+0.2*uv.y,0.8+0.2*uv.y,0.8+0.2*uv.y,1);
            
                // Bubbles
                for (int i = 0; i < 40; i++) {

                    // Bubble seeds
                    float pha =      sin(float(i)*546.13+1.0)*0.5 + 0.5;
                    float siz = pow( sin(float(i)*651.74+5.0)*0.5 + 0.5, 4.0 );
                    float pox =      sin(float(i)*321.55+4.1);

                    // Bubble size, position and color
                    float rad = 0.1 + 0.5*siz;
                    float2  pos = float2( pox, -1.0-rad + (2.0+2.0*rad)*fmod(pha+0.1*_Time.y*(0.2+0.8*siz),1.0));
                    float dis = length(uv-pos);
                    float3 col = lerp( float3(0.94,0.3,0.0), float3(0.1,0.4,0.8), 0.5+0.5*sin(float(i)*1.2+1.9));
                    
                    // Add a black outline around each bubble
                    col+= 8.0*smoothstep( rad*0.95, rad, dis );
            
                    // Render
                    float f = length(uv-pos)/rad;
                    f = sqrt(clamp(1.0-f*f,0.0,1.0));

                    outColour.rgb -= col.zyx *(1.0-smoothstep( rad*0.95, rad, dis )) * f;
                }
            
                // Vignetting    
                outColour *= sqrt(1.5-0.5*length(uv));

                return outColour;
            }

            ENDCG
        }
    }
}

# 三、 最终效果       将CS代码拖到摄像机上,然后参考下图修改设置就可以看到效果啦,注意脚本组件中的分辨率要和当前屏幕保持一致才不会变形。

参考设置如下:
这里写图片描述

最终效果如图:
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Unity】ShaderToys——将大神们写的shader搬到unity中来吧 的相关文章

随机推荐

  • 【网络运维与安全岗位】月薪2.5w,您还不知道的前景!

    一 为什么学网络安全 标重点 1 市场巨大 每年各安全厂商收入高达400亿左右 随着5G的发展 万物互联时代 市场将进一步扩大 2 薪资高 网安人才的匮乏 用人开出招聘薪资往往高于求职者的预期 3 靠能力说话 在网络安全专业 专业技能竞争力
  • SourceTree 总是提示 git credential manager

    解决 1 使用sourcetree内嵌的git 还不行的话更新下版本 2 仓库设置里面加上用户名密码 格式 http 用户名 密码 xxx git
  • 常见数据库安装

    简介 本文记录了常用数据库 MySQL PostgreSQL MSSQL Oracle Redis MongoDB在Windows 及Linux Ubuntu 下 MSSQL Oracle除外 的安装 macOS可参考前两者 解决了Orac
  • 摄像机控制脚本

    脚本效果 1 跟随目标物体 2 通过滚轮调整距离 右键或Ctrl 左键旋转角度 using System Collections using System Collections Generic using UnityEngine publ
  • ASP.NET MVC3 类面向切面AOP 的Filter操作

    在开发大项目的时候总会有相关的AOP面向切面编程的组件 而MVC 特指 Asp Net MVC 以下皆同 项目中不想让MVC开发人员去关心和写类似身份验证 日志 异常 行为截取等这部分重复的代码 那我们可以通过AOP截取实现 而在MVC项目
  • 生产者/消费者代码(使用notify和wait实现)

    package cn wzy Lock import java util Random public class ConsumerAndProducer static String food new String 5 static Stri
  • TypeScript入门二(类型)

    1 TypeScrip 的静态类型 TypeScript 的一个最主要特点就是可以定义静态类型 英文是 Static Typing 那到底是什么意思那 太复杂的概念性东西这里就不讲了 你可以简单的理解 静态类型 为 就是你一旦定义了 就不可
  • js 数据转换(保留两位小数,去除前面多余的0等)

    保留两位小数 不够的添0补齐 function changeTwoDecimal f x var f x parseFloat x if isNaN f x return 0 var f x Math round x 100 100 var
  • 为什么const 定义的对象和数组可以改变它的值呢

    碰到这个问题我第一反应是肯定不能改变 如果要改变值的话 用const定义干嘛 然后不信邪在浏览器控制台试试结果 卧槽 但是定义一个基本类型 确实改不了 那为什么const 定义的对象和数组可以改变它的值呢 我来为大家解释一下 都知道对象和数
  • Unity3D实战【七】Cinemachine & Post Processing 摄像机跟踪和后处理

    一 摄像机跟随 1 PackManger中安装Cinemachine 2 点击菜单栏的Cinemachine gt Create Virtual Camera 会代替原来的Main Camera 3 调整参数 Body Framing Tr
  • js中根据已知key得到某对象中相对应的value的方法

    给自己打个小广告 有开发APP 小程序 网站 后台系统需求 或者 想学习前端的可以私信我哈 var key accountBingFlag1 var value obj key var key accountBingFlag1 var va
  • 如何用git命令生成Patch和打Patch

    在程序员的日常开发与合作过程中 对于code的生成patch和打patch 应用patch 成为经常需要做的事情 什么是patch 简单来讲 patch中存储的是你对代码的修改 什么是生成patch 生成patch就是记录你对代码的修改并将
  • python-selenium-规避检测,无头浏览器

    1 无头浏览器 取消的浏览器的可视化界面 在一定程度上加了自动化速度 chrome options Options chrome options add argument headless chrome options add argume
  • Eclipse 解决JSON parse error: Invalid UTF-8 总结 完善

    今天在本地测试通过的代码 部署之Tomcat 服务器 前端同事给我反馈如下的错误信息 org springframework http converter HttpMessageNotReadableException message JS
  • 下载的python没有pip_python – 所有依赖项都不会通过“pip download”下载

    我正在尝试使用可以在没有互联网连接的计算机上重新安装的软件包来设置本地目录 但是我遇到了一些软件包的问题 我首先下载包 pip download r requirements txt d my packages no binary all
  • python_元组_1.07

    一 元组 1 定义 python的元组与列表类似 不同之处在于元组的元素一旦定义就不能修改 添加 删除 可以访问 元组使用小括号 列表使用方括号 元组创建很简单 只需要在括号中添加元素 并使用逗号隔开即可 course chinese ma
  • 微信小程序-消息提示框实例

    做Android的时候对toast是很熟悉的 微信小程序开发中toast也是重要的消息提示方式 提示框 wx showToast OBJECT 显示消息提示框 OBJECT参数说明 示例代码 wx showToast title 成功 ic
  • 第5讲:业务扩展模型图

    业务扩展模型图主要是将雨雾流程相关的重要人 事 物及这个业务流程所要达成的目标做一个链接 不过有关业务流程的内部细节 通常不会在这张图中介绍 一 元素 1 1 流程 Process 代表一连串有意义的工作流程 在一个 流程 中通常要达成一个
  • myeclipse出现Could not find the main class原因分析

    昨天晚上像往常一样打开myeclipse 随便运行一个类 run as java application 居然弹出Could not find the main class Program will exit 按照以往的经验 做如下检查 编
  • 【Unity】ShaderToys——将大神们写的shader搬到unity中来吧

    这篇文章翻译自国外的一篇文章 这里是原文链接 正在使用unity的你是否在shader toy上发现很多牛逼哄哄的shader却不知道如何使用 那么这篇文章就是帮助你来进行转换的 本文只是基础文章 那些对HLSL CG GLSL都很熟悉的大