I’ve tried to make it work with the decal shader i use:
But the thing is that im a noob when it comes to shaders
I’ve tried to make it work with the decal shader i use:
But the thing is that im a noob when it comes to shaders
I am a shader noob too so really not sure if this is the best way to do it, but…
it seemed like it might be tricky to make an unlit shader using surface shaders? Tried using a fragment shader instead
(preview image of surface vs fragment)
I noticed that the fragment one oriented the decal texture differently from the shader one. No idea why… maybe i did something wrong in the code there :'D
Shader "Custom/DecalShaderTest2"
{
Properties
{
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
_DecalTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _DecalTex;
float4 _DecalTex_ST;
//standard 'appdata' function, but renamed to something less confusing
struct VertexInput
{
float4 vertex : POSITION;
float2 mainUv : TEXCOORD0;
float2 decalUv : TEXCOORD1;
};
//standard 'v2f' function, but renamed to something less confusing
struct VertexOutput
{
float4 vertex : SV_POSITION;
float2 mainUv : TEXCOORD0;
float2 decalUv : TEXCOORD1;
};
//take the vertex input, and
//process it into output that can be used by the frag function.
VertexOutput vert (VertexInput v)
{
VertexOutput o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.mainUv = v.mainUv;
o.decalUv = v.decalUv;
return o;
}
fixed4 frag (VertexOutput i) : SV_Target
{
fixed4 c = tex2D(_MainTex, i.mainUv * _MainTex_ST.xy + _MainTex_ST.zw);
half4 decal = tex2D(_DecalTex, i.decalUv * _DecalTex_ST.xy + _DecalTex_ST.zw);
c.rgb = lerp (c.rgb, decal.rgb, decal.a);
c *= _Color;
return c;
}
ENDCG
}
}
}
Lambert is not Unlit, Lambert in oversimplified terms is just lighting without the specular component. A full roughness material basically. A quick hack to make it Unlit is to output your color to o.Emission
(and maybe output black on the o.Albedo
). Emission is added on-top of the final results.
Likely the issue there is that in your VertexInput struct, you’ve bound decalUV
to TEXCOORD1
. This means it will grab the second UV channel of the mesh, which is a different UV layout (usually lightmap UVs), and thus the texture position/orientation will likely be different unless the two UV channels were matching.
The VertexInput
struct only needs to bind a single float2
to TEXCOORD0
so that you have access to the mesh’s first UV channel. There is no need to define a second input binding for sampling another texture, same goes for the VertexOutput
unless some sort of special manipulation needs to happen in the vertex shader for sampling the other texture which you want to pass the result to the fragment shader. Such as in the example of per-texture Offset/Scaling values being applied which you’ll see with the usage of the TRANSFORM_TEX(uv)
macro at times.
Both textures in this case can simply use the i.mainUv
. It has no relevance to the texture itself.
Oh cool-- sounds like using the surface shader set to ‘emissive’ instead of ‘lambert’ (and doing the albedo stuff for black) is probably the easiest way to go then, for OP. : )
And thanks!! I was fundamentally misunderstanding UV channel basics there – that was a succinct explanation that makes a lot of things make sense! Appreciate the breakdown!
OP has another better lead here, but i will edit this post to add a fixed-up version of the frag shader here later just for completeness’ sake lol.
ETA:
updated shader preview image: LINK
updated shader:
Shader "Custom/DecalShaderTest"
{
Properties
{
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
_DecalTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _DecalTex;
float4 _DecalTex_ST;
//standard 'appdata' function, but renamed to something less confusing
struct VertexInput
{
float4 vertex : POSITION;
float2 mainUv : TEXCOORD0;
};
//standard 'v2f' function, but renamed to something less confusing
struct VertexOutput
{
float4 vertex : SV_POSITION;
float2 mainUv : TEXCOORD0;
float2 decalUv : TEXCOORD1;
};
//take the vertex input, and
//convert vertex data into an output that can be used by the frag function.
//use the TRANSFORM_TEX macro to apply main texture's scale and offset values to the main UV, and decal texture's scale and offset values to the decal UV!
VertexOutput vert (VertexInput v)
{
VertexOutput o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.mainUv = TRANSFORM_TEX(v.mainUv, _MainTex);
o.decalUv = TRANSFORM_TEX(v.mainUv, _DecalTex);
return o;
}
fixed4 frag (VertexOutput i) : SV_Target
{
fixed4 c = tex2D(_MainTex, i.mainUv);
half4 decal = tex2D(_DecalTex, i.decalUv);
c.rgb = lerp (c.rgb, decal.rgb, decal.a);
c *= _Color;
return c;
}
ENDCG
}
}
}