#need help on a shader, happy to pay
1 messages · Page 1 of 1 (latest)
trying to mimmic WarpPerspective from opencv on the gpu. this is a function that - when provided a homography matrix - projects a source image onto a destination image. the homography matrix, notably, operates in pixel space of RGB values rather than UV space.
our current approach is not working 😦
Shader "XR/Reprojection"
{
Properties
{
_MainTex ("Main Texture", 2D) = "black" {}
_BlendTex ("Overlay Texture", 2D) = "black" {}
_BlendFactor ("Blend Factor", Range(0, 1)) = 0.5
_ImageWidth ("Image Width", Float) = 1920
_ImageHeight ("Image Height", Float) = 1080
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" "RenderPipeline"="UniversalPipeline" }
LOD 100
ZWrite Off
Cull Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
uint vertexID : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
TEXTURE2D(_BlendTex);
SAMPLER(sampler_BlendTex);
float4x4 _HomographyMatrix;
float _ImageWidth;
float _ImageHeight;
float _BlendFactor;
Varyings vert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
float2 uv = float2((input.vertexID << 1) & 2, input.vertexID & 2);
output.positionCS = float4(uv * 2 - 1, 0, 1);
output.uv = uv;
return output;
}
float4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
// Apply homography transformation
float3 frameCoordinate = float3(input.uv.x * _ImageWidth, input.uv.y * _ImageHeight, 1.0);
float3 trans = mul(_HomographyMatrix, frameCoordinate);
// Perform perspective division
float2 coords = trans.xy / trans.z;
// Convert back to UV space
coords = float2(coords.x / _ImageWidth, coords.y / _ImageHeight);
// Sample the texture if we're mapping within the image, otherwise set color to black
// Sample both textures
float4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
float4 blendColor = SAMPLE_TEXTURE2D(_BlendTex, sampler_BlendTex, coords);
// Blend the textures
float4 finalColor = lerp(mainColor, blendColor, _BlendFactor);
// Convert to grayscale (optional)
float gray = dot(finalColor.rgb, float3(0.299, 0.587, 0.114));
finalColor.rgb = float3(gray, gray, gray);
finalColor.a = 1.0; // Set alpha to 1
return finalColor;
}
ENDHLSL
}
}
}