Skip to content

Commit

Permalink
Updated readme and added intensity to crt effect
Browse files Browse the repository at this point in the history
  • Loading branch information
ben_singer committed Nov 11, 2024
1 parent ff82a60 commit d0c88c1
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 19 deletions.
33 changes: 33 additions & 0 deletions .nuget/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,36 @@ Reduces apparent bit depth across all channels individually to produce a banding

## Hello World
For a Hello World example with a simple UI see [LoFiEffects.WPF.TestApp/MainWindow.xaml](https://github.com/benpollarduk/LoFiEffects.WPF/blob/main/LoFiEffects.WPF.TestApp/MainWindow.xaml)

## Compiling Shaders
Shaders can be compiled using FXC.exe. The *LoiEffects.WPF* project has a pre-build event that can be used to compile a shader effect when it is built.

The *Shader* variable needs to be set to the name of the shader effect to compile:

```
set Shader=Noise
```

> Note: The path to fxc.exe may need to be changed to suit your build environment depending on the version installed.
```
REM to compile a shader specify the name of the shader, e.g:
REM set Shader=Crt
REM Otherwise use "", e.g:
REM set Shader=""
set Shader=""
set Fxc=C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\fxc.exe
set Input=$(ProjectDir)Effects\HLSL\%Shader%.fx
set Output=$(ProjectDir)Effects\Shaders\%Shader%.ps
if %Shader% == "" (
echo Not compiling shader as not shader set. To compile a shader edit the $(ProjectName) pre-build event.
) else (
echo Compiling shader %Input%...
"%Fxc%" /O0 /Zi /T ps_2_0 /Fo "%Output%" "%Input%"
echo Shader compiled to %Output%. Don't forget to set compiled shader build action to "Resource".
)
```

> Note: If a shader is built for the first time its *Build Action* will need to be manually set to *Resource* to be used by the project.
14 changes: 13 additions & 1 deletion LoFiEffects.WPF.TestApp/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,19 @@
<Label Content="{Binding Source={StaticResource PixelateEffect}, Path=Intensity, Mode=OneWay, Converter={StaticResource DoubleRoundingConverter}}" Grid.Row="0" Grid.Column="2"/>
</Grid>
<Grid Visibility="{Binding ElementName=CrtRadioButton, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}">
<CheckBox Content="Include scanlines?" IsChecked="{Binding Source={StaticResource CrtEffect}, Path=IncludeScanlines, Mode=TwoWay}"/>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Label Content="Intensity:" Grid.Row="0" Grid.Column="0"/>
<Slider Value="{Binding Source={StaticResource CrtEffect}, Path=Intensity, Mode=TwoWay}" TickFrequency="0.01" Minimum="0" Maximum="1" Grid.Row="0" Grid.Column="1"/>
<Label Content="{Binding Source={StaticResource CrtEffect}, Path=Intensity, Mode=OneWay, Converter={StaticResource DoubleRoundingConverter}}" Grid.Row="0" Grid.Column="2"/>
<CheckBox Content="Include scanlines?" IsChecked="{Binding Source={StaticResource CrtEffect}, Path=IncludeScanlines, Mode=TwoWay}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"/>
</Grid>
</StackPanel>
</GroupBox>
Expand Down
17 changes: 17 additions & 0 deletions LoFiEffects.WPF.Tests/Effects/CrtEffect_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,22 @@ public void GAdjustIncludeScanlines_ThenNoException()
Assert.Fail($"Exception occurred: {ex.Message}");
}
}

[TestMethod]
public void GAdjustIntensity_ThenNoException()
{
try
{
CrtEffect effect = new()
{
Intensity = 0.5
};
Assert.AreEqual(0.5, effect.Intensity);
}
catch (Exception ex)
{
Assert.Fail($"Exception occurred: {ex.Message}");
}
}
}
}
15 changes: 15 additions & 0 deletions LoFiEffects.WPF/Effects/CrtEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ protected double IncludeScanlinesDouble
set { SetValue(IncludeScanlinesDoubleProperty, value); }
}

/// <summary>
/// Get or set the intensity. Higher values will produce a more pronounced effect. This is a dependency property.
/// </summary>
public double Intensity
{
get { return (double)GetValue(IntensityProperty); }
set { SetValue(IntensityProperty, value); }
}

#endregion

#region DependencyProperties
Expand Down Expand Up @@ -91,6 +100,11 @@ protected double IncludeScanlinesDouble
/// </summary>
public static readonly DependencyProperty IncludeScanlinesDoubleProperty = DependencyProperty.Register("IncludeScanlinesDouble", typeof(double), typeof(CrtEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(2)));

/// <summary>
/// Identifies the CrtEffect.Intensity property.
/// </summary>
public static readonly DependencyProperty IntensityProperty = DependencyProperty.Register("Intensity", typeof(double), typeof(CrtEffect), new UIPropertyMetadata(1.0, PixelShaderConstantCallback(3)));

#endregion

#region Constructors
Expand All @@ -106,6 +120,7 @@ public CrtEffect()
UpdateShaderValue(TextureWidthProperty);
UpdateShaderValue(TextureHeightProperty);
UpdateShaderValue(IncludeScanlinesDoubleProperty);
UpdateShaderValue(IntensityProperty);
}

#endregion
Expand Down
23 changes: 7 additions & 16 deletions LoFiEffects.WPF/Effects/HLSL/Crt.fx
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,24 @@ sampler2D implicitInput;
float textureWidth : register(c0);
float textureHeight : register(c1);
float includeScanlines : register(c2);
float intensity : register(c3);

float4 main(float2 uv : TEXCOORD0) : COLOR
{
float2 pixelCoords = uv * float2(textureWidth, textureHeight);
int x = int(pixelCoords.x);
int y = int(pixelCoords.y);
float4 color = tex2D(implicitInput, uv);
float clampedIntensity = clamp(intensity, 0.0, 1.0);

// scanline mode
if (includeScanlines > 0)
if (includeScanlines > 0 && y % 2 == 1)
{
if (y % 2 == 1)
{
return float4(0.0, 0.0, 0.0, color.a);
}

float redChannel = (x % 4 == 0) ? color.r : 0.0;
float greenChannel = (x % 4 == 1) ? color.g : 0.0;
float blueChannel = (x % 4 == 2) ? color.b : 0.0;

return float4(redChannel, greenChannel, blueChannel, color.a);
return float4 (0.0, 0.0, 0.0, color.a);
}

// non-scanline mode
float redChannel = (x % 3 == 0) ? color.r : 0.0;
float greenChannel = (x % 3 == 1) ? color.g : 0.0;
float blueChannel = (x % 3 == 2) ? color.b : 0.0;
float redChannel = (x % 3 == 0) ? color.r : (1.0 - clampedIntensity) * color.r;
float greenChannel = (x % 3 == 1) ? color.g : (1.0 - clampedIntensity) * color.g;
float blueChannel = (x % 3 == 2) ? color.b : (1.0 - clampedIntensity) * color.b;

return float4(redChannel, greenChannel, blueChannel, color.a);
}
Binary file modified LoFiEffects.WPF/Effects/Shaders/Crt.ps
Binary file not shown.
2 changes: 1 addition & 1 deletion LoFiEffects.WPF/LoFiEffects.WPF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
</ItemGroup>

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="::echo COMPILING SHADERS:&#xD;&#xA;::set Fxc=C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\fxc.exe&#xD;&#xA;::set Input=$(ProjectDir)Effects\HLSL\Crt.fx&#xD;&#xA;::set Output=$(ProjectDir)Effects\Shaders\Crt.ps&#xD;&#xA;::&quot;%25Fxc%25&quot; /O0 /Zi /T ps_2_0 /Fo &quot;%25Output%25&quot; &quot;%25Input%25&quot;&#xD;&#xA;::echo DON'T FORGET TO SET SHADER (.ps) FILE BUILD ACTION TO RESOURCE!" />
<Exec Command="REM to compile a shader specify the name of the shader, e.g:&#xD;&#xA;REM set Shader=Crt&#xD;&#xA;REM Otherwise use &quot;&quot;, e.g:&#xD;&#xA;REM set Shader=&quot;&quot;&#xD;&#xA;set Shader=&quot;&quot;&#xD;&#xA;&#xD;&#xA;set Fxc=C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\fxc.exe&#xD;&#xA;set Input=$(ProjectDir)Effects\HLSL\%25Shader%25.fx&#xD;&#xA;set Output=$(ProjectDir)Effects\Shaders\%25Shader%25.ps&#xD;&#xA;&#xD;&#xA;if %25Shader%25 == &quot;&quot; (&#xD;&#xA; echo Not compiling shader as not shader set. To compile a shader edit the $(ProjectName) pre-build event.&#xD;&#xA;) else (&#xD;&#xA; echo Compiling shader %25Input%25...&#xD;&#xA; &quot;%25Fxc%25&quot; /O0 /Zi /T ps_2_0 /Fo &quot;%25Output%25&quot; &quot;%25Input%25&quot;&#xD;&#xA; echo Shader compiled to %25Output%25. Don't forget to set compiled shader build action to &quot;Resource&quot;.&#xD;&#xA;)" />
</Target>

