Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
1.0.0:postfx [2023/02/23 14:13] – created admin | 1.0.0:postfx [2023/02/23 14:41] (current) – [Shaders] admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PostFX ====== | ====== PostFX ====== | ||
- | Even though Gorilla3D is compatible Firemonkey post effects, it is difficult for many users to build their own post effect. | + | Even though Gorilla3D is compatible |
To solve this issue we provide the TGorillaRenderPassPostFX component. | To solve this issue we provide the TGorillaRenderPassPostFX component. | ||
- | It is now possible for you to easily create your own effect and to design it in the IDE at design time. | + | It is now possible for you to easily create your own effect and to write a shader |
{{: | {{: | ||
+ | |||
+ | ===== DesignTime ===== | ||
+ | |||
+ | - Drop a TGorillaRenderPassPostFX component from component palette onto your form | ||
+ | - Select your TGorillaRenderPassPostFX instance in structure view | ||
+ | - Link the GorillaViewport instance to the " | ||
+ | - Open " | ||
+ | - Write GLSL shader code using "vec3 SurfaceShader(inout TLocals DATA){...}" | ||
+ | |||
+ | Here is some nice television post-effect for the surface shader. | ||
+ | |||
+ | Just copy & paste into **GorillaRenderPassPostFX1.SurfaceShader** property editor: | ||
+ | |||
+ | <file glsl> | ||
+ | vec3 mod289(vec3 x) { | ||
+ | return x - floor(x * (1.0 / 289.0)) * 289.0; | ||
+ | } | ||
+ | |||
+ | vec2 mod289(vec2 x) { | ||
+ | return x - floor(x * (1.0 / 289.0)) * 289.0; | ||
+ | } | ||
+ | |||
+ | vec3 permute(vec3 x) { | ||
+ | return mod289(((x*34.0)+1.0)*x); | ||
+ | } | ||
+ | |||
+ | float snoise(vec2 v){ | ||
+ | const vec4 C = vec4(0.211324865405187, | ||
+ | vec2 i = floor(v + dot(v, C.yy) ); | ||
+ | vec2 x0 = v - i + dot(i, C.xx); | ||
+ | |||
+ | vec2 i1; | ||
+ | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); | ||
+ | vec4 x12 = x0.xyxy + C.xxzz; | ||
+ | x12.xy -= i1; | ||
+ | |||
+ | i = mod289(i); | ||
+ | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); | ||
+ | |||
+ | vec3 m = max(0.5 - vec3(dot(x0, | ||
+ | m = m*m ; | ||
+ | m = m*m ; | ||
+ | |||
+ | vec3 x = 2.0 * fract(p * C.www) - 1.0; | ||
+ | vec3 h = abs(x) - 0.5; | ||
+ | vec3 ox = floor(x + 0.5); | ||
+ | vec3 a0 = x - ox; | ||
+ | |||
+ | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); | ||
+ | |||
+ | vec3 g; | ||
+ | g.x = a0.x * x0.x + h.x * x0.y; | ||
+ | g.yz = a0.yz * x12.xz + h.yz * x12.yw; | ||
+ | return 130.0 * dot(m, g); | ||
+ | } | ||
+ | |||
+ | float rand(vec2 co){ | ||
+ | | ||
+ | } | ||
+ | |||
+ | vec3 SurfaceShader(inout TLocals DATA){ | ||
+ | vec2 uv = DATA.TexCoord0.xy; | ||
+ | float iTime = mod(_TimeInfo.y, | ||
+ | float time = iTime * 2.0; | ||
+ | | ||
+ | float noise = max(0.0, snoise(vec2(time, | ||
+ | | ||
+ | noise = noise + (snoise(vec2(time*10.0, | ||
+ | | ||
+ | vec4 fragColor; | ||
+ | float xpos = uv.x - noise * noise * 0.25; | ||
+ | fragColor = tex2D(_RenderedTexture, | ||
+ | | ||
+ | fragColor.rgb = mix(fragColor.rgb, | ||
+ | | ||
+ | if (floor(mod(gl_FragCoord.y * 0.25, 2.0)) == 0.0){ | ||
+ | fragColor.rgb *= 1.0 - (0.15 * noise); | ||
+ | } | ||
+ | | ||
+ | fragColor.g = mix(fragColor.r, | ||
+ | fragColor.b = mix(fragColor.r, | ||
+ | |||
+ | return fragColor.rgb; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Source: [[https:// | ||
+ | ===== Runtime ===== | ||
+ | |||
+ | Of course you can also setup post effects at runtime. | ||
+ | |||
+ | Have a look at the following function simply extracting the red-color channel from main render pass. | ||
+ | |||
+ | <file pascal> | ||
+ | var LPostFX := TGorillaRenderPassPostFX.Create(GorillaViewport1, | ||
+ | LPostFX.Viewport := GorillaViewport1; | ||
+ | LPostFX.SurfaceShader.Text := | ||
+ | 'vec3 SurfaceShader(inout TLocals DATA){'# | ||
+ | ' | ||
+ | ' | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Shaders ===== | ||
+ | |||
+ | You can write shaders in GLSL syntax compatible with OpenGL 4.3 (on Windows) and OpenGLES 3.1+ (on Android). | ||
+ | |||
+ | __WARNING: | ||
+ | |||
+ | The **SurfaceShader** property of the PostFX instance allows to put a string with compatible shader code into. | ||
+ | |||
+ | At least every shader needs a " | ||
+ | |||
+ | <file glsl> | ||
+ | vec3 SurfaceShader(inout TLocals DATA){ | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The shader itself provides some variables for usage: | ||
+ | |||
+ | ^Shader Variable ^Type ^ Description ^ | ||
+ | |_RenderedTexture|sampler2D|The main render pass result texture.| | ||
+ | |_MaskTexture|sampler2D|Optional texture for post effects. You can use this texture for additional shader computation.| | ||
+ | |_TimeInfo.x|float|Starting timestamp of the post effect shader| | ||
+ | |_TimeInfo.y|float|Current timestamp of the post effect shader| | ||
+ | |_TimeInfo.z|float|Previous timestamp of the post effect shader| | ||
+ | |_TimeInfo.w|float|Delta timestamp of the post effect shader| | ||
+ | |DATA.TexCoord0|vec2|Texture coordinate of the post effect plane.| | ||
+ | |DATA.WorldViewProjVertPos|vec4|World-View-Projected vertex position of the post effect plane.| | ||
+ | |DATA.Normal|vec3|Normal vector of the post effect plane.| | ||
+ | |||
+ | ==== Links ==== | ||
+ | |||
+ | You can find many free shaders in the web with less need of change. | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * ... |