Hey there,
I’m trying to get some shaders I wrote to work with Single Pass VR with URP. It works in Multi-Pass already and I’m happy with the result. I just can’t make it work with Single Pass…
I guess the problem I’m having here is that I cannot sample the UV correctly, I’ve tried a couple of things but it just won’t render in Single Pass on my Oculus Quest.
Shader "Unlit/SobelFilter"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType"="Opaque" }
LOD 200
Pass
{
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
CBUFFER_START(UnityPerMaterial)
half4 _MainTex_ST;
float2 _MainTex_TexelSize;
CBUFFER_END;
float _Intensity;
float _Weight;
float _Blend;
half4 _OutlineColor;
half4 _BackgroundColor;
float _Threshold;
float _SobelValue;
float _ShowGrayscale;
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
float2 UnityStereoScreenSpaceUVAdjust(float2 uv, float4 scaleAndOffset)
{
return uv.xy * scaleAndOffset.xy + scaleAndOffset.zw;
}
float intensity(float4 color){
return sqrt((color.x*color.x)+(color.y*color.y)+(color.z*color.z));
}
float sobel(float stepx, float stepy, float2 uv)
{
float tleft = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(-stepx, stepy)));
float left = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(-stepx, 0)));
float bleft = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(-stepx, -stepy)));
float top = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(0, stepy)));
float bottom = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(0, -stepy)));
float tright = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(stepx, stepy)));
float right = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(stepx, 0)));
float bright = intensity(SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + float2(stepx, -stepy)));
float x = (_SobelValue/2 * tleft) + (_SobelValue * left) + (_SobelValue/2 * bleft) - (_SobelValue/2 * tright) - (_SobelValue * right) - (_SobelValue/2 * bright);
float y = -(_SobelValue/2 * tleft) - (_SobelValue * top) - (_SobelValue/2 * tright) + (_SobelValue/2 * bleft) + (_SobelValue * bottom) + (_SobelValue/2 * bright);
float xlum = dot(x, float3(0.2126729, 0.7151522, 0.0721750));
float ylum = dot(y, float3(0.2126729, 0.7151522, 0.0721750));
float color = sqrt((xlum*xlum) + (ylum*ylum));
if(_ShowGrayscale == 1){
return color;
}
// Replacing all values bellow threshold to black and white above (greyscale to b&w)
if( color <= _Threshold ) { color = 0; }
else { color = 1; }
return color;
}
half4 applyColors(half4 s) {
// Replacing blacks with background color and whites with outline color
if (s.r == 0) {
s = _BackgroundColor;
} else if (s.r == 1) {
s = lerp(_BackgroundColor, _OutlineColor, _Intensity);
}
return s;
}
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv = input.uv;
return output;
}
half4 frag (Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
// Apply Sobel Filter
half4 s = sobel(_MainTex_TexelSize.x, _MainTex_TexelSize.y, UnityStereoScreenSpaceUVAdjust(input.uv, _MainTex_ST));
half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, UnityStereoScreenSpaceUVAdjust(input.uv, _MainTex_ST));
// Apply outline and background color
half4 r = applyColors(s);
if(_ShowGrayscale == 1){
return s;
}
// blending with normal texture and weight
r = lerp(r, r * color, _Blend);
r = lerp(color, r, _Weight);
return r;
}
#pragma vertex vert
#pragma fragment frag
ENDHLSL
}
}
FallBack "Diffuse"
}