Ein "Negative-Shader" ist mathematisch nicht sonderlich spannend. Gehen wir vom RGB-Farbraum mit einem Farbvektor \(v=\left(\begin{matrix}\mathrm{r}&\mathrm{g}&\mathrm{b}\end{matrix}\right)^T\) aus, musst Du zur Berechnung des entsprechend negativen Pendants lediglich jede Farbvektorkomponente von \(255\) abziehen, also
$$v'=\left(\begin{matrix}255\\255\\255\end{matrix}\right)-\left(\begin{matrix}\mathrm{r}\\\mathrm{g}\\\mathrm{b}\end{matrix}\right)=\left(\begin{matrix}255-\mathrm{r}\\255-\mathrm{g}\\255-\mathrm{b}\end{matrix}\right)$$Unity rechnet allerdings mit Werten bezogen auf \(1.0\), was sich durch eine Division durch \(255\) leicht umrechnen lässt (solltest Du mit Online-Tools experimentieren, die in \(\left\{x\in\mathbb{N}_0\mid 0\leq x\leq 255\right\}\) rechnen). Glücklicherweise liest Unity die Textur auch direkt mit diesen Werten ein, wodurch Du keine Umrechnung durchführen musst.
Eine mögliche Lösung für den Shader könnte so aussehen:
Shader "Negative" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
// Funktion zur Negation von Farbwerten
float4 negate (sampler2D tex, float2 uv) {
float4 texel = tex2D(tex, uv);
texel.x = 1.0 - texel.x;
texel.y = 1.0 - texel.y;
texel.z = 1.0 - texel.z;
return texel;
}
// Funktion, mit der die Bildverarbeitung durchgeführt wird.
float4 frag (v2f_img IN) : COLOR {
// Farbwertberechnung
float4 frag_color = negate(_MainTex, IN.uv);
return float4(frag_color.x, frag_color.y, frag_color.z, 1.0);
}
ENDCG
Pass {
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
ENDCG
}
}
FallBack Off
}
Dieser Code ist als .shader-Datei zu speichern und an ein benutzerdefiniertes Material zu binden. Das Material kann dann einem (Game-)Object zugewiesen werden. Mein Test liefert:
Ich habe mal für meine VR-Brille einen Kantendetektor (nach Laplace) in Unity geschrieben, der dann auch in Echtzeit den visuellen Input gerendert hat. Das sieht schon schick aus ;-) Da die Berechnung dafür weitaus komplexer ist, sollte das mit dem Negativeshader auch gehen. Willst Du das in Kombination mit VR nutzen oder einfach "nur" zur Modellierung?