Cleaned up and commented version.

This commit is contained in:
Thorbjoern
2025-10-02 00:07:11 +02:00
parent 2b86d9f0a2
commit 4c613c3436
66 changed files with 260 additions and 1020 deletions
@@ -0,0 +1,25 @@
using UnityEngine;
public class GazeDirection : MonoBehaviour
{
[Header("Head and Eye-Transforms")]
public Transform headcam;
public Transform eyeLeft;
public Transform eyeRight;
[Header("Renderer Feature")]
public GazeOverlayRendererFeature overlayRendererFeature;
GazeOverlayRendererFeature.GazeRenderPass pass;
private void Awake()
{
pass = overlayRendererFeature.GetPass();
}
private void LateUpdate()
{
pass.gazeOrigin = (eyeLeft.position + eyeRight.position) * 0.5f; // Mittelpunkt zwischen den Augen
pass.gazeDirection = ((eyeLeft.forward + eyeRight.forward) * 0.5f).normalized; // Errechnete mittlere Blickrichtung
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 318f8ae78f0375c4db5613429c9ef197
@@ -0,0 +1,84 @@
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;
// Render Feature, das den Sichtkegel mit fovealem und peripherem Bereich darstellt und pro Kamera aktiviert werden kann.
public class GazeOverlayRendererFeature : ScriptableRendererFeature
{
public sealed class GazeRenderPass : ScriptableRenderPass
{
internal Vector3 gazeOrigin;
internal Vector3 gazeDirection;
internal float foveaHalfRad = Mathf.Deg2Rad * 2.5f; // für 5° fovealer Bereich
internal float periHalfRad = Mathf.Deg2Rad * 10f; // für 20° peripheren Bereich
static readonly int gazeOriginID = Shader.PropertyToID("_GazeOrigin");
static readonly int gazeDirectionID = Shader.PropertyToID("_GazeDirection");
static readonly int foveaHalfRadID = Shader.PropertyToID("_FoveaAngle");
static readonly int periHalfRadID = Shader.PropertyToID("_PeriAngle");
readonly Material gazeMaterial;
public GazeRenderPass(Material material) => gazeMaterial = material;
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
Debug.Log("RecordRenderGraph");
var resourceData = frameData.Get<UniversalResourceData>();
TextureHandle depth = resourceData.activeDepthTexture;
TextureHandle color = resourceData.activeColorTexture;
using var builder = renderGraph.AddRasterRenderPass<PassData>("GazeOverlay", out var passData);
passData.depth = depth;
passData.color = color;
passData.gazeMaterial = gazeMaterial;
passData.gazeOrigin = gazeOrigin;
passData.gazeDirection = gazeDirection;
passData.foveaHalfRad = foveaHalfRad;
passData.periHalfRad = periHalfRad;
builder.UseTexture(depth, AccessFlags.Read);
builder.UseTexture(color, AccessFlags.ReadWrite);
builder.SetRenderAttachment(color, 0);
builder.SetRenderFunc((PassData data, RasterGraphContext ctx) =>
{
ctx.cmd.ClearRenderTarget(RTClearFlags.Color, new Color(1, 0, 1, 1), 1.0f, 0);
//ctx.cmd.SetGlobalVector(gazeOriginID, data.gazeOrigin);
//ctx.cmd.SetGlobalVector(gazeDirectionID, data.gazeDirection);
//ctx.cmd.SetGlobalFloat(foveaHalfRadID, data.foveaHalfRad);
//ctx.cmd.SetGlobalFloat(periHalfRadID, data.periHalfRad);
//Blitter.BlitTexture(ctx.cmd, data.depth, new Vector4(1, 1, 0, 0),
//data.gazeMaterial, 0);
});
}
class PassData
{
internal TextureHandle depth;
internal TextureHandle color;
internal Material gazeMaterial;
internal Vector3 gazeOrigin, gazeDirection;
internal float foveaHalfRad, periHalfRad;
}
}
[SerializeField] Material gazeOverlayMaterial;
GazeRenderPass pass;
public GazeRenderPass GetPass() { return pass; }
public override void Create()
{
pass = new GazeRenderPass(gazeOverlayMaterial);
Debug.Log("Feature created");
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(pass);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0d63223eecd1d7e4dbb01821c5a37dbd
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 44a39c1f66022ab4e9d01650f2c52d08
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,40 @@
Shader "Hidden/GazeOverlay"
{
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
pass
{
Name "GazeOverlayPass"
ZTest Always
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma vertex VertFullScreenTriangle
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
Varyings VertFullScreenTriangle (uint vertexID : SV_VERTEXID)
{
Varyings o;
o.positionHCS = GetFullScreenTriangleVertexPosition(vertexID);
o.texcoord = GetFullScreenTriangleTexCoord(vertexID);
return o;
}
#include "GazeOverlayPass.hlsl"
ENDHLSL
}
}
FallBack Off
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 777cec444743bc44b817fad6d93d915b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,42 @@
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
TEXTURE2D_X(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
float3 _GazeOrigin;
float3 _GazeDirection;
float _FoveaAngle;
float _PeriAngle;
float4 _FoveaColor = float4(0,1,0,0.25);
float4 _periColor = float4(1,0,0,0.18);
float4 _BlockedCol = float4(0.3,0.3,0.3,0.22);
half4 frag (Varyings input) : SV_Target
{
return float4(1, 0, 1, 0.5);
// Nimmt die Depth Texture und rekonstruiert daraus die World Position
//float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, input.texcoord).r;
//float4 clip = float4(input.texcoord * 2 - 1, depth, 1);
//float4 view = mul(UNITY_MATRIX_I_P, clip); view /= view.w;
//float3 world = mul(UNITY_MATRIX_I_V, view).xyz;
// Eryeugt einen Vektor vom Origin zum gewünschten Pixel
//float3 v = normalize(world - _GazeOrigin);
//float cosAng = dot(v, normalize(_GazeOrigin));
// Berechnung Cosinus
//float cosF = cos(_FoveaAngle);
//float cosP = cos(_PeriAngle);
//float4 col;
//if (cosAng >= cosF) col = _FoveaColor;
//else if (cosAng >= cosP) col = _periColor;
//else discard;
//uint gLayer = 8;
//if (unity_RenderingLayer.x & (1u << gLayer))
//col = _BlockedCol;
//return col;
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: da1b9d6b6b4c65941be255287d846932
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: