-
-
Save harunseng/dae9ddd9af12d88b8a7778aff2424d93 to your computer and use it in GitHub Desktop.
Add curvature to the rendering without changing simulation code.
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_VerticalCurvature = 0f; | |
[SerializeField] [Range(-k_CurvatureClamp, k_CurvatureClamp)] private float m_HorizontalCurvature = 0f; | |
private static readonly int s_StraightRenderDistanceID = Shader.PropertyToID("_CURVER_STRAIGHT_RENDER_DISTANCE"); | |
private static readonly int s_HorizontalCurvatureID = Shader.PropertyToID("_CURVER_HORIZONTAL_CURVATURE"); | |
private static readonly int s_VerticalCurvatureID = Shader.PropertyToID("_CURVER_VERTICAL_CURVATURE"); | |
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; | |
horizontalCurvature = m_HorizontalCurvature; | |
verticalCurvature = m_VerticalCurvature; | |
} | |
public float straightDistance | |
{ | |
get => m_StraightDistance; | |
set | |
{ | |
value = Mathf.Clamp(value, 0f, k_StraightDistanceClamp); | |
m_StraightDistance = value; | |
Shader.SetGlobalFloat(s_StraightRenderDistanceID, value); | |
} | |
} | |
public float horizontalCurvature | |
{ | |
get => m_HorizontalCurvature; | |
set | |
{ | |
value = Mathf.Clamp(value, -k_CurvatureClamp, k_CurvatureClamp); | |
m_HorizontalCurvature = value; | |
Shader.SetGlobalFloat(s_HorizontalCurvatureID, value); | |
} | |
} | |
public float verticalCurvature | |
{ | |
get => m_VerticalCurvature; | |
set | |
{ | |
value = Mathf.Clamp(value, -k_CurvatureClamp, k_CurvatureClamp); | |
m_VerticalCurvature = value; | |
Shader.SetGlobalFloat(s_VerticalCurvatureID, 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; | |
uniform float _CURVER_VERTICAL_CURVATURE; | |
#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 Curvature = pow(DistanceToCamera - _CURVER_STRAIGHT_RENDER_DISTANCE, CURVER_CURVATURE_POWER) | |
* float2(_CURVER_HORIZONTAL_CURVATURE, _CURVER_VERTICAL_CURVATURE) * 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 Curvature = pow(DistanceToCamera - _CURVER_STRAIGHT_RENDER_DISTANCE, CURVER_CURVATURE_POWER) | |
* half2(_CURVER_HORIZONTAL_CURVATURE, _CURVER_VERTICAL_CURVATURE) * 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