Last active
January 19, 2022 22:15
-
-
Save herohiralal/e9dc58fadab7cc0184b7da2a829fc530 to your computer and use it in GitHub Desktop.
Add curvature to the rendering without changing simulation code. Modified for a specific use-case where +Z/-Z have a different curvature.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace AIEngineTest | |
{ | |
public class CurveController : MonoBehaviour | |
{ | |
private static CurveController s_Instance = null; | |
private const float k_StraightDistanceClamp = 50f; | |
private const float k_CurvatureClamp = 10f; | |
[SerializeField] [Range(0f, k_StraightDistanceClamp)] private float m_StraightDistance = 10f; | |
[SerializeField] [Range(-k_CurvatureClamp, k_CurvatureClamp)] private float m_VerticalCurvaturePositiveZ = 0f; | |
[SerializeField] [Range(-k_CurvatureClamp, k_CurvatureClamp)] private float m_HorizontalCurvaturePositiveZ = 0f; | |
[SerializeField] [Range(-k_CurvatureClamp, k_CurvatureClamp)] private float m_VerticalCurvatureNegativeZ = 0f; | |
[SerializeField] [Range(-k_CurvatureClamp, k_CurvatureClamp)] private float m_HorizontalCurvatureNegativeZ = 0f; | |
private static readonly int s_StraightRenderDistanceID = Shader.PropertyToID("_CURVER_STRAIGHT_RENDER_DISTANCE"); | |
private static readonly int s_HorizontalCurvaturePositiveZID = Shader.PropertyToID("_CURVER_HORIZONTAL_CURVATURE_POSITIVE_Z"); | |
private static readonly int s_VerticalCurvaturePositiveZID = Shader.PropertyToID("_CURVER_VERTICAL_CURVATURE_POSITIVE_Z"); | |
private static readonly int s_HorizontalCurvatureNegativeZID = Shader.PropertyToID("_CURVER_HORIZONTAL_CURVATURE_NEGATIVE_Z"); | |
private static readonly int s_VerticalCurvatureNegativeZID = Shader.PropertyToID("_CURVER_VERTICAL_CURVATURE_NEGATIVE_Z"); | |
private void Awake() | |
{ | |
if (s_Instance == null) | |
{ | |
s_Instance = this; | |
} | |
else | |
{ | |
Debug.Log("Duplicate curve controller detected.", this); | |
return; | |
} | |
UpdateValues(); | |
} | |
private void OnDestroy() | |
{ | |
if (s_Instance == this) | |
{ | |
s_Instance = null; | |
} | |
} | |
private void OnValidate() | |
{ | |
UpdateValues(); | |
} | |
private void UpdateValues() | |
{ | |
straightDistance = m_StraightDistance; | |
horizontalCurvaturePositiveZ = m_HorizontalCurvaturePositiveZ; | |
verticalCurvaturePositiveZ = m_VerticalCurvaturePositiveZ; | |
horizontalCurvatureNegativeZ = m_HorizontalCurvatureNegativeZ; | |
verticalCurvatureNegativeZ = m_VerticalCurvatureNegativeZ; | |
} | |
public float straightDistance | |
{ | |
get => m_StraightDistance; | |
set | |
{ | |
value = Mathf.Clamp(value, 0f, k_StraightDistanceClamp); | |
m_StraightDistance = value; | |
Shader.SetGlobalFloat(s_StraightRenderDistanceID, value); | |
} | |
} | |
public float horizontalCurvaturePositiveZ | |
{ | |
get => m_HorizontalCurvaturePositiveZ; | |
set | |
{ | |
value = Mathf.Clamp(value, -k_CurvatureClamp, k_CurvatureClamp); | |
m_HorizontalCurvaturePositiveZ = value; | |
Shader.SetGlobalFloat(s_HorizontalCurvaturePositiveZID, value); | |
} | |
} | |
public float verticalCurvaturePositiveZ | |
{ | |
get => m_VerticalCurvaturePositiveZ; | |
set | |
{ | |
value = Mathf.Clamp(value, -k_CurvatureClamp, k_CurvatureClamp); | |
m_VerticalCurvaturePositiveZ = value; | |
Shader.SetGlobalFloat(s_VerticalCurvaturePositiveZID, value); | |
} | |
} | |
public float horizontalCurvatureNegativeZ | |
{ | |
get => m_HorizontalCurvatureNegativeZ; | |
set | |
{ | |
value = Mathf.Clamp(value, -k_CurvatureClamp, k_CurvatureClamp); | |
m_HorizontalCurvatureNegativeZ = value; | |
Shader.SetGlobalFloat(s_HorizontalCurvatureNegativeZID, value); | |
} | |
} | |
public float verticalCurvatureNegativeZ | |
{ | |
get => m_VerticalCurvatureNegativeZ; | |
set | |
{ | |
value = Mathf.Clamp(value, -k_CurvatureClamp, k_CurvatureClamp); | |
m_VerticalCurvatureNegativeZ = value; | |
Shader.SetGlobalFloat(s_VerticalCurvatureNegativeZID, value); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this file is meant to be used in conjunction with a Custom Function node | |
// in ShaderGraph. You can find out more about how to use it at | |
// https://docs.unity3d.com/Packages/[email protected]/manual/Custom-Function-Node.html | |
// all you need is the Position node (Object Space), connect its input to VertexPosOS and optionally | |
// provide an origin to determine where the rendering looks straight (and not curved) | |
#ifndef CURVER_INCLUDED | |
#define CURVER_INCLUDED | |
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl" | |
uniform float _CURVER_STRAIGHT_RENDER_DISTANCE; | |
uniform float _CURVER_HORIZONTAL_CURVATURE_POSITIVE_Z; | |
uniform float _CURVER_VERTICAL_CURVATURE_POSITIVE_Z; | |
uniform float _CURVER_HORIZONTAL_CURVATURE_NEGATIVE_Z; | |
uniform float _CURVER_VERTICAL_CURVATURE_NEGATIVE_Z; | |
#define CURVER_CURVATURE_POWER 2 | |
void GetModifiedObjectSpace_float(const float3 OriginWS, const float3 VertexPosOS, out float3 ModifiedVertexPosOS) | |
{ | |
const float3 VertexPosWS = TransformObjectToWorld(VertexPosOS); | |
const float DistanceToCamera = distance(OriginWS, VertexPosWS); | |
const float StraighteningMask = step(_CURVER_STRAIGHT_RENDER_DISTANCE, DistanceToCamera); | |
const float2 CurvatureModifier = lerp( | |
float2(_CURVER_HORIZONTAL_CURVATURE_NEGATIVE_Z, _CURVER_VERTICAL_CURVATURE_NEGATIVE_Z), | |
float2(_CURVER_HORIZONTAL_CURVATURE_POSITIVE_Z, _CURVER_VERTICAL_CURVATURE_POSITIVE_Z), | |
(sign(VertexPosWS.z) + 1) * 0.5f); | |
const float2 Curvature = pow(abs(DistanceToCamera - _CURVER_STRAIGHT_RENDER_DISTANCE), CURVER_CURVATURE_POWER) | |
* CurvatureModifier * pow(0.1f, CURVER_CURVATURE_POWER); | |
const float3 ModifiedVertexPosWS = VertexPosWS + (StraighteningMask * float3(Curvature.x, Curvature.y, 0)); | |
ModifiedVertexPosOS = TransformWorldToObject(ModifiedVertexPosWS); | |
} | |
void GetModifiedObjectSpace_half(const half3 OriginWS, const half3 VertexPosOS, out half3 ModifiedVertexPosOS) | |
{ | |
const half3 VertexPosWS = TransformObjectToWorld(VertexPosOS); | |
const half DistanceToCamera = distance(OriginWS, VertexPosWS); | |
const half StraighteningMask = step(_CURVER_STRAIGHT_RENDER_DISTANCE, DistanceToCamera); | |
const half2 CurvatureModifier = lerp( | |
half2(_CURVER_HORIZONTAL_CURVATURE_NEGATIVE_Z, _CURVER_VERTICAL_CURVATURE_NEGATIVE_Z), | |
half2(_CURVER_HORIZONTAL_CURVATURE_POSITIVE_Z, _CURVER_VERTICAL_CURVATURE_POSITIVE_Z), | |
(sign(VertexPosWS.z) + 1) * 0.5f); | |
const half2 Curvature = pow(abs(DistanceToCamera - _CURVER_STRAIGHT_RENDER_DISTANCE), CURVER_CURVATURE_POWER) | |
* CurvatureModifier * pow(0.1f, CURVER_CURVATURE_POWER); | |
const half3 ModifiedVertexPosWS = VertexPosWS + (StraighteningMask * half3(Curvature.x, Curvature.y, 0)); | |
ModifiedVertexPosOS = TransformWorldToObject(ModifiedVertexPosWS); | |
} | |
#undef CURVER_CURVATURE_POWER | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment