Skip to content

Instantly share code, notes, and snippets.

@elringus
Created October 31, 2016 21:18
Show Gist options
  • Save elringus/5b15dff785f802a1ca8f193022045e54 to your computer and use it in GitHub Desktop.
Save elringus/5b15dff785f802a1ca8f193022045e54 to your computer and use it in GitHub Desktop.
Shader for meshes, which responds to light by applying blend mode effect
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