About Monkey 2 › Forums › Monkey 2 Programming Help › Fragment shader fails with additional uniform
Tagged: debug, debugger, fragment shader, GLSL, SetInt, Shaders, simple shader, switch, wtf
This topic contains 11 replies, has 3 voices, and was last updated by
DruggedBunny
12 months ago.
-
AuthorPosts
-
April 15, 2018 at 2:07 pm #14369
I’m trying to produce a minimal sample for experimenting with fragment shaders, at the moment just darkening the existing pixels.
I’ve stripped down BloomShader to the bare minimum and it works fine, but as soon as I add my own uniform, I end up with a white screen (grey with the 0.1 * rgb shader applied).
What am I doing wrong here? Shader and code below, but runnable version attached…
*** Note the two ENABLE_ME comments! This is when it fails… ****
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233[crayon-5cb9a3c6c4afd611347066 inline="true" ]//@renderpasses 0uniform sampler2D m_SourceTexture;uniform vec2 m_SourceTextureSize;uniform vec2 m_SourceTextureScale;uniform float m_MousePos;varying vec2 v_TexCoord0;//@vertexattribute vec2 a_Position; //0...1 (1=viewport size)void main(){v_TexCoord0 = a_Position * m_SourceTextureScale;gl_Position=vec4( a_Position * 2.0 - 1.0,-1.0,1.0 );}//@fragmentvoid main(){vec3 pixels = texture2D (m_SourceTexture, v_TexCoord0).rgb;gl_FragColor = vec4 (pixels * 0.1, 1.0);// gl_FragColor = vec4 (1.0, 0.0, 1.0, 1.0);}[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227[crayon-5cb9a3c6c4b03018449219 inline="true" ]#Import "<std>"#Import "<mojo3d>"#Import "assets/"Using std..Using mojo..Using mojo3d..' ----------------------------------------' Application name...' ----------------------------------------Global AppName:String = "My 3D Game"Class MagentaEffect Extends PostEffectMethod New (passes:Int = 1)_shader = Shader.Open ("base")_uniforms = New UniformBlock (3) ' DISABLE_ME' _uniforms = New UniformBlock (4) ' ENABLE_MEPasses = passesEndProperty Passes:Int ()Return _passesSetter (passes:Int)_passes = passesEndProtectedMethod OnRender () OverrideLocal rsize:Vec2i = Device.Viewport.SizeLocal rtarget:RenderTarget = Device.RenderTargetLocal rtexture:Texture = rtarget.GetColorTexture (0)If Not _target0 Or rsize.x > _target0.Size.x Or rsize.y > _target0.Size.y_texture0?.Discard ()_target0?.Discard ()_texture0 = New Texture (rsize.x, rsize.y, rtexture.Format, TextureFlags.Dynamic | TextureFlags.Filter)_target0 = New RenderTarget (New Texture [] (_texture0), Null)EndifDevice.Shader = _shaderDevice.BindUniformBlock (_uniforms)Local target:RenderTarget = _target0Local source:Texture = rtexture_uniforms.SetTexture ("SourceTexture", source)_uniforms.SetVec2f ("SourceTextureSize", source.Size)_uniforms.SetVec2f ("SourceTextureScale", Cast <Vec2f> (rsize) / Cast <Vec2f> (source.Size))'_uniforms.SetFloat ("MousePos", 1.0) ' ENABLE_MEDevice.BlendMode = BlendMode.OpaqueDevice.RenderPass = 0RenderQuad ()EndPrivateField _shader:ShaderField _uniforms:UniformBlockField _passes:Int=4Field _texture0:TextureField _target0:RenderTargetEndClass Game Extends WindowConst SHIFT_BOOST:Float = 5.0Field camera_boost:Float = 1.0' Basic 3D scene requirements...Field scene:SceneField camera:CameraField light:Light' Test cube...Field cube:ModelField cubemesh:MeshField cubematerial:MaterialField magenta:MagentaEffectMethod New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)scene = Scene.GetCurrent () ' Important!camera = New Camera' Camera settings...camera.Near = 0.1' Camera position...camera.Move (0, 0, -2)camera.Rotate (0, 0, 0)light = New Lightlight.Move (-10, 10, -10)light.Rotate (0, 0, 0)cubemesh = Mesh.CreateBox (New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5)) ' 1 x 1 x 1cubematerial = New PbrMaterial (Color.Lime)Cast <PbrMaterial> (cubematerial).EmissiveFactor = Color.LimeCast <PbrMaterial> (cubematerial).MetalnessFactor = 1.0cube = New Model (cubemesh, cubematerial)cube.Rotate (0, 45, 0)Print AppDir ()magenta = New MagentaEffect (0)scene.AddPostEffect (magenta)EndMethod UpdateGame:Void ()EndMethod OnRender (canvas:Canvas) OverrideProcessInput ()UpdateGame ()cube.Rotate (0.0, 1.0, 0.0)' Tell app to draw frame when ready...RequestRender ()' Render scene to canvas (passed to OnRender by mojo), from camera...scene.Render (canvas)EndMethod ProcessInput:Void ()If Keyboard.KeyHit (Key.Space) Then light.CastsShadow = Not light.CastsShadowIf Keyboard.KeyDown (Key.LeftShift)camera_boost = SHIFT_BOOSTElsecamera_boost = 1.0EndifIf Keyboard.KeyHit (Key.Escape) Then App.Terminate ()If Keyboard.KeyDown (Key.A)camera.Move (0.0, 0.0, 0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Z)camera.Move (0.0, 0.0, -0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Left)camera.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)camera.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)camera.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)camera.Rotate (-1.0, 0.0, 0.0, true)EndifEndEndFunction Main ()' Windowed mode...Local width:Int = 640Local height:Int = 480Local flags:WindowFlags = WindowFlags.Center' Full-screen mode (comment out above)...' Local width:Int = 1920' Local height:Int = 1080' Local flags:WindowFlags = WindowFlags.FullscreenNew AppInstanceNew Game (AppName, width, height, flags)App.Run ()EndAttachments:
April 15, 2018 at 9:06 pm #14372Hi,
You should leave the ctor arg to new UniformBlock as 3. Why did you change this to 4? With it set to 4 I get a runtime error trying to bind SourceTexture.
This arg refers to the ‘type’ of uniform block being created, where ‘3’ means ‘material’ uniforms, so they get a ‘m_’ prefix. Other uniform types include ‘render’ which have an ‘r_’ prefix and instance which has an ‘i_’ prefix etc. There is no real logic to these I’m just making them up as I go. It’s highly likely there will end up being lighting and scene uniform block types too with “l_” and “s_” prefixes (maybe) and all these uniform block types will eventually get enumed preventing lots of confusion here. The base class of PostEffect should probably be the one creating the uniform block anyway, but the PostEffect system is way underdeveoped and I’m really just experimenting with the shaders right now so it’s likely to stay this way for a while.
Anyway, leaving ctor uniform block type as 3 and SetFloat mousepos enabled I can run the demo and get the same dodgy greenish cube, but shader isn’t using mouse pos yet so that’s what I’d expect.
April 15, 2018 at 9:43 pm #14373Hi Mark, I was kinda guessing that it related to the number of uniforms in the block! As in, for each SetFloat, SetVec3f, etc, I’d need another entry in the ‘block’. Obviously misunderstood this!
Number 3 happened to tie in with:
[/crayon]Monkey123456[crayon-5cb9a3c6cff21990143966 inline="true" ]_uniforms.SetTexture ("SourceTexture", source)_uniforms.SetVec2f ("SourceTextureSize", source.Size)_uniforms.SetVec2f ("SourceTextureScale", Cast <Vec2f> (rsize) / Cast <Vec2f> (source.Size))Setting to 3 does indeed work! (Yes, dodgy green cube/no mouse position is expected at this point.)
Thanks for the explanation.
April 15, 2018 at 9:51 pm #14374That’s what I was after! Working nicely.
[/crayon]Monkey1234567891011121314151617181920212223242526272829303132[crayon-5cb9a3c6d2437794671083 inline="true" ]//@renderpasses 0uniform sampler2D m_SourceTexture;uniform vec2 m_SourceTextureSize;uniform vec2 m_SourceTextureScale;uniform float m_MousePos;varying vec2 v_TexCoord0;//@vertexattribute vec2 a_Position; //0...1 (1=viewport size)void main(){v_TexCoord0 = a_Position * m_SourceTextureScale;gl_Position=vec4( a_Position * 2.0 - 1.0,-1.0,1.0 );}//@fragmentvoid main(){vec3 pixels = texture2D (m_SourceTexture, v_TexCoord0).rgb;gl_FragColor = vec4 (pixels * m_MousePos, 1.0);}[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230[crayon-5cb9a3c6d243c354161628 inline="true" ]#Import "<std>"#Import "<mojo3d>"#Import "assets/"Using std..Using mojo..Using mojo3d..' ----------------------------------------' Application name...' ----------------------------------------Global AppName:String = "My 3D Game"Class MagentaEffect Extends PostEffectMethod New (passes:Int = 1)_shader = Shader.Open ("base")_uniforms = New UniformBlock (3) ' DISABLE_ME' _uniforms = New UniformBlock (4) ' ENABLE_ME' Passes = passesEnd'Property Passes:Int ()' Return _passes'Setter (passes:Int)' _passes = passes'EndProtectedMethod OnRender () OverrideLocal rsize:Vec2i = Device.Viewport.SizeLocal rtarget:RenderTarget = Device.RenderTargetLocal rtexture:Texture = rtarget.GetColorTexture (0)If Not _target0 Or rsize.x > _target0.Size.x Or rsize.y > _target0.Size.y_texture0?.Discard ()_target0?.Discard ()_texture0 = New Texture (rsize.x, rsize.y, rtexture.Format, TextureFlags.Dynamic | TextureFlags.Filter)_target0 = New RenderTarget (New Texture [] (_texture0), Null)EndifDevice.Shader = _shaderDevice.BindUniformBlock (_uniforms)Local target:RenderTarget = _target0Local source:Texture = rtexture_uniforms.SetTexture ("SourceTexture", source)_uniforms.SetVec2f ("SourceTextureSize", source.Size)_uniforms.SetVec2f ("SourceTextureScale", Cast <Vec2f> (rsize) / Cast <Vec2f> (source.Size))_uniforms.SetFloat ("MousePos", Float (Mouse.Y) / Device.Viewport.Height)Device.BlendMode = BlendMode.OpaqueDevice.RenderPass = 0RenderQuad ()EndPrivateField _shader:ShaderField _uniforms:UniformBlock'Field _passes:Int=4Field _texture0:TextureField _target0:RenderTargetEndClass Game Extends WindowConst SHIFT_BOOST:Float = 5.0Field camera_boost:Float = 1.0' Basic 3D scene requirements...Field scene:SceneField camera:CameraField light:Light' Test cube...Field cube:ModelField cubemesh:MeshField cubematerial:MaterialField magenta:MagentaEffectMethod New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)scene = Scene.GetCurrent () ' Important!camera = New Camera' Camera settings...camera.Near = 0.1' Camera position...camera.Move (0, 0, -2)camera.Rotate (0, 0, 0)light = New Lightlight.Move (-10, 10, -10)light.Rotate (0, 0, 0)cubemesh = Mesh.CreateBox (New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5)) ' 1 x 1 x 1cubematerial = New PbrMaterial (Color.Lime)Cast <PbrMaterial> (cubematerial).EmissiveFactor = Color.LimeCast <PbrMaterial> (cubematerial).MetalnessFactor = 1.0cube = New Model (cubemesh, cubematerial)cube.Rotate (0, 45, 0)Print AppDir ()magenta = New MagentaEffect (0)scene.AddPostEffect (magenta)EndMethod UpdateGame:Void ()EndMethod OnRender (canvas:Canvas) OverrideProcessInput ()UpdateGame ()cube.Rotate (0.0, 1.0, 0.0)' Tell app to draw frame when ready...RequestRender ()' Render scene to canvas (passed to OnRender by mojo), from camera...scene.Render (canvas)canvas.DrawText ("Mouse up/down to change brightness", 0, 0)EndMethod ProcessInput:Void ()If Keyboard.KeyHit (Key.Space) Then light.CastsShadow = Not light.CastsShadowIf Keyboard.KeyDown (Key.LeftShift)camera_boost = SHIFT_BOOSTElsecamera_boost = 1.0EndifIf Keyboard.KeyHit (Key.Escape) Then App.Terminate ()If Keyboard.KeyDown (Key.A)camera.Move (0.0, 0.0, 0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Z)camera.Move (0.0, 0.0, -0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Left)camera.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)camera.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)camera.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)camera.Rotate (-1.0, 0.0, 0.0, true)EndifEndEndFunction Main ()' Windowed mode...Local width:Int = 640Local height:Int = 480Local flags:WindowFlags = WindowFlags.Center' Full-screen mode (comment out above)...' Local width:Int = 1920' Local height:Int = 1080' Local flags:WindowFlags = WindowFlags.FullscreenNew AppInstanceNew Game (AppName, width, height, flags)App.Run ()EndApril 17, 2018 at 2:01 am #14375EDIT: Skip this and cut to the chase, below!
This appears to be a general GLSL query, rather than MX2-specific, so anyone with some background welcome, doesn’t have to be Mark!
I’m trying to get an old greyscale shader working, whereby an integer Mode uniform is passed to set the greyscale algorithm used.
This used to work (in OpenB3D):
[/crayon]Monkey12345678910111213141516171819202122[crayon-5cb9a3c6dae70214967998 inline="true" ]switch (int(mode)) // NB. Used to be a float! Tried changing back to this, but no difference...{case 0:// Default RGBbreak;case 1:// Lightnessrgb = (max(max(pixel.r, pixel.g), pixel.b) + min(min(pixel.r, pixel.g), pixel.b)) / 2.0;pixel.r = rgb;pixel.g = rgb;pixel.b = rgb;break;...etcNote the break lines.
… but now it seems as if it always exits the switch at the first break, regardless of the value of m_Mode!
For example, this always exits at case 0 (no greyscale applied) if I enable the break within that case, even if m_Mode is set to 1 or above (ie. it shouldn’t even hit case 0):
[/crayon]Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253[crayon-5cb9a3c6dae76139005252 inline="true" ]switch (m_Mode){case 0:// Default RGB//break; // Disabled, jumps through to case 3// (as if going through all cases and// simply ending up there)// Enabled, always skips the rest, even// though m_Mode is set to higher value!case 1:// Lightnessrgb = (max(max(pixel.r, pixel.g), pixel.b) + min(min(pixel.r, pixel.g), pixel.b)) / 2.0;pixel.r = rgb;pixel.g = rgb;pixel.b = rgb;//break;case 2:// Averagergb = (pixel.r + pixel.g + pixel.b) / 3.0;pixel.r = rgb;pixel.g = rgb;pixel.b = rgb;//break;case 3:// Luminosityrgb = (pixel.r * 0.21) + (pixel.g * 0.72) + (pixel.b * 0.07);pixel.r = rgb;pixel.g = rgb;pixel.b = rgb;pixel = vec3 (1.0, 0.0, 0.0); // *** TEST - RED PIXELS ***}Yet without the break, it seems to end up at the last breaking case (the final case if there is no earlier break). So with no breaks enabled, the screen always ends up red (per the last line there), even if m_Mode is < 3.
Example is attached — anyone got any idea what’s going wrong here? Is it some later GLSL spec that works differently?? How do I get it to just select a path based on m_Mode?
Note that m_Mode is set by this line (0-3, where 0 is normal RGB), and it can then be changed via -/+ on the main keyboard:
[/crayon]Monkey1234[crayon-5cb9a3c6dae7a664488845 inline="true" ]greyscale = New GreyscaleEffect (1)Help!
Attachments:
April 18, 2018 at 1:20 am #14383It seems my m_Mode value isn’t being received by the shader… what am I doing wrong here?
Even explicitly calling…
[/crayon]Monkey1234[crayon-5cb9a3c6e027a090276622 inline="true" ]uniforms.SetInt ("Mode", 1)… results in m_Mode apparently being zero. This still produces a black screen instead of the magenta I’d expect:
[/crayon]Monkey1234567891011121314151617181920[crayon-5cb9a3c6e027f575028998 inline="true" ]...uniform int m_Mode;...//@fragmentvoid main(){vec3 pixel = texture2D (m_SourceTexture, v_TexCoord0).rgb;if (m_Mode == 1){gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);}}Runnable version attached…
Attachments:
April 18, 2018 at 1:24 am #14385EDIT: To see that fail more clearly, amend the shader check to:
[/crayon]Monkey1234[crayon-5cb9a3c6e2fcc148672618 inline="true" ]if (m_Mode == 0)… which results in magenta, even though m_Mode should be 1, it is in fact 0.
I assume I’m doing something stupid!
April 18, 2018 at 7:15 am #14389This gives an error for me, but maybe that gives a away a clue for you or someone else
“GL_VERSION=2.1 ATI 10.4.14
Renderer is using deferred rendering”April 18, 2018 at 11:22 am #14392I don’t think that’s an error, I get that too, it’s just mojo3d printing out version info while WIP, I believe.
April 20, 2018 at 12:38 pm #14421I’m still stuck on this — trying to set an int in the shader, in the existing uniform block, it’s always 0 on the GLSL side. (Have tried checking for both m_Mode and i_Mode!)
I’ve been trying to add another UniformBlock, but I get the impression that’s not the way to handle it. (Am I right in thinking you just have to set the largest data type that’s going to be passed?)
Tried a new UniformBlock using both types 1 (scalar) and 9 (int), but scalar causes textures not to be found (think because it effectively replaces the existing block ?), while int just crashes when I try to call SetInt.
(Assume scalar is same as float?)
So I’m back to what I posted above (see code), which just passes 0 all the time!
April 20, 2018 at 10:47 pm #14428Looks like a bug in mx2’s handling of int uniforms – possible fix now pushed to develop.
Also, you never seem to use debug mode! I know it’s a bit rough, but many of your issues always cause some kind of debug error for me which makes them quite easy to find…
April 21, 2018 at 9:22 am #14437I don’t generally use Debug because it usually crashes Ted to desktop on ‘7, depending on what you click. (I admit I’m a Print debugger that uses Debug rarely anyway.)
I’ll try remember to use it before posting bug reports!
Will give SetInt a whirl today, many thanks.
By the way, the debug crash error was traced by Ferdi to some degree (but see later comment from same):
I’d come to a similar conclusion on an epic 6-hour debugger-debug session, but it seemed to be failing in the underlying C++ call for WriteStdIn, and as far as I could tell was being called correctly, so sort of lost the trail at that, and I knew you didn’t have 7 to be able to follow it up.
-
AuthorPosts
You must be logged in to reply to this topic.