-
-
Save kayk5654/42df15a9c1ddec4b1134e1e2684eaed1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "3DDrawing/WaterColorPainting" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
_Color("Color", COLOR) = (1,1,1,1) | |
[Header(Graphic Pattern Settings)] | |
_PaintMap("Paint map", 2D) = "white" {} | |
_SecondaryTilingOffset("Secondary Tiling Offset", Vector) = (1,1,0,0) | |
_PatternPower("Pattern Power", Float) = 1 | |
_ColorMap("Color map", 2D) = "white" {} | |
_AlphaMap("Alpha map", 2D) = "white" {} | |
_SecondaryAlphaTilingOffset("Secondary Alpha Tiling Offset", Vector) = (1,1,0,0) | |
_AlphaMul("Alpha Multiplier", Float) = 1 | |
_AlphaPower("Alpha Poser", Float) = 1 | |
[Header(FlowMap Settings)] | |
[Toggle] _UseFlowMap("Use FlowMap", Float) = 0 | |
_FlowMap("Flowmap", 2D) = "white" {} | |
_FlowSpeed("Flow Speed", Float) = 1 | |
[Header(Pseudo Color Bleeding)] | |
[Toggle] _UsePsuedoColorBleeding("Use Pseudo Color Bleeding", Float) = 0 | |
_CubeMap("CubeMap", CUBE) = "white" {} | |
_BoxCenter("Center of Box Projection Boundary", Vector) = (0, 0, 0, 0) | |
_BoxMax("Max Box Projection Boundary", Vector) = (0.5, 0.5, 0.5, 0) | |
_BoxMin("Min Box Projection Boundary", Vector) = (-0.5, -0.5, -0.5, 0) | |
[Header(Lighting)] | |
_ShadowIntensity("Shadow Intensity", Range(0,1)) = 1 | |
} | |
SubShader | |
{ | |
Tags { "RenderType" = "Transparent"} | |
LOD 100 | |
// shadowcaster pass | |
Pass | |
{ | |
Name "ShadowCast" | |
Tags { "LightMode" = "ShadowCaster"} | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma multi_compile_shadowcaster | |
#include "UnityCG.cginc" | |
struct v2f { | |
V2F_SHADOW_CASTER; | |
}; | |
v2f vert(appdata_base v) | |
{ | |
v2f o; | |
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o) | |
return o; | |
} | |
float4 frag(v2f i) : SV_Target | |
{ | |
SHADOW_CASTER_FRAGMENT(i) | |
} | |
ENDCG | |
} | |
// prevent from drawing hidden front surface | |
Pass | |
{ | |
ZWrite On | |
ColorMask 0 | |
} | |
// main pass | |
Pass | |
{ | |
Tags { "LightMode" = "ForwardBase" "Queue" = "Transparent" } | |
Blend SrcAlpha OneMinusSrcAlpha | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma multi_compile_fwdbase | |
#include "UnityCG.cginc" | |
#include "ShaderCalculationHelper.cginc" | |
// shadow helper functions and macros | |
#include "AutoLight.cginc" | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
float3 normal : NORMAL; | |
float2 lightmapUv : TEXCOORD1; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
}; | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
float4 vertex : SV_POSITION; | |
float3 normal : NORMAL; | |
float2 lightmapUv : TEXCOORD1; | |
float3 worldPos : TEXCOORD2; | |
float3 viewDir : TEXCOORD4; | |
SHADOW_COORDS(3) // put shadows data into TEXCOORD3 | |
UNITY_VERTEX_OUTPUT_STEREO | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
fixed4 _Color; | |
sampler2D _PaintMap; | |
fixed4 _PaintMap_ST; | |
fixed4 _SecondaryTilingOffset; | |
half _PatternPower; | |
sampler2D _ColorMap; | |
sampler2D _AlphaMap; | |
fixed4 _AlphaMap_ST; | |
fixed4 _SecondaryAlphaTilingOffset; | |
half _AlphaMul; | |
half _AlphaPower; | |
fixed _UseVColorForAlpha; | |
UNITY_DECLARE_TEXCUBE(_CubeMap); | |
fixed _UseFlowMap; | |
sampler2D _FlowMap; | |
half _FlowSpeed; | |
fixed _UsePsuedoColorBleeding; | |
float3 _BoxCenter; | |
float3 _BoxMax; | |
float3 _BoxMin; | |
half _ShadowIntensity; | |
v2f vert (appdata v) | |
{ | |
UNITY_SETUP_INSTANCE_ID(v); | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv = TRANSFORM_TEX(v.uv, _MainTex); | |
o.lightmapUv = v.lightmapUv * unity_LightmapST.xy + unity_LightmapST.zw; | |
o.worldPos = mul(unity_ObjectToWorld, v.vertex); | |
o.normal = v.normal; | |
o.viewDir = normalize(UnityWorldSpaceViewDir(o.worldPos)); | |
// compute shadows data | |
TRANSFER_SHADOW(o) | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); | |
return o; | |
} | |
// sample 2d alpha texture using 3d position | |
float sample2DAlphaFromPosition(float3 pos) | |
{ | |
float alphaX = tex2D(_AlphaMap, pos.yz * _AlphaMap_ST.xy + _AlphaMap_ST.zw).r; | |
float alphaY = tex2D(_AlphaMap, pos.xz * _AlphaMap_ST.xy + _AlphaMap_ST.zw).r; | |
float alphaZ = tex2D(_AlphaMap, pos.yx * _AlphaMap_ST.xy + _AlphaMap_ST.zw).r; | |
alphaX = lerp(alphaX, tex2D(_AlphaMap, pos.yz * _SecondaryAlphaTilingOffset.xy + _SecondaryAlphaTilingOffset.zw).r, 0.5); | |
alphaY = lerp(alphaY, tex2D(_AlphaMap, pos.xz * _SecondaryAlphaTilingOffset.xy + _SecondaryAlphaTilingOffset.zw).r, 0.5); | |
alphaZ = lerp(alphaZ, tex2D(_AlphaMap, pos.yx * _SecondaryAlphaTilingOffset.xy + _SecondaryAlphaTilingOffset.zw).r, 0.5); | |
return (alphaX + alphaY + alphaZ) / 3; | |
} | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
// sample the texture | |
fixed4 col = tex2D(_MainTex, i.uv) * _Color; | |
float3 worldNormal = UnityObjectToWorldNormal(i.normal); | |
/*** psuedo color bleeding ***/ | |
fixed4 bleedColor = fixed4(1, 1, 1, 0); | |
if (_UsePsuedoColorBleeding == 1) | |
{ | |
float3 boxProjSampleVector = boxProjection(i.worldPos - _BoxCenter, i.worldPos, _BoxCenter, _BoxMin, _BoxMax); | |
bleedColor = UNITY_SAMPLE_TEXCUBE(_CubeMap, boxProjSampleVector); | |
float bleedLerpFactor = length(i.worldPos - _BoxCenter) / max(length(_BoxMin - _BoxCenter), length(_BoxMax - _BoxCenter)); | |
bleedColor = lerp(fixed4(bleedColor.rgb, 0), bleedColor, bleedLerpFactor); | |
} | |
/*** calculate lighting ***/ | |
// test with simple lighting using dot product | |
float NdotL = dot(_WorldSpaceLightPos0.xyz, worldNormal); | |
// test with lightmap | |
half3 lightmap = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.lightmapUv)); | |
// test environmental lighting using a shading function on UnityCG.cginc | |
half3 indirectLighting = ShadeSH9(half4(i.normal, 1)); | |
half3 lighting = lerp(1, clamp(NdotL, 0, 1), _ShadowIntensity) * 0.5 + lightmap + indirectLighting; | |
// compute shadow attenuation (1.0 = fully lit, 0.0 = fully shadowed) | |
fixed shadow = lerp(1, SHADOW_ATTENUATION(i), saturate(_ShadowIntensity)); | |
lighting *= shadow; | |
/*** create painting pattern ***/ | |
float normalViewDot = dot(worldNormal, i.viewDir); | |
float power = (1 - lighting) * _PatternPower; | |
float paintPattern = tex2D(_PaintMap, i.uv * _PaintMap_ST.xy + _PaintMap_ST.zw).r; | |
// blend paint maps using lerp | |
paintPattern = lerp(paintPattern, tex2D(_PaintMap, i.uv * _SecondaryTilingOffset.xy + _SecondaryTilingOffset.zw), 0.5); | |
paintPattern = saturate(pow(paintPattern, power)); | |
// sample color ramp by lighting result | |
float NdotLLighting = fitRange(NdotL, -1, 1, 0, 1); | |
float otherLighting = fitRange(lightmap + indirectLighting, 0, 1, 0.5, 1); | |
float2 sampleCoord = float2((NdotLLighting + otherLighting) * 0.5 * shadow + (paintPattern - 0.5), 0.5); | |
fixed3 colorRamp = tex2D(_ColorMap, sampleCoord).rgb; | |
col.rgb *= colorRamp; | |
/* apply flow map on alpha */ | |
float2 flowDir = float2(0, 0); | |
float progress1 = 0; | |
float progress2 = 0; | |
if (_UseFlowMap == 1) | |
{ | |
// set uv range of flow map uv from -0.5 to 0.5 | |
flowDir.xy = tex2D(_FlowMap, i.uv) - 0.5; | |
// loop time between 0 and 1 | |
progress1 = frac(_Time.x * _FlowSpeed); | |
// offset time looping 0.5 | |
progress2 = frac(_Time.x * _FlowSpeed + 0.5); | |
} | |
// create 2 uv layouts for each texture tiling offset | |
float2 uv1_PrimaryAlpha = i.uv * _AlphaMap_ST.xy + _AlphaMap_ST.zw + flowDir * progress1; | |
float2 uv2_PrimaryAlpha = i.uv * _AlphaMap_ST.xy + _AlphaMap_ST.zw + flowDir * progress2; | |
float2 uv1_SecondaryAlpha = i.uv * _SecondaryAlphaTilingOffset.xy + _SecondaryAlphaTilingOffset.zw + flowDir * progress1; | |
float2 uv2_SecondaryAlpha = i.uv * _SecondaryAlphaTilingOffset.xy + _SecondaryAlphaTilingOffset.zw + flowDir * progress2; | |
// interpolate loop end | |
float flowLerpRate = abs((0.5 - progress1) / 0.5); | |
float primaryAlpha = lerp(tex2D(_AlphaMap, uv1_PrimaryAlpha), tex2D(_AlphaMap, uv2_PrimaryAlpha), flowLerpRate).r; | |
float secondaryAlpha = lerp(tex2D(_AlphaMap, uv1_SecondaryAlpha), tex2D(_AlphaMap, uv2_SecondaryAlpha), flowLerpRate).r; | |
col.a = lerp(primaryAlpha, secondaryAlpha, 0.5); | |
// calculate alpha | |
col.a = saturate(pow(col.a * _AlphaMul, _AlphaPower)); | |
// add highlight by alpha | |
fixed minimumAlpha = 0.7; | |
col.a *= max(1 - pow(clamp(NdotL, 0, 1), 5), minimumAlpha); | |
// add silhouette by alpha | |
fixed silhouetteAlpha = 3; | |
col.a = saturate(col.a + pow(1 - abs(normalViewDot), silhouetteAlpha)); | |
//col.rgb = fixed3(0, 0, 0); | |
//col.rgb = lighting; | |
if (_UsePsuedoColorBleeding == 1) | |
{ | |
col.rgb = lerp(col.rgb, bleedColor.rgb, bleedColor.a); | |
} | |
return col; | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment