In a space exploration game I’m developing, I’m experimenting with putting a plane directly in front of the camera, so it occupies the entire screen. I intend to use it for full screen effects (lens flaring and ‘speed particles’, etc). If that’s not standard, please just bear with me.
I have a lens flare effect working in my custom sky box shader, but obviously in-game objects will obscure the effect.
What’s weird is, the calculations I make in that shader - to get both the screen coordinates of the in-game light and the current fragment - don’t seem to be working in the shader for my full-screen plane. Here’s a stripped-back version of the new screen effects shader:
-
Shader “Custom/screen effects”
-
{
-
Properties
-
{
-
_sunDirection (“Sun Direction”, Vector) = (0, 1, 0, 0)
-
_sunRadius (“Sun Radius”, float) = 1000000
-
_starColour (“Star Colour”, Color) = (0.75, 0.6, 0.4, 1)
-
_sunVisibility (“Sun Visibility”, float) = 1
-
}
-
Category {
-
Tags { “Queue”=“Transparent” “IgnoreProjector”=“True” “RenderType”=“Transparent” “PreviewType”=“Plane” }
-
Blend SrcAlpha OneMinusSrcAlpha
-
SubShader
-
{
-
Pass
-
{
-
Fog { Mode Off }
-
CGPROGRAM
-
#pragma vertex vert
-
#pragma fragment frag
-
#include “UnityCG.cginc”
-
- float4 _sunDirection;
-
float4 _starColour;
-
float _sunRadius;
-
float _sunVisibility;
-
half4 color;
-
- struct vInput
-
{
-
half4 vertex : POSITION;
-
};
-
-
- struct v2f
-
-
{
-
half4 sunWorldPos : SV_POSITION;
-
float3 worldPos : TEXCOORD0;
-
float4 sunScreenPos : TEXCOORD1;
-
float4 vertScreenPos : TEXCOORD2;
-
};
-
-
- v2f vert(vInput input)
-
-
{
-
v2f output;
-
output.sunWorldPos = mul(UNITY_MATRIX_MVP, _sunDirection); // <<< unused in this shader so far
-
output.worldPos = mul(unity_ObjectToWorld, input.vertex).xyz;
-
// it’s the following four calculations that I’d like confirmed are correct
-
output.sunScreenPos = mul(UNITY_MATRIX_MVP, _sunDirection);
-
output.sunScreenPos = ComputeScreenPos(output.sunScreenPos);
-
output.vertScreenPos = mul(UNITY_MATRIX_MVP, input.vertex);
-
output.vertScreenPos = ComputeScreenPos(output.vertScreenPos);
-
return output;
-
}
-
-
- half4 frag(v2f input) : COLOR
-
-
{
-
float3 viewDir = UNITY_MATRIX_IT_MV[2].xyz;
-
float sunDP = saturate(dot(normalize(input.worldPos), normalize(_sunDirection)));
-
- // positive-only dot product of player view direction and sun direction
-
float sunCameraDP = saturate(dot(normalize(-viewDir), normalize(_sunDirection)));
-
- float sunDistance = length(_sunDirection);
-
float sunSize = atan((_sunRadius * 0.5) / sunDistance) * 0.63662; // multiplied to convert from 0-(PI/2) range to 0-1 range
-
if (sunSize<0.0001) {
-
sunSize = 0.0001;
-
}
-
- float sunCameraDPLines = pow(sunCameraDP, 32) * saturate(sunSize * 1000);
-
- // exaggerate camera/sun dot product
-
sunCameraDP = ( sunCameraDP / ((1 - saturate(sunCameraDP)) + 0.1) );
-
sunCameraDP = sunCameraDP * pow((sunDP + sunSize), 4);
-
- // convert screen coords so 0,0 is screen centre
-
input.sunScreenPos.xy /= input.sunScreenPos.w;
-
input.vertScreenPos.xy /= input.vertScreenPos.w;
-
input.sunScreenPos.x -= 0.5;
-
input.sunScreenPos.y -= 0.5;
-
input.vertScreenPos.x -= 0.5;
-
input.vertScreenPos.y -= 0.5;
-
- // account for non-square (16/9) screen dimensions
-
input.sunScreenPos.x = input.sunScreenPos.x * 1.777;
-
input.vertScreenPos.x = input.vertScreenPos.x * 1.777;
-
- float angle = atan2(input.sunScreenPos.y - input.vertScreenPos.y, input.sunScreenPos.x - input.vertScreenPos.x);
-
- color = angle; // this is just a temporary test to see if angle is being calculated correctly - nothing displays when just this option is used
-
- // alternatively, I have also tried using the following values, which I would expect to be blue at the bottom left, purple at top left, blue/green at bottom right and white at top right - unfortunately it displays nothing
-
//color.r = input.sunScreenPos.x;
-
//color.g = input.sunScreenPos.y;
-
//color.b = 1;
-
- //color = sunDP; // this correctly displays a gradated ‘glowing’ area in the direction of the light source
-
return color;
-
- }
-
- ENDCG
-
}
-
}
-
- FallBack off
-
}
-
}
I’d like to know if there’s something wrong about how I’m calculating the screen coordinates of the ‘star’ and the current fragment, in the ‘v2f vert’ function. And, if that’s correct - as the answers to the following question seem to imply…
…why doesn’t it work?
Thanks.