From Shadertoy To Unity

Conver Wet stone shadertoy effect to unity3D
ShaderToy https://www.shadertoy.com/view/ldSSzV
“Wet stone” by Alexander Alekseev aka TDM - 2014
License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
Contact: [email protected]

reference: candycat https://blog.csdn.net/candycat1992/article/details/44039077
reference:光能蜗牛 https://www.jianshu.com/p/0dd606730177

wet_stone Shadertoy

/*
Conver Wet stone shadertoy effect to unity3D
ShaderToy https://www.shadertoy.com/view/ldSSzV
"Wet stone" by Alexander Alekseev aka TDM - 2014
License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
Contact: [email protected]

reference:candycat https://blog.csdn.net/candycat1992/article/details/44039077
reference:光能蜗牛 https://www.jianshu.com/p/0dd606730177
*/

Shader "Shadertoy/ShaderWebStone" {
	Properties{
		iMouse("Mouse Pos", Vector) = (100, 100, 0, 0)
		iChannel0("iChannel0", 2D) = "white" {}
		iChannelResolution0("iChannelResolution0", Vector) = (100, 100, 0, 0)
	}

		CGINCLUDE
#include "UnityCG.cginc"   
#pragma target 3.0      

#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)

		fixed4 iMouse;
		sampler2D iChannel0;
		fixed4 iChannelResolution0;


//////////////////

#define SMOOTH
#define  NUM_STEPS  32;
#define  AO_SAMPLES  3;
#define  F_AO_SAMPLES  3.0;
#define  AO_PARAM  vec2(1.2, 3.8);
#define  AO_PARAM_X 1.2;
#define  AO_PARAM_Y 3.8;
#define  CORNER_PARAM  vec2(0.25, 40.0);
#define CORNER_PARAM_X 0.25;
#define CORNER_PARAM_Y 40.0;
#define  INV_AO_SAMPLES  1.0 / F_AO_SAMPLES;
#define  TRESHOLD  0.1;
#define  EPSILON  1e-3;
#define  LIGHT_INTENSITY  0.25;
#define  RED  vec3(1.0, 0.7, 0.7) * LIGHT_INTENSITY;
#define  ORANGE  vec3(1.0, 0.67, 0.43) * LIGHT_INTENSITY;
#define  BLUE  vec3(0.54, 0.77, 1.0) * LIGHT_INTENSITY;
#define  WHITE  vec3(1.2, 1.07, 0.98) * LIGHT_INTENSITY;
#define  DISPLACEMENT  0.1;
#define  iTime _Time.y;

// math
		mat3 fromEuler(vec3 ang) {
			vec2 a1 = vec2(sin(ang.x), cos(ang.x));
			vec2 a2 = vec2(sin(ang.y), cos(ang.y));
			vec2 a3 = vec2(sin(ang.z), cos(ang.z));
			mat3 m;
			m[0] = vec3(a1.y*a3.y + a1.x*a2.x*a3.x, a1.y*a2.x*a3.x + a3.y*a1.x, -a2.y*a3.x);
			m[1] = vec3(-a2.y*a1.x, a1.y*a2.y, a2.x);
			m[2] = vec3(a3.y*a1.x*a2.x + a1.y*a3.x, a1.x*a3.x - a1.y*a3.y*a2.x, a2.y*a3.y);
			return m;
		}

		float hash11(float p) {
			return fract(sin(p * 727.1)*435.545);
		}
		float hash12(vec2 p) {
			float h = dot(p, vec2(127.1, 311.7));
			return fract(sin(h)*437.545);
		}
		vec3 hash31(float p) {
			vec3 h = vec3(127.231, 491.7, 718.423) * p;
			return fract(sin(h)*435.543);
		}

		// 3d noise
		float noise_3(in vec3 p) {
			vec3 i = floor(p);
			vec3 f = fract(p);
			vec3 u = f * f*(3.0 - 2.0*f);

			vec2 ii = i.xy + i.z * vec2(5.0,5.0);
			float a = hash12(ii + vec2(0.0, 0.0));
			float b = hash12(ii + vec2(1.0, 0.0));
			float c = hash12(ii + vec2(0.0, 1.0));
			float d = hash12(ii + vec2(1.0, 1.0));
			float v1 = mix(mix(a, b, u.x), mix(c, d, u.x), u.y);

			ii += vec2(5.0,5.0);
			a = hash12(ii + vec2(0.0, 0.0));
			b = hash12(ii + vec2(1.0, 0.0));
			c = hash12(ii + vec2(0.0, 1.0));
			d = hash12(ii + vec2(1.0, 1.0));
			float v2 = mix(mix(a, b, u.x), mix(c, d, u.x), u.y);

			return max(mix(v1, v2, u.z), 0.0);
		}

		// fBm
		float fbm3(vec3 p, float a, float f) {
			return noise_3(p);
		}

		float fbm3_high(vec3 p, float a, float f) {
			float ret = 0.0;
			float amp = 1.0;
			float frq = 1.0;
			for (int i = 0; i < 4; i++) {
				float n = pow(noise_3(p * frq), 2.0);
				ret += n * amp;
				frq *= f;
				amp *= a * (pow(n, 0.2));
			}
			return ret;
		}

		// lighting
		float diffuse(vec3 n, vec3 l, float p) { return pow(max(dot(n, l), 0.0), p); }
		float specular(vec3 n, vec3 l, vec3 e, float s) {
			float nrm = (s + 8.0) / (3.1415 * 8.0);
			return pow(max(dot(reflect(e, n), l), 0.0), s) * nrm;
		}

		// distance functions
		float plane(vec3 gp, vec4 p) {
			return dot(p.xyz, gp + p.xyz*p.w);
		}
		float sphere(vec3 p, float r) {
			return length(p) - r;
		}
		float capsule(vec3 p, float r, float h) {
			p.y -= clamp(p.y, -h, h);
			return length(p) - r;
		}
		float cylinder(vec3 p, float r, float h) {
			return max(abs(p.y / h), capsule(p, r, h));
		}
		float box(vec3 p, vec3 s) {
			p = abs(p) - s;
			return max(max(p.x, p.y), p.z);
		}
		float rbox(vec3 p, vec3 s) {
			p = abs(p) - s;
			return length(p - min(p, 0.0));
		}
		float quad(vec3 p, vec2 s) {
			p = abs(p) - vec3(s.x, 0.0, s.y);
			return max(max(p.x, p.y), p.z);
		}

		// boolean operations
		float boolUnion(float a, float b) { return min(a, b); }
		float boolIntersect(float a, float b) { return max(a, b); }
		float boolSub(float a, float b) { return max(a, -b); }

		// smooth operations. thanks to iq
		float boolSmoothIntersect(float a, float b, float k) {
			float h = clamp(0.5 + 0.5*(b - a) / k, 0.0, 1.0);
			return mix(a, b, h) + k * h*(1.0 - h);
		}
		float boolSmoothSub(float a, float b, float k) {
			return boolSmoothIntersect(a, -b, k);
		}

		// world
		float rock(vec3 p) {
			float d = sphere(p, 1.0);
			for (int i = 0; i < 9; i++) {
				float ii = float(i);
				float r = 2.5 + hash11(ii);
				vec3 v = normalize(hash31(ii) * 2.0 - 1.0);
#ifdef SMOOTH
				d = boolSmoothSub(d, sphere(p + v * r, r * 0.8), 0.03);
#else
				d = boolSub(d, sphere(p + v * r, r * 0.8));
#endif        
			}
			return d;
		}

		/*float map(vec3 p) {
			float d = rock(p) + fbm3(p*4.0, 0.4, 2.96) * DISPLACEMENT;
			d = boolUnion(d, plane(p, vec4(0.0, 1.0, 0.0, 1.0)));
			return d;
		}*/

		float map(vec3 p) {
			float d = rock(p) + fbm3(p*4.0, 0.4, 2.96) * DISPLACEMENT;
			d = boolUnion(d, plane(p, vec4(0.0, 1.0, 0.0, 1.0)));
			return d;
		}

		float map_detailed(vec3 p) {
			float d = rock(p) + fbm3_high(p*4.0, 0.4, 2.96) * DISPLACEMENT;
			d = boolUnion(d, plane(p, vec4(0.0, 1.0, 0.0, 1.0)));
			return d;
		}

		// tracing
		vec3 getNormal(vec3 p, float dens) {
			vec3 n = vec3(0.0,0.0,0.0);
			float ex = p.x + EPSILON;
			float ey = p.y + EPSILON;
			float ez = p.z + EPSILON;

			vec3 vx = vec3(ex, p.y, p.z);
			vec3 vy = vec3(p.x, ey, p.z);
			vec3 vz = vec3(p.x, p.y, ez);

			n.x = map_detailed(vx);
			n.y = map_detailed(vy);
			n.z = map_detailed(vz);	
			return normalize(n - map_detailed(p));
		}

		vec2 getOcclusion(vec3 p, vec3 n) {
			vec2 r = vec2(0.0,0.0);
			for (int i = 0; i < 3; i++) {
				float f = float(i)*INV_AO_SAMPLES;
				float hao = 0.01 + f * AO_PARAM_X;
				float hc = 0.01 + f * CORNER_PARAM_X;
				float dao = map(p + n * hao) - TRESHOLD;
				float dc = map(p - n * hc) - TRESHOLD;
				r.x += clamp(hao - dao, 0.0, 1.0) * (1.0 - f);
				r.y += clamp(hc + dc, 0.0, 1.0) * (1.0 - f);
			}

			float conp = 1 / 3 * 3.8;
			float rxvalue = r.x;
			float rx = 1.0 - rxvalue * conp;
			float rclamp = clamp(rx, 0.0, 1.0);
			r.x = pow(rclamp,0.5);
			r.y = clamp(r.y*1/3*40, 0.0, 1.0);
			return r;
		}

		vec2 spheretracing(vec3 ori, vec3 dir, out vec3 p) {
			vec2 td = vec2(0.0,0.0);
			for (int i = 0; i < 32; i++) {
				p = ori + dir * td.x;
				td.y = map(p);
				if (td.y < 0.1) break;
				td.x += (td.y - 0.1) * 0.9;
			}
			return td;
		}

		//vec3 stonewhite = vec3(1.2, 1.07, 0.98) * 0.25;
		// stone
		// stone
		vec3 getStoneColor(vec3 p, float c, vec3 l, vec3 n, vec3 e) {

			vec3 stonewhite = vec3(1.2, 1.07, 0.98) * 0.25;

			c = min(c + pow(noise_3(vec3(p.x*20.0, 0.0, p.z*20.0)), 70.0) * 8.0, 1.0);
			float mc = 1.0 - c;
			float ic = pow(1.0 - mc, 0.5);
			vec3 base = vec3(0.42, 0.3, 0.2) * 0.6;
			vec3 sand = vec3(0.51, 0.41, 0.32);
			vec3 color = mix(base, sand, c);

			float f = pow(1.0 - max(dot(n, -e), 0.0), 1.5) * 0.75 * ic;
			color = mix(color, vec3(1.0,1.0,1.0), f);
			color += vec3(diffuse(n, l, 0.5) * stonewhite);
			color += vec3(specular(n, l, e, 8.0) * stonewhite * 1.5 * ic);
			n = normalize(n - normalize(p) * 0.4);
			color += vec3(specular(n, l, e, 80.0) * stonewhite * 1.5 * ic);
			return color;
		}


		// main
		vec4 mainImage(in vec2 fragCoord) {
			vec2 iuv = fragCoord.xy / iResolution.xy * 2.0 - vec2(1.0,1.0);
			vec2 uv = iuv;
			float uvrate = iResolution.x / iResolution.y;
			uv.x = uvrate * uv.x;
			float time = _Time.y * 0.3;

			// ray
			vec3 ang = vec3(0.0, 0.2, time);
			if (iMouse.z > 0.0) ang = vec3(0.0, clamp(2.0 - iMouse.y*0.01, 0.0, 3.1415), iMouse.x*0.01);
			mat3 rot = fromEuler(ang);

			vec3 ori = vec3(0.0, 0.0, 2.8);			
			vec3 dir = normalize(vec3(uv.xy, -2.0));
			ori = mul(ori, rot);
			dir = mul(dir, rot);

			// tracing
			vec3 p;
			vec2 td = spheretracing(ori, dir, p);
			vec3 n = getNormal(p, td.y);
			vec2 occ = getOcclusion(p, n);
			vec3 light = normalize(vec3(0.0, 1.0, 0.0));

			// color
			vec3 color = vec3(1.0,1.0,1.0);
			if (td.x < 3.5 && p.y > -0.89) color = getStoneColor(p, occ.y, light, n, dir);
			color *= occ.x;

			// post
			float vgn = smoothstep(1.2, 0.7, abs(iuv.y)) * smoothstep(1.1, 0.8, abs(iuv.x));
			color *= 1.0 - (1.0 - vgn) * 0.15;
			return vec4(color, 1.0);

		}

////////////////////////////////////

		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(vec2 fragCoord);

		fixed4 frag(v2f _iParam) : COLOR0{
			vec2 fragCoord = gl_FragCoord;
			return main(gl_FragCoord);
		}

			vec4 main(vec2 fragCoord) {
			vec2 viewPortCoor = vec2(fragCoord.x / iResolution.x, fragCoord.y / iResolution.y);// (0,0) - (1,1) 中心位置为(0.5,0.5)
			return mainImage(fragCoord);
		}

		ENDCG

			SubShader{
				Pass {
					CGPROGRAM

					#pragma vertex vert    
					#pragma fragment frag    
					#pragma fragmentoption ARB_precision_hint_fastest     

					ENDCG
				}
		}
			FallBack Off
}

猜你喜欢

转载自blog.csdn.net/frank120120/article/details/83089151