97 lines
No EOL
2.5 KiB
Text
97 lines
No EOL
2.5 KiB
Text
Shader "Custom/ColorCube"
|
|
{
|
|
Properties
|
|
{
|
|
_MainTex ("Texture", 3D) = "white" {}
|
|
_Alpha ("Alpha", float) = 0.02
|
|
_StepSize ("Step Size", float) = 0.01
|
|
}
|
|
SubShader
|
|
{
|
|
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
|
|
Blend One OneMinusSrcAlpha
|
|
LOD 100
|
|
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
// Maximum amount of raymarching samples
|
|
#define MAX_STEP_COUNT 128
|
|
|
|
// Allowed floating point inaccuracy
|
|
#define EPSILON 0.00001f
|
|
|
|
struct appdata
|
|
{
|
|
float4 vertex : POSITION;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float3 objectVertex : TEXCOORD0;
|
|
float3 vectorToSurface : TEXCOORD1;
|
|
};
|
|
|
|
sampler3D _MainTex;
|
|
float4 _MainTex_ST;
|
|
float _Alpha;
|
|
float _StepSize;
|
|
|
|
v2f vert (appdata v)
|
|
{
|
|
v2f o;
|
|
|
|
// Vertex in object space this will be the starting point of raymarching
|
|
o.objectVertex = v.vertex;
|
|
|
|
// Calculate vector from camera to vertex in world space
|
|
float3 worldVertex = mul(unity_ObjectToWorld, v.vertex).xyz;
|
|
o.vectorToSurface = worldVertex - _WorldSpaceCameraPos;
|
|
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
return o;
|
|
}
|
|
|
|
float4 BlendUnder(float4 color, float4 newColor)
|
|
{
|
|
color.rgb += (1.0 - color.a) * newColor.a * newColor.rgb;
|
|
color.a += (1.0 - color.a) * newColor.a;
|
|
return color;
|
|
}
|
|
|
|
fixed4 frag(v2f i) : SV_Target
|
|
{
|
|
// Start raymarching at the front surface of the object
|
|
float3 rayOrigin = i.objectVertex;
|
|
|
|
// Use vector from camera to object surface to get ray direction
|
|
float3 rayDirection = mul(unity_WorldToObject, float4(normalize(i.vectorToSurface), 1));
|
|
|
|
float4 color = float4(0, 0, 0, 0);
|
|
float3 samplePosition = rayOrigin;
|
|
|
|
// Raymarch through object space
|
|
for (int i = 0; i < MAX_STEP_COUNT; i++)
|
|
{
|
|
// Accumulate color only within unit cube bounds
|
|
if(max(abs(samplePosition.x), max(abs(samplePosition.y), abs(samplePosition.z))) < 0.5f + EPSILON)
|
|
{
|
|
float4 sampledColor = tex3D(_MainTex, samplePosition + float3(0.5f, 0.5f, 0.5f));
|
|
sampledColor.a *= _Alpha;
|
|
color = BlendUnder(color, sampledColor);
|
|
samplePosition += rayDirection * _StepSize;
|
|
}
|
|
}
|
|
|
|
return color;
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
} |