Skip to content

Commit

Permalink
fow fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmdesmail0 committed Sep 13, 2022
1 parent cc24fc9 commit 7b72414
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 94 deletions.
17 changes: 9 additions & 8 deletions Assets/Example Scenes/Dungeon/Dungeon.unity
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 922553028}
m_LocalRotation: {x: 0.46193978, y: 0.33141357, z: -0.19134171, w: 0.8001032}
m_LocalPosition: {x: -6.4471517, y: 24.571493, z: -9.652845}
m_LocalPosition: {x: -8.655901, y: 28.454464, z: -11.861595}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 983891336}
Expand Down Expand Up @@ -808,7 +808,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_BindingMode: 1
m_FollowOffset: {x: -7.611013, y: 13.37999, z: -7.611013}
m_FollowOffset: {x: -9.819762, y: 17.26296, z: -9.819762}
m_XDamping: 1
m_YDamping: 1
m_ZDamping: 1
Expand Down Expand Up @@ -1049,8 +1049,9 @@ MonoBehaviour:
m_EditorClassIdentifier:
mode: 1
radius: 10
resolution: 1
NearClipFromVS: 2
resolution: 4
CameraOffset: 2
ShadowReach: 5
area:
serializedVersion: 2
x: 0
Expand All @@ -1077,8 +1078,8 @@ MonoBehaviour:
- {fileID: 1417781027}
- {fileID: 1417781026}
NoiseScale: 20
NoiseMagnitude: 2
BlurItterations: 2
NoiseMagnitude: 0.002
BlurItterations: 1
BlendSpeed: 5
--- !u!81 &1080201540
AudioListener:
Expand Down Expand Up @@ -1139,7 +1140,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1080201538}
m_LocalRotation: {x: 0.46193978, y: 0.33141357, z: -0.19134171, w: 0.8001032}
m_LocalPosition: {x: -6.4471517, y: 24.571493, z: -9.652845}
m_LocalPosition: {x: -8.655901, y: 28.454464, z: -11.861595}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1405400200}
Expand Down Expand Up @@ -1826,7 +1827,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1891384457}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalPosition: {x: 0, y: 0.5, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1159673613}
Expand Down
11 changes: 6 additions & 5 deletions Assets/Example Scenes/Dungeon/FOW/Demo.unity
Original file line number Diff line number Diff line change
Expand Up @@ -921,8 +921,9 @@ MonoBehaviour:
m_EditorClassIdentifier:
mode: 0
radius: 10
resolution: 1
NearClipFromVS: 5
resolution: 4
CameraOffset: 5
ShadowReach: 1
area:
serializedVersion: 2
x: -20
Expand All @@ -940,9 +941,9 @@ MonoBehaviour:
- {fileID: 1481871345}
- {fileID: 196712691}
- {fileID: 1422430232}
NoiseScale: 50
NoiseMagnitude: 2
BlurItterations: 2
NoiseScale: 20
NoiseMagnitude: 0.002
BlurItterations: 1
BlendSpeed: 5
--- !u!1 &409308431
GameObject:
Expand Down
114 changes: 56 additions & 58 deletions Assets/Example Scenes/Dungeon/FOW/FogOfWar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum Resolution
_256,
_128
}

enum Pass
{
Vision,
Expand All @@ -35,7 +36,8 @@ enum Pass
public float radius = 10f;
public Resolution resolution;
[Tooltip("distance of the near clip plane from vision source, useful when the vision source inside the geometry to clip the ceiling")]
public float NearClipFromVS = 5f;
public float CameraOffset = 5f;
public float ShadowReach = 1f;
public Rect area;
public List<Transform> VisionSources = new List<Transform>();
public List<MeshFilter> Occluders = new List<MeshFilter>();
Expand All @@ -49,7 +51,6 @@ enum Pass
public float BlendSpeed = 5;

static int
stencil_rt_id = Shader.PropertyToID("_Stencil"),
fow_rt_id = Shader.PropertyToID("_FOW"),
saturate_rt_id = Shader.PropertyToID("_Saturate"),
visionSrcWS_id = Shader.PropertyToID("_VisionSource_WS"),
Expand All @@ -65,93 +66,86 @@ static int
private Material blur_mat;

private static int BlurPyramidID;
private RenderTexture fow;
private RenderTexture fow_0;
private RenderTexture fow_1;

[ImageEffectUsesCommandBuffer]
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (VisionSources.Count > 0)
if (VisionSources.Count > 0 && Occluders.Count > 0)
{
buffer.Clear();

buffer.SetGlobalVector(bounds_id, new Vector4(area.min.x, area.min.y, area.max.x, area.max.y));

var desc = fow.descriptor;
//using stencil with command buffer isn't well documented
desc.graphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R16_SFloat;
buffer.GetTemporaryRT(stencil_rt_id, desc);
buffer.SetRenderTarget(stencil_rt_id, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare);
var desc = fow_0.descriptor;
buffer.SetRenderTarget(fow_0, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare);
buffer.ClearRenderTarget(false, true, Color.black);

for (int i = 0; i < VisionSources.Count; i++)
DrawVisionSource(VisionSources[i].position, radius);

buffer.SetRenderTarget(fow, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare);

buffer.SetGlobalVector(noiseParam_id, new Vector4(NoiseScale, 0, NoiseMagnitude));
buffer.SetGlobalFloat(blendFactor_id, BlendSpeed * Time.deltaTime);

buffer.Blit(stencil_rt_id, fow, fow_mat,(int)Pass.PostProcess);
Saturate(fow);
Blur(fow);
buffer.Blit(fow_0, fow_1, fow_mat, (int)Pass.PostProcess);
buffer.Blit(fow_1, fow_0, fow_mat, (int)Pass.Saturate);
buffer.Blit(fow_0, fow_1, fow_mat, (int)Pass.Saturate);

Blur(fow_0);

buffer.ReleaseTemporaryRT(stencil_rt_id);
buffer.SetGlobalTexture(fow_rt_id, fow);
buffer.SetGlobalTexture(fow_rt_id, fow_0);

if (mode == Mode.Overlay)
FOWOverlay(source, destination);

Graphics.ExecuteCommandBuffer(buffer);
}

if(mode == Mode.BlendWithShadow)
if (mode == Mode.BlendWithShadow)
Graphics.Blit(source, destination);
}
else
Graphics.Blit(source, destination);
}

void Saturate(RenderTexture source)
{
buffer.GetTemporaryRT(saturate_rt_id, source.descriptor);
//the normal blit could flip the texture vertically
buffer.Blit(source, saturate_rt_id, fow_mat, (int)Pass.Saturate);
buffer.Blit(saturate_rt_id, source, fow_mat, (int)Pass.Saturate);
buffer.ReleaseTemporaryRT(saturate_rt_id);
}

