diff --git a/src/DynamoCoreWpf/ViewModels/Watch3D/HelixWatch3DViewModel.cs b/src/DynamoCoreWpf/ViewModels/Watch3D/HelixWatch3DViewModel.cs index 56bade0b24e..1bd5523d7ac 100644 --- a/src/DynamoCoreWpf/ViewModels/Watch3D/HelixWatch3DViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Watch3D/HelixWatch3DViewModel.cs @@ -1285,12 +1285,10 @@ private void InitializeHelix() Name = HeadLightName }; - //TODO verify this binding is working. headLight.SetBinding( DirectionalLight3D.DirectionProperty, - new Binding("LookDirection") { - Source = this, - Path = new PropertyPath("Camera.LookDirection") + new Binding(nameof(PerspectiveCamera.LookDirection)) { + Source = this.Camera } ); diff --git a/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/psDynamoMesh b/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/psDynamoMesh index 8982354695f..31bfa80c955 100644 Binary files a/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/psDynamoMesh and b/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/psDynamoMesh differ diff --git a/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/vsDynamoMesh b/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/vsDynamoMesh index bee73b04560..db55687595c 100644 Binary files a/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/vsDynamoMesh and b/src/DynamoCoreWpf/ViewModels/Watch3D/compiledShaders/vsDynamoMesh differ diff --git a/src/DynamoCoreWpf/ViewModels/Watch3D/shaderSource/psDynamoMesh.hlsl b/src/DynamoCoreWpf/ViewModels/Watch3D/shaderSource/psDynamoMesh.hlsl index eb39717432c..7229c0920c8 100644 --- a/src/DynamoCoreWpf/ViewModels/Watch3D/shaderSource/psDynamoMesh.hlsl +++ b/src/DynamoCoreWpf/ViewModels/Watch3D/shaderSource/psDynamoMesh.hlsl @@ -26,7 +26,7 @@ SamplerState LinearSampler MaxAnisotropy = 16; }; -float4 main(PSInputCustom input) : SV_Target +float4 main(PSInputCustom input, bool isFrontFacing : SV_IsFrontFace) : SV_Target { //TODO move to common or pass in from material or the vParams. float4 vSelectionColor = float4(0.0, 0.62, 1.0, 1.0); @@ -61,6 +61,15 @@ float4 main(PSInputCustom input) : SV_Target // get per pixel vector to eye-position float3 eye = normalize(vEyePos - input.wp.xyz); + // To support two-sided surface lighting, we flip + // the normal of the surface if it's facing + // away from us. There are many tessellated surfaces that have + // normals that are not as expected. + // SV_IsFrontFace is a system value (GPU sets this for us) you can read about here: + //https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics + input.n = isFrontFacing ? input.n : -input.n; + + //we need to support diffuse masps for nodes like Display.BySurfaceColors which use diffuse maps //instead of vertex colors. if (bHasDiffuseMap) diff --git a/src/VisualizationTests/HelixWatch3DViewModelTests.cs b/src/VisualizationTests/HelixWatch3DViewModelTests.cs index 17384bad4a1..a39175e0887 100644 --- a/src/VisualizationTests/HelixWatch3DViewModelTests.cs +++ b/src/VisualizationTests/HelixWatch3DViewModelTests.cs @@ -646,6 +646,23 @@ public void Watch3D_Disconnect_Reconnect_CorrectRenderings() Assert.AreEqual(5, ((HelixWatch3DViewModel)view.DataContext).Element3DDictionary.Count()); } + [Test] + public void HelixWatch3dViewModel_HeadLight_Camera_HaveSameLookVector() + { + var bPreviewVm = ViewModel.BackgroundPreviewViewModel as HelixWatch3DViewModel; + var camdir = bPreviewVm.Camera.LookDirection; + var headlight = bPreviewVm.SceneItems.Where(x => x.Name.ToLower().Contains("headlight")).FirstOrDefault(); + var headlightDir = (headlight as DirectionalLight3D).Direction; + Assert.AreEqual(camdir, headlightDir); + + //move the camera + bPreviewVm.Camera.LookDirection = new Vector3D(5,5,5); + //assert they match + headlightDir = (headlight as DirectionalLight3D).Direction; + Assert.AreEqual(new Vector3D(5, 5, 5), headlightDir); + + } + [Test] public void HelixWatch3DViewModel_DisableGrid_GridDoesNotDraw() {