Created
May 28, 2020 08:49
-
-
Save hakanai/6ee4ac29be7d9e32d36fa61c1286a4a8 to your computer and use it in GitHub Desktop.
Implementing raycast abstraction by defining a raymarch abstraction
This file contains 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
#ifndef EL_RAYMARCH_BASE_CGINC | |
#define EL_RAYMARCH_BASE_CGINC | |
#include "ELRaycastBase.cginc" | |
float2 ELMap(float3 objectPos); | |
float3 ELRaymarchNormal(in float3 objectPos) | |
{ | |
static const float2 e = fixed2(0.000001, -0.000001); | |
return normalize(e.xyy * ELMap(objectPos + e.xyy).x + | |
e.yyx * ELMap(objectPos + e.yyx).x + | |
e.yxy * ELMap(objectPos + e.yxy).x + | |
e.xxx * ELMap(objectPos + e.xxx).x); | |
} | |
#define MAX_STEPS 200 | |
#define MIN_DISTANCE 0.00001 | |
#define MAX_DISTANCE 200.0 | |
bool ELRaymarch(ELRay ray, out float3 objectPos, out float material) | |
{ | |
float2 mapResult; | |
for (uint i = 0; i < MAX_STEPS; i++) | |
{ | |
mapResult = ELMap(ray.pos); | |
objectPos = ray.pos; | |
if (mapResult.x > MAX_DISTANCE) | |
{ | |
return false; | |
} | |
ELAdvanceRay(ray, mapResult.x); | |
if (mapResult.x < MIN_DISTANCE) | |
{ | |
material = mapResult.y; | |
return true; | |
} | |
} | |
material = mapResult.y; | |
return true; | |
} | |
bool ELRaycast(ELRay ray, out float3 objectPos, out float3 objectNormal, out float material) | |
{ | |
bool hit = ELRaymarch(ray, objectPos, material); | |
// Avoid potential multiple map calls if it didn't hit at all | |
UNITY_BRANCH | |
if (hit) | |
{ | |
objectNormal = ELRaymarchNormal(objectPos); | |
} | |
else | |
{ | |
// Just to silence the warning | |
objectNormal = float3(0.0, 0.0, 1.0); | |
} | |
return hit; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment