Skip to content

Commit 8db9737

Browse files
Translucency and fresnel.
1 parent 5918463 commit 8db9737

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

subsurface_scattering.shader

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
//reference: https://www.shadertoy.com/view/ldcGWH
2+
//In Unity3D editor, add 3D Object/Quad to Main Camera, then bind material with shader to the quad. Set quad position at (x=0 ; y=0; z=0.4;). Play.
3+
4+
Shader "Subsurface Scattering"
5+
{
6+
Properties
7+
{
8+
density("Density",Range(0.0,2.0)) = 0.4
9+
ss_power("Power",Range(0.0,10.0)) = 3.0
10+
ss_scattering("Scattering",Range(0.0,2.0)) = 0.4
11+
ss_offset("Offset",Range(0.0,2.0)) = 0.5
12+
ss_intensity("Intensity",Range(0.0,5.0)) = 1.0
13+
ss_mix("Mix",Range(0.0,2.0)) = 1.0
14+
ss_color("SSS Color",Color) = (0.85, 0.05, 0.2, 0.0)
15+
surfaceThickness("Thickness",Range(0.0,0.02)) = 0.008
16+
rimCol("Rim Color",Color) = (1.0, 1.0, 1.0, 1.0)
17+
rimPow("Rim Power",Range(0.0,5.0)) = 2.5
18+
rimAmount("Rim Amount",Range(0.0,2.0)) = 1.0
19+
F("Fresnel",Range(0.0,5.0)) = 2.2
20+
LP("Light Position",Vector) = (14.0, 10.0, 29.0, 1.0)
21+
}
22+
Subshader
23+
{
24+
Pass
25+
{
26+
CGPROGRAM
27+
#pragma vertex vertex_shader
28+
#pragma fragment pixel_shader
29+
#pragma target 3.0
30+
31+
struct custom_type
32+
{
33+
float4 screen_vertex : SV_POSITION;
34+
float3 world_vertex : TEXCOORD1;
35+
};
36+
37+
float density ;
38+
float ss_power ;
39+
float ss_scattering;
40+
float ss_offset;
41+
float ss_intensity;
42+
float ss_mix;
43+
float4 ss_color;
44+
float surfaceThickness ;
45+
float4 rimCol;
46+
float rimPow;
47+
float rimAmount;
48+
float F;
49+
float4 LP;
50+
51+
float hash(float2 co)
52+
{
53+
return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453);
54+
}
55+
56+
float map(float3 p)
57+
{
58+
return length(p)-1.0;
59+
}
60+
61+
float3 set_normal (float3 p)
62+
{
63+
float3 x = float3 (0.001,0.00,0.00);
64+
float3 y = float3 (0.00,0.001,0.00);
65+
float3 z = float3 (0.00,0.00,0.001);
66+
return normalize(float3(map(p+x)-map(p-x), map(p+y)-map(p-y), map(p+z)-map(p-z)));
67+
}
68+
69+
float subsurface_scattering (float3 ro, float3 rd, float3 light, float3 n)
70+
{
71+
float len = 0.0;
72+
const float samples = 12.0;
73+
const float sqs = sqrt(samples);
74+
for (float s = -samples / 2.0; s < samples / 2.0; s+= 1.0)
75+
{
76+
float3 p = ro + (-n * surfaceThickness);
77+
float3 ld = light;
78+
ld.x += fmod(abs(s), sqs) * ss_scattering * sign(s);
79+
ld.y += (s / sqs) * ss_scattering;
80+
ld.x += hash(p.xy * s) * ss_scattering;
81+
ld.y += hash(p.yx * s) * ss_scattering;
82+
ld.z += hash(p.zx * s) * ss_scattering;
83+
ld = normalize(ld);
84+
float3 dir = ld;
85+
for (int i = 0; i < 50; ++i)
86+
{
87+
float d = map(p);
88+
if(d < 0.0) d = min(d, -0.0001);
89+
if(d >= 0.0) break;
90+
dir = normalize(ld);
91+
p += abs(d * 0.5) * dir;
92+
}
93+
len += length(ro - p);
94+
}
95+
return len / samples;
96+
}
97+
98+
float4 lighting (float3 ro, float3 rd)
99+
{
100+
float4 AmbientLight = float4(0.0,0.0,0.0,0.0);
101+
float3 LightDirection = normalize( LP.xyz );
102+
float3 NormalDirection = set_normal(ro);
103+
float Diffuse = saturate(dot(NormalDirection, LightDirection));
104+
float3 Reflection = reflect(-LightDirection, NormalDirection);
105+
float Rim = pow(saturate(1.0 - dot(Reflection, -rd)),rimPow);
106+
float fresnel = Rim + F * (1.0 - Rim);
107+
float4 color = AmbientLight + fresnel * rimCol * rimAmount * Diffuse;
108+
float s = subsurface_scattering(ro, rd, LightDirection, NormalDirection);
109+
s = pow(exp(ss_offset -s * density),ss_power);
110+
float4 sscol = s * ss_color * ss_intensity;
111+
sscol = lerp(sscol, ss_color, 1.0 - ss_mix);
112+
return color+sscol;
113+
}
114+
115+
float4 raymarch (float3 ro, float3 rd)
116+
{
117+
for (int i=0; i<128; i++)
118+
{
119+
float t = map(ro);
120+
if (t < 0.001) return lighting (ro,rd);
121+
ro+=t*rd;
122+
}
123+
return 0;
124+
}
125+
126+
custom_type vertex_shader (float4 vertex : POSITION)
127+
{
128+
custom_type vs;
129+
vs.screen_vertex = mul (UNITY_MATRIX_MVP, vertex);
130+
vs.world_vertex = mul (_Object2World, vertex);
131+
return vs;
132+
}
133+
134+
float4 pixel_shader (custom_type ps ) : SV_TARGET
135+
{
136+
float3 worldPosition = ps.world_vertex;
137+
float3 viewDirection = normalize(ps.world_vertex - _WorldSpaceCameraPos.xyz);
138+
return raymarch(worldPosition,viewDirection);
139+
}
140+
141+
ENDCG
142+
143+
}
144+
}
145+
}

0 commit comments

Comments
 (0)