ShaderToy上GLSL代码移植到unity平台总结

此处借用shadertoy上大神的glslShader   https://www.shadertoy.com/view/MdX3zr

方法一:自定义一个cginc文件来映射两种语言的数据类型,然后在shader中移植算法部分,最后在片段程序中输出颜色时调用mainImage(main)方法。

GlslToHlsl.cginc

#ifndef GlslToHlsl
#define GlslToHlsl
#define vec2 float2  
#define vec3 float3  
#define vec4 float4  
#define mat2 float2x2  
#define mat3 float3x3  
#define mat4 float4x4  
#define iGlobalTime _Time.y  
#define mod fmod  
#define mix lerp  
#define fract frac  
#define texture2D tex2D  
#define iResolution _ScreenParams  
#define gl_FragCoord ((_iParam.scrPos.xy/_iParam.scrPos.w) * _ScreenParams.xy)  
#define PI2 6.28318530718  
#define pi 3.14159265358979  
#define halfpi (pi * 0.5)  
#define oneoverpi (1.0 / pi)  

#endif

Shader代码:

Shader"fire"{
     CGINCLUDE
   #include "UnityCG.cginc"   
   #include "GlslToHlsl.cginc"//引用自定义的cginc    
    struct v2f 
    {
      float4 pos : SV_POSITION;
      float4 scrPos : TEXCOORD0;
    };  
    v2f vert(appdata_base v) //顶点程序
    {
      v2f o;
      o.pos = UnityObjectToClipPos(v.vertex);
      o.scrPos = ComputeScreenPos(o.pos);
      return o;
    }
    vec4 main(in vec2 fragCoord);//因为该方法的实现在片段程序下面,所以要提前声明一下;
  fixed4 frag(v2f _iParam) : COLOR0 //片段程序
  {
   vec2 fragCoord = gl_FragCoord;
    return main(gl_FragCoord);
  }
//----------------------图像生成的算法部分
float noise(vec3 p)
  {
      vec3 i = floor(p);
      vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
      vec3 f = cos((p - i)*acos(-1.))*(-.5) + .5;
      a = mix(sin(cos(a)*a), sin(cos(1. + a)*(1. + a)), f.x);
      a.xy = mix(a.xz, a.yw, f.y);
      return mix(a.x, a.y, f.z);
  }
  float sphere(vec3 p, vec4 spr)
  {
      return length(spr.xyz - p) - spr.w;
  }
  float flame(vec3 p)
  {
      float d = sphere(p*vec3(1., .5, 1.), vec4(.0, -1., .0, 1.));
      return d + (noise(p + vec3(.0, iGlobalTime*2., .0)) + noise(p*3.)*.5)*.25*(p.y);
  }
  float scene(vec3 p)
  {
      return min(100. - length(p), abs(flame(p)));
  }
  vec4 raymarch(vec3 org, vec3 dir)
  {
      float d = 0.0, glow = 0.0, eps = 0.02;
      vec3  p = org;
      bool glowed = false;
      for (int i = 0; i< 64; i++)
      {
          d = scene(p) + eps;
          p += d * dir;
          if (d >= eps)
          {
              if (flame(p)< .0)
                  glowed = true;
              if (glowed)
                  glow = float(i) / 64.;
          }
      }
      return vec4(p, glow);
  }
  vec4 main(in vec2 fragCoord)
  {
      vec4 fragColor;
      vec2 v = -1.0 + 2.0 * fragCoord.xy / iResolution.xy;
      v.x *= iResolution.x / iResolution.y;
      vec3 org = vec3(0., -2., 4.);
      vec3 dir = normalize(vec3(v.x*1.6, -v.y, -1.5));
      vec4 p = raymarch(org, dir);
      float glow = p.w;
      vec4 col = mix(vec4(1.0, 0.5, 0.1, 1.0), vec4(0.1, 0.5, 1.0, 1.0), p.y*0.02 + 0.4);
      fragColor = mix(vec4(0, 0, 0, 0), col, pow(glow*2., 4.));
      return fragColor;
  }
//----------------------end
     ENDCG
  SubShader {
     Pass {
    Blend Srcalpha OneMinusSrcAlpha
   CGPROGRAM  
    #pragma vertex vert      
    #pragma fragment frag      
    #pragma fragmentoption ARB_precision_hint_fastest   
   ENDCG
  }
  }
  FallBack Off
  }

方法二:直接在unity里撸glsl代码

右键unity快捷方式,在目标中加入-force-opengl使unity直接支持glsl语言

ShaderToy上GLSL代码移植到unity平台总结_第1张图片

Shader代码如下:

Shader "LearnShader/GLSL/GLSLTest"{
    //Properties{
    //    _MainTex("Base(RGB)",2D) = "white"{}
    //}
        SubShader{
        Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
        Blend Srcalpha OneMinusSrcAlpha
        Pass{
        GLSLPROGRAM
#include "UnityCG.glslinc"
#ifdef VERTEX    //顶点程序
        varying vec4 textureCoordinates;
    void main() {
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;//vertex
        textureCoordinates = gl_MultiTexCoord0;//uv
    }
#endif
#ifdef FRAGMENT//片段程序
    //uniform sampler2D _MainTex;
    varying vec4 textureCoordinates;
    //---------------------图像生成算法部分
    float noise(vec3 p) //Thx to Las^Mercury
    {
        vec3 i = floor(p);
        vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
        vec3 f = cos((p - i)*acos(-1.))*(-.5) + .5;
        a = mix(sin(cos(a)*a), sin(cos(1. + a)*(1. + a)), f.x);
        a.xy = mix(a.xz, a.yw, f.y);
        return mix(a.x, a.y, f.z);
    }

    float sphere(vec3 p, vec4 spr)
    {
        return length(spr.xyz - p) - spr.w;
    }

    float flame(vec3 p)
    {
        float d = sphere(p*vec3(1., .5, 1.), vec4(.0, -1., .0, 1.));
        return d + (noise(p + vec3(.0, _Time.y*2., .0)) + noise(p*3.)*.5)*.25*(p.y);
    }

    float scene(vec3 p)
    {
        return min(100. - length(p), abs(flame(p)));
    }

    vec4 raymarch(vec3 org, vec3 dir)
    {
        float d = 0.0, glow = 0.0, eps = 0.02;
        vec3  p = org;
        bool glowed = false;

        for (int i = 0; i<64; i++)
        {
            d = scene(p) + eps;
            p += d * dir;
            if (d>eps)
            {
                if (flame(p) < .0)
                    glowed = true;
                if (glowed)
                    glow = float(i) / 64.;
            }
        }
        return vec4(p, glow);
    }
    //------------------------end
    void main()//mian函数输出最终颜色
    {
        vec2 v = -1.0 + 2.0 * textureCoordinates.xy;
        v.x *= _ScreenParams.x / _ScreenParams.y;

        vec3 org = vec3(0., -2., 4.);
        vec3 dir = normalize(vec3(v.x*1.6, -v.y, -1.5));

        vec4 p = raymarch(org, dir);
        float glow = p.w;

        vec4 col = mix(vec4(1., .5, .1, 1.), vec4(0.1, .5, 1., 1.), p.y*.02 + .4);

        gl_FragColor = mix(vec4(0), col, pow(glow*2., 4.));
    }
#endif
    ENDGLSL
    }
    }
}


 

你可能感兴趣的:(Unity)