Created
October 31, 2016 21:18
-
-
Save elringus/5b15dff785f802a1ca8f193022045e54 to your computer and use it in GitHub Desktop.
Shader for meshes, which responds to light by applying blend mode effect
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 "BlendModes/Extra/BlendLightedMesh" | |
{ | |
Properties | |
{ | |
_Color ("Tint Color", Color) = (1,1,1,1) | |
_MainTex ("Base (RGB)", 2D) = "white" {} | |
_NormalMap ("Normal Map", 2D) = "bump" {} | |
_BumpDepth ("Bump Depth", Range(0.0, 1.0)) = 1.0 | |
} | |
CGINCLUDE | |
#include "../BlendModes.cginc" | |
#include "UnityCG.cginc" | |
#pragma target 3.0 | |
#pragma multi_compile BmDarken BmMultiply BmColorBurn BmLinearBurn BmDarkerColor BmLighten BmScreen BmColorDodge BmLinearDodge BmLighterColor BmOverlay BmSoftLight BmHardLight BmVividLight BmLinearLight BmPinLight BmHardMix BmDifference BmExclusion BmSubtract BmDivide BmHue BmSaturation BmColor BmLuminosity | |
fixed4 _Color; | |
sampler2D _MainTex; | |
sampler2D _NormalMap; | |
sampler2D _GrabTexture; | |
float4 _MainTex_ST; | |
float4 _NormalMap_ST; | |
float _BumpDepth; | |
float4 _LightColor0; | |
struct VertexInput | |
{ | |
float4 Vertex : POSITION; | |
float2 TexCoord : TEXCOORD0; | |
float3 Normal : NORMAL; | |
float4 Tangent : TANGENT; | |
}; | |
struct VertexOutput | |
{ | |
float4 Vertex : SV_POSITION; | |
float2 TexCoord : TEXCOORD0; | |
float4 ScreenPos : TEXCOORD1; | |
float3 NormalDir : TEXCOORD2; | |
float3 TangentDir : TEXCOORD3; | |
float3 BinormalDir : TEXCOORD4; | |
float4 LightDir : TEXCOORD5; | |
float3 ViewDir : TEXCOORD6; | |
}; | |
ENDCG | |
SubShader | |
{ | |
Tags | |
{ | |
"Queue" = "Transparent" | |
"RenderType" = "Transparent" | |
} | |
GrabPass { } | |
Pass | |
{ | |
Tags { "LightMode" = "ForwardBase" } | |
Blend SrcAlpha OneMinusSrcAlpha | |
CGPROGRAM | |
#pragma vertex ComputeVertex | |
#pragma fragment ComputeFragment | |
VertexOutput ComputeVertex(VertexInput vertexInput) | |
{ | |
VertexOutput vertexOutput; | |
vertexOutput.Vertex = mul(UNITY_MATRIX_MVP, vertexInput.Vertex); | |
vertexOutput.ScreenPos = vertexOutput.Vertex; | |
vertexOutput.TexCoord = TRANSFORM_TEX(vertexInput.TexCoord, _MainTex); | |
vertexOutput.NormalDir = normalize(mul(half4(vertexInput.Normal, 0.0), _World2Object).xyz); | |
vertexOutput.TangentDir = normalize(mul(_Object2World, vertexInput.Tangent).xyz); | |
vertexOutput.BinormalDir = normalize(cross(vertexOutput.NormalDir, vertexOutput.TangentDir) * vertexInput.Tangent.w); | |
vertexOutput.LightDir = float4(normalize(_WorldSpaceLightPos0.xyz), 0); | |
vertexOutput.ViewDir = normalize(_WorldSpaceCameraPos.xyz - mul(_Object2World, vertexInput.Vertex).xyz); | |
return vertexOutput; | |
} | |
fixed4 ComputeFragment(VertexOutput vertexOutput) : SV_Target | |
{ | |
float2 grabTexCoord = vertexOutput.ScreenPos.xy / vertexOutput.ScreenPos.w; | |
grabTexCoord.x = (grabTexCoord.x + 1.0) * .5; | |
grabTexCoord.y = (grabTexCoord.y + 1.0) * .5; | |
#if UNITY_UV_STARTS_AT_TOP | |
grabTexCoord.y = 1.0 - grabTexCoord.y; | |
#endif | |
fixed4 grabColor = tex2D(_GrabTexture, grabTexCoord); | |
fixed4 normalColor = tex2D(_NormalMap, vertexOutput.TexCoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw); | |
fixed3 localNormal = fixed3(2.0 * normalColor.ag - fixed2(1.0, 1.0), _BumpDepth); | |
fixed3x3 localToWorld = fixed3x3(vertexOutput.TangentDir, vertexOutput.BinormalDir, vertexOutput.NormalDir); | |
fixed3 normalDirection = normalize(mul(localNormal, localToWorld)); | |
fixed3 lightColor = _LightColor0.xyz * saturate(dot(normalDirection, vertexOutput.LightDir)); | |
fixed lightPower = dot(lightColor, float3(0.3, 0.59, 0.11)); | |
fixed4 texColor = tex2D(_MainTex, vertexOutput.TexCoord) * _Color; | |
#include "../BlendOps.cginc" | |
return lerp(fixed4(0, 0, 0, 0), blendResult, lightPower); | |
} | |
ENDCG | |
} | |
Pass | |
{ | |
Tags { "LightMode" = "ForwardAdd" } | |
Blend One One | |
CGPROGRAM | |
#pragma vertex ComputeVertex | |
#pragma fragment ComputeFragment | |
VertexOutput ComputeVertex(VertexInput vertexInput) | |
{ | |
VertexOutput vertexOutput; | |
half4 posWorld = mul(_Object2World, vertexInput.Vertex); | |
vertexOutput.Vertex = mul(UNITY_MATRIX_MVP, vertexInput.Vertex); | |
vertexOutput.ScreenPos = vertexOutput.Vertex; | |
vertexOutput.TexCoord = TRANSFORM_TEX(vertexInput.TexCoord, _MainTex); | |
vertexOutput.NormalDir = normalize(mul(half4(vertexInput.Normal, 0.0), _World2Object).xyz); | |
vertexOutput.TangentDir = normalize(mul(_Object2World, vertexInput.Tangent).xyz); | |
vertexOutput.BinormalDir = normalize(cross(vertexOutput.NormalDir, vertexOutput.TangentDir) * vertexInput.Tangent.w); | |
vertexOutput.ViewDir = normalize(_WorldSpaceCameraPos.xyz - posWorld.xyz); | |
half3 vertexToLight = _WorldSpaceLightPos0.xyz - posWorld.xyz; | |
vertexOutput.LightDir = fixed4(normalize(lerp(_WorldSpaceLightPos0.xyz, vertexToLight, _WorldSpaceLightPos0.w)), | |
lerp(1.0, 1.0 / length(vertexToLight), _WorldSpaceLightPos0.w)); | |
return vertexOutput; | |
} | |
fixed4 ComputeFragment(VertexOutput vertexOutput) : SV_Target | |
{ | |
float2 grabTexCoord = vertexOutput.ScreenPos.xy / vertexOutput.ScreenPos.w; | |
grabTexCoord.x = (grabTexCoord.x + 1.0) * .5; | |
grabTexCoord.y = (grabTexCoord.y + 1.0) * .5; | |
#if UNITY_UV_STARTS_AT_TOP | |
grabTexCoord.y = 1.0 - grabTexCoord.y; | |
#endif | |
fixed4 grabColor = tex2D(_GrabTexture, grabTexCoord); | |
fixed4 normalColor = tex2D(_NormalMap, vertexOutput.TexCoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw); | |
fixed3 localNormal = fixed3(2.0 * normalColor.ag - fixed2(1.0, 1.0), _BumpDepth); | |
fixed3x3 localToWorld = fixed3x3(vertexOutput.TangentDir, vertexOutput.BinormalDir, vertexOutput.NormalDir); | |
fixed3 normalDirection = normalize(mul(localNormal, localToWorld)); | |
fixed3 lightColor = vertexOutput.LightDir.w * _LightColor0.xyz * saturate(dot(normalDirection, vertexOutput.LightDir.xyz)); | |
fixed lightPower = dot(lightColor, float3(0.3, 0.59, 0.11)); | |
fixed4 texColor = tex2D(_MainTex, vertexOutput.TexCoord) * _Color; | |
#include "../BlendOps.cginc" | |
return lerp(fixed4(0, 0, 0, 0), blendResult, lightPower); | |
} | |
ENDCG | |
} | |
} | |
FallBack "Diffuse" | |
CustomEditor "BmMaterialEditor" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment