forked from stride3d/stride
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
89 changes: 89 additions & 0 deletions
89
sources/engine/Stride.Rendering/Rendering/Images/Outline/Outline.cs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) | ||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. | ||
|
||
using System; | ||
using Stride.Core; | ||
using Stride.Core.Mathematics; | ||
using Stride.Graphics; | ||
|
||
namespace Stride.Rendering.Images { | ||
/// <summary> | ||
/// A fog filter. | ||
/// </summary> | ||
[DataContract("Outline")] | ||
public class Outline : ImageEffect { | ||
private readonly ImageEffectShader outlineFilter; | ||
private Texture depthTexture; | ||
private float zMin, zMax; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Outline"/> class. | ||
/// </summary> | ||
public Outline() | ||
: this("OutlineEffect") { | ||
} | ||
|
||
[DataMember(10)] | ||
public float NormalWeight { get; set; } = 2f; | ||
|
||
[DataMember(20)] | ||
public float DepthWeight { get; set; } = 0.2f; | ||
|
||
[DataMember(30)] | ||
public float NormalNearCutoff { get; set; } = 0.1f; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Outline"/> class. | ||
/// </summary> | ||
/// <param name="shaderName">Name of the outline shader.</param> | ||
public Outline(string shaderName) : base(shaderName) { | ||
if (shaderName == null) throw new ArgumentNullException("outlineFilterName"); | ||
outlineFilter = new ImageEffectShader(shaderName); | ||
} | ||
|
||
protected override void InitializeCore() { | ||
base.InitializeCore(); | ||
ToLoadAndUnload(outlineFilter); | ||
} | ||
|
||
/// <summary> | ||
/// Provides a color buffer and a depth buffer to apply the fog to. | ||
/// </summary> | ||
/// <param name="colorBuffer">A color buffer to process.</param> | ||
/// <param name="depthBuffer">The depth buffer corresponding to the color buffer provided.</param> | ||
public void SetColorDepthInput(Texture colorBuffer, Texture depthBuffer, float zMin, float zMax) { | ||
SetInput(0, colorBuffer); | ||
depthTexture = depthBuffer; | ||
this.zMin = zMin; | ||
this.zMax = zMax; | ||
} | ||
|
||
protected override void SetDefaultParameters() { | ||
NormalWeight = 2f; | ||
DepthWeight = 0.2f; | ||
NormalNearCutoff = 0.1f; | ||
base.SetDefaultParameters(); | ||
} | ||
|
||
protected override void DrawCore(RenderDrawContext context) { | ||
Texture color = GetInput(0); | ||
Texture output = GetOutput(0); | ||
if (color == null || output == null || depthTexture == null) { | ||
return; | ||
} | ||
|
||
outlineFilter.Parameters.Set(OutlineEffectKeys.ScreenDiffs, new Vector2(0.5f / color.Width, 0.5f / color.Height)); | ||
outlineFilter.Parameters.Set(OutlineEffectKeys.DepthTexture, depthTexture); | ||
outlineFilter.Parameters.Set(OutlineEffectKeys.zFar, zMax); | ||
outlineFilter.Parameters.Set(OutlineEffectKeys.zNear, zMin); | ||
|
||
outlineFilter.Parameters.Set(OutlineEffectKeys.NormalWeight, NormalWeight); | ||
outlineFilter.Parameters.Set(OutlineEffectKeys.DepthWeight, DepthWeight); | ||
outlineFilter.Parameters.Set(OutlineEffectKeys.NormalNearCutoff, NormalNearCutoff); | ||
|
||
outlineFilter.SetInput(0, color); | ||
outlineFilter.SetOutput(output); | ||
((RendererBase)outlineFilter).Draw(context); | ||
} | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
sources/engine/Stride.Rendering/Rendering/Images/Outline/OutlineEffect.cs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// <auto-generated> | ||
// Do not edit this file yourself! | ||
// | ||
// This code was generated by Xenko Shader Mixin Code Generator. | ||
// To generate it yourself, please install Xenko.VisualStudio.Package .vsix | ||
// and re-save the associated .xkfx. | ||
// </auto-generated> | ||
|
||
using Stride.Graphics; | ||
using Stride.Core.Mathematics; | ||
|
||
namespace Stride.Rendering | ||
{ | ||
internal static partial class OutlineEffectKeys | ||
{ | ||
public static readonly ValueParameterKey<Vector2> ScreenDiffs = ParameterKeys.NewValue<Vector2>(); | ||
public static readonly ValueParameterKey<float> zFar = ParameterKeys.NewValue<float>(1000f); | ||
public static readonly ValueParameterKey<float> zNear = ParameterKeys.NewValue<float>(0.1f); | ||
public static readonly ValueParameterKey<float> NormalWeight = ParameterKeys.NewValue<float>(2f); | ||
public static readonly ValueParameterKey<float> DepthWeight = ParameterKeys.NewValue<float>(0.2f); | ||
public static readonly ValueParameterKey<float> NormalNearCutoff = ParameterKeys.NewValue<float>(0.1f); | ||
public static readonly ObjectParameterKey<Texture> DepthTexture = ParameterKeys.NewObject<Texture>(); | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
sources/engine/Stride.Rendering/Rendering/Images/Outline/OutlineEffect.sdsl
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
namespace Stride.Rendering.Images | ||
{ | ||
/// <summary> | ||
/// Simple fog | ||
/// </summary> | ||
internal shader OutlineEffect : ImageEffectShader | ||
{ | ||
stage float2 ScreenDiffs; // .x = Width, .y = Height | ||
|
||
stage float zFar; | ||
stage float zNear; | ||
|
||
stage float NormalWeight; | ||
stage float DepthWeight; | ||
stage float NormalNearCutoff; | ||
|
||
stage Texture2D DepthTexture; | ||
|
||
float3 normal_from_depth(float depth, float2 texcoords) { | ||
const float2 offset1 = float2(0.0,ScreenDiffs.y); | ||
const float2 offset2 = float2(ScreenDiffs.x,0.0); | ||
|
||
float depth1 = DepthTexture.SampleLevel(PointSampler, texcoords + offset1, 0.0).x; | ||
float depth2 = DepthTexture.SampleLevel(PointSampler, texcoords + offset2, 0.0).x; | ||
|
||
float3 p1 = float3(offset1, depth1 - depth); | ||
float3 p2 = float3(offset2, depth2 - depth); | ||
|
||
float3 normal = cross(p1, p2); | ||
normal.z = -normal.z; | ||
|
||
return normalize(normal); | ||
} | ||
|
||
float4 fetchNormalDepth(float2 tc){ | ||
float4 nd; // return value | ||
|
||
// get depth | ||
float z_b = DepthTexture.SampleLevel(PointSampler, tc, 0.0).x; | ||
float z_n = 2.0 * z_b - 1.0; | ||
float linearDepth = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); | ||
|
||
// linear depth | ||
nd.w = DepthWeight * linearDepth; | ||
|
||
// normal, but skip stuff really close | ||
nd.xyz = step(NormalNearCutoff, linearDepth) * normal_from_depth(z_b, tc) * NormalWeight; | ||
|
||
return nd; | ||
} | ||
|
||
stage override float4 Shading() { | ||
float4 color = Texture0.Sample(PointSampler, streams.TexCoord); | ||
|
||
float4 n1 = fetchNormalDepth(streams.TexCoord + float2(-ScreenDiffs.x, -ScreenDiffs.y)); | ||
float4 n2 = fetchNormalDepth(streams.TexCoord + float2( ScreenDiffs.x, ScreenDiffs.y)); | ||
float4 n3 = fetchNormalDepth(streams.TexCoord + float2(-ScreenDiffs.x, ScreenDiffs.y)); | ||
float4 n4 = fetchNormalDepth(streams.TexCoord + float2( ScreenDiffs.x, -ScreenDiffs.y)); | ||
|
||
// Work out how much the normal and depth values are changing. | ||
float4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4); | ||
|
||
float normalDelta = dot(diagonalDelta.xyz, float3(1.0, 1.0, 1.0)); | ||
float totalDelta = diagonalDelta.w + normalDelta * 0.4; | ||
|
||
return float4(color.xyz * (1.0 - clamp(totalDelta, 0.0, 1.0)), 1.0); | ||
} | ||
}; | ||
} |
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