Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
334 changes: 318 additions & 16 deletions VL.Stride.Runtime/VL.Stride.Engine.vl

Large diffs are not rendered by default.

278 changes: 270 additions & 8 deletions VL.Stride.Runtime/VL.Stride.Graphics.vl

Large diffs are not rendered by default.

277 changes: 159 additions & 118 deletions VL.Stride.Runtime/VL.Stride.Rendering.vl

Large diffs are not rendered by default.

73 changes: 70 additions & 3 deletions VL.Stride.Runtime/VL.Stride.Runtime.TypeForwards.vl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:p="property" xmlns:r="reflection" Id="TiJxb2oN2LtNWRy2MbJV6Q" LanguageVersion="2024.6.0-0313-g70edef4106" Version="0.128">
<Document xmlns:p="property" xmlns:r="reflection" Id="TiJxb2oN2LtNWRy2MbJV6Q" LanguageVersion="2024.6.7-0136-ga34ff89f71" Version="0.128">
<NugetDependency Id="LpDzfnL2ypqNzyyOieWuHI" Location="VL.CoreLib" Version="2021.4.11-1125-g2d2d476ad1" />
<PlatformDependency Id="JJ0ZRRgadtbPuisZUaeinf" Location="Stride.Graphics.dll" />
<NugetDependency Id="RUpxj8weM25L4I4AlKb6Yw" Location="VL.Core" Version="2021.4.11-1125-g2d2d476ad1" />
Expand Down Expand Up @@ -2513,8 +2513,39 @@
<Choice Kind="TypeFlag" Name="CommandList" />
</p:TypeAnnotation>
<Patch Id="BBsQros4BSiLqyyg7Kqe5Q">
<Canvas Id="MvSYpVSXs37PwMoCoR7mQu" BordersChecked="false" CanvasType="Group" />
<ProcessDefinition Id="SNu3a8iMSXnP4matC4BIAH" IsHidden="true" />
<Canvas Id="MvSYpVSXs37PwMoCoR7mQu" CanvasType="Group">
<!--

************************ DrawMesh ************************

-->
<Node Name="DrawMesh" Bounds="797,440,113,80" Id="O5F59rFB1TuObsZjMUIzfs">
<p:NodeReference>
<Choice Kind="OperationDefinition" Name="Operation" />
<CategoryReference Kind="Category" Name="Primitive" />
</p:NodeReference>
<p:HideCategory p:Type="Boolean">false</p:HideCategory>
<Patch Id="Jck1aiKCUwJPewjx3YKloG">
<Node Bounds="809,469,89,26" AutoConnect="true" Id="GJfpgVzNEfKMEbyl7WD0Oz">
<p:NodeReference LastCategoryFullName="VL.Stride.Rendering.CommandListHelper" LastDependency="VL.Stride.Runtime.dll">
<Choice Kind="OperationNode" Name="DrawMesh" />
<FullNameCategoryReference ID="VL.Stride.Rendering.CommandListHelper" />
</p:NodeReference>
<Pin Id="RVzihOLeKQBLCiAZSjllad" Name="Input" Kind="StateInputPin" />
<Pin Id="NiYdRZpNhhCNzMyCh2LvOi" Name="Draw Data" Kind="InputPin" />
<Pin Id="MIFABM8AMvyOYQLwffivsd" Name="Instance Count" Kind="InputPin" />
<Pin Id="QBXQ0wUGdwmPPZKQJD3vWK" Name="Output" Kind="OutputPin" />
</Node>
<Pin Id="N9KXFQgSWbwMD2Gias0nm9" Name="Input" Kind="InputPin" />
<Pin Id="OnPO56EZld6Mlf54m7knS8" Name="Draw Data" Kind="InputPin" />
<Pin Id="T5EAClRLNrUPJ17qjthbFs" Name="Instance Count" Kind="InputPin" />
<Pin Id="Uz93UuqASjtNs4SxOAXKWB" Name="Output" Kind="OutputPin" />
</Patch>
</Node>
</Canvas>
<ProcessDefinition Id="SNu3a8iMSXnP4matC4BIAH" IsHidden="true">
<Fragment Id="K7cKpTh3E1wP1u7grNjAID" Patch="O5F59rFB1TuObsZjMUIzfs" />
</ProcessDefinition>
</Patch>
</Node>
<!--
Expand Down Expand Up @@ -7755,6 +7786,42 @@
</Patch>
</Node>
</Canvas>
<!--

************************ WireframeComponent ************************

-->
<Node Name="WireframeComponent" Bounds="322,663" Id="IqvxKVg6GbdMYTv0tIm53B">
<p:NodeReference>
<Choice Kind="ForwardDefinition" Name="Forward" />
<CategoryReference Kind="Category" Name="Primitive" />
</p:NodeReference>
<p:TypeAnnotation LastCategoryFullName="VL.Stride.Rendering" LastDependency="VL.Stride.Runtime.dll">
<Choice Kind="TypeFlag" Name="WireframeComponent" />
</p:TypeAnnotation>
<Patch Id="OWwMuUrHbBqNicsPQDlZOH">
<Canvas Id="OvSoD0TkTPGN7qY4Hy5egx" CanvasType="Group" />
<ProcessDefinition Id="FbQFLMDT5QzQQhADIMy2as" IsHidden="true" />
</Patch>
</Node>
<!--

************************ MeshOutlineComponent ************************

-->
<Node Name="MeshOutlineComponent" Bounds="324,722" Id="VM9SSRF7ixIOUNXq4xMOJT">
<p:NodeReference>
<Choice Kind="ForwardDefinition" Name="Forward" />
<CategoryReference Kind="Category" Name="Primitive" />
</p:NodeReference>
<p:TypeAnnotation LastCategoryFullName="VL.Stride.Rendering" LastDependency="VL.Stride.Runtime.dll">
<Choice Kind="TypeFlag" Name="MeshOutlineComponent" />
</p:TypeAnnotation>
<Patch Id="BEdedK1qDBBQDKNZhaCF67">
<Canvas Id="HHpKLCGtd7UMeT2UB2KjXE" BordersChecked="false" CanvasType="Group" />
<ProcessDefinition Id="GlynMHkAxr6MCHzbPb0qGy" IsHidden="true" />
</Patch>
</Node>
</Canvas>
<Canvas Id="Bd789eT964HO9PAhxU72OF" Name="Engine" Position="386,328">
<!--
Expand Down
29 changes: 29 additions & 0 deletions VL.Stride.Runtime/src/Effects/Common/MeshOutlineShader.sdsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
shader MeshOutlineShader : ShaderBase, Transformation, Texturing, PositionStream4
{
stage stream float3 Normal : NORMAL;

float4 Color;
float Intensity;
float Size;

cbuffer PerView
{
stage float4 Viewport;
}

float4 projToWorld(in float4 pos, in float3 normal)
{
float3 scaling = normal * (WorldScale - clamp(1-(Size* 0.1), 0.9, 1.0));
return mul(pos + float4(scaling.x, scaling.y, scaling.z, 0), WorldViewProjection);
}

stage override void VSMain()
{
streams.ShadingPosition = projToWorld(streams.Position, streams.Normal);
}

stage override void PSMain()
{
streams.ColorTarget = Color * Intensity;
}
};
26 changes: 26 additions & 0 deletions VL.Stride.Runtime/src/Effects/Common/MeshOutlineShader.sdsl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// <auto-generated>
// Do not edit this file yourself!
//
// This code was generated by Stride Shader Mixin Code Generator.
// To generate it yourself, please install Stride.VisualStudio.Package .vsix
// and re-save the associated .sdfx.
// </auto-generated>

using System;
using Stride.Core;
using Stride.Rendering;
using Stride.Graphics;
using Stride.Shaders;
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;

namespace Stride.Rendering
{
public static partial class MeshOutlineShaderKeys
{
public static readonly ValueParameterKey<Vector4> Color = ParameterKeys.NewValue<Vector4>();
public static readonly ValueParameterKey<float> Intensity = ParameterKeys.NewValue<float>();
public static readonly ValueParameterKey<float> Size = ParameterKeys.NewValue<float>();
public static readonly ValueParameterKey<Vector4> Viewport = ParameterKeys.NewValue<Vector4>();
}
}
242 changes: 242 additions & 0 deletions VL.Stride.Runtime/src/Effects/Common/WireframeShader.sdsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
shader WireframeShader : ShaderBase, Transformation, Texturing, PositionStream4
{
noperspective stage stream float4 EdgeA;
noperspective stage stream float4 EdgeB;
stage stream float3 Normal : NORMAL;
stage stream uint Case;

static const uint infoA[] = { 0, 0, 0, 0, 1, 1, 2 };
static const uint infoB[] = { 1, 1, 2, 0, 2, 1, 2 };
static const uint infoAd[] = { 2, 2, 1, 1, 0, 0, 0 };
static const uint infoBd[] = { 2, 2, 1, 2, 0, 2, 1 };
static const uint infoEdge0[] = { 0, 2, 0, 0, 0, 0, 2 };

float LineWidth;

[Color]
float4 LineColor;

cbuffer PerView
{
stage float4 Viewport;
}

float4 projToWorld(in float4 pos, in float3 normal)
{
float3 scaling = normal * (WorldScale - 1);
return mul(pos + float4(scaling.x, scaling.y, scaling.z, 0), WorldViewProjection);
}

float2 projToWindow(in float4 pos)
{
return float2(
Viewport.x * 0.5 * (1 + (pos.x / pos.w)) + Viewport.z,
Viewport.y * 0.5 * (1 - (pos.y / pos.w)) + Viewport.w
);
}

float evalMinDistanceToEdges()
{
float dist;

if (streams.Case == 0)
{
// the easy case, the 3 distances of the fragment to the 3 edges
// is already computed, get the min

dist = min(min(streams.EdgeA.x, streams.EdgeA.y), streams.EdgeA.z);
}
else
{
// the tricky case, compute the distances and get the min from 2D lines
// given from the geometry shader

float2 af = streams.Position.xy - streams.EdgeA.xy;
float sqaf = dot(af, af);
float afCosA = dot(af, streams.EdgeA.zw);
dist = abs(sqaf - afCosA * afCosA);

float2 bf = streams.Position.xy - streams.EdgeB.xy;
float sqbf = dot(bf, bf);
float bfCosB = dot(bf, streams.EdgeB.zw);
dist = min(dist, abs(sqbf - bfCosB * bfCosB));

// only need to care about the 3rd edge for some cases
if (streams.Case == 1 || streams.Case == 2 || streams.Case == 4)
{
float afCosA0 = dot(af, normalize(streams.EdgeB.xy - streams.EdgeA.xy));
dist = min(dist, abs(sqaf - afCosA0 * afCosA0));
}

dist = sqrt(dist);
}

return dist;
}

// geometry shader
[maxvertexcount(3)]
void GSMain(triangle Input input[3], inout TriangleStream<Output> triangleStream)
{
// project to world
float4 positionWS[3];
positionWS[0] = projToWorld(input[0].Position, input[0].Normal);
positionWS[1] = projToWorld(input[1].Position, input[1].Normal);
positionWS[2] = projToWorld(input[2].Position, input[2].Normal);

// Compute the case from the positions of point in space.

uint vertexCase
= (positionWS[0].z < 0 ? 1 : 0) * 4
+ (positionWS[1].z < 0 ? 1 : 0) * 2
+ (positionWS[2].z < 0 ? 1 : 0);

// Compute the case from the positions of point in space.
if (vertexCase == 7)
{
return;
}

float2 points[3];
points[0] = projToWindow(positionWS[0]);
points[1] = projToWindow(positionWS[1]);
points[2] = projToWindow(positionWS[2]);

float3 vertExclude = float3(0, 0, 0);
float excludeEdgeLength = LineWidth + 100;

// general computation
if (vertexCase == 0)
{
// compute the edges vectors of transformed triangle
float2 edges[3];
edges[0] = points[1] - points[0];
edges[1] = points[2] - points[1];
edges[2] = points[0] - points[2];

// store the length of the edges
float lengths[3];
lengths[0] = length(edges[0]);
lengths[1] = length(edges[1]);
lengths[2] = length(edges[2]);

float3 edgesWS[3];
edgesWS[0] = input[1].Position.xyz - input[0].Position.xyz;
edgesWS[1] = input[2].Position.xyz - input[1].Position.xyz;
edgesWS[2] = input[0].Position.xyz - input[2].Position.xyz;

float lengthsWS[3];
lengthsWS[0] = length(edgesWS[0]);
lengthsWS[1] = length(edgesWS[1]);
lengthsWS[2] = length(edgesWS[2]);

float maxLength = max(max(lengthsWS[0], lengthsWS[1]), lengthsWS[2]);

vertExclude.x = lengthsWS[0] == maxLength ? 1 : 0;
vertExclude.y = lengthsWS[1] == maxLength ? 1 : 0;
vertExclude.z = lengthsWS[2] == maxLength ? 1 : 0;

// compute the cos angle of each vertices
float cosAngles[3];
cosAngles[0] = dot(-edges[2], edges[0]) / (lengths[2] * lengths[0]);
cosAngles[1] = dot(-edges[0], edges[1]) / (lengths[0] * lengths[1]);
cosAngles[2] = dot(-edges[1], edges[2]) / (lengths[1] * lengths[2]);

// the height for each vertices of triangle
float heights[3];
heights[1] = lengths[0] * sqrt(1 - cosAngles[0] * cosAngles[0]);
heights[2] = lengths[1] * sqrt(1 - cosAngles[1] * cosAngles[1]);
heights[0] = lengths[2] * sqrt(1 - cosAngles[2] * cosAngles[2]);

float edgeSigns[3];
edgeSigns[0] = (edges[0] > 0 ? 1 : -1);
edgeSigns[1] = (edges[1] > 0 ? 1 : -1);
edgeSigns[2] = (edges[2] > 0 ? 1 : -1);

float edgeOffsets[3];
edgeOffsets[0] = lengths[0] * (0.5 - 0.5 * edgeSigns[0]);
edgeOffsets[1] = lengths[1] * (0.5 - 0.5 * edgeSigns[1]);
edgeOffsets[2] = lengths[2] * (0.5 - 0.5 * edgeSigns[2]);

// vertex 0
streams = input[0];
streams.Case = vertexCase;
streams.Position = input[0].Position;
streams.EdgeA[0] = vertExclude.x * excludeEdgeLength;
streams.EdgeA[1] = heights[0];
streams.EdgeA[2] = vertExclude.z * excludeEdgeLength;
streams.EdgeB[0] = edgeOffsets[0];
streams.EdgeB[1] = edgeOffsets[1] + edgeSigns[1] * cosAngles[1] * lengths[0];
streams.EdgeB[2] = edgeOffsets[2] + edgeSigns[2] * lengths[2];
triangleStream.Append(streams);

// vertex 1
streams = input[1];
streams.Case = vertexCase;
streams.Position = input[1].Position;
streams.EdgeA[0] = vertExclude.x * excludeEdgeLength;
streams.EdgeA[1] = vertExclude.y * excludeEdgeLength;
streams.EdgeA[2] = heights[1];
streams.EdgeB[0] = edgeOffsets[0] + edgeSigns[0] * lengths[0];
streams.EdgeB[1] = edgeOffsets[1];
streams.EdgeB[2] = edgeOffsets[2] * edgeSigns[2] * cosAngles[2] * lengths[1];
triangleStream.Append(streams);

// vertex 2
streams = input[2];
streams.Case = vertexCase;
streams.Position = input[2].Position;
streams.EdgeA[0] = heights[2];
streams.EdgeA[1] = vertExclude.y * excludeEdgeLength;
streams.EdgeA[2] = vertExclude.z * excludeEdgeLength;
streams.EdgeB[0] = edgeOffsets[0] + edgeSigns[0] * cosAngles[0] * lengths[2];
streams.EdgeB[1] = edgeOffsets[1] + edgeSigns[1] * lengths[1];
streams.EdgeB[2] = edgeOffsets[2];
triangleStream.Append(streams);

triangleStream.RestartStrip();
}
else
{
// Else need some tricky computations

for (int i = 0; i < 3; i++)
{
streams = input[i];

streams.EdgeA = float4(0, 0, 0, 0);
streams.EdgeB = float4(0, 0, 0, 0);

streams.Case = vertexCase;
streams.EdgeA.xy = points[infoA[vertexCase]];
streams.EdgeB.xy = points[infoB[vertexCase]];

streams.EdgeA.zw = normalize(streams.EdgeA.xy - points[infoAd[vertexCase]]);
streams.EdgeB.zw = normalize(streams.EdgeB.xy - points[infoBd[vertexCase]]);

triangleStream.Append(streams);
}

triangleStream.RestartStrip();
}
}

// vertex shader
stage override void VSMain()
{
streams.ShadingPosition = projToWorld(streams.Position, streams.Normal);
}

// pixel shader
stage override void PSMain()
{
float dist = evalMinDistanceToEdges();
if (dist > 0.5 * LineWidth)
{
// too far from edge
discard;
}

streams.ColorTarget = LineColor;
}
};
Loading