- Home /
Volumetric Lighting Help
I am trying to make a custom solution for volumetric lighting. I have a camera set up on a spotlight which renders a depth texture. I then pass that depth texture and some other information about the light to an image effect shadow to actually draw the volumetric light. However, the light does not seem to be working properly. I am not using proper code to account for the spotlight's cookie and angle of view, but the light shafts are not working properly either.
Here's what happening (the volumetric fog is rendered, but light shafts are not):
Here is the code for my shader:
Shader "Hidden/VolumetricLightRenderer"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Shadowmap("Shadowmap", 2D) = "white" {}
_LightColor("Light Color", Color) = (1,1,1,1)
_ShadowmapPos("Shadowmap Pos", Vector) = (0,0,0)
_ShadowmapDir("Shadowmap Dir", Vector) = (0,0,1)
_ShadowmapNear("Shadowmap Near", Float) = 0.1
_ShadowmapFar("Shadowmap Far", Float) = 50
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#define SAMPLES 12
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 viewDir : TEXCOORD1;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.uv;
o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
return o;
}
sampler2D _MainTex;
sampler2D _Shadowmap;
fixed4 _LightColor;
fixed4 _ShadowmapPos;
fixed4 _ShadowmapDir;
fixed _ShadowmapNear;
fixed _ShadowmapFar;
float fract(float x) {
return x - floor(x);
}
// Source: http://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl
float rand(half2 co) {
return fract(sin(dot(co.xy, half2(12.9898,78.233))) * 43758.5453);
}
fixed3 calcVolumetric(fixed3 ori, fixed3 dir, float dist) {
half3 col = half3(0.,0.,0.);
float is = dist / 50.;
float vrs = dist / float(SAMPLES - 1);
float rs = rand(_ScreenParams.xy) + vrs;
half3 samplePos = ori + dir * rs;
for(int i = 0; i < SAMPLES; i++) {
half3 sampleDir = _ShadowmapDir;
float depthSample = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_Shadowmap, samplePos));
float fragmentDepth = _ShadowmapNear + (distance(_ShadowmapPos,samplePos) / _ShadowmapFar);
if(depthSample > fragmentDepth) {
col += _LightColor * is;
}
samplePos += dir * vrs;
}
return col;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed4 vol = fixed4(calcVolumetric(_WorldSpaceCameraPos, i.viewDir, 3.), 1.);
col -= vol * .5;
col += vol;
return col;
}
ENDCG
}
}
}
Anybody know what my issue is? Help would be greatly appreciated. My only guess is that I am not finding the depth of the sample properly, but I'm not sure. I'm pretty nooby with Shaderlab and I have never touched Cg/HLSL outside of Unity in my life :P
Thanks in advance!
Answer by Romejanic · Oct 18, 2016 at 01:59 AM
Don't worry guys! I think I know what the problem is. For anyone else wondering, you need to pass the worldToCamera matrix of your shadowmap camera to your shader, so you can transform the ray to shadow space and sample the depth properly.
Your answer
Follow this Question
Related Questions
Is it possible to increase the HDRP volumetric light quality? 1 Answer
Image Effect Scripts on a separate object from Camera 1 Answer
Unity Fog Problem 0 Answers
Why CYAN is default object color (with default materials & shaders) 0 Answers
cast shadow - export lightmap from 3ds max to unity 2 Answers