</Project>
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ An effect that aims to create the impression that the visual is being displayed
```xaml
<Button>
<Button.Effect>
<CrtEffect TextureWidth="100" TextureHeight="35" IncludeScanlines="False"/>
<CrtEffect TextureWidth="100" TextureHeight="35" IncludeScanlines="False" Intensity="1"/>
</Button.Effect>
</Button>
```
Expand All @@ -93,6 +93,7 @@ An effect that aims to create the impression that the visual is being displayed
* **TextureWidth**: A double specifying the rendered width of the texture in WPF units.
* **TextureHeight**: A double specifying the rendered height of the texture in WPF units.
* **IncludeScanlines**: A boolean specifying if scan lines should be included.
* **Intensity**: A double specifying the intensity of the effect within a normalised range of 0-1.

### Degrade
Adds overall degradation to the visual. Similar to the *Noise* effect but works in a subtractive manner.
Expand Down Expand Up @@ -201,3 +202,36 @@ Reduces apparent bit depth across all channels individually to produce a banding

## Hello World
For a Hello World example with a simple UI see [LoFiEffects.WPF.TestApp/MainWindow.xaml](https://github.com/benpollarduk/LoFiEffects.WPF/blob/main/LoFiEffects.WPF.TestApp/MainWindow.xaml)

## Compiling Shaders
Shaders can be compiled using FXC.exe. The *LoiEffects.WPF* project has a pre-build event that can be used to compile a shader effect when it is built.

The *Shader* variable needs to be set to the name of the shader effect to compile:

```
set Shader=Noise
```

> Note: The path to fxc.exe may need to be changed to suit your build environment depending on the version installed.
```
REM to compile a shader specify the name of the shader, e.g:
REM set Shader=Crt
REM Otherwise use "", e.g:
REM set Shader=""
set Shader=""
set Fxc=C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\fxc.exe
set Input=$(ProjectDir)Effects\HLSL\%Shader%.fx
set Output=$(ProjectDir)Effects\Shaders\%Shader%.ps
if %Shader% == "" (
echo Not compiling shader as not shader set. To compile a shader edit the $(ProjectName) pre-build event.
) else (
echo Compiling shader %Input%...
"%Fxc%" /O0 /Zi /T ps_2_0 /Fo "%Output%" "%Input%"
echo Shader compiled to %Output%. Don't forget to set compiled shader build action to "Resource".
)
```

> Note: If a shader is built for the first time its *Build Action* will need to be manually set to *Resource* to be used by the project.

0 comments on commit d0c88c1

Please sign in to comment.