├── imgui-glitch-shader.o ├── README.md ├── imgui-glitch-shader.hlsl └── shader.cpp /imgui-glitch-shader.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blick1337/imgui-glitch-shader/HEAD/imgui-glitch-shader.o -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Glitch Shader ImGui implementation 2 | Preview: https://youtu.be/0zXr7dUkJJg 3 | 4 | # Author 5 | This shader ported from GLSL Shader 6 | https://www.shadertoy.com/view/XtK3W3 7 | 8 | All thanks dyvoid(https://www.shadertoy.com/user/dyvoid) for shader. 9 | 10 | # Self compile 11 | fxc /T ps_2_a /Fo imgui-glitch-shader.o imgui-glitch-shader.hlsl 12 | -------------------------------------------------------------------------------- /imgui-glitch-shader.hlsl: -------------------------------------------------------------------------------- 1 | //ported from https://www.shadertoy.com/view/XtK3W3 2 | 3 | sampler texSampler : register(s0); 4 | 5 | const float2 iResolution : register(c0); 6 | 7 | const float iTime : register(c1); 8 | 9 | float3 fmod289(float3 x) { 10 | return x - floor(x * (1.0 / 289.0)) * 289.0; 11 | } 12 | 13 | float2 fmod289(float2 x) { 14 | return x - floor(x * (1.0 / 289.0)) * 289.0; 15 | } 16 | 17 | float3 permute(float3 x) { 18 | return fmod289(((x*34.0)+1.0)*x); 19 | } 20 | 21 | float snoise(float2 v) 22 | { 23 | const float4 C = float4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 24 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) 25 | -0.577350269189626, // -1.0 + 2.0 * C.x 26 | 0.024390243902439); // 1.0 / 41.0 27 | // First corner 28 | float2 i = floor(v + dot(v, C.yy) ); 29 | float2 x0 = v - i + dot(i, C.xx); 30 | 31 | // Other corners 32 | float2 i1; 33 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 34 | //i1.y = 1.0 - i1.x; 35 | i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0); 36 | // x0 = x0 - 0.0 + 0.0 * C.xx ; 37 | // x1 = x0 - i1 + 1.0 * C.xx ; 38 | // x2 = x0 - 1.0 + 2.0 * C.xx ; 39 | float4 x12 = x0.xyxy + C.xxzz; 40 | x12.xy -= i1; 41 | 42 | // Permutations 43 | i = fmod289(i); // Avoid truncation effects in permutation 44 | float3 p = permute( permute( i.y + float3(0.0, i1.y, 1.0 )) 45 | + i.x + float3(0.0, i1.x, 1.0 )); 46 | 47 | float3 m = max(0.5 - float3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); 48 | m = m*m ; 49 | m = m*m ; 50 | 51 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. 52 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 53 | 54 | float3 x = 2.0 * frac(p * C.www) - 1.0; 55 | float3 h = abs(x) - 0.5; 56 | float3 ox = floor(x + 0.5); 57 | float3 a0 = x - ox; 58 | 59 | // Normalise gradients implicitly by scaling m 60 | // Approximation of: m *= inversesqrt( a0*a0 + h*h ); 61 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 62 | 63 | // Compute final noise value at P 64 | float3 g; 65 | g.x = a0.x * x0.x + h.x * x0.y; 66 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 67 | return 130.0 * dot(m, g); 68 | } 69 | 70 | float rand(float2 co) 71 | { 72 | return frac(sin(dot(co.xy,float2(12.9898,78.233))) * 43758.5453); 73 | } 74 | 75 | 76 | float4 main(float2 fragCoord : TEXCOORD0) : COLOR0 77 | { 78 | float4 fragColor = tex2D(texSampler, fragCoord); 79 | 80 | float2 uv = fragCoord.xy / iResolution.xy; 81 | float time = iTime * 2.0; 82 | 83 | // Create large, incidental noise waves 84 | float noise = max(0.0, snoise(float2(time, uv.y * 0.3)) - 0.3) * (1.0 / 0.7); 85 | 86 | // Offset by smaller, constant noise waves 87 | noise = noise + (snoise(float2(time*10.0, uv.y * 2.4)) - 0.5) * 0.15; 88 | 89 | // Apply the noise as x displacement for every line 90 | float xpos = uv.x - noise * noise * 0.25; 91 | fragColor = tex2D(texSampler, float2(xpos, uv.y)); 92 | 93 | // lerp in some random interference for lines 94 | 95 | float randtest = rand(float2(uv.y * time, uv.y * time)); 96 | 97 | fragColor.rgb = lerp(fragColor.rgb, float3(randtest, randtest, randtest), noise * 0.3).rgb; 98 | 99 | // Apply a line pattern every 4 pixels 100 | if (floor(fmod(fragCoord.y * 0.25, 2.0)) == 0.0) 101 | { 102 | fragColor.rgb *= 1.0 - (0.15 * noise); 103 | } 104 | 105 | // Shift green/blue channels (using the red channel) 106 | fragColor.g = lerp(fragColor.r, tex2D(texSampler, float2(xpos + noise * 0.05, uv.y)).g, 0.25); 107 | fragColor.b = lerp(fragColor.r, tex2D(texSampler, float2(xpos - noise * 0.05, uv.y)).b, 0.25); 108 | 109 | return fragColor; 110 | } 111 | -------------------------------------------------------------------------------- /shader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "imgui.h" 9 | #include "imgui_internal.h" 10 | #include "imgui_impl_dx9.h" 11 | #include "imgui_impl_win32.h" 12 | 13 | #pragma comment( lib, "d3d9.lib" ) 14 | #pragma comment( lib, "d3dx9.lib" ) 15 | 16 | IDirect3DPixelShader9* m_pGlitchShader = nullptr; 17 | IDirect3DTexture9* m_pGlitchTexture = nullptr; 18 | IDirect3DDevice9* m_pDevice = nullptr; //fill on initialize render 19 | IDirect3DSurface9* m_pBackupRenderTarget = nullptr; //backbuffer surface 20 | 21 | 22 | /// initialize part /// 23 | bool initialize_shader() 24 | { 25 | if (m_pDevice->CreatePixelShader(reinterpret_cast(blur_shader_data), &m_pBlurShader) != D3D_OK) //blur_shader_data - array of bytes imgui-glitch-shader.o 26 | return false; 27 | 28 | if (m_pDevice->CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pGlitchTexture, nullptr) != D3D_OK) // m_width and m_height - screen size 29 | return false; 30 | 31 | return true; 32 | } 33 | 34 | void on_lost_device() 35 | { 36 | if (m_pGlitchShader) 37 | { 38 | m_pGlitchShader->Release(); 39 | m_pGlitchShader = nullptr; 40 | } 41 | 42 | if (m_pGlitchTexture) 43 | { 44 | m_pGlitchTexture->Release(); 45 | m_pGlitchTexture = nullptr; 46 | } 47 | } 48 | 49 | 50 | /// imgui implementation part /// 51 | 52 | void glitch_begin(const ImDrawList* parent_list, const ImDrawCmd* cmd) 53 | { 54 | IDirect3DSurface9* m_pBackupBuffer; 55 | m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackupBuffer); //get backbuffer 56 | m_pDevice->GetRenderTarget(0, &m_pBackupRenderTarget); 57 | 58 | IDirect3DSurface9* m_pSurface; 59 | 60 | m_pGlitchTexture->GetSurfaceLevel(0, &m_pSurface); //get glitch texture surface 61 | m_pDevice->StretchRect(m_pBackupBuffer, NULL, m_pSurface, NULL, D3DTEXF_NONE); //copy backbuffer texture to glitch texture 62 | m_pDevice->SetRenderTarget(0, m_pSurface); //set new render target(glitch) 63 | 64 | m_pBackupBuffer->Release(); 65 | m_pSurface->Release(); 66 | 67 | m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); 68 | m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); 69 | } 70 | 71 | void glitch_texture(const ImDrawList* parent_list, const ImDrawCmd* cmd) 72 | { 73 | static float time = 0.f; 74 | 75 | m_pDevice->SetPixelShader(m_pGlitchShader); //set glitch shader 76 | 77 | const float params_size[2] = { 1.f, 1.f }; 78 | const float params_time[1] = { time }; 79 | 80 | m_pDevice->SetPixelShaderConstantF(0, params_size, 2); //set screen size (1.f, 1.f) - fullscreen 81 | m_pDevice->SetPixelShaderConstantF(1, params_time, 1); //set time 82 | 83 | time += ImGui::GetIO().DeltaTime * 0.25f; //update time counter 84 | } 85 | 86 | void glitch_end(const ImDrawList* parent_list, const ImDrawCmd* cmd) 87 | { 88 | //restore render target, restore states 89 | m_pDevice->SetRenderTarget(0, m_pBackupRenderTarget); 90 | m_pBackupRenderTarget->Release(); 91 | 92 | m_pDevice->SetPixelShader(nullptr); 93 | m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); 94 | m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); 95 | } 96 | 97 | /// render shader texture where u want /// 98 | 99 | void glitch_draw(ImDrawList* drawList) 100 | { 101 | auto& io = ImGui::GetIO(); 102 | 103 | drawList->AddCallback(glitch_begin, 0); //prepare texture 104 | 105 | drawList->AddCallback(glitch_texture, 0); //draw glitch 106 | drawList->AddImage(m_pGlitchTexture, ImVec2(0.f, 0.f), ImVec2(io.DisplaySize.x, io.DisplaySize.y)); 107 | 108 | drawList->AddCallback(glitch_end, 0); //restore texture 109 | 110 | drawList->AddImage(m_pGlitchTexture, ImVec2(0.f, 0.f), ImVec2(io.DisplaySize.x, io.DisplaySize.y)); //render texture 111 | } 112 | 113 | --------------------------------------------------------------------------------