Skip to content

Instantly share code, notes, and snippets.

@Ohmnivore
Created May 18, 2023 22:00
Show Gist options
  • Save Ohmnivore/46cdffe3bd55814c4f413d87fa589bbc to your computer and use it in GitHub Desktop.
Save Ohmnivore/46cdffe3bd55814c4f413d87fa589bbc to your computer and use it in GitHub Desktop.
Shader "Ohmnivore/Heightmap"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
float frag(v2f i) : SV_Target
{
float flipped = _ProjectionParams.x;
float nearPlane = _ProjectionParams.y;
float farPlane = _ProjectionParams.z;
float rawDepth = i.vertex.z;
float orthoLinearDepth = flipped > 0.0 ? 1.0 - rawDepth : rawDepth;
return orthoLinearDepth;
}
ENDCG
}
}
}
using System;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering.Universal;
[ExecuteAlways]
public class HeightmapCamera : MonoBehaviour
{
[Serializable]
public struct State
{
public static readonly State Default = new State
{
Size = 10f,
Depth = 16f,
Resolution = new Vector2Int(512, 512)
};
public float Size;
public float Depth;
public Vector2Int Resolution;
}
public State Settings = State.Default;
public RenderTexture RT => m_RT;
[SerializeField]
private RenderTexture m_RT;
private void OnEnable()
{
SetupCamera();
}
private void Update()
{
transform.SetPositionAndRotation(transform.position, Quaternion.Euler(90f, 0f, 0f));
}
private void SetupCamera()
{
var cam = GetComponent<Camera>();
cam.orthographic = true;
cam.orthographicSize = Settings.Size * 0.5f;
cam.nearClipPlane = 0f;
cam.farClipPlane = Settings.Depth;
cam.clearFlags = CameraClearFlags.SolidColor;
cam.backgroundColor = Color.black;
cam.allowMSAA = false;
var additionalCam = GetComponent<UniversalAdditionalCameraData>();
additionalCam.antialiasing = AntialiasingMode.None;
additionalCam.renderShadows = false;
additionalCam.dithering = false;
if (m_RT == null &&
m_RT.width == Settings.Resolution.x &&
m_RT.height == Settings.Resolution.y)
{
m_RT = new RenderTexture(Settings.Resolution.x, Settings.Resolution.y, 24, GraphicsFormat.R32_SFloat);
m_RT.filterMode = FilterMode.Point;
cam.targetTexture = m_RT;
m_RT.hideFlags = HideFlags.None;
}
}
}
using UnityEngine.Experimental.Rendering.Universal;
using UnityEngine.Rendering.Universal;
public class HeightmapFeature : RenderObjects
{
RenderObjectsPass Pass;
/// <inheritdoc/>
public override void Create()
{
FilterSettings filter = settings.filterSettings;
if (settings.Event < RenderPassEvent.BeforeRenderingPrePasses)
settings.Event = RenderPassEvent.BeforeRenderingPrePasses;
Pass = new RenderObjectsPass(settings.passTag, settings.Event, filter.PassNames,
filter.RenderQueueType, filter.LayerMask, settings.cameraSettings);
Pass.overrideMaterial = null;
Pass.overrideShader = settings.overrideShader;
Pass.overrideShaderPassIndex = settings.overrideShaderPassIndex;
if (settings.overrideDepthState)
Pass.SetDepthState(settings.enableWrite, settings.depthCompareFunction);
if (settings.stencilSettings.overrideStencilState)
Pass.SetStencilState(settings.stencilSettings.stencilReference,
settings.stencilSettings.stencilCompareFunction, settings.stencilSettings.passOperation,
settings.stencilSettings.failOperation, settings.stencilSettings.zFailOperation);
}
/// <inheritdoc/>
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
var heightmapCamera = renderingData.cameraData.camera.GetComponent<HeightmapCamera>();
if (heightmapCamera != null)
renderer.EnqueuePass(Pass);
}
}
namespace UnityEngine.VFX.Utility
{
/// <summary>
/// Camera parameter binding helper class.
/// </summary>
[VFXBinder("URP/URP Camera")]
public class URPCameraBinder : VFXBinderBase
{
/// <summary>
/// The camera to bind to the VFX.
/// </summary>
public Camera Camera;
[VFXPropertyBinding("UnityEditor.VFX.CameraType"), SerializeField]
ExposedProperty CameraProperty = "Camera";
ExposedProperty m_Position;
ExposedProperty m_Angles;
ExposedProperty m_Scale;
ExposedProperty m_Orthographic;
ExposedProperty m_FieldOfView;
ExposedProperty m_NearPlane;
ExposedProperty m_FarPlane;
ExposedProperty m_OrthographicSize;
ExposedProperty m_AspectRatio;
ExposedProperty m_Dimensions;
ExposedProperty m_DepthBuffer;
ExposedProperty m_ColorBuffer;
/// <inheritdoc/>
public void SetCameraProperty(string name)
{
CameraProperty = name;
UpdateSubProperties();
}
void UpdateSubProperties()
{
// Update VFX Sub Properties
m_Position = CameraProperty + "_transform_position";
m_Angles = CameraProperty + "_transform_angles";
m_Scale = CameraProperty + "_transform_scale";
m_Orthographic = CameraProperty + "_orthographic";
m_FieldOfView = CameraProperty + "_fieldOfView";
m_NearPlane = CameraProperty + "_nearPlane";
m_FarPlane = CameraProperty + "_farPlane";
m_OrthographicSize = CameraProperty + "_orthographicSize";
m_AspectRatio = CameraProperty + "_aspectRatio";
m_Dimensions = CameraProperty + "_pixelDimensions";
m_DepthBuffer = CameraProperty + "_depthBuffer";
m_ColorBuffer = CameraProperty + "_colorBuffer";
}
/// <inheritdoc/>
protected override void OnEnable()
{
base.OnEnable();
UpdateSubProperties();
}
/// <inheritdoc/>
protected override void OnDisable()
{
base.OnDisable();
}
private void OnValidate()
{
UpdateSubProperties();
}
/// <inheritdoc/>
public override bool IsValid(VisualEffect component)
{
return Camera != null
&& component.HasVector3(m_Position)
&& component.HasVector3(m_Angles)
&& component.HasVector3(m_Scale)
&& component.HasBool(m_Orthographic)
&& component.HasFloat(m_FieldOfView)
&& component.HasFloat(m_NearPlane)
&& component.HasFloat(m_FarPlane)
&& component.HasFloat(m_OrthographicSize)
&& component.HasFloat(m_AspectRatio)
&& component.HasVector2(m_Dimensions)
&& component.HasTexture(m_DepthBuffer)
&& component.HasTexture(m_ColorBuffer);
}
/// <inheritdoc/>
public override void UpdateBinding(VisualEffect component)
{
component.SetVector3(m_Position, Camera.transform.position);
component.SetVector3(m_Angles, Camera.transform.eulerAngles);
component.SetVector3(m_Scale, Camera.transform.lossyScale);
component.SetBool(m_Orthographic, Camera.orthographic);
// While field of View is set in degrees for the camera, it is expected in radians in VFX
component.SetFloat(m_FieldOfView, Mathf.Deg2Rad * Camera.fieldOfView);
component.SetFloat(m_NearPlane, Camera.nearClipPlane);
component.SetFloat(m_FarPlane, Camera.farClipPlane);
component.SetFloat(m_OrthographicSize, Camera.orthographicSize);
component.SetFloat(m_AspectRatio, Camera.aspect);
component.SetVector2(m_Dimensions, new Vector2(Camera.pixelWidth, Camera.pixelHeight));
component.SetTexture(m_DepthBuffer, Camera.targetTexture);
}
/// <inheritdoc/>
public override string ToString()
{
return string.Format($"URP Camera : '{(Camera == null ? "null" : Camera.gameObject.name)}' -> {CameraProperty}");
}
}
}
@Zeyt8
Copy link

Zeyt8 commented Jun 9, 2024

Making a separate renderer for that camera fixed the issue. Thank you so much for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment