////////////////////////////////////////////////////// // 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