diff --git a/DX11Starter.vcxproj b/DX11Starter.vcxproj index 3479be6..17469ca 100644 --- a/DX11Starter.vcxproj +++ b/DX11Starter.vcxproj @@ -285,6 +285,9 @@ $(OutDir)/Assets/Models + + + diff --git a/DX11Starter.vcxproj.filters b/DX11Starter.vcxproj.filters index f39a2d5..1959b75 100644 --- a/DX11Starter.vcxproj.filters +++ b/DX11Starter.vcxproj.filters @@ -121,4 +121,9 @@ Assets\Models + + + Shaders + + \ No newline at end of file diff --git a/Includes.hlsli b/Includes.hlsli new file mode 100644 index 0000000..80f696b --- /dev/null +++ b/Includes.hlsli @@ -0,0 +1,124 @@ +#ifndef __SHADER_INCLUDES__ +#define __SHADER_INCLUDES__ + +// Struct representing the data we expect to receive from earlier pipeline stages +// - Should match the output of our corresponding vertex shader +// - The name of the struct itself is unimportant +// - The variable names don't have to match other shaders (just the semantics) +// - Each variable must have a semantic, which defines its usage +struct VertexToPixel +{ + // Data type + // | + // | Name Semantic + // | | | + // v v v + float4 screenPosition : SV_POSITION; + float2 uv : TEXCOORD; +}; + +// Struct representing a single vertex worth of data +// - This should match the vertex definition in our C++ code +// - By "match", I mean the size, order and number of members +// - The name of the struct itself is unimportant, but should be descriptive +// - Each variable must have a semantic, which defines its usage +struct VertexShaderInput +{ + // Data type + // | + // | Name Semantic + // | | | + // v v v + float3 localPosition : POSITION; + float3 normal : NORMAL; + float2 uv : UV; +}; + +/// BEGIN THIRD PARTY /// +/// SOURCE: https://thebookofshaders.com/edit.php#11/2d-snoise-clear.frag /// + +// Some useful functions +float3 mod289(float3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } +float2 mod289(float2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } +float3 permute(float3 x) { return mod289(((x * 34.0) + 1.0) * x); } + +// +// Description : GLSL 2D simplex noise function +// Author : Ian McEwan, Ashima Arts +// Maintainer : ijm +// Lastmod : 20110822 (ijm) +// License : +// Copyright (C) 2011 Ashima Arts. All rights reserved. +// Distributed under the MIT License. See LICENSE file. +// https://github.com/ashima/webgl-noise +// +float snoise(float2 v) +{ + // Precompute values for skewed triangular grid + const float4 C = float4(0.211324865405187, + // (3.0-sqrt(3.0))/6.0 + 0.366025403784439, + // 0.5*(sqrt(3.0)-1.0) + -0.577350269189626, + // -1.0 + 2.0 * C.x + 0.024390243902439); + // 1.0 / 41.0 + + // First corner (x0) + float2 i = floor(v + dot(v, C.yy)); + float2 x0 = v - i + dot(i, C.xx); + + // Other two corners (x1, x2) + float2 i1 = float2(0, 0); + i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0); + float2 x1 = x0.xy + C.xx - i1; + float2 x2 = x0.xy + C.zz; + + // Do some permutations to avoid + // truncation effects in permutation + i = mod289(i); + float3 p = permute( + permute(i.y + float3(0.0, i1.y, 1.0)) + + i.x + float3(0.0, i1.x, 1.0)); + + float3 m = max(0.5 - float3( + dot(x0, x0), + dot(x1, x1), + dot(x2, x2) + ), 0.0); + + m = m * m; + m = m * m; + + // Gradients: + // 41 pts uniformly over a line, mapped onto a diamond + // The ring size 17*17 = 289 is close to a multiple + // of 41 (41*7 = 287) + + float3 x = 2.0 * frac(p * C.www) - 1.0; + float3 h = abs(x) - 0.5; + float3 ox = floor(x + 0.5); + float3 a0 = x - ox; + + // Normalise gradients implicitly by scaling m + // Approximation of: m *= inversesqrt(a0*a0 + h*h); + m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h); + + // Compute final noise value at P + float3 g = float3(0, 0, 0); + g.x = a0.x * x0.x + h.x * x0.y; + g.yz = a0.yz * float2(x1.x, x2.x) + h.yz * float2(x1.y, x2.y); + return 130.0 * dot(m, g); +} + +/// SOURCE: https://thebookofshaders.com/10/ /// +float random(float2 st) +{ + return frac(sin(dot(st.xy, + float2(12.9898, 78.233))) * + 43758.5453123); +} + +/// END THIRD PARTY /// + +#endif diff --git a/PixelShader.hlsl b/PixelShader.hlsl index fbc68fb..302a409 100644 --- a/PixelShader.hlsl +++ b/PixelShader.hlsl @@ -1,24 +1,10 @@ +#include "Includes.hlsli" + cbuffer ExternalData : register(b0) { float4 tint; } -// Struct representing the data we expect to receive from earlier pipeline stages -// - Should match the output of our corresponding vertex shader -// - The name of the struct itself is unimportant -// - The variable names don't have to match other shaders (just the semantics) -// - Each variable must have a semantic, which defines its usage -struct VertexToPixel -{ - // Data type - // | - // | Name Semantic - // | | | - // v v v - float4 screenPosition : SV_POSITION; - float2 uv : TEXCOORD; -}; - // -------------------------------------------------------- // The entry point (main method) for our pixel shader // @@ -35,4 +21,4 @@ float4 main(VertexToPixel input) : SV_TARGET // interpolated for each pixel between the corresponding vertices // of the triangle we're rendering return tint; -} \ No newline at end of file +} diff --git a/RandomPixelShader.hlsl b/RandomPixelShader.hlsl index ad0ec8b..addc7b7 100644 --- a/RandomPixelShader.hlsl +++ b/RandomPixelShader.hlsl @@ -1,89 +1,4 @@ -/// BEGIN THIRD PARTY /// -/// SOURCE: https://thebookofshaders.com/edit.php#11/2d-snoise-clear.frag /// - -// Some useful functions -float3 mod289(float3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } -float2 mod289(float2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } -float3 permute(float3 x) { return mod289(((x * 34.0) + 1.0) * x); } - -// -// Description : GLSL 2D simplex noise function -// Author : Ian McEwan, Ashima Arts -// Maintainer : ijm -// Lastmod : 20110822 (ijm) -// License : -// Copyright (C) 2011 Ashima Arts. All rights reserved. -// Distributed under the MIT License. See LICENSE file. -// https://github.com/ashima/webgl-noise -// -float snoise(float2 v) -{ - // Precompute values for skewed triangular grid - const float4 C = float4(0.211324865405187, - // (3.0-sqrt(3.0))/6.0 - 0.366025403784439, - // 0.5*(sqrt(3.0)-1.0) - -0.577350269189626, - // -1.0 + 2.0 * C.x - 0.024390243902439); - // 1.0 / 41.0 - - // First corner (x0) - float2 i = floor(v + dot(v, C.yy)); - float2 x0 = v - i + dot(i, C.xx); - - // Other two corners (x1, x2) - float2 i1 = float2(0, 0); - i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0); - float2 x1 = x0.xy + C.xx - i1; - float2 x2 = x0.xy + C.zz; - - // Do some permutations to avoid - // truncation effects in permutation - i = mod289(i); - float3 p = permute( - permute(i.y + float3(0.0, i1.y, 1.0)) - + i.x + float3(0.0, i1.x, 1.0)); - - float3 m = max(0.5 - float3( - dot(x0, x0), - dot(x1, x1), - dot(x2, x2) - ), 0.0); - - m = m * m; - m = m * m; - - // Gradients: - // 41 pts uniformly over a line, mapped onto a diamond - // The ring size 17*17 = 289 is close to a multiple - // of 41 (41*7 = 287) - - float3 x = 2.0 * frac(p * C.www) - 1.0; - float3 h = abs(x) - 0.5; - float3 ox = floor(x + 0.5); - float3 a0 = x - ox; - - // Normalise gradients implicitly by scaling m - // Approximation of: m *= inversesqrt(a0*a0 + h*h); - m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h); - - // Compute final noise value at P - float3 g = float3(0, 0, 0); - g.x = a0.x * x0.x + h.x * x0.y; - g.yz = a0.yz * float2(x1.x, x2.x) + h.yz * float2(x1.y, x2.y); - return 130.0 * dot(m, g); -} - -/// SOURCE: https://thebookofshaders.com/10/ /// -float random(float2 st) -{ - return frac(sin(dot(st.xy, - float2(12.9898, 78.233))) * - 43758.5453123); -} - -/// END THIRD PARTY /// +#include "Includes.hlsli" cbuffer ExternalData : register(b0) { @@ -91,22 +6,6 @@ cbuffer ExternalData : register(b0) float noise; } -// Struct representing the data we expect to receive from earlier pipeline stages -// - Should match the output of our corresponding vertex shader -// - The name of the struct itself is unimportant -// - The variable names don't have to match other shaders (just the semantics) -// - Each variable must have a semantic, which defines its usage -struct VertexToPixel -{ - // Data type - // | - // | Name Semantic - // | | | - // v v v - float4 screenPosition : SV_POSITION; - float2 uv : TEXCOORD; -}; - // -------------------------------------------------------- // The entry point (main method) for our pixel shader // @@ -127,4 +26,4 @@ float4 main(VertexToPixel input) : SV_TARGET sin(snoise(input.uv * noise) + tint.g - random(input.uv)) + (tint.g * 0.5), sin(snoise(input.uv * noise) + tint.b - random(input.uv)) + (tint.b * 0.5), cos(random(input.screenPosition))); -} \ No newline at end of file +} diff --git a/VertexShader.hlsl b/VertexShader.hlsl index 471a4d8..cd0ab93 100644 --- a/VertexShader.hlsl +++ b/VertexShader.hlsl @@ -1,3 +1,5 @@ +#include "Includes.hlsli" + cbuffer ExternalData : register(b0) { matrix world; @@ -5,39 +7,6 @@ cbuffer ExternalData : register(b0) matrix projection; } -// Struct representing a single vertex worth of data -// - This should match the vertex definition in our C++ code -// - By "match", I mean the size, order and number of members -// - The name of the struct itself is unimportant, but should be descriptive -// - Each variable must have a semantic, which defines its usage -struct VertexShaderInput -{ - // Data type - // | - // | Name Semantic - // | | | - // v v v - float3 localPosition : POSITION; - float3 normal : NORMAL; - float2 uv : UV; -}; - -// Struct representing the data we're sending down the pipeline -// - Should match our pixel shader's input (hence the name: Vertex to Pixel) -// - At a minimum, we need a piece of data defined tagged as SV_POSITION -// - The name of the struct itself is unimportant, but should be descriptive -// - Each variable must have a semantic, which defines its usage -struct VertexToPixel -{ - // Data type - // | - // | Name Semantic - // | | | - // v v v - float4 screenPosition : SV_POSITION; - float2 uv : TEXCOORD; -}; - // -------------------------------------------------------- // The entry point (main method) for our vertex shader // @@ -71,4 +40,4 @@ VertexToPixel main( VertexShaderInput input ) // Whatever we return will make its way through the pipeline to the // next programmable stage we're using (the pixel shader for now) return output; -} \ No newline at end of file +}