1
0
mirror of https://github.com/AcChosen/VR-Stage-Lighting.git synced 2025-02-25 21:58:09 +01:00

Updated VRSL DMX: Creating Custom DMX Shaders (markdown)

AcChosen 2023-02-17 06:41:41 -05:00
parent 8595ead2fb
commit add8958d67

@ -11,6 +11,122 @@ VRSL DMX works similarly to audiolink in that there is a single CGINC file that
This file contains a few instanced defined properties, standard defined properties, and some functions needed to read DMX from the grid node. Once you have this file in, there are some properties you may want to define first before you get started writing.
## Example Code
It is recommended, if possible, to get the DMX data in the vertex shader rather than the fragment shader. This is because since there is no UV mapping involved when sampling, it is generally faster to sample the data in the vertex shader and send it to the fragment shader through the v2f struct. (If it's not possible, all of the functions will still work in the fragment shader as normal).
In this example, we created a custom parameter in the v2f struct with `float4 finalColor : TEXCOORD1;`, which simply stores the final emission color of our DMX shader. We then use `isDMX()` to determine if we are using DMX at runtime, and adjust the final output of `finalColor` with dmx data accordingly.
```hlsl
Shader "Unlit/VRSL-TutorialV2"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[Toggle] _EnableDMX ("Enable Stream DMX/DMX Control", Int) = 0
[Toggle] _NineUniverseMode ("Extended Universe Mode", Int) = 0
[Toggle] _EnableVerticalMode ("Enable Vertical Mode", Int) = 0
[Toggle] _EnableCompatibilityMode ("Enable Compatibility Mode", Int) = 0
[Toggle] _EnableStrobe ("Enable Strobe", Int) = 0
[Header(Base Properties)]
[HDR] _Emission ("Base DMX Emission Color", Color) = (1,1,1,1)
_GlobalIntensity ("Global Intensity", Range(0,1)) = 1
_FinalIntensity ("Final Intensity", Range(0,1)) = 1
// Use this for World Shaders
_DMXChannel ("Starting DMX Channel", Int) = 1 //raw dmx channel
//Use these for Avatar Shaders
// _Channel ("DMX Channel", Int) = 1
// _Universe ("DMX Universe", Int) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
nointerpolation float4 finalColor : TEXCOORD1; //final output color from DMX
};
//Main CGINC File
#include "Packages/com.acchosen.vr-stage-lighting/Runtime/Shaders/VRSLDMX.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
int _Channel, _Universe;
//Channel Mappings
//intensity = ch1
//rgb = ch2, ch3, ch4
//strobe = ch5
//always read DMX data from the vertex shader
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
//Use this for Avatar Shaders
//int dmx = ConvertToRawDMXChannel(_Channel, _Universe);
//Use this for World Shaders
int dmx = GetDMXChannel();
float intensity = ReadDMX(dmx, _Udon_DMXGridRenderTexture); // 0-1
float4 color = GetDMXColor(dmx+1);
float strobe = GetStrobeOutput(dmx + 4);
o.finalColor = (intensity * color) * strobe;
o.finalColor = isDMX() ? o.finalColor : getBaseEmission();
o.finalColor *= getGlobalIntensity() * getFinalIntensity();
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture, multiply by dmx final output.
fixed4 col = tex2D(_MainTex, i.uv) * i.finalColor;
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
```
This way, our fragment shader only needs to grab `i.finalColor` to get the final output of our DMX color.
You do not need to only send color data, you can also send the dmx data values themselves if needed through the same method.
## The Main Properties
These two are the two properties most important:
@ -29,21 +145,6 @@ These two are the two properties most important:
These two properties are required for all world-based DMX shaders (for now).
## Example Code
It is recommended, if possible, to get the DMX data in the vertex shader rather than the fragment shader. This is because since there is no UV mapping involved when sampling, it is generally faster to sample the data in the vertex shader and send it to the fragment shader through the v2f struct. (If its not possible, all of the functions will still work in the fragment shader as normal).
Here is an example:
In this example, we created a custom parameter in the v2f struct with `float4 finalColor : TEXCOORD1;`, which simply stores the final emission color of our DMX shader. We then use `isDMX()` to determine if we are using DMX at runtime, and adjust the final output of `finalColor` with dmx data accordingly.
This way, our fragment shader only needs to grab `i.finalColor` to get the final output of our DMX color.
You do not need to only send color data, you can also send the dmx data values themselves if needed through the same method.
## The Extra Properties