void DrawVisionSource(Vector3 pos,float radius)
{
Vector3 pos_ss = default;
pos_ss.x = InvLerpUnlamp(area.min.x, area.max.x, pos.x);
pos_ss.y = InvLerpUnlamp(area.min.y, area.max.y, pos.z);
pos_ss.z = radius / area.height;
pos_ss *= GetResolution(resolution);
float dominant = Mathf.Max(area.width, area.height);
float texelPerUnit = GetResolution(resolution) / dominant;
Vector3 pos_ss = default;
pos_ss.x = (pos.x - area.xMin);
pos_ss.y = (pos.z - area.yMin);
pos_ss.z = radius;
pos_ss *= texelPerUnit;
buffer.SetGlobalVector(visionSrcSS_id, pos_ss);
buffer.SetGlobalVector(visionSrcWS_id, new Vector4(pos.x, pos.y, pos.z, radius));
buffer.SetGlobalVector("_FOWParams", new Vector4(ShadowReach,0.1f,0,0));

float n = 0.01f;
float f = n + NearClipFromVS;
float f = n + CameraOffset;

Matrix4x4 view =
Matrix4x4.TRS(new Vector3(area.center.x, pos.y + NearClipFromVS + n, area.center.y),
Matrix4x4.TRS(new Vector3(area.center.x, pos.y + f, area.center.y),
Quaternion.LookRotation(Vector3.down, Vector3.forward),
Vector3.one);
Vector3.one).inverse;

Matrix4x4 projection = default;
projection.m00 = 2f/area.width;
projection.m11 = -2f/area.height;
projection.m22 = 2f / (f - n);
projection.m22 = 2f / (f - n);
projection.m23 = -(f + n) / (f - n);
projection.m33 = 1f;

buffer.SetViewProjectionMatrices(view.inverse, projection);
buffer.SetViewProjectionMatrices(view, projection);

var visionMatrix = Matrix4x4.TRS(pos,
Quaternion.LookRotation(Vector3.up, Vector3.forward),
new Vector3(2*radius,2*radius, 1f));

buffer.DrawMesh(quad_mesh, visionMatrix, fow_mat, 0, (int)Pass.Vision);

pos.y = NearClipFromVS * 0.5f + pos.y;
Bounds bounds = new Bounds(pos, new Vector3(radius, NearClipFromVS, radius));
pos.y = CameraOffset * 0.5f + pos.y;
Bounds bounds = new Bounds(pos, new Vector3(radius*2, CameraOffset, radius*2));
var cullResult = Cull(bounds);

for (int i = 0; i < cullResult.Count; i++)
Expand Down Expand Up @@ -190,28 +184,39 @@ private void OnEnable()
for (int i = 1; i < MaxBlurItterations * 2; i++)
Shader.PropertyToID("_BlurPyramid" + i);

var res = GetResolution(resolution);
var size = GetSize();
var desc = new RenderTextureDescriptor()
{
width = res,
height = res,
width = size.x,
height = size.y,
dimension = TextureDimension.Tex2D,
graphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R16_SNorm,
graphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R16_SFloat,
volumeDepth = 1,
msaaSamples = 1,
depthBufferBits = 0,
};
fow = new RenderTexture(desc);
fow_0 = new RenderTexture(desc);
fow_1 = new RenderTexture(desc);

quad_mesh = GetPrimitiveMesh(PrimitiveType.Quad);
fow_mat = new Material(Shader.Find("Hidden/FOW"));
buffer = new CommandBuffer() { name = "FOW" };
}

Vector2Int GetSize()
{
var res = GetResolution(resolution);
return area.width > area.height ?
new Vector2Int(res, (int)(area.height * res / area.width) ) :
new Vector2Int((int)(area.width * res / area.height) , res) ;
}

private void OnDisable()
{
fow?.Release();
SafeDestroy(fow);
fow_0?.Release();
fow_1?.Release();
SafeDestroy(fow_0);
SafeDestroy(fow_1);
Shader.SetGlobalTexture(fow_rt_id, Texture2D.whiteTexture);

SafeDestroy(blur_mat);
Expand All @@ -225,7 +230,7 @@ private void Blur(RenderTargetIdentifier source)
if (BlurItterations < 1)
return;

var dsec = fow.descriptor;
var dsec = fow_0.descriptor;
int height = GetResolution(resolution) / 2;
int fromId = 0, toId = BlurPyramidID + 1;
int i;
Expand Down Expand Up @@ -285,11 +290,6 @@ private int GetResolution(Resolution resolution)
return 0;
}

float InvLerpUnlamp(float a, float b, float v)
{
return (v - a) / (b - a);
}

public List<MeshFilter> Cull(Bounds bounds)
{
var renderers = new List<MeshFilter>();
Expand All @@ -301,8 +301,6 @@ public List<MeshFilter> Cull(Bounds bounds)
return renderers;
}

Vector3 SetY(Vector3 vec, float value) { vec.y = value; return vec; }

