Im pretty new to scripting shaders and i was trying to make a unlit shader work so it generates an outline around the object and lets me interpolate between 2 diferent textures, but I get 3 errors:
·Shader error in 'Unlit/Both': Duplicate system value semantic definition: output semantic 'POSITION' and output semantic 'SV_POSITION' at line 38
·Shader error in 'Unlit/Both': Duplicate system value semantic definition: input semantic 'SV_POSITION' and input semantic 'POSITION' at line 39
·Shader error in 'Unlit/Both': Duplicate system value semantic definition: output semantic 'SV_POSITION' and output semantic 'POSITION' at line 39
I guess there is something wrong with the position values but i have no idea about what to do so if anyone knows how to fix it i would be so thankful
{
Properties
{
_Color("Main Color", Color) = (0.5,0.5,0.5,1)
_MainTex ("Texture", 2D) = "white" {}
_SecondaryTex ("2nd Texture", 2D) = "white" {}
_LerpValue("Transition float", Range(0,1))= 0.5
_OutlineColor("Outline color", color) = (0,0,0,1)
_OutlineWidth("Outline width", Range(1.0,5.0)) = 1.01
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 pos : POSITION;
float3 normal : NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _SecondaryTex;
float4 _SecondaryTex_ST;
float4 _LerpValue;
float _OutlineWidth;
float4 _OutlineColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
v.vertex.xyz *= _OutlineWidth;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = lerp(tex2D(_MainTex, i.uv), tex2D(_SecondaryTex, i.uv),_LerpValue);
return col;
}
ENDCG
}
}
SubShader
{
Tags{"Queue" = "Transparent"}
Pass//Render the Outline
{
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 frag(v2f i) : COLOR
{
return _OutlineColor;
}
ENDCG
}
Pass//Normal render
{
ZWrite On
Material
{
Diffuse[_Color]
Ambient[_Color]
}
Lighting On
SetTexture[_MainTex]
{
ConstantColor[_Color]
}
SetTexture[_MainTex]
{
Combine previous * primary DOUBLE
}
}
}
}
When you want to pass data from vertex shader to pixel shader you need to use TEXCOORD as semantic, in this case, you should change the 'POSITION' semantic with 'TEXCOORD2'(in v2f struct).
Semantics will specify what data you are passing(actually how to
interpret data). The first stage in the pipeline is IA(Input
Assembler) when you pass data from IA to vertex shader you use
semantic to know which property you are using, for example, in your 'appdata' struct, vertex is POSITION so when the data(like geometry,3d objects) is passed to the IA stage you need to know which data you are using in the GPU so by using semantic you can easily find the properties of each object(each object must have position and it's better to have normal, tangent, color,....)
Related
I'm trying to archieve a chilindrical effect like this on Unity3D:
But every solution is using material based shader, sadly I must have a Post Process effect or an Image Effect, for these reasons:
One map out of 30 needs to use this effect and there are many materials that are shared between them...
Every solution is vertex based. I've done some experiments but I have models with different polygon count, this means that the effect would create visual artifacts (but this can by fixed by editing the 3d models eventually).
I'm at an advanced stage of development.
Do you think it's possible to create a simple effect (even a fake one) that moves the pixels downwards/upwards based on the distance to the camera? (I assume I need to use the depth map)
I've tried very hard but I had no success, the effect doesn't do anything or just won't compile :(
This is the best I could come up with, the grayscale in the frag method is only to check if the shader is working, but once I define the Vert function the grayscale disappears and the shader does nothing.
Shader "Hidden/Custom/WorldCurvature"
{
HLSLINCLUDE
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
float _Bend;
struct Attributes
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
float4 Frag(Varyings i) : SV_Target
{
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
float luminance = dot(color.rgb, float3(0.2126729, 0.7151522, 0.0721750));
color.rgb = lerp(color.rgb, luminance.xxx, _Bend.xxx);
return color;
}
Varyings Vert(Attributes v)
{
Varyings o;
float4 vv = mul(unity_ObjectToWorld, v.vertex );
vv.xyz -= _WorldSpaceCameraPos.xyz;
vv = float4( 0.0f, (vv.x * vv.x) * - _Bend, 0.0f, 0.0f );
v.vertex += mul(unity_WorldToCamera, vv);
o.vertex = mul(unity_WorldToCamera, vv);
o.texcoord = v.texcoord;
return o;
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
}
}
I've done another experiment but I think it would only work in a 2D environment, here the image stops once I activate the image effect:
Shader "Hidden/Custom/CylinderImageEffect" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert( appdata_img v )
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord.xy;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target {
i.uv.x = 1 - acos(i.uv.x * 2 - 1) / 3.14159265;
return tex2D(_MainTex, i.uv);
}
ENDCG
}
}
}
I am developing a game where I want to visualize user path - showing also where track overlaps (with some darker color than normal "not overlapped" track). Long time ago I have found this answer where it was advised to use stencil to create two-pass shader. That day it was very helpful.
But lately I have met an additional requirement: I want to expose the path (part of mesh) which is inside some irregular area. For the rest of the path there are two options based on user choice in the runtime:
should be marked with any other different color (e.g. darker),
should be not visible at all.
I have found that answer as a suggestion to use stencil in another shader which will be put to some mesh to create a "mask". I made some adjustments and I ended up with those shaders:
Mask shader:
Shader "Custom/AreaValidator"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Geometry-1" }
ColorMask 0
ZWrite off
Stencil{
Ref 3
Comp always
Pass replace
}
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
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;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
And path shader:
Shader "Unlit/Path"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Stencil {
Ref 0
Comp Equal
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(0.545, 0.780, 0.341, 0.8);
return col;
}
ENDCG
}
Pass
{
Stencil {
Ref 3
Comp Equal
Pass IncrSat
Fail IncrSat
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(0.710, 0.859, 0.580, 1);
return col;
}
ENDCG
}
Pass
{
Stencil {
Ref 4
Comp Less
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(0.545, 0.780, 0.341, 0.8);
return col;
}
ENDCG
}
}
}
As you can see in mask shader I have:
Stencil{
Ref 3
Comp always
Pass replace
}
but in path shader I have 3 passes: for "outside validated area", "inside validated area - without overlaps", "inside validated area - overlapping".
1.
Stencil {
Ref 0
Comp Equal
}
2.
Stencil {
Ref 3
Comp Equal
Pass IncrSat
Fail IncrSat
}
3.
Stencil {
Ref 4
Comp Less
}
I do not fully understand how shaders are rendered - I am showing the solution which was the closest to my goal. In general it "works" in some simple cases:
here - all tracks visible (outside valid area color is darker like
during overlapping),
here - when I remove from shader code full section responsible for first pass the track outside area is removed - that is good,
but there are 3 major problems which I cannot solve.
First problem - "glitching/flickering" when 2 different meshes are overlapping:
Another problem- because stencil 2) is incrementing buffer in both pass/fail situations when user goes around few times then even outside "valid" area track will be rendered.
Third problem is that I do not know how switch between "visible outside track" and "not visible outside track" rendering options during runtime.
Summing up:
I would like to have a mesh:
which is rendered differently when it overlaps,
can be render only inside certain "masking" area,
user is able to show/hide mesh outside masking area dynamically, visible mesh outside has other color,
but I do not know how to achieve that without glitches and some weird artifacts.
Im pretty new to shader coding but I made this one by grouping 2 unlit shaders
When I try to make this shader, which is meant to create an outline and let me interpolate 2 textures unity tells me that there is this error: invalid subscript `vertex´ at line 61
Ive tried some things but i dont get this shader to work properly, if someone knows what do i have to do id be so thankful
Shader "Unlit/Combined"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_SecondaryTex("Secondary Texture", 2D) = "white" {}
_LerpValue("Transition float", Range(0,1)) = 0.5
_OutlineColor("Outline color", color) = (0,0,0,1)
_OutlineWidth("Outline width", Range(1.0,5.0)) = 1.01
}
SubShader
{
Tags { "RenderType" = "Opaque" "Queue" = "Transparent"}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
//float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 outvertex : SV_POSITION;
float4 pos : POSITION;
float3 normal : NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _SecondaryTex;
float4 _SecondaryTex_ST;
float _LerpValue;
float _OutlineWidth;
float4 _OutlineColor;
v2f vert(appdata v)
{
v2f o;
v.vertex.xyz *= _OutlineWidth;
o.outvertex = UnityObjectToClipPos(v.vertex);
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = lerp(tex2D(_MainTex, i.uv),tex2D(_SecondaryTex, i.uv), _LerpValue);
return col;
return _OutlineColor;
}
ENDCG
}
Pass//Normal render
{
ZWrite On
Material
{
Diffuse[_Color]
Ambient[_Color]
}
Lighting On
SetTexture[_MainTex]
{
ConstantColor[_Color]
}
SetTexture[_MainTex]
{
Combine previous * primary DOUBLE
}
}
}
}
The line that has a problem is line 61:
v.vertex.xyz *= _OutlineWidth;
If you look at the type that v is declared as, its declared as appdata:
v2f vert(appdata v)
If you look at the definition of appdata:
struct appdata
{
//float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
You'll see that it does not have a vertex property, only uv and normal.
So the line that's an issue should be changed to one of those, probably normal as you're trying to modify a 3-value property of it (and uv only has xy).
v.normal.xyz *= _OutlineWidth;
Alternatively you can modify appdata to have a vertex property by uncommenteing the commented out vertex:
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
Or by removing line 61, depending on what you're trying to do.
I want to merge the functionality of these two shaders for Unity.
First shader is main shader that adds a glitch hologram effect.
The Second shader is making a surface texture flimmer for added visual effect.
I am trying to merge my versions of the code, alternatively different passes that allows me to implement both features on same material, if possible.
I have tried shaderpass function, but cannot make it work.
Is it possible to do?
1st shadercode
Shader "Custom/Cool Hologram Original"
{
Properties
{
//This program takes an existing shader script and builds upon it, by adding the features :
//Tintcolor - allowing for manipulation of colors
//Transparency - Changing opaque in tags to transparency so that the model becomes transparent
//Properties allow defining public manipulative variables
_MainTex ("AlbedoTexture", 2D) = "white" {} //braces are useless leftover braces no longer needed according to Unity developer
_TintColor("Tint Color", Color) = (1,1,1,1) //Public variable appearing in inspector
_Transparency("Transparency", Range(0.0,0.5)) = 0.25
_CutoutTresh("Cutout Threshold", Range(0.0,1.0)) = 0.2
_Distance("Distance", Float) = 1
_Amplitude("Amplitude", Float) = 1
_Speed("Speed", Float) = 1
_Amount("Amount", Range(0.0,1.0)) = 1
}
//The actual shader program
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent" } //Added queue and transparent elements because order matters (see render order queu tag)
LOD 100 //LOD means level of details and used for when player is close or far away
ZWrite Off //This is related to culling and depth testing, controlling if something is written to depth buffer. Zwrite off is for transparent objects
Blend SrcAlpha OneMinusSrcAlpha //See blend factors in unity doc. It is about render order and how they should blend
Pass //A pass can be made for each type of situation, like Virtual Reality etc
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" //Shaders does not use inheritance, it has got monobehaviour instead, so it must be defined as #included
struct appdata //Structs are objects with 2 objects each. appdata is passed in to v2f vert as argument
{
float4 vertex : POSITION; //Variable with 4 floating point numbers x,y,z,w. POSITION is a semantic binding telling where it is to be used
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION; //SV_Position corresponds to screen position in Unity
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _TintColor;
float _Transparency;
float _CutoutThresh;
float _Distance;
float _Amplitude;
float _Speed;
float _Amount;
v2f vert (appdata v)
{
v2f o;
v.vertex.x += sin(_Time.y * _Speed + v.vertex.y * _Amplitude) * _Distance * _Amount; //Allows sinusoidal movement to vertices in object space b4 translation to clip
o.vertex = UnityObjectToClipPos(v.vertex); //See learnopengl.com to see 5 spaces: local space, world space, view space, clip space, screen space
o.uv = TRANSFORM_TEX(v.uv, _MainTex); //Taking uv data from model and data from maintexture (see the shader texture in inspector)
return o; //Returns struct after it has been build in coordinate system, it will then be passed to fragment function
}
fixed4 frag (v2f i) : SV_Target //Takes in v2f struct calling it i and then bind it to render target, which is frame buffer for screen
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv) + _TintColor; //fixed 4 col is color. Can be fixed rgbA for 3 colors and an alpha channel. tex2D reads in colors from maintex and struct data from i
col.a = _Transparency; //The colors are what actually drawed in this feature with tex3D
clip(col.r - _CutoutThresh); //Not drawing pixels with certain amount of red color
return col;
}
ENDCG
}
}
}
2nd shadercode
Shader "Custom/Offset 1"
{
Properties {
_MainTex ("Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (0, -3, 0, 0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
// Declare our new parameter here so it's visible to the CG shader
float4 _ScrollSpeeds;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Shift the uvs over time.
o.uv += _ScrollSpeeds * _Time.x;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
3rd shadercode
Shader "Custom/Combined"
{
Properties
{
_MainTex ("AlbedoTexture", 2D) = "white" {}
_HoloColor("Hologram Color", Color) = (1,1,1,1)
_Transparency("Transparency", Range(0.0,0.5)) = 0.25
_CutoutTresh("Cutout Threshold", Range(0.0,1.0)) = 0.2
_Distance("Distance", Float) = 1
_Amplitude("Amplitude", Float) = 1
_Speed("Speed", Float) = 1
_ScrollSpeeds("Scroll Speeds", vector) = (0,-3,0,0) //added from offset shader
_Amount("Amount", Range(0.0,1.0)) = 1
}
SubShader {
Tags {"Queue"="Transparent" "RenderType"="Transparent" }
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1) //added from offset shader
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _HoloColor;
float4 _ScrollSpeeds;
float _Transparency;
float _CutoutThresh;
float _Distance;
float _Amplitude;
float _Speed;
float _Amount;
v2f vert (appdata v)
{
v2f o;
v.vertex.x += sin(_Time.y * _Speed + v.vertex.y * _Amplitude) * _Distance * _Amount;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.uv += _ScrollSpeeds * _Time.x; //Added from offset shader
UNITY_TRANSFER_FOG(o,o.vertex); //added from offset shader
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv) + _HoloColor;
col.a = _Transparency;
clip(col.r - _CutoutThresh);
UNITY_APPLY_FOG(i.fogCoord, col); //Added from offset shader
return col;
}
ENDCG
}
}
Fallback "Diffuse"
}
I wrote the following Shader:
Shader "Custom/SimpleShader" {
Properties {
_MainTex("Base (RGB)", 2D) = "white" { }
}
SubShader {
Pass {
ZTest Always
Cull Off
ZWrite Off
/* LINE 16*/CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uvb : TEXCOORD1;
};
uniform sampler2D _MainTex;
uniform sampler2D _Texture0;
uniform fixed _Alpha0;
v2f vert(appdata_img v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord);
o.uvb = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
col.rgb += (tex2D(_Texture0, i.uvb).rgb * _Alpha0);
return col;
}
ENDCG
}
}
Fallback off
}
Unity tells me that there is a "Syntax Error" in line 16 (see mark). This happens, when I put this text into a string and give this string to the Material(string contents) constructor. However, when I put the text into a .shader file and import it in the normal way, the shader is accepted and does not produce an error.
This documentation concerning the Material(string contents) constructor (or rather its JavaScript counterpart) says that:
[...] Creating materials this way supports only simple shaders (fixed function ones). If you need a surface shader, or vertex/pixel shaders, you'll need to create shader asset in the editor and use that.
Thus, the answer is that fragment- and/or vertex-shaders are not supported this way.