I am trying to apply a raymarching shader to my Unity VR project. It is supposed to apply a shader to particles that represent a fluid using Smooth Particle Hydrodynamics. However, I am running into this error:
Compute shader (Raymarching): Property (_DepthTexture) at kernel index (0) is not set
UnityEngine.StackTraceUtility:ExtractStackTrace ()
FluidRayMarching:OnRenderImage (UnityEngine.RenderTexture,UnityEngine.RenderTexture) (at Assets/Scripts/FluidRayMarching.cs:90)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
And the Unity VR scene fails to start beyond the Unity Logo at the beginning.
In the Unity Game window, all I get is a black screen.

I am new to shaders and am still trying to learn but I am not making good sense of it. I appreciate any help with this.
Thank you.
This is the script that I have, called FluidRayMarching.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FluidRayMarching : MonoBehaviour
{
public ComputeShader raymarching;
public Camera cam;
List<ComputeBuffer> buffersToDispose = new List<ComputeBuffer>();
public SPH sph;
RenderTexture target;
[Header("Params")]
public float viewRadius;
public float blendStrength;
public Color waterColor;
public Color ambientLight;
public Light lightSource;
void InitRenderTexture () {
if (target == null || target.width != cam.pixelWidth || target.height != cam.pixelHeight) {
if (target != null) {
target.Release ();
}
cam.depthTextureMode = DepthTextureMode.Depth;
target = new RenderTexture (cam.pixelWidth, cam.pixelHeight, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
target.enableRandomWrite = true;
target.Create ();
}
}
private bool render = false;
public ComputeBuffer _particlesBuffer;
private void SpawnParticlesInBox()
{
_particlesBuffer = new ComputeBuffer(1, 44);
_particlesBuffer.SetData(new Particle[] {
new Particle {
position = new Vector3(0,0,0)
}});
}
public void Begin() {
// SpawnParticlesInBox();
InitRenderTexture();
raymarching.SetBuffer(0,"particles",sph._particlesBuffer);
raymarching.SetInt("numParticles",sph.particles.Length);
raymarching.SetFloat("particleRadius", viewRadius);
raymarching.SetFloat("blendStrength", blendStrength);
raymarching.SetVector("waterColor", waterColor);
raymarching.SetVector("_AmbientLight", ambientLight);
raymarching.SetTextureFromGlobal(0, "_DepthTexture", "_CameraDepthTexture");
render = true;
}
void OnRenderImage (RenderTexture source, RenderTexture destination) {
// InitRenderTexture();
if (!render) {
Begin();
}
if (render) {
raymarching.SetVector ("_Light", lightSource.transform.forward);
raymarching.SetTexture (0, "Source", source);
raymarching.SetTexture (0, "Destination", target);
raymarching.SetVector("_CameraPos", cam.transform.position);
raymarching.SetMatrix ("_CameraToWorld", cam.cameraToWorldMatrix);
raymarching.SetMatrix ("_CameraInverseProjection", cam.projectionMatrix.inverse);
int threadGroupsX = Mathf.CeilToInt (cam.pixelWidth / 8.0f);
int threadGroupsY = Mathf.CeilToInt (cam.pixelHeight / 8.0f);
raymarching.Dispatch (0, threadGroupsX, threadGroupsY, 1);
Graphics.Blit (target, destination);
}
}
}
And this is the shader, called Raymarching.compute:
#pragma kernel CSMain
Texture2D<float4> Source;
RWTexture2D<float4> Destination;
Texture2D<float4> _DepthTexture;
float4x4 _CameraToWorld;
float4x4 _CameraInverseProjection;
static const float maxDst = 80;
static const float epsilon = 0.001f;
static const float shadowBias = epsilon * 50;
struct Particle
{
float pressure;
float density;
float3 currentForce;
float3 velocity;
float3 position;
};
StructuredBuffer<Particle> particles;
int numParticles;
float particleRadius;
float blendStrength;
float3 waterColor;
float3 _Light;
float3 _AmbientLight;
float3 _CameraPos;
struct Ray {
float3 origin;
float3 direction;
};
float SphereDistance(float3 eye, float3 centre, float radius) {
return distance(eye, centre) - radius;
}
Ray CreateRay(float3 origin, float3 direction) {
Ray ray;
ray.origin = origin;
ray.direction = direction;
return ray;
}
Ray CreateCameraRay(float2 uv) {
float3 origin = mul(_CameraToWorld, float4(0,0,0,1)).xyz;
float3 direction = mul(_CameraInverseProjection, float4(uv,0,1)).xyz;
direction = mul(_CameraToWorld, float4(direction,0)).xyz;
direction = normalize(direction);
return CreateRay(origin,direction);
}
// polynomial smooth min (k = 0.1);
// from https://www.iquilezles.org/www/articles/smin/smin.htm
float4 Blend( float a, float b, float3 colA, float3 colB, float k )
{
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
float blendDst = lerp( b, a, h ) - k*h*(1.0-h);
float3 blendCol = lerp(colB,colA,h);
return float4(blendCol, blendDst);
}
float4 Combine(float dstA, float dstB, float3 colourA, float3 colourB) {
float dst = dstA;
float3 colour = colourA;
float4 blend = Blend(dstA,dstB,colourA,colourB, blendStrength);
dst = blend.w;
colour = blend.xyz;
return float4(colour,dst);
}
float GetShapeDistance(Particle particle, float3 eye) {
return SphereDistance(eye, particle.position, particleRadius);
return maxDst;
}
float4 SceneInfo(float3 eye) {
float globalDst = maxDst;
float3 globalColour = waterColor;
for (int i = 0; i < numParticles; i ++) {
Particle particle = particles[i];
float localDst = GetShapeDistance(particle,eye);
float3 localColour = waterColor;
float4 globalCombined = Combine(globalDst, localDst, globalColour, localColour);
globalColour = globalCombined.xyz;
globalDst = globalCombined.w;
}
return float4(globalColour, globalDst);
}
float3 EstimateNormal(float3 p) {
float x = SceneInfo(float3(p.x+epsilon,p.y,p.z)).w - SceneInfo(float3(p.x-epsilon,p.y,p.z)).w;
float y = SceneInfo(float3(p.x,p.y+epsilon,p.z)).w - SceneInfo(float3(p.x,p.y-epsilon,p.z)).w;
float z = SceneInfo(float3(p.x,p.y,p.z+epsilon)).w - SceneInfo(float3(p.x,p.y,p.z-epsilon)).w;
return normalize(float3(x,y,z));
}
float CalculateShadow(Ray ray, float dstToShadePoint) {
float rayDst = 0;
int marchSteps = 0;
float shadowIntensity = .2;
float brightness = 1;
while (rayDst < dstToShadePoint) {
marchSteps ++;
float4 sceneInfo = SceneInfo(ray.origin);
float dst = sceneInfo.w;
if (dst <= epsilon) {
return shadowIntensity;
}
brightness = min(brightness,dst*200);
ray.origin += ray.direction * dst;
rayDst += dst;
}
return shadowIntensity + (1-shadowIntensity) * brightness;
}
float LinearEyeDepth( float rawdepth )
{
float _NearClip = 0.3;
float FarClip = 1000;
float x, y, z, w;
#if SHADER_API_GLES3 // insted of UNITY_REVERSED_Z
x = -1.0 + _NearClip/ FarClip;
y = 1;
z = x / _NearClip;
w = 1 / _NearClip;
#else
x = 1.0 - _NearClip/ FarClip;
y = _NearClip / FarClip;
z = x / _NearClip;
w = y / _NearClip;
#endif
return 1.0 / (z * rawdepth + w);
}
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
uint width,height;
Destination.GetDimensions(width, height);
Destination[id.xy] = Source[id.xy];
float2 uv = id.xy / float2(width,height) * 2 - 1;
float rayDst = 0;
Ray ray = CreateCameraRay(uv);
int marchSteps = 0;
float depth = LinearEyeDepth(_DepthTexture[id.xy]);
while (rayDst < maxDst) {
marchSteps ++;
float4 sceneInfo = SceneInfo(ray.origin);
float dst = sceneInfo.w;
if (rayDst >= depth) {
Destination[id.xy] = Source[id.xy];
break;
}
if (dst <= epsilon) {
float3 pointOnSurface = ray.origin + ray.direction * dst;
float3 normal = EstimateNormal(pointOnSurface - ray.direction * epsilon);
float3 lightDir = -_Light;
float lighting = saturate(saturate(dot(normal,lightDir))) ;
float3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(ray.direction, reflectDir), 0.0), 32);
float3 specular = 0.7 * spec * float3(1,1,1);
float3 col = sceneInfo.xyz;
float3 t1 = cross(normal, float3(0,0,1));
float3 t2 = cross(normal, float3(0,1,0));
float3 tangent = float3(0,0,0);
if (length(t1) > length(t2)) {
tangent = normalize(t1);
}
else {
tangent = normalize(t2);
}
float3x3 tangentMatrix = float3x3(tangent,cross(tangent, normal),normal);
float3 viewDir = normalize(pointOnSurface-_CameraPos);
float3 refracted = mul(tangentMatrix, refract(viewDir, normal,1));
Destination[id.xy] = float4(lerp(col, Source[id.xy+(refracted.xy)], 0.8) * (specular + _AmbientLight + lighting * 0.01),1);
break;
}
ray.origin += ray.direction * dst;
rayDst += dst;
}
}