Skip to content

Instantly share code, notes, and snippets.

@khlorghaal
Created Jan 20, 2019
Embed
What would you like to do?
// 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