Last active
January 10, 2018 17:43
-
-
Save hecomi/30b7987a188d94cdfca8 to your computer and use it in GitHub Desktop.
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
Shader "Raymarching/Test" | |
{ | |
SubShader | |
{ | |
Tags { "RenderType" = "Opaque" "DisableBatching" = "True" "Queue" = "Geometry+10" } | |
Cull Off | |
CGINCLUDE | |
#include "UnityCG.cginc" | |
float DistanceFunc(float3 p) | |
{ | |
return length(p - float3(0, 0, 0)) - 2.0; | |
} | |
float3 GetCameraPosition() { return _WorldSpaceCameraPos; } | |
float3 GetCameraForward() { return -UNITY_MATRIX_V[2].xyz; } | |
float3 GetCameraUp() { return UNITY_MATRIX_V[1].xyz; } | |
float3 GetCameraRight() { return UNITY_MATRIX_V[0].xyz; } | |
float GetCameraFocalLength() { return abs(UNITY_MATRIX_P[1][1]); } | |
float GetDepth(float3 pos) | |
{ | |
float4 vpPos = mul(UNITY_MATRIX_VP, float4(pos, 1.0)); | |
#if defined(SHADER_TARGET_GLSL) | |
return (vpPos.z / vpPos.w) * 0.5 + 0.5; | |
#else | |
return vpPos.z / vpPos.w; | |
#endif | |
} | |
float3 GetNormal(float3 pos) | |
{ | |
const float d = 0.001; | |
return 0.5 + 0.5 * normalize(float3( | |
DistanceFunc(pos + float3( d, 0.0, 0.0)) - DistanceFunc(pos + float3( -d, 0.0, 0.0)), | |
DistanceFunc(pos + float3(0.0, d, 0.0)) - DistanceFunc(pos + float3(0.0, -d, 0.0)), | |
DistanceFunc(pos + float3(0.0, 0.0, d)) - DistanceFunc(pos + float3(0.0, 0.0, -d)))); | |
} | |
ENDCG | |
Pass | |
{ | |
Tags { "LightMode" = "Deferred" } | |
Stencil | |
{ | |
Comp Always | |
Pass Replace | |
Ref 128 | |
} | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma target 3.0 | |
#pragma multi_compile ___ UNITY_HDR_ON | |
#include "UnityCG.cginc" | |
struct VertInput | |
{ | |
float4 vertex : POSITION; | |
}; | |
struct VertOutput | |
{ | |
float4 vertex : SV_POSITION; | |
float4 screenPos : TEXCOORD0; | |
}; | |
struct GBufferOut | |
{ | |
half4 diffuse : SV_Target0; // rgb: diffuse, a: occlusion | |
half4 specular : SV_Target1; // rgb: specular, a: smoothness | |
half4 normal : SV_Target2; // rgb: normal, a: unused | |
half4 emission : SV_Target3; // rgb: emission, a: unused | |
float depth : SV_Depth; | |
}; | |
VertOutput vert(VertInput v) | |
{ | |
VertOutput o; | |
o.vertex = v.vertex; | |
o.screenPos = o.vertex; | |
return o; | |
} | |
GBufferOut frag(VertOutput i) | |
{ | |
float4 screenPos = i.screenPos; | |
screenPos.xy /= screenPos.w; | |
#if UNITY_UV_STARTS_AT_TOP | |
screenPos.y *= -1.0; | |
#endif | |
float3 camPos = GetCameraPosition(); | |
float3 camDir = GetCameraForward(); | |
float3 camUp = GetCameraUp(); | |
float3 camSide = GetCameraRight(); | |
float focalLen = GetCameraFocalLength(); | |
float maxDistance = _ProjectionParams.z - _ProjectionParams.y; | |
float3 rayDir = normalize( | |
camSide * screenPos.x + | |
camUp * screenPos.y + | |
camDir * focalLen); | |
float distance = 0.0; | |
float len = 0.0; | |
float3 pos = camPos + _ProjectionParams.y * rayDir; | |
for (int i = 0; i < 16; ++i) { | |
distance = DistanceFunc(pos); | |
len += distance; | |
pos += rayDir * distance; | |
if (distance < 0.001 || len > maxDistance) break; | |
} | |
if (distance > 0.001) discard; | |
GBufferOut o; | |
o.diffuse = float4(1.0, 1.0, 1.0, 1.0); | |
o.specular = float4(0.2, 0.2, 0.2, 0.5); | |
o.emission = float4(0.2, 0.2, 0.2, 1.0); | |
o.depth = GetDepth(pos); | |
o.normal = float4(GetNormal(pos), 1.0); | |
#ifndef UNITY_HDR_ON | |
o.emission = exp2(-o.emission); | |
#endif | |
return o; | |
} | |
ENDCG | |
} | |
} | |
Fallback Off | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment