#ifndef __PBR_INC #define __PBR_INC #include "filamented.cginc" #include "globals.cginc" #include "interpolators.cginc" #include "texture_utils.cginc" struct Pbr { float4 albedo; float3 normal; float3x3 tbn; float smoothness; float roughness_perceptual; float roughness; float metallic; #if defined(_CLEARCOAT) float cc_roughness; float cc_strength; #endif #if defined(_CLOTH_SHEEN) float cl_strength; float3 cl_color; #endif }; #define MIN_PERCEPTUAL_ROUGHNESS 5e-2f #define MIN_ROUGHNESS 5e-3f // TODO consider normal filtering like filamented void propagateSmoothness(inout Pbr pbr) { pbr.roughness_perceptual = max(MIN_PERCEPTUAL_ROUGHNESS, 1.0f - pbr.smoothness); pbr.roughness = max(MIN_ROUGHNESS, pbr.roughness_perceptual * pbr.roughness_perceptual); #if defined(_CLEARCOAT) pbr.cc_roughness = max(MIN_ROUGHNESS, pbr.cc_roughness * pbr.cc_roughness); #endif } void apply_marble(float3 world_pos, inout float3 albedo) { #if defined(_MARBLE) float3 uvw = world_pos * _Marble_Scale; float noise_r = sin_noise_3d_fbm(uvw + _Time[0], _Marble_Octaves, 2.0f, _Marble_Strength); float noise_g = sin_noise_3d_fbm(uvw+3.1 + _Time[0], _Marble_Octaves, 2.0f, _Marble_Strength); float noise_b = sin_noise_3d_fbm(uvw+3.7 + _Time[0], _Marble_Octaves, 2.0f, _Marble_Strength); float3 r = _Marble_U_Ramp.Sample(linear_repeat_s, float2(noise_r, 0)); float3 g = _Marble_V_Ramp.Sample(linear_repeat_s, float2(noise_g, 0)); float3 b = _Marble_W_Ramp.Sample(linear_repeat_s, float2(noise_b, 0)); albedo = r + g + b; #endif } Pbr getPbr(v2f i) { Pbr pbr = (Pbr) 0; #if defined(_UV_SCROLL) i.uv01.xy += getTime() * _UV_Scroll_Speed; #endif // _UV_SCROLL pbr.albedo = _MainTex.Sample(aniso16_trilinear_repeat_s, i.uv01.xy * _MainTex_ST.xy + _MainTex_ST.zw); pbr.albedo *= _Color; apply_marble(i.worldPos, pbr.albedo.xyz); float3 normal_tangent = UnpackNormal(_BumpMap.Sample(aniso16_trilinear_repeat_s, i.uv01.xy * _BumpMap_ST.xy)); normal_tangent.xy *= _BumpScale; #if defined(_DETAILS) float2 detail_uv = get_uv_by_channel(i, _Details_UV_Channel); float3 detail_normal = UnpackNormal(_DetailNormalMap.Sample(aniso16_trilinear_repeat_s, detail_uv * _DetailNormalMap_ST.xy)); detail_normal.xy *= _DetailNormalMapScale; float detail_mask = _DetailMask.Sample(aniso16_trilinear_repeat_s, detail_uv * _DetailMask_ST.xy).r; detail_normal.xy *= detail_mask; normal_tangent = blendNormalsHill12(normal_tangent, detail_normal); #endif // Map from tangent space to world space. float3 bitangent = cross(i.normal, i.tangent.xyz) * i.tangent.w; pbr.tbn = float3x3(i.tangent.xyz, bitangent, i.normal); pbr.normal = normalize(mul(normal_tangent, pbr.tbn)); float4 metallic_gloss = _MetallicGlossMap.Sample(aniso16_trilinear_repeat_s, i.uv01.xy * _MetallicGlossMap_ST.xy); pbr.smoothness = metallic_gloss.a * _Glossiness; pbr.metallic = metallic_gloss.r * _Metallic; #if defined(_CLEARCOAT) pbr.cc_roughness = _Clearcoat_Roughness; pbr.cc_strength = _Clearcoat_Strength; #endif #if defined(_CLOTH_SHEEN) pbr.cl_strength = _Cloth_Sheen_Strength; pbr.cl_color = _Cloth_Sheen_Color; #endif propagateSmoothness(pbr); return pbr; } #endif // __PBR_INC