2022-01-17 11:26:35 +03:00

798 lines
26 KiB
HLSL

//////////////////////////////////////////////////////
// MK Toon Surface //
// //
// Created by Michael Kremmel //
// www.michaelkremmel.de //
// Copyright © 2021 All rights reserved. //
//////////////////////////////////////////////////////
#ifndef MK_TOON_SURFACE
#define MK_TOON_SURFACE
#include "Core.hlsl"
/////////////////////////////////////////////////////////////////////////////////////////////
// Surface Data
/////////////////////////////////////////////////////////////////////////////////////////////
//Dynamic precalc struct
struct MKSurfaceData
{
#ifdef MK_NORMAL
half3 vertexNormalWorld;
#endif
#ifdef MK_LIT
#ifdef MK_ENVIRONMENT_REFLECTIONS
float4 lightmapUV;
#endif
#ifdef MK_VERTEX_LIGHTING
half3 vertexLighting;
#endif
half3 normalWorld;
#ifdef MK_TBN
half3 tangentWorld;
half3 bitangentWorld;
#endif
#ifdef MK_PARALLAX
half height;
#endif
#endif
#ifdef MK_VD
half3 viewWorld;
#endif
#ifdef MK_VD_O
half3 viewTangent;
#endif
#ifdef MK_POS_WORLD
float3 positionWorld;
#endif
#ifdef MK_FOG
float fogFactor;
#endif
#if defined(MK_VERTCLR) || defined(MK_PARTICLES) || defined(MK_POLYBRUSH)
autoLP4 vertexColor;
#endif
#if defined(MK_TCM) || defined(MK_TCD)
float4 baseUV;
#endif
#ifdef MK_THRESHOLD_MAP
float2 thresholdUV;
#endif
#if defined(MK_SCREEN_UV)
float4 screenUV;
#endif
#if defined(MK_REFRACTION)
float2 refractionUV;
#endif
#ifdef MK_ARTISTIC
float2 artisticUV;
#endif
#ifdef MK_FLIPBOOK
float3 flipbookUV;
#endif
#ifdef MK_DISSOLVE
half dissolveClip;
#endif
#ifdef MK_V_DOT_N
half VoN;
half OneMinusVoN;
#endif
#ifdef MK_MV_REF_N
half3 MVrN;
#endif
};
struct MKPBSData
{
half reflectivity;
half oneMinusReflectivity;
half roughness;
#if defined(MK_ENVIRONMENT_REFLECTIONS) || defined(MK_SPECULAR) || defined(MK_DIFFUSE_OREN_NAYAR) || defined(MK_DIFFUSE_MINNAERT)
half roughnessPow2;
#endif
#if defined(MK_ENVIRONMENT_REFLECTIONS) || defined(MK_SPECULAR)
half roughnessPow4;
#endif
half smoothness;
half3 diffuseRadiance;
half3 specularRadiance;
#ifdef MK_FRESNEL_HIGHLIGHTS
half3 fresnel;
#endif
};
//dynamic surface struct
struct Surface
{
half4 final;
half3 albedo;
half alpha;
#ifdef MK_REFRACTION
half3 refraction;
#endif
// RGB - RAW
#if defined(MK_LIT)
#ifdef MK_THRESHOLD_MAP
half thresholdOffset;
#endif
half4 goochBright;
half4 goochDark;
half2 occlusion;
#ifdef MK_EMISSION
half3 emission;
#endif
#ifdef MK_INDIRECT
half3 indirect;
#endif
half4 direct;
#ifdef MK_ARTISTIC
#if defined(MK_ARTISTIC_DRAWN) || defined(MK_ARTISTIC_SKETCH)
half artistic0;
#elif defined(MK_ARTISTIC_HATCHING)
half3 artistic0;
half3 artistic1;
#endif
#endif
#ifdef MK_THICKNESS_MAP
half thickness;
#endif
#if defined(MK_RIM)
half4 rim;
#endif
#ifdef MK_IRIDESCENCE
half4 iridescence;
#endif
#endif
};
half3 FresnelSchlickGGXIBL(half oneMinusVoN, half3 f0, half smoothness)
{
return FastPow5(oneMinusVoN) * (max(smoothness, f0) - f0) + f0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Header macros
/////////////////////////////////////////////////////////////////////////////////////////////
#ifdef MK_PBS
#define PASS_BLENDING_ARG(surface, surfaceData, pbsData) surface, surfaceData, pbsData
#else
#define PASS_BLENDING_ARG(surface, surfaceData, pbsData) surface, surfaceData
#endif
#ifdef MK_FLIPBOOK
#define SURFACE_FLIPBOOK_UV surfaceData.flipbookUV
#else
#define SURFACE_FLIPBOOK_UV 0
#endif
#ifdef MK_POS_WORLD
#define PASS_POSITION_WORLD_ARG(positionWorld) positionWorld
#else
#define PASS_POSITION_WORLD_ARG(positionWorld) 0
#endif
#ifdef MK_FOG
#define PASS_FOG_FACTOR_WORLD_ARG(fogFacor) ,fogFacor
#else
#define PASS_FOG_FACTOR_WORLD_ARG(fogFacor)
#endif
#if defined(MK_TCM) || defined(MK_TCD)
#define PASS_BASE_UV_ARG(baseUV) ,baseUV
#else
#define PASS_BASE_UV_ARG(baseUV)
#endif
#if defined(MK_VERTCLR) || defined(MK_PARTICLES) || defined(MK_POLYBRUSH)
#define PASS_VERTEX_COLOR_ARG(vertexColor) ,vertexColor
#else
#define PASS_VERTEX_COLOR_ARG(vertexColor)
#endif
#if defined(MK_NORMAL)
#define PASS_NORMAL_WORLD_ARG(normalWorld) ,normalWorld
#else
#define PASS_NORMAL_WORLD_ARG(normalWorld)
#endif
#if defined(MK_VERTEX_LIGHTING)
#define PASS_VERTEX_LIGHTING_ARG(vertexLighting) ,vertexLighting
#else
#define PASS_VERTEX_LIGHTING_ARG(vertexLighting)
#endif
#if defined(MK_TBN)
#define PASS_TANGENT_WORLD_ARG(tangentWorld) ,tangentWorld
#define PASS_BITANGENT_WORLD_ARG(bitangentWorld) ,bitangentWorld
#else
#define PASS_TANGENT_WORLD_ARG(bitangentWorld)
#define PASS_BITANGENT_WORLD_ARG(bitangentWorld)
#endif
#ifdef MK_ENVIRONMENT_REFLECTIONS
#define PASS_LIGHTMAP_UV_ARG(lightmapUV) ,lightmapUV
#else
#define PASS_LIGHTMAP_UV_ARG(lightmapUV)
#endif
#if defined(MK_PARALLAX)
#define PASS_VIEW_TANGENT_ARG(viewTangent) ,viewTangent
#else
#define PASS_VIEW_TANGENT_ARG(viewTangent)
#endif
#ifdef MK_POS_CLIP
#define PASS_POSITION_CLIP_ARG(positionClip) ,positionClip
#else
#define PASS_POSITION_CLIP_ARG(positionClip)
#endif
#ifdef MK_POS_NULL_CLIP
#define PASS_NULL_CLIP_ARG(nullClip) ,nullClip
#else
#define PASS_NULL_CLIP_ARG(nullClip)
#endif
#ifdef MK_FLIPBOOK
#define PASS_FLIPBOOK_UV_ARG(flipbookUV) ,flipbookUV
#else
#define PASS_FLIPBOOK_UV_ARG(flipbookUV)
#endif
//Texture color
inline void SurfaceColor(out half3 albedo, out half alpha, DECLARE_TEXTURE_2D_ARGS(albedoMap, samplerTex), float2 uv, float3 blendUV, autoLP4 color)
{
half4 c;
#ifdef MK_OUTLINE_PASS
c = half4(color.rgb, SAMPLE_TEX2D_FLIPBOOK(albedoMap, SAMPLER_REPEAT_MAIN, uv, blendUV).a * color.a);
#else
c = SAMPLE_TEX2D_FLIPBOOK(albedoMap, SAMPLER_REPEAT_MAIN, uv, blendUV) * color;
#endif
albedo = c.rgb;
#if defined(MK_ALPHA_LOOKUP)
alpha = c.a;
#else
alpha = 1.0h;
#endif
}
inline void SurfaceColor(out half3 albedo, out half alpha, DECLARE_TEXTURE_2D_ARGS(albedoMap, samplerTex), DECLARE_TEXTURE_2D_ARGS(albedoMap1, samplerTex1), DECLARE_TEXTURE_2D_ARGS(albedoMap2, samplerTex2), DECLARE_TEXTURE_2D_ARGS(albedoMap3, samplerTex3), float2 uv, autoLP4 blendColor, float3 blendUV, autoLP4 color)
{
half4 c0, c1, c2, c3;
#ifdef MK_OUTLINE_PASS
c0 = half4(color.rgb, SAMPLE_TEX2D_FLIPBOOK(albedoMap, SAMPLER_REPEAT_MAIN, uv, blendUV).a * color.a);
c1 = half4(color.rgb, SAMPLE_TEX2D_FLIPBOOK(albedoMap1, SAMPLER_REPEAT_MAIN, uv, blendUV).a) * blendColor.g;
c2 = half4(color.rgb, SAMPLE_TEX2D_FLIPBOOK(albedoMap2, SAMPLER_REPEAT_MAIN, uv, blendUV).a) * blendColor.b;
c3 = half4(color.rgb, SAMPLE_TEX2D_FLIPBOOK(albedoMap3, SAMPLER_REPEAT_MAIN, uv, blendUV).a) * blendColor.a;
#else
c0 = SAMPLE_TEX2D_FLIPBOOK(albedoMap, SAMPLER_REPEAT_MAIN, uv, blendUV) * color;
c1 = SAMPLE_TEX2D_FLIPBOOK(albedoMap1, SAMPLER_REPEAT_MAIN, uv, blendUV) * blendColor.y;
c2 = SAMPLE_TEX2D_FLIPBOOK(albedoMap2, SAMPLER_REPEAT_MAIN, uv, blendUV) * blendColor.z;
c3 = SAMPLE_TEX2D_FLIPBOOK(albedoMap3, SAMPLER_REPEAT_MAIN, uv, blendUV) * blendColor.w;
#endif
half4 mixedColor = lerp(lerp(lerp(c0, c1, blendColor.g), c2, blendColor.b), c3, blendColor.a);
albedo = mixedColor.rgb;
#if defined(MK_ALPHA_LOOKUP)
alpha = mixedColor.a;
#else
alpha = 1.0h;
#endif
}
//Non texture color
inline void SurfaceColor(out half3 albedo, out half alpha, autoLP4 vertexColor, autoLP4 color)
{
half4 c = vertexColor * color;
albedo = c.rgb;
#if defined(MK_ALPHA_LOOKUP)
alpha = c.a;
#else
alpha = 1.0h;
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Initialize
/////////////////////////////////////////////////////////////////////////////////////////////
inline MKSurfaceData ComputeSurfaceData
(
//#ifdef MK_POS_WORLD
in float3 positionWorld
//#endif
#ifdef MK_FOG
, in float fogFactor
#endif
#if defined(MK_TCM) || defined(MK_TCD)
, in float4 baseUV
#endif
#ifdef MK_ENVIRONMENT_REFLECTIONS
, in float4 lightmapUV
#endif
#if defined(MK_VERTCLR) || defined(MK_PARTICLES) || defined(MK_POLYBRUSH)
, in autoLP4 vertexColor
#endif
#ifdef MK_NORMAL
, in half3 normalWorld
#endif
#ifdef MK_VERTEX_LIGHTING
, in autoLP3 vertexLighting
#endif
#if defined(MK_TBN)
, in half3 tangentWorld
#endif
#if defined(MK_PARALLAX)
, in half3 viewTangent
#endif
#if defined(MK_TBN)
, in half3 bitangentWorld
#endif
#ifdef MK_POS_CLIP
, in float4 positionClip
#endif
#ifdef MK_POS_NULL_CLIP
, in float4 nullClip
#endif
#ifdef MK_FLIPBOOK
, in float3 flipbookUV
#endif
)
{
MKSurfaceData surfaceData;
INITIALIZE_STRUCT(MKSurfaceData, surfaceData);
#ifdef MK_POS_WORLD
surfaceData.positionWorld = positionWorld;
#endif
#ifdef MK_FOG
surfaceData.fogFactor = fogFactor;
#endif
#if defined(MK_VERTCLR) || defined(MK_PARTICLES) || defined(MK_POLYBRUSH)
surfaceData.vertexColor = vertexColor;
#endif
#if defined(MK_TCM) || defined(MK_TCD)
surfaceData.baseUV = 0;
#endif
#if defined(MK_TCM)
surfaceData.baseUV.xy = baseUV.xy * _AlbedoMap_ST.xy + _AlbedoMap_ST.zw;
#endif
#if defined(MK_TCD)
surfaceData.baseUV.zw = baseUV.zw;
#endif
#ifdef MK_FLIPBOOK
SURFACE_FLIPBOOK_UV = flipbookUV;
#endif
#ifdef MK_VD
surfaceData.viewWorld = SafeNormalize(CAMERA_POSITION_WORLD - surfaceData.positionWorld);
#endif
#ifdef MK_VD_O
surfaceData.viewTangent = SafeNormalize(viewTangent);
#endif
#ifdef MK_PARALLAX
surfaceData.height = SAMPLE_TEX2D_FLIPBOOK(_HeightMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV).r;
float2 parallaxUVOffset = Parallax(surfaceData.viewTangent, surfaceData.height, _Parallax, 0.42);
#if defined(MK_TCM)
surfaceData.baseUV.xy += parallaxUVOffset;
#endif
#if defined(MK_TCD)
surfaceData.baseUV.zw += parallaxUVOffset;
#endif
#endif
#ifdef MK_THRESHOLD_MAP
surfaceData.thresholdUV = surfaceData.baseUV.xy * _ThresholdMapScale;
#endif
#if defined(MK_SCREEN_UV)
surfaceData.screenUV = ComputeNDC(positionClip);
#endif
#if defined(MK_ARTISTIC)
#if defined(MK_ARTISTIC_DRAWN)
#if defined(MK_ARTISTIC_PROJECTION_SCREEN_SPACE)
surfaceData.artisticUV = ComputeNormalizedScreenUV(surfaceData.screenUV, ComputeNDC(nullClip), _DrawnMapScale);
#else
surfaceData.artisticUV = surfaceData.baseUV.xy * _DrawnMapScale;
#endif
#elif defined(MK_ARTISTIC_HATCHING)
#if defined(MK_ARTISTIC_PROJECTION_SCREEN_SPACE)
surfaceData.artisticUV = ComputeNormalizedScreenUV(surfaceData.screenUV, ComputeNDC(nullClip), _HatchingMapScale);
#else
surfaceData.artisticUV = surfaceData.baseUV.xy * _HatchingMapScale;
#endif
#elif defined(MK_ARTISTIC_SKETCH)
#if defined(MK_ARTISTIC_PROJECTION_SCREEN_SPACE)
surfaceData.artisticUV = ComputeNormalizedScreenUV(surfaceData.screenUV, ComputeNDC(nullClip), _SketchMapScale);
#else
surfaceData.artisticUV = surfaceData.baseUV.xy * _SketchMapScale;
#endif
#endif
#ifdef MK_ARTISTIC_ANIMATION_STUTTER
surfaceData.artisticUV.xy += Stutter(_Time.y, _ArtisticFrequency);
#endif
#endif
//dissolve could be moved above the screen uv to safe some instructions while clipping
#ifdef MK_DISSOLVE
float2 dissolveUV;
#ifdef MK_DISSOLVE_PROJECTION_SCREEN_SPACE
dissolveUV = ComputeNormalizedScreenUV(surfaceData.screenUV, ComputeNDC(nullClip), _DissolveMapScale);
#else
dissolveUV = surfaceData.baseUV.xy;
#endif
surfaceData.dissolveClip = SAMPLE_TEX2D_FLIPBOOK(_DissolveMap, SAMPLER_REPEAT_MAIN, dissolveUV, SURFACE_FLIPBOOK_UV).r - _DissolveAmount;
Clip0(surfaceData.dissolveClip);
#endif
#ifdef MK_NORMAL
surfaceData.vertexNormalWorld = SafeNormalize(normalWorld);
#endif
#ifdef MK_TBN
surfaceData.tangentWorld = SafeNormalize(tangentWorld);
surfaceData.bitangentWorld = SafeNormalize(bitangentWorld);
#endif
#if defined(MK_LIT)
//get normal direction
#ifdef MK_TBN
//Normalmap extraction
#if defined(MK_NORMAL_MAP) && !defined(MK_DETAIL_NORMAL_MAP)
surfaceData.normalWorld = NormalMappingWorld(PASS_TEXTURE_2D(_NormalMap, SAMPLER_REPEAT_MAIN), surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV, _NormalMapIntensity, half3x3(surfaceData.tangentWorld, surfaceData.bitangentWorld, surfaceData.vertexNormalWorld));
#elif defined(MK_NORMAL_MAP) && defined(MK_DETAIL_NORMAL_MAP)
surfaceData.normalWorld = NormalMappingWorld(PASS_TEXTURE_2D(_NormalMap, SAMPLER_REPEAT_MAIN), surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV, _NormalMapIntensity, PASS_TEXTURE_2D(_DetailNormalMap, SAMPLER_REPEAT_MAIN), surfaceData.baseUV.zw, _DetailNormalMapIntensity, half3x3(surfaceData.tangentWorld, surfaceData.bitangentWorld, surfaceData.vertexNormalWorld));
#elif !defined(MK_NORMAL_MAP) && defined(MK_DETAIL_NORMAL_MAP)
surfaceData.normalWorld = NormalMappingWorld(PASS_TEXTURE_2D(_DetailNormalMap, SAMPLER_REPEAT_MAIN), surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV, _DetailNormalMapIntensity, half3x3(surfaceData.tangentWorld, surfaceData.bitangentWorld, surfaceData.vertexNormalWorld));
#else
surfaceData.normalWorld = surfaceData.vertexNormalWorld;
#endif
#ifdef MK_SPECULAR_ANISOTROPIC
//rebuild tangent and bitangent
surfaceData.tangentWorld = SafeNormalize(cross(surfaceData.normalWorld, half3(0.0, 1.0, 0.0)));
surfaceData.bitangentWorld = SafeNormalize(cross(surfaceData.normalWorld, surfaceData.tangentWorld));
#endif
#else
surfaceData.normalWorld = surfaceData.vertexNormalWorld;
#endif
#ifdef MK_VERTEX_LIGHTING
surfaceData.vertexLighting = vertexLighting;
#endif
#ifdef MK_ENVIRONMENT_REFLECTIONS
surfaceData.lightmapUV = lightmapUV;
#endif
#endif
#if defined(MK_REFRACTION)
#ifdef MK_INDEX_OF_REFRACTION
float3 ssY = float3(UNITY_MATRIX_V[1][0], UNITY_MATRIX_V[1][1], UNITY_MATRIX_V[1][2]);
float3 ssX = normalize( cross(surfaceData.viewWorld, ssY));
float4x4 ssView = float4x4
(
ssX.x, ssX.y, ssX.z, 0,
ssY.x, ssY.y, ssY.z, 0,
surfaceData.viewWorld, 0,
0,0,0,1
);
float2 ssIOR = mul(ssView, float4(surfaceData.vertexNormalWorld, 0.0)).xy;
ssIOR.x *= SafeDivide(_ScreenParams.y, _ScreenParams.x);
ssIOR *= (1.0 - saturate(dot(surfaceData.vertexNormalWorld, surfaceData.viewWorld))) * _IndexOfRefraction;
surfaceData.refractionUV = surfaceData.screenUV.xy - ssIOR;
#else
surfaceData.refractionUV = surfaceData.screenUV.xy;
#endif
#endif
#ifdef MK_V_DOT_N
surfaceData.VoN = saturate(dot(surfaceData.viewWorld, surfaceData.normalWorld));
surfaceData.OneMinusVoN = 1.0 - surfaceData.VoN;
#endif
#ifdef MK_MV_REF_N
surfaceData.MVrN = reflect(-surfaceData.viewWorld, surfaceData.normalWorld);
#endif
return surfaceData;
}
inline void ComputeBlending
(
inout Surface surface
, in MKSurfaceData surfaceData
#ifdef MK_PBS
, inout MKPBSData pbsData
#endif
)
{
#if defined(MK_BLEND_PREMULTIPLY) || defined(MK_BLEND_ADDITIVE)
#if defined(MK_PBS)
pbsData.diffuseRadiance *= surface.alpha;
half premulGISpec;
#ifdef MK_FRESNEL_HIGHLIGHTS
premulGISpec = dot(pbsData.fresnel, REL_LUMA);
#else
premulGISpec = pbsData.specularRadiance;
#endif
surface.alpha = surface.alpha * pbsData.oneMinusReflectivity + premulGISpec;
#else
surface.albedo *= surface.alpha;
#endif
#elif defined(MK_BLEND_MULTIPLY)
#if defined(MK_PBS)
surface.albedo = lerp(HALF3_ONE, surface.albedo, surface.alpha);
pbsData.diffuseRadiance = lerp(HALF3_ONE, pbsData.diffuseRadiance, surface.alpha * pbsData.oneMinusReflectivity + pbsData.reflectivity);
#else
surface.albedo = lerp(HALF3_ONE, surface.albedo, surface.alpha);
#endif
#endif
#ifdef MK_SOFT_FADE
#if defined(MK_BLEND_PREMULTIPLY) || defined(MK_BLEND_ADDITIVE)
surface.albedo *= SoftFade(_SoftFadeNearDistance, _SoftFadeFarDistance, surfaceData.screenUV);
#else
surface.alpha *= SoftFade(_SoftFadeNearDistance, _SoftFadeFarDistance, surfaceData.screenUV);
#endif
#endif
#ifdef MK_CAMERA_FADE
#if defined(MK_BLEND_PREMULTIPLY) || defined(MK_BLEND_ADDITIVE)
surface.albedo *= CameraFade(_CameraFadeNearDistance, _CameraFadeFarDistance, surfaceData.screenUV);
#else
surface.alpha *= CameraFade(_CameraFadeNearDistance, _CameraFadeFarDistance, surfaceData.screenUV);
#endif
#endif
#ifdef MK_LIT
#if defined(MK_ALPHA_LOOKUP)
surface.goochBright.a *= surface.alpha;
surface.goochDark.a *= surface.alpha;
#endif
#endif
}
inline MKPBSData ComputePBSData(inout Surface surface, in MKSurfaceData surfaceData)
{
MKPBSData pbsData;
INITIALIZE_STRUCT(MKPBSData, pbsData);
half4 pbsInput;
#if defined(MK_WORKFLOW_METALLIC)
#ifdef MK_PBS_MAP_0
pbsInput = SAMPLE_TEX2D_FLIPBOOK(_MetallicMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV).rrra;
pbsInput.a *= _Smoothness;
#else
pbsInput.rgb = _Metallic;
pbsInput.a = _Smoothness;
#endif
#elif defined(MK_WORKFLOW_ROUGHNESS)
#ifdef MK_PBS_MAP_0
pbsInput.rgb = SAMPLE_TEX2D_FLIPBOOK(_MetallicMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV).rrr;
#else
pbsInput.rgb = _Metallic;
#endif
#ifdef MK_PBS_MAP_1
pbsInput.a = 1.0 - SAMPLE_TEX2D_FLIPBOOK(_RoughnessMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV).r;
#else
pbsInput.a = 1.0 - _Roughness;
#endif
#else //MK_WORKFLOW_SPECULAR / Simple
#ifdef MK_PBS_MAP_0
pbsInput = SAMPLE_TEX2D_FLIPBOOK(_SpecularMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV);
pbsInput.a *= _Smoothness;
#else
pbsInput.rgb = _SpecularColor.rgb;
pbsInput.a = _Smoothness;
#endif
#endif
#if defined(MK_WORKFLOW_METALLIC)
pbsData.smoothness = pbsInput.a;
pbsData.oneMinusReflectivity = K_SPEC_DIELECTRIC_MAX - pbsInput.r * K_SPEC_DIELECTRIC_MAX;
pbsData.reflectivity = 1.0 - pbsData.oneMinusReflectivity;
pbsData.specularRadiance = lerp(K_SPEC_DIELECTRIC_MIN, surface.albedo, pbsInput.r);
pbsData.diffuseRadiance = surface.albedo * (pbsData.oneMinusReflectivity * (1.0 - pbsData.specularRadiance));//surface.albedo * pbsData.oneMinusReflectivity;
#elif defined(MK_WORKFLOW_ROUGHNESS)
pbsData.smoothness = pbsInput.a;
pbsData.oneMinusReflectivity = K_SPEC_DIELECTRIC_MAX - pbsInput.r * K_SPEC_DIELECTRIC_MAX;
pbsData.reflectivity = 1.0 - pbsData.oneMinusReflectivity;
pbsData.specularRadiance = lerp(K_SPEC_DIELECTRIC_MIN, surface.albedo, pbsInput.r);
pbsData.diffuseRadiance = surface.albedo * ((1.0 - pbsData.specularRadiance) * pbsData.oneMinusReflectivity);
#elif defined(MK_WORKFLOW_SPECULAR)
pbsData.reflectivity = max(max(pbsInput.r, pbsInput.g), pbsInput.b);
pbsData.smoothness = pbsInput.a;
pbsData.oneMinusReflectivity = 1.0 - pbsData.reflectivity;
pbsData.specularRadiance = pbsInput.rgb;
pbsData.diffuseRadiance = surface.albedo * (half3(1.0, 1.0, 1.0) - pbsInput.rgb);
#else //Simple
pbsData.reflectivity = 0;
pbsData.smoothness = pbsInput.a;
pbsData.oneMinusReflectivity = 1.0 - pbsData.reflectivity;
pbsData.diffuseRadiance = surface.albedo;
pbsData.specularRadiance = pbsInput.rgb;
#endif
pbsData.roughness = 1.0 - pbsData.smoothness;
#if defined(MK_ENVIRONMENT_REFLECTIONS) || defined(MK_SPECULAR) || defined(MK_DIFFUSE_OREN_NAYAR) || defined(MK_DIFFUSE_MINNAERT)
pbsData.roughnessPow2 = FastPow2(pbsData.roughness);
#endif
#if defined(MK_ENVIRONMENT_REFLECTIONS) || defined(MK_SPECULAR)
pbsData.roughnessPow4 = FastPow2(pbsData.roughnessPow2);
#endif
#ifdef MK_FRESNEL_HIGHLIGHTS
pbsData.fresnel = FresnelSchlickGGXIBL(surfaceData.OneMinusVoN, pbsData.specularRadiance, pbsData.smoothness);
#endif
#ifdef MK_PBS
ComputeBlending(PASS_BLENDING_ARG(surface, surfaceData, pbsData));
#endif
return pbsData;
}
inline Surface InitSurface(in MKSurfaceData surfaceData, DECLARE_TEXTURE_2D_ARGS(albedoMap, samplerTex), inout half4 albedoTint)
{
//Init Surface
Surface surface;
INITIALIZE_STRUCT(Surface, surface);
#ifdef MK_ARTISTIC
#if defined(MK_ARTISTIC_DRAWN)
surface.artistic0 = 1.0 - SampleTex2D(PASS_TEXTURE_2D(_DrawnMap, SAMPLER_REPEAT_MAIN), surfaceData.artisticUV).r;
#elif defined(MK_ARTISTIC_SKETCH)
surface.artistic0 = SampleTex2D(PASS_TEXTURE_2D(_SketchMap, SAMPLER_REPEAT_MAIN), surfaceData.artisticUV).r;
#elif defined(MK_ARTISTIC_HATCHING)
surface.artistic0 = SampleTex2D(PASS_TEXTURE_2D(_HatchingDarkMap, SAMPLER_REPEAT_MAIN), surfaceData.artisticUV).rgb;
surface.artistic1 = SampleTex2D(PASS_TEXTURE_2D(_HatchingBrightMap, SAMPLER_REPEAT_MAIN), surfaceData.artisticUV).rgb;
#endif
#endif
//init surface color
#if defined(MK_TEXCLR)
#if defined(MK_PARTICLES) || defined(MK_COMBINE_VERTEX_COLOR_WITH_ALBEDO_MAP)
albedoTint *= surfaceData.vertexColor;
#endif
SurfaceColor(surface.albedo, surface.alpha, PASS_TEXTURE_2D(albedoMap, samplerTex), surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV, albedoTint);
#elif defined(MK_POLYBRUSH)
SurfaceColor(surface.albedo, surface.alpha, PASS_TEXTURE_2D(albedoMap, samplerTex), PASS_TEXTURE_2D(_AlbedoMap1, samplerTex), PASS_TEXTURE_2D(_AlbedoMap2, samplerTex), PASS_TEXTURE_2D(_AlbedoMap3, samplerTex), surfaceData.baseUV.xy, surfaceData.vertexColor, SURFACE_FLIPBOOK_UV, albedoTint);
#else
SurfaceColor(surface.albedo, surface.alpha, surfaceData.vertexColor, albedoTint);
#endif
//add detail
#ifdef MK_DETAIL_MAP
MixAlbedoDetail(surface.albedo, PASS_TEXTURE_2D(_DetailMap, SAMPLER_REPEAT_MAIN), surfaceData.baseUV.zw, SURFACE_FLIPBOOK_UV);
#endif
#if defined(MK_ALPHA_CLIPPING)
Clip0(surface.alpha - _AlphaCutoff);
#endif
#ifdef MK_REFRACTION
half2 refractionDir;
#ifdef MK_REFRACTION_DISTORTION_MAP
refractionDir = (_RefractionDistortion * REFRACTION_DISTORTION_SCALE * surface.alpha) * UnpackDudv(PASS_TEXTURE_2D(_RefractionDistortionMap, SAMPLER_REPEAT_MAIN), surfaceData.baseUV.xy * _RefractionDistortionMapScale, SURFACE_FLIPBOOK_UV);
#else
//currently disabled if no normal mapping is set, could be optimized using a procedural noise
refractionDir = 0;
#endif
surface.refraction = SampleRefraction(surfaceData.refractionUV + refractionDir);
surface.albedo.rgb = lerp(surface.refraction.rgb, surface.albedo.rgb, saturate(surface.alpha - _RefractionDistortionFade));
#endif
#ifdef MK_COLOR_GRADING_ALBEDO
surface.albedo = ColorGrading(surface.albedo, _Brightness, _Saturation, _Contrast);
#endif
#ifdef MK_LIT
#ifdef MK_THRESHOLD_MAP
surface.thresholdOffset = SAMPLE_TEX2D_FLIPBOOK(_ThresholdMap, SAMPLER_REPEAT_MAIN, surfaceData.thresholdUV, SURFACE_FLIPBOOK_UV).r;
#endif
surface.direct = 0;
surface.goochBright = _GoochBrightColor;
#ifdef MK_LEGACY_RP
#ifdef USING_DIRECTIONAL_LIGHT
surface.goochDark = _GoochDarkColor;
#else
surface.goochDark = 0;
#endif
#else
surface.goochDark = _GoochDarkColor;
#endif
#if defined(MK_GOOCH_BRIGHT_MAP)
surface.goochBright *= SAMPLE_TEX2D_FLIPBOOK(_GoochBrightMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV);
#endif
#if defined(MK_GOOCH_DARK_MAP)
#ifdef MK_LEGACY_RP
#ifdef USING_DIRECTIONAL_LIGHT
surface.goochDark *= SAMPLE_TEX2D_FLIPBOOK(_GoochDarkMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV);
#endif
#else
surface.goochDark *= SAMPLE_TEX2D_FLIPBOOK(_GoochDarkMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV);
#endif
#endif
#ifdef MK_INDIRECT
surface.indirect = 0;
#endif
#ifdef MK_THICKNESS_MAP
surface.thickness = SAMPLE_TEX2D_FLIPBOOK(_ThicknessMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV).r;
#endif
#if defined(MK_RIM)
surface.rim = 0;
#endif
#ifdef MK_IRIDESCENCE
surface.iridescence = 0;
#endif
#ifdef MK_OCCLUSION_MAP
surface.occlusion = (1.0 - _OcclusionMapIntensity) + SAMPLE_TEX2D_FLIPBOOK(_OcclusionMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV).rg * _OcclusionMapIntensity;
#else
surface.occlusion = 1.0;
#endif
#ifdef MK_EMISSION
#if defined(MK_EMISSION_MAP)
surface.emission = _EmissionColor * SAMPLE_TEX2D_FLIPBOOK(_EmissionMap, SAMPLER_REPEAT_MAIN, surfaceData.baseUV.xy, SURFACE_FLIPBOOK_UV).rgb;
#else
surface.emission = _EmissionColor;
#endif
#endif
#endif
#ifdef MK_COLOR
#if defined(MK_COLOR_BLEND_ADDITIVE)
surface.albedo = surface.albedo + surfaceData.vertexColor;
surface.alpha *= surfaceData.vertexColor.a;
#elif defined(MK_COLOR_BLEND_SUBTRACTIVE)
surface.albedo = surface.albedo + surfaceData.vertexColor * (-1.0h);
surface.alpha *= surfaceData.vertexColor.a;
#elif defined(MK_COLOR_BLEND_OVERLAY)
surface.albedo = lerp(1 - 2 * (1 - surface.albedo) * (1 - surface.albedo), 2 * surface.albedo * surfaceData.vertexColor.rgb, step(surface.albedo, 0.5));
surface.alpha *= surfaceData.vertexColor.a;
#elif defined(MK_COLOR_BLEND_COLOR)
half3 aHSL = RGBToHSV(surface.albedo);
half3 bHSL = RGBToHSV(surfaceData.vertexColor.rgb);
half3 rHSL = half3(bHSL.x, bHSL.y, aHSL.z);
surface.albedo = HSVToRGB(rHSL);
surface.alpha = surface.alpha * surfaceData.vertexColor.a;
#elif defined(MK_COLOR_BLEND_DIFFERENCE)
surface.albedo = abs(surface.albedo + surfaceData.vertexColor * (-1.0h));
surface.alpha *= surfaceData.vertexColor.a;
#else
surface.albedo *= surfaceData.vertexColor.rgb;
surface.alpha *= surfaceData.vertexColor.a;
#endif
#endif
//avoid not initialized value
surface.final = 0;
#ifndef MK_PBS
ComputeBlending(PASS_BLENDING_ARG(surface, surfaceData, 0));
#endif
return surface;
}
#endif