Mesh GetPrimitiveMesh(PrimitiveType primitive)
{
var go = GameObject.CreatePrimitive(primitive);
Expand All @@ -329,9 +327,9 @@ void SafeDestroy(Object obj)
private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
Gizmos.DrawLine(new Vector3(area.min.x, NearClipFromVS, area.min.y), new Vector3(area.max.x, NearClipFromVS, area.min.y));
Gizmos.DrawLine(new Vector3(area.max.x, NearClipFromVS, area.min.y), new Vector3(area.max.x, NearClipFromVS, area.max.y));
Gizmos.DrawLine(new Vector3(area.max.x, NearClipFromVS, area.max.y), new Vector3(area.min.x, NearClipFromVS, area.max.y));
Gizmos.DrawLine(new Vector3(area.min.x, NearClipFromVS, area.max.y), new Vector3(area.min.x, NearClipFromVS, area.min.y));
Gizmos.DrawLine(new Vector3(area.min.x, CameraOffset, area.min.y), new Vector3(area.max.x, CameraOffset, area.min.y));
Gizmos.DrawLine(new Vector3(area.max.x, CameraOffset, area.min.y), new Vector3(area.max.x, CameraOffset, area.max.y));
Gizmos.DrawLine(new Vector3(area.max.x, CameraOffset, area.max.y), new Vector3(area.min.x, CameraOffset, area.max.y));
Gizmos.DrawLine(new Vector3(area.min.x, CameraOffset, area.max.y), new Vector3(area.min.x, CameraOffset, area.min.y));
}
}
7 changes: 3 additions & 4 deletions Assets/Example Scenes/Dungeon/FOW/Shaders/FOW.shader
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ Shader "Hidden/FOW"
Name "Occluder"

Blend one one
BlendOp RevSub
Cull front

CGPROGRAM
Expand All @@ -50,7 +49,7 @@ Shader "Hidden/FOW"

float frag(v2f i) : SV_Target
{
return step(length(i.vertex.xy - _VisionSource_SS.xy),_VisionSource_SS.z);
return -step(length(i.vertex.xy - _VisionSource_SS.xy),_VisionSource_SS.z);
}

ENDCG
Expand All @@ -76,8 +75,8 @@ Shader "Hidden/FOW"
i.uv.y = 1 - i.uv.y;
#endif
float3 n = sdnoise(i.uv * _NoiseParam.x + _NoiseParam.y)* _NoiseParam.z;
float s = _Stencil.Load(int3(floor(i.uv.x* _Stencil_TexelSize.z + n.y),floor(i.uv.y* _Stencil_TexelSize.w + n.z),0)).r;
float v = step(0.00001, s);
float s = tex2D(_MainTex, i.uv + n.yz);
float v = step(0.00001,s);
return (v * 2 - 1) * _BlendFactor;
}

Expand Down
9 changes: 4 additions & 5 deletions Assets/Example Scenes/Dungeon/FOW/Shaders/FOWINC.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ struct v2f

sampler2D _MainTex;
float4 _MainTex_ST;

Texture2D<float> _Stencil;
float4 _Stencil_TexelSize;
float4 _MainTex_TexelSize;

float4 _Bounds;
float4 _VisionSource_WS;
float4 _VisionSource_SS;
float4 _FOWParams;
// (scale, offset, magnitude)
float4 _NoiseParam;
float _BlendFactor;
Expand All @@ -44,8 +43,8 @@ v2f vert_occluder(appdata v)
v2f o = (v2f)0;
float4 wpos = mul(UNITY_MATRIX_M, v.vertex);
float3 delta = wpos - _VisionSource_WS;
float d = exp(delta.y*2);
delta.y = 0;
float d = max(0,exp(delta.y) - 1)* _FOWParams.x + _FOWParams.y;
delta.y = 0;
wpos.xyz += normalize(delta) * d ;
o.vertex = mul(UNITY_MATRIX_VP, wpos);
return o;
Expand Down
Loading

0 comments on commit 7b72414

Please sign in to comment.