This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' | |
| Shader "HanaTerrainSand" | |
| { | |
| Properties | |
| { | |
| [HideInInspector] _Control ("Control (RGBA)", 2D) = "red" {} | |
| [HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {} | |
| [HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {} | |
| [HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {} | |
| [HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {} | |
| [HideInInspector] _Normal3 ("Normal 3 (A)", 2D) = "bump" {} | |
| [HideInInspector] _Normal2 ("Normal 2 (B)", 2D) = "bump" {} | |
| [HideInInspector] _Normal1 ("Normal 1 (G)", 2D) = "bump" {} | |
| [HideInInspector] _Normal0 ("Normal 0 (R)", 2D) = "bump" {} | |
| _Wave("waves", 2D) = "bump" {} | |
| _Noise("noise", 2D) = "bump" {} | |
| _Skybox("Skybox", Cube) = "" {} | |
| _grain_freq("Noise Frequency", range(0,.5)) = .06 | |
| [Header(Diffuse)] | |
| _ColorA("Color A", Color)= (1,1,1,1) | |
| _ColorB("Color B", Color)= (1,1,1,1) | |
| _ColorC("Color C", Color)= (1,1,1,1) | |
| _Ambient("Ambient", Color)= (0,0,.1,1) | |
| _grainmag("Grain Magnitude", range(0,1)) = .5 | |
| _diff_exp("Modifier", range(0,1)) = 1 | |
| [Header(Specular)] | |
| _SpecularPower("Exponent", Range(0,300)) = 1 | |
| _SpecularMagnitude("Gloss", Range(0,1)) = 0 | |
| [Header(Mirage)] | |
| _mirage_dist("Distance", Range(0,1000)) = 1. | |
| _mirage_rate("Ramp", Range(0,100)) = 1. | |
| [Header(Sparkle)] | |
| _sparkle_mag("Magnitude", range(0,1)) = .8 | |
| _sparkle_freq("Sparkle Frequency", range(0,.5)) = .06 | |
| _sparkle_harmonic("Rate", range(.01, 20)) = 10 | |
| [PowerSlider(2.)]_sparkle_exp("Exponent", range(1,1000)) = 100 | |
| [PowerSlider(2.)]_sparkle_fade("Fade", range(0,1)) = .1 | |
| [Header(Wave)] | |
| _wave_height("Height", range(0,1)) = .5 | |
| //_wave_sharp("sharpness", range(0,8)) = 1 | |
| _wave_f0("Freqency0", range(0,32)) = .4 | |
| _wave_f1("Freqency1", range(0,32)) = 8 | |
| _wave_ratio("0:1 Ratio", range(0,1)) = .5 | |
| } | |
| SubShader | |
| { | |
| Tags { | |
| "SplatCount" = "4" | |
| "RenderType"="Opaque" | |
| "LightMode"="ForwardBase" | |
| } | |
| //Blend Off | |
| //Cull Back | |
| //ZTest LEqual | |
| //ZWrite On | |
| CGPROGRAM | |
| // Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members uv_Splat0,uv_Splat1,uv_Splat2,uv_Splat3,tc_Control) | |
| #pragma exclude_renderers d3d11 | |
| #pragma surface surf Lambert | |
| #pragma target 4.5 | |
| #pragma multi_compile_fog | |
| #pragma multi_compile_fwdbase | |
| sampler2D _Noise; | |
| sampler2D _Wave; | |
| samplerCUBE _Skybox; | |
| float3 _ColorA; | |
| float3 _ColorB; | |
| float3 _ColorC; | |
| float3 _Ambient; | |
| float _SpecularPower; | |
| float _SpecularMagnitude; | |
| float _Gloss; | |
| float _grainmag; | |
| float _Scale; | |
| float _wave_f0; | |
| float _wave_f1; | |
| float _wave_ratio; | |
| float _wave_height; | |
| float _wave_sharp; | |
| float _diff_exp; | |
| float _sparkle_exp; | |
| float _sparkle_fade; | |
| float _grain_freq; | |
| float _sparkle_freq; | |
| float _sparkle_mag; | |
| float _sparkle_harmonic; | |
| float _mirage_dist; | |
| float _mirage_rate; | |
| #include "UnityCG.cginc" | |
| #include "AutoLight.cginc" | |
| #include "Lighting.cginc" | |
| #define _TERRAIN_NORMAL_MAP | |
| #include "TerrainSplatmapCommon.cginc" | |
| #define PI 3.14159265 | |
| #define TAU 6.28318531 | |
| #define deg2rad 0.0174532925 | |
| #define sat saturate | |
| float2 miplvl(float2 t){ | |
| float2 dtdx= abs(ddx(t)); | |
| float2 dtdy= abs(ddy(t)); | |
| float2 tmax= max(dtdx,dtdy); | |
| float2 tmin= max(dtdx,dtdy); | |
| return ceil(tmax); | |
| } | |
| float max(float2 x){ return max(x.x,x.y);} | |
| float max(float3 x){ return max(x.z,max(x.x,x.y));} | |
| float2 psmooth(float2 x){ | |
| return x*x*(3.-2.*x); | |
| } | |
| #define CR1A float(4375.5453123) | |
| #define CR3B float3(4.7136731, 4.7486425,4.7576731) | |
| float rand_31(float3 t){ | |
| return frac(sin(dot(t,CR3B))*CR1A); | |
| } | |
| float3 rand_norm(float3 t){ | |
| return normalize(float3( | |
| rand_31(t ), | |
| rand_31(t+2), | |
| rand_31(t-8) | |
| )*2-1);//not proper distrubution but thats fine | |
| } | |
| float3 nse_rect(float3 t, float3 g){ | |
| t/= g; | |
| //float nyquist= saturate(1-.25*max(max( abs(ddx(t)),abs(ddy(t)) ))); | |
| t= floor(t); | |
| return rand_norm(t); | |
| } | |
| /*float3 nse_grid(float2 t, float2 g){ | |
| t/= g; | |
| float2 flr_t= floor(t); | |
| float2 frc_t= t-flr_t; | |
| float3 gnn= rand_norm(flr_t+float2(0,0)); | |
| float3 gnp= rand_norm(flr_t+float2(0,1)); | |
| float3 gpn= rand_norm(flr_t+float2(1,0)); | |
| float3 gpp= rand_norm(flr_t+float2(1,1)); | |
| float3 gdxn= lerp(gnn,gnp, frc_t.y); | |
| float3 gdxp= lerp(gpn,gpp, frc_t.y); | |
| float3 n= lerp(gdxn,gdxp, frc_t.x); | |
| return n; | |
| }*/ | |
| /* | |
| v2f o; | |
| Input splat; | |
| v.position= SplatmapVert(v, splat); | |
| o.pos = UnityObjectToClipPos(v.vertex); | |
| o.posw = mul(unity_ObjectToWorld, v.vertex); | |
| o.uv_Splat0= v.texcoord*_Scale; | |
| o.norm= v.normal; | |
| TRANSFER_VERTEX_TO_FRAGMENT(o);*/ | |
| /*struct v2f | |
| { | |
| //float4 pos : SV_POSITION; | |
| float3 norm : NORMAL; | |
| float2 uv_Splat0; | |
| float2 uv_Splat1; | |
| float2 uv_Splat2; | |
| float2 uv_Splat3; | |
| float2 tc_Control; | |
| float3 posw : TEXCOORD6; | |
| LIGHTING_COORDS(7,8) | |
| };*//* | |
| struct surfin{ | |
| float3 viewDir; | |
| float4 color; | |
| float2 uv_MainTex; | |
| float4 screenPos; | |
| float3 worldPos; | |
| float3 worldRefl; | |
| float3 worldNormal; | |
| };*/ | |
| struct v2f | |
| { | |
| Input splat;//terrain common | |
| float4 pos; | |
| float3 norm; | |
| float3 posw; | |
| LIGHTING_COORDS(7,8) | |
| }; | |
| #pragma vertex vert | |
| void vert(inout appdata_full v, out v2f o){ | |
| SplatmapVert(v, o.splat); | |
| o.pos = UnityObjectToClipPos(v.vertex); | |
| o.posw = mul(unity_ObjectToWorld, v.vertex); | |
| o.splat.uv_Splat0= v.texcoord*_Scale; | |
| o.norm= v.normal; | |
| //TRANSFER_VERTEX_TO_FRAGMENT(o); | |
| } | |
| void surf(v2f i, inout SurfaceOutput o) { | |
| o.Albedo = 1; | |
| //terrain | |
| //void SplatmapMix(Input IN, out half4 splat_control, out half weight, out fixed4 mixedDiffuse, inout fixed3 mixedNormal) | |
| //copypasted and hacked from splatmap common | |
| //i have no idea why it doesnt work normally | |
| float2 tc_Control; | |
| float4 splat= tex2D(_Control, tc_Control); | |
| float weight= dot(splat, half4(1,1,1,1)); | |
| splat/= (weight + 1e-3f); | |
| float3 diffuse= 0; | |
| diffuse+= splat.x * _ColorA; | |
| diffuse+= splat.y * _ColorB; | |
| diffuse+= splat.z * _ColorC; | |
| float3 norm= 0.0f; | |
| //nrm += splat_control.a * tex2D(_Normal3, i.splat.uv_Splat3); | |
| norm= i.norm.xzy; | |
| float3 col= fixed3(0,0,0); | |
| //worldspace | |
| float3 wP= i.posw; | |
| float3 wL= normalize(_WorldSpaceLightPos0);//is direction not position | |
| float3 wC= _WorldSpaceCameraPos; | |
| float3 wD= normalize(UNITY_MATRIX_IT_MV[2].xyz);//camera direction | |
| float3 wV= wP-wC;//direction to fragment | |
| float dist= length(wV); | |
| wV= normalize(wV); | |
| float2 mip= miplvl(wP.xz); | |
| float mips= max(mip); | |
| float mip_len= length(mip); | |
| float mip_exp= exp(mips); | |
| //normal displacement | |
| fixed3 disp= 0; | |
| //waves | |
| disp+= UnpackNormal(tex2D(_Wave, wP.xz*_wave_f0)) * _wave_ratio * splat.z;//splat z is abovewater | |
| disp+= UnpackNormal(tex2D(_Wave, wP.xz*_wave_f1)) * (1-_wave_ratio); | |
| disp= normalize(disp); | |
| //disp.z= pow(disp.z, _wave_sharp); | |
| //grain | |
| float3 ngrain= nse_rect(wP,_grain_freq); | |
| _grainmag*= sat(1-dist*.5); | |
| disp= lerp(disp, ngrain, _grainmag); | |
| disp= normalize(disp); | |
| norm= lerp(norm, disp, _wave_height);//no need for tangentspace, because terrain | |
| norm= normalize( norm ).xzy; | |
| //objectspace | |
| float3 oL= normalize(mul( unity_WorldToObject, wL )); | |
| float3 oD= normalize(mul( unity_WorldToObject, wD )); | |
| float3 oV= normalize(mul( unity_WorldToObject, wV )); | |
| float3 oH= normalize(oL+oV); | |
| float3 oR= reflect(oV,norm); | |
| //viewspace | |
| float2 fc= i.pos.xy; | |
| //diffuse | |
| float3 diffnorm= norm; | |
| //decrease norm y in direction of light | |
| //this approximates sand grain sphere brdf | |
| diffnorm-= oL*_diff_exp; | |
| diffnorm= normalize(diffnorm); | |
| float diff= saturate(dot(diffnorm,oL)); | |
| //sparkle | |
| float3 spnorm= nse_rect(wP, _sparkle_freq*ceil(dist*4.)/4.); | |
| float sparkle= cos(acos(dot(spnorm, oD))*_sparkle_harmonic); | |
| sparkle= sat(sparkle); | |
| sparkle= pow(sparkle, _sparkle_exp); | |
| //sparkle*= 1-saturate(log(wD*_sparkle_fade));//distance fade | |
| sparkle*= _sparkle_mag*splat.z; | |
| //gloss | |
| //float spec= saturate(dot(norm,oH)); | |
| //spec= pow(spec, _SpecularPower)*_SpecularMagnitude; | |
| float spec= 0; | |
| float dsmag= max(1, diff+spec); | |
| col+= ( (diff+spec*.5)*diffuse.rgb + spec*.5 + sparkle )*_LightColor0; | |
| //mirage | |
| //float mir= sat(1 - oR.y*_mirage_rate); | |
| //mir*= sat(dist-_mirage_dist); | |
| //float3 sky= .2+texCUBE(_Skybox, oR, 0,0);//lod0 prevents mips blurring | |
| //col= lerp(col, sky, mir); | |
| //ambient | |
| col+= diffuse*_Ambient; | |
| //shadow | |
| float shadow= LIGHT_ATTENUATION(i); | |
| col*= shadow+.09; | |
| //tonemap | |
| col/= max(1., max(col)); | |
| //tests | |
| //col= sparkle; | |
| //col= spec; | |
| //col= mir; | |
| //col= sky; | |
| //col= oN*.5+.5; | |
| //col= oV; | |
| //col= fmod(ceil(nse_mip*1.), 4)/4; | |
| //col= nse(i.posw.xz, (nmip)/1); | |
| //col= diffuse.rgb/1; | |
| //col= tex2D(_Normal2, wP.xz); | |
| //col= norm; | |
| //col.r= 0; col.gb= i.splat.uv_Splat0; | |
| //col= nse(wP.xz); | |
| //col= i.norm; | |
| o.Emission= half4(col, 1); | |
| } | |
| /* | |
| v2f vert(appdata_full v) | |
| { | |
| v2f o; | |
| SplatmapVert(v, o.splat); | |
| o.pos = UnityObjectToClipPos(v.vertex); | |
| o.posw = mul(unity_ObjectToWorld, v.vertex); | |
| o.splat.uv_Splat0= v.texcoord*_Scale; | |
| o.norm= v.normal; | |
| TRANSFER_VERTEX_TO_FRAGMENT(o); | |
| return o; | |
| }*/ | |
| /* | |
| half4 frag(v2f i) : SV_Target | |
| { | |
| } | |
| */ | |
| ENDCG | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment