How do I adjust shader tint based on normal/face orientation?
Using a very handy shader reference from http://answers.unity3d.com/answers/882217/view.html, I adapted the solution to be used with flat shading/colours. I am new to shaders, so the solution is likely far from optimal, but available below.
This gets me mostly to the effect I am after, but as this shader is used on mesh that has faces strictly orient flat or vertical (like stairs), I have been trying to apply a darker tint to the vertical faces to achieve a pseudo-shadow effect.
I have struggled to learn how shaders can adapt to face orientation, and failed attempts result in an "invalid" pink shader that I'm failing to resolve. Any help is much appreciated, thank you.
Shader "TintedHeight" {
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_HeightMin ("Height Min", Float) = -1
_HeightMax ("Height Max", Float) = 1
_ColorMin ("Tint Color At Min", Color) = (0,0,0,1)
_ColorMax ("Tint Color At Max", Color) = (1,1,1,1)
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _HeightMax;
float _HeightMin;
fixed4 _ColorMin;
fixed4 _ColorMax;
struct Input
{
float3 worldPos;
};
struct v2f {
float4 pos : SV_POSITION;
fixed3 color : COLOR0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float3 worldPos = mul (unity_ObjectToWorld, v.vertex).xyz;
float h = (_HeightMax - worldPos.y) / (_HeightMax - _HeightMin);
o.color = lerp (_ColorMax.rgba, _ColorMin.rgba, h);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4 (i.color, 1);
}
ENDCG
}
}
}
Answer by Glurth · Jul 31, 2016 at 04:30 PM
I see that you are using the vertex position in your computation. This will adjust the color based upon the vertex location, rather than the face's direction. I suspect you want to use v.normal, which is a vector that defines the direction the face is pointing.
This page has an example, scroll down a bit to the "visualizing normals" section. https://docs.unity3d.com/Manual/SL-VertexProgramInputs.html
Thank you for your suggestion, after investigation (and also referring to another question: http://answers.unity3d.com/questions/170589/shader-actual-view-directionnormal.html), my v2f
solution had some adjustments using:
float3 viewN = mul ((float3x3)UNITY_$$anonymous$$ATRIX_IT_$$anonymous$$V, v.normal);
// Shade the vertical normals
o.color = lerp (o.color.rgba, _ColorShadow.rgba, (1 - viewN.y) * 0.18f);
// Curved shading
o.color = lerp (o.color.rgba, _ColorShadow.rgba, viewN.x * 0.1f);
I would like to know if this can be turned into a screen space camera shader and how, so the camera automaticly renders all it gets like this surface shader.
As an example, that will come in handy for a $$anonymous$$imap where the $$anonymous$$imap camera renders with height lerping as screen space effect and the environment that is rendered by the main camera should stay just like it is.
Hope anyone understand what I mean and thanks in advance.
@Noxury :were you able to apply the same concept in $$anonymous$$imap?
Your answer
Follow this Question
Related Questions
How to affect Shader _Color by the Tint Color of Button (Through Shader) 0 Answers
Standard shader or mobile/legacy shader for better performance on mobile? 0 Answers
Need help with projector shader 4 Answers
Is it possible to have a grid shader with gradient lines? (Without external assets) 0 Answers