1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| Shader "KerryTA/Code/302IBLMap" { Properties { _CubeMap ("CubeMap", Cube) = "white" {} _Rotate("Rotate", Range(0,360)) = 0 _Tint("Tint", Color) = (1,1,1,1) _Expose("Expose", Float) = 1 _NormalMap("NormalMap", 2D) = "bump" {} _NormalIntensity("NormalIntensity", Range(0.0, 5.0)) = 0.5 _AOMap("AOMap", 2D) = "white" {} _AOAdjust("AOAdjust", Range(0,1)) = 1 _RoughnessMap("RoughnessMap", 2D) = "black" {} _RoughnessContrast("RoughnessContrast", Range(0.01,10)) = 1 _RoughnessBrightness("RoughnessBrightness", Float) = 1 _RoughnessMin("RoughMin", Range(0,1)) = 0 _RoughnessMax("RoughMax", Range(0,1)) = 1 } SubShader { Tags { "RenderType"="Opaque" } LOD 100
Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag
#include "UnityCG.cginc"
struct appdata { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; float3 normal : NORMAL; float4 tangent : TANGENT; };
struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; float3 normal_world : TEXCOORD1; float3 pos_world : TEXCOORD2; float3 tangent_world : TEXCOORD3; float3 binormal_world : TEXCOORD4; };
samplerCUBE _CubeMap; float4 _CubeMap_HDR; sampler2D _NormalMap; float4 _NormalMap_ST; float _NormalIntensity; sampler2D _AOMap; float _AOAdjust; float4 _Tint; float _Expose; float _Rotate; sampler2D _RoughnessMap; float _RoughnessContrast; float _RoughnessBrightness; float _RoughnessMin; float _RoughnessMax;
float3 RotateYAround(float degree, float3 target) { float rad = degree * UNITY_PI / 100; float2x2 m_rotate = float2x2(cos(rad), -sin(rad), sin(rad), cos(rad)); float2 dir_rotate = mul(m_rotate, target.xz); target = float3(dir_rotate.x, target.y, dir_rotate.y); return target; }
float3 ACESFilm(float3 x) { float a = 2.51f; float b = 0.03f; float c = 2.43f; float d = 0.59f; float e = 0.14f; return saturate((x*(a*x + b)) / (x*(c*x + d) + e)); }
v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord * _NormalMap_ST.xy + _NormalMap_ST.zw; o.normal_world = normalize(mul(float4(v.normal, 0.0), unity_WorldToObject).xyz); o.tangent_world = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz); o.binormal_world = normalize(cross(o.normal_world, o.tangent_world)) * v.tangent.w; o.pos_world = mul(unity_ObjectToWorld, v.vertex).xyz; return o; }
half4 frag (v2f i) : SV_Target { half3 normal_dir = normalize(i.normal_world); half3 tangent_dir = normalize(i.tangent_world); half3 binormal_dir = normalize(i.binormal_world); float3x3 TBN = float3x3(tangent_dir, binormal_dir, normal_dir); half3 normaldata = UnpackNormal(tex2D(_NormalMap, i.uv)); normaldata.xy = normaldata.xy * _NormalIntensity; normal_dir = normalize(mul(normaldata, TBN));
half ao = tex2D(_AOMap, i.uv).r; ao = lerp(1.0, ao, _AOAdjust); half3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.pos_world); half3 reflect_dir = reflect(-view_dir, normal_dir);
reflect_dir = RotateYAround(_Rotate, reflect_dir);
float roughness = tex2D(_RoughnessMap, i.uv); roughness = saturate(pow(roughness, _RoughnessContrast) * _RoughnessBrightness); roughness = lerp(_RoughnessMin, _RoughnessMax, roughness); roughness = roughness * (1.7 - 0.7 * roughness); float mip_level = roughness * 6.0; half4 color_cubemap = texCUBElod(_CubeMap, float4(reflect_dir, mip_level)); half3 env_color = DecodeHDR(color_cubemap, _CubeMap_HDR); half3 final_color = env_color * ao * _Tint.rgb * _Tint.rgb * _Expose;
half3 final_color_linear = pow(final_color, 2.2); final_color = ACESFilm(final_color); half3 final_color_gamma = pow(final_color, 1.0/2.2);
return half4(final_color_gamma, 1.0); } ENDCG } } }
|