1
+ Shader "Raymarching room"
2
+ {
3
+ Subshader
4
+ {
5
+ Pass
6
+ {
7
+ CGPROGRAM
8
+ #pragma vertex vertex_shader
9
+ #pragma fragment pixel_shader
10
+ #pragma target 3.0
11
+
12
+ struct custom_type
13
+ {
14
+ float4 screen_vertex : SV_POSITION ;
15
+ float3 world_vertex : TEXCOORD1 ;
16
+ };
17
+
18
+ static float time = sin (_Time .g)*0.5 +0.5 ;
19
+
20
+ float4 plane (float3 p, float4 n, float3 m)
21
+ {
22
+ return float4 (m,dot (p,n.xyz) + n.w);
23
+ }
24
+
25
+ float4 sphere (float3 p,float3 c,float r, float3 m)
26
+ {
27
+ return float4 (m,length (p-c)-r);
28
+ }
29
+
30
+ float4 map (float3 p)
31
+ {
32
+ float4 up = plane (p,float4 (0.0 ,-1.0 ,0.0 ,20.0 ),float3 (0.0 ,0.5 ,0.0 ));
33
+ float4 down = plane (p,float4 (0.0 ,1.0 ,0.0 ,10.0 ),float3 (0.0 ,0.5 ,0.0 ));
34
+ float4 left = plane (p,float4 (1.0 ,0.0 ,0.0 ,20.0 ),float3 (1.0 ,1.0 ,0.0 ));
35
+ float4 right = plane (p,float4 (-1.0 ,0.0 ,0.0 ,20.0 ),float3 (1.0 ,1.0 ,0.0 ));
36
+ float4 front = plane (p,float4 (0.0 ,0.0 ,1.0 ,20.0 ),float3 (0.0 ,0.0 ,1.0 ));
37
+ float4 back = plane (p,float4 (0.0 ,0.0 ,-1.0 ,20.0 ),float3 (0.0 ,0.0 ,1.0 ));
38
+ float4 room = lerp (up,down,step (down.w,up.w));
39
+ room = lerp (room,left,step (left.w,room.w));
40
+ room = lerp (room,right,step (right.w,room.w));
41
+ room = lerp (room,front ,step (front .w,room.w));
42
+ room = lerp (room,back ,step (back .w,room.w));
43
+ return lerp (room,sphere (p,float3 (0.0 ,0.0 ,0.0 ),2.0 ,float3 (1.0 ,1.0 ,1.0 )),step (sphere (p,float3 (0.0 ,0.0 ,0.0 ),2.0 ,float3 (1.0 ,1.0 ,1.0 )).w,room.w));
44
+ }
45
+
46
+ float3 set_normal (float3 p)
47
+ {
48
+ float3 x = float3 (0.01 ,0.00 ,0.00 );
49
+ float3 y = float3 (0.00 ,0.01 ,0.00 );
50
+ float3 z = float3 (0.00 ,0.00 ,0.01 );
51
+ return normalize (float3 (map (p+x).w-map (p-x).w,map (p+y).w-map (p-y).w,map (p+z).w-map (p-z).w));
52
+ }
53
+
54
+ float soft_shadow ( float3 ro, float3 rd, float mint, float maxt, float k )
55
+ {
56
+ float t = mint;
57
+ float res = 1.0 ;
58
+ for ( int i = 0 ; i < 128 ; ++i )
59
+ {
60
+ float h = map (ro + rd * t).w;
61
+ if ( h < 0.001 ) return 0.0 ;
62
+ res = min ( res, k * h / t );
63
+ t += h;
64
+ if ( t > maxt ) break ;
65
+ }
66
+ return res;
67
+ }
68
+
69
+ float3 lighting (float3 p, float3 ViewDirection)
70
+ {
71
+ float3 Material = map (p).xyz;
72
+ float3 LightPosition = float3 ( 4.0 , 5.0 , -10.0 );
73
+ LightPosition .x = cos ( _Time .g * 0.5 ) * 8.0 ;
74
+ LightPosition .z = sin ( _Time .g * 0.5 ) * 8.0 ;
75
+ float3 LightDirection = LightPosition - p;
76
+ float LightDistance= length ( LightDirection );
77
+ LightDirection = normalize ( LightDirection );
78
+ float Shadow = soft_shadow ( p, LightDirection , 0.0625 , LightDistance,32.0 );
79
+ float3 AmbientDiffuseLight = float3 (0.0 ,0.0 ,0.0 );
80
+ float3 AmbientSpecularLight = float3 (0.1 ,0.1 ,0.1 );
81
+ float3 LightColor = float3 (1.0 ,1.0 ,1.0 );
82
+ float3 SpecularBase = float3 (1.0 ,1.0 ,1.0 );
83
+ float SpecularSpread = 50.0 ;
84
+ float SpecularPower = 1.0 ;
85
+ float3 NormalDirection = set_normal (p);
86
+ float3 HalfVector = normalize (LightDirection-ViewDirection);
87
+ float3 DiffuseColor = max (dot (LightDirection , NormalDirection),0.0 ) * LightColor * Material;
88
+ float3 SpecularColor = pow (clamp (dot (HalfVector, NormalDirection),0.0 ,1.0 ),SpecularSpread) * SpecularPower * SpecularBase;
89
+ return lerp ((DiffuseColor+SpecularColor+AmbientSpecularLight),(DiffuseColor+AmbientDiffuseLight)*Shadow,step (dot (Material,Material),2.99 ));
90
+ }
91
+
92
+ float4 raymarch (float3 ro, float3 rd)
93
+ {
94
+ for (int i=0 ; i<128 ; i++)
95
+ {
96
+ float ray = map (ro).w;
97
+ if (distance (ro,ray*rd)>50 ) break ;
98
+ if (ray < 0.001 ) return float4 (lighting (ro,rd),1.0 ); else ro+=ray*rd;
99
+ }
100
+ clip (-1 );
101
+ return float4 (0.0 ,0.0 ,0.0 ,1.0 );
102
+ }
103
+
104
+ custom_type vertex_shader (float4 vertex : POSITION )
105
+ {
106
+ custom_type vs;
107
+ vs.screen_vertex = mul (UNITY_MATRIX_MVP , vertex);
108
+ vs.world_vertex = mul (_Object2World , vertex);
109
+ return vs;
110
+ }
111
+
112
+ float4 pixel_shader (custom_type ps ) : SV_TARGET
113
+ {
114
+ float3 worldPosition = ps.world_vertex;
115
+ float3 viewDirection = normalize (ps.world_vertex - _WorldSpaceCameraPos .xyz);
116
+ return raymarch (worldPosition,viewDirection);
117
+ }
118
+
119
+ ENDCG
120
+
121
+ }
122
+ }
123
+ }
0 commit comments