此处借用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语言
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
}
}
}