Using stencil buffer to make windows - unity3d

I would like to create windows in different walls and I want it to be dynamic so I do not want to change geometry of the wall because I want to be able to move the window. So I want to use stencil shader. I am new to shaders, but I have found some things already and I have come up with this:
Shader I use for Windows:
Shader "Custom/Window" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_StencilVal ("stencilVal", Int) = 1
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
ZWrite Off
ColorMask 0
Pass {
Stencil {
Ref [_StencilVal]
Comp NotEqual
Pass replace
}
}
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Shader I use for walls:
Shader "Custom/Rest" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Color ("Color", Color) = (1, 0, 0, 1)
_StencilVal ("stencilVal", Int) = 1
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Stencil {
Ref [_StencilVal]
Comp NotEqual
}
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
uniform fixed4 _Color;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
I set _StencilVal from script so that every wall has its own unique value and I have achieved pretty good result but the problem is that I can not look through two (or more) windows at the same time. When they overlap in the view the second window is grey (it is not seethrough) but I can still look through the first window.

Related

Unity surface shader not casting shadows on itself

I'm new to shaders and I'm trying to make a shader for some very simple low poly water. I have created this simple surface shader that changes the vertex heights.
The problem is that it doesn't receive shadows as you can see in the gif and there is a weird behavior on the edges.
What am I doing wrong?
Shader "Ramble/LowPolyWater" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_Color ("Main Color", Color) = (1,1,1,1)
_Emission ("Emission", Color) = (1,1,1,1)
_ScrollYSpeed("Scroll y speed", Float) = 0.1
}
SubShader {
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Lambert vertex:vert
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
fixed4 _Color;
fixed4 _Emission;
float _ScrollYSpeed;
void vert (inout appdata_full v)
{
v.vertex.z += frac(sin( dot(v.vertex.xyz ,float3(12.9898,78.233,45.5432) )) * 43758.5453) * sin(_Time.y) * _ScrollYSpeed;
}
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = (tex2D (_MainTex, IN.uv_MainTex) * _Color).rgb;
o.Emission = _Emission.rgb;
}
ENDCG
}
Fallback "VertexLit"
}
Figured it out!
I just need to add addshadow to this line #pragma surface surf Lambert vertex:vert addshadow

In Unity Shaderlab, how can you animate towards a value using lerp and deltaTime

How can a Custom Standard Surface Shader be used to animate a value towards a target value?
For Example:
...
float targetAlpha; //Set by the property block, or a C# script
float currrentAlpha; //Used internally only.
void surf (Input IN, inout SurfaceOutputStandard o)
{
currrentAlpha = lerp(currrentAlpha, targetAlpha, unity_DeltaTime.x);
o.Alpha = currrentAlpha;
}
This code does not work but should demonstrate what the goal is: when targetAlpha is set, the shader will fade towards that value.
There are few ways this can be done. One of them is using built-in shader variables:
Shader "Custom/Test" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_TargetAlpha ("TargetAlpha", Range(0, 1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows alpha:fade
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Alpha;
fixed4 _Color;
half _TargetAlpha;
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = lerp(o.Alpha, _TargetAlpha, clamp(_SinTime.w, 0, 1));
}
ENDCG
}
FallBack "Diffuse"
}
The shader in the answer above still works in Unity 2018.2. However, _SinTime oscillates between -1 and 1, while we want the range to be between 0 and 1. The code clamp(_SinTime.w, 0, 1) clamps onto the desired values, however the alpha stays at zero too long. So we need the absolute value, like so: abs(_SinTime.w).
The modified shader:
Shader "Custom/Test" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_TargetAlpha ("TargetAlpha", Range(0, 1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows alpha:fade
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Alpha;
fixed4 _Color;
half _TargetAlpha;
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = lerp(o.Alpha, _TargetAlpha, abs(_SinTime.w));
}
ENDCG
}
FallBack "Diffuse"
}

unity custom shader not receiving Shadow

Shader "Custom/1_displayImageOnSlide" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_CutoffX("CutoffX", Range(0.0,1.0)) = 1
_CutoffY("CutoffY", Range(0.0,1.0)) = 1
}
Category {
Cull off
Blend SrcAlpha OneMinusSrcAlpha
Lighting Off
Fog { Mode Off }
SubShader {
// Tags {"LighMode"="ForwardBase"}
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
//UsePass "VertexLit/SHADOWCOLLECTOR"
//UsePass "VertexLit/SHADOWCASTER"
CGPROGRAM
#pragma surface surf Unlit
//#pragma surface surf Lambert
// Inside CGPROGRAM block.
half4 LightingUnlit (SurfaceOutput s, half3 lightDir, half atten) {
half4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
float4 color : Color;
};
fixed _CutoffX;
fixed _CutoffY;
void surf (Input IN, inout SurfaceOutput o) {
half4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = IN.color.rgb * tex.rgb;
o.Alpha = IN.uv_MainTex.x > _CutoffX ? 0 : IN.uv_MainTex.y > _CutoffY ? 0 : IN.color.a*tex.a;
}
ENDCG
}//sub Shader End
}//Categoy End
FallBack "VertexLit" // Use VertexLit's shadow caster/receiver passes.
}
This is the code of my shader file and it is applied to a cube object. The problem is, shader is casting correctly by cube but cube is not receiving shader. Whats wrong in it? I don't have enough knowledge about shader programming so it is requested to share you answer with description

Outline Shader in Unity3d

I'm trying to configure this shader I got from the net to have a white outline not a black one. but the "_OutlineColor ("Outline Color", Color) = (1,1,1,1)" doesnt work.
I'm new to unity and how things work in it so I hope you can help me.
here is the complete shader:
Shader "Outlined/Diffuse" {
Properties {
_Color ("Main Color", Color) = (0,0,0,0)
_OutlineColor ("Outline Color", Color) = (1,1,1,1)
_Outline ("Outline width", Range (.002, 0.03)) = 5
_MainTex ("Base (RGB)", 2D) = "white" { }
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 pos : POSITION;
float4 color : COLOR;
};
uniform float _Outline;
uniform float4 _OutlineColor;
v2f vert(appdata v) {
// just make a copy of incoming vertex data but scaled according to normal direction
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
float2 offset = TransformViewToProjection(norm.xy);
o.pos.xy += offset * o.pos.z * _Outline;
o.color = _OutlineColor;
return o;
}
ENDCG
SubShader {
//Tags {"Queue" = "Geometry+100" }
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
fixed4 _Color;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
// note that a vertex shader is specified here but its using the one above
Pass {
Name "OUTLINE"
Tags { "LightMode" = "Always" }
Cull Front
ZWrite On
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
//Offset 50,50
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 frag(v2f i) :COLOR { return i.color; }
ENDCG
}
}
SubShader {
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
fixed4 _Color;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
Pass {
Name "OUTLINE"
Tags { "LightMode" = "Always" }
Cull Front
ZWrite On
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma exclude_renderers gles xbox360 ps3
ENDCG
SetTexture [_MainTex] { combine primary }
}
}
Fallback "Diffuse"
}
The "(1,1,1,1)" you are assigning to "_OutlineColor" describes a default value. That value is taken into consideration when you create new material that utilises that shader (here "Outlined/Diffuse"). Just create new material and assign to it your shader. You will notice that the Outline color this time will be white. Also you can simply select your material in the Editor and change the outline colour via inspector window.
As for your problem - probably you've created a new material combined with the shader you describe, BEFORE you made a change in the shader's body from black (0,0,0,1) to white (1,1,1,1) colour (I recognize the body of the shader, so I assume the black color). And what that means is that the default black colour has already been assigned to the material. If you want to change the colour, as I wrote above, do it on the material through the Editor's inspector.

Unity 3D multiple UV sets

I have created an object that has the texture and an AO , they are on different UV sets in maya(with Layered Texture) and in maya the mash looks ok.
How do i achive the same effect in Unity3D?
I can not make unity use the 2nd UV set.
You'll need to write a shader that does this. Here's a very minimal example, but you'd probably need to have a more elaborate setup for things specular, etc.
Shader "Custom/twotex" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_AoTex ("AO (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
sampler2D _AoTex;
struct Input {
float2 uv_MainTex : TEXCOORD0;
float2 uv_AoTex : TEXCOORD1;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex.xy);
half4 ao = tex2D (_AoTex, IN.uv_AoTex.xy);
o.Albedo = c.rgb * ao.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}