About Monkey 2 › Forums › Monkey 2 Programming Help › GLSL shader: set material uniforms
This topic contains 4 replies, has 3 voices, and was last updated by
Anatol
1 year, 4 months ago.
-
AuthorPosts
-
November 20, 2017 at 2:03 pm #11851
Hi!
I’m still brand new at GLSL shaders and I’m trying to pass a value into a shader. So in the .glsl file I have this (simplified):
C++12345uniform vec4 m_TestColor;void main(){gl_FragColor=m_TestColor;}From Monkey2 (in a class that extends Image) I’m trying to set m_TestColor via
Monkey12Local testColor := New Vec4f( 1.0, 0.0, 0.0, 1.0 )Material.SetVec4f( "TestColor", testColor )This causes an error: “Invalid uniform type 0 expecting 4”.
So how can I use SetVec4f or other UniformBlock methods? I assume I need those to pass something to a shader?
Thank you.
November 21, 2017 at 1:44 am #11869Would need to see more code, it looks like it can’t find a uniform but I can’t really see how you’re setting things up etc.
It’s the right general idea though.
[edit]The shader related error message REALLY need some work! I’ll see what I can do here.[/edit]
November 21, 2017 at 3:48 am #11874Don’t know what you do, but maybe my example will be useful.
I took mojo’s sprite shader, removed unused vars and added TestColor into fragment section.
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class MyWindow Extends WindowMethod New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )Super.New( title,width,height,flags )Local shader:=New Shader( "painter",shaderData,"" )image=New Image( 100,100,,shader )image.Handle=New Vec2f( .5 )EndMethod OnRender( canvas:Canvas ) Overrideimage.Material.SetColor( "TestColor",New Color( Mouse.Location.x/Float(Width),.5,Mouse.Location.y/Float(Height),1 ) )App.RequestRender()canvas.DrawImage( image,Width/2,Height/2 )EndField image:ImageEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndConst shaderData:="//@renderpasses 0,1,2//@vertexattribute vec4 a_Position;uniform mat4 r_ModelViewProjectionMatrix;void main(){gl_Position=r_ModelViewProjectionMatrix * a_Position;}//@fragmentuniform vec4 m_TestColor;void main(){gl_FragColor=m_TestColor;}"November 21, 2017 at 7:03 am #11877Thanks Mark and nerobot. Both answers were really helpful, plus it’s a face palm situation for me. It’s true that the shader couldn’t find the uniform. I set it in a method that was never called, so naturally the shader was expecting a Vec4f but probably had a null, or 0 vector if that even exists. I’m still confused enough by shaders that I was looking in the wrong place.
Actually I base my shader and ImageExtend on your sprite-masked shader, nerobot. That post was incredibly helpful. I just need to add a few “features” to the shader mask and I’m getting there one step at a time. Next up is a way to move/translate and scale the shader mask. I’ll see how I go and will share it in the forum.
December 12, 2017 at 1:13 pm #12249Sometimes it’s literally weeks until I find some more time for this, but for completeness’ sake and as I said I’ll share the result, I can simply send an offset value to the shader, e.g.
Monkey12CanvasLayer.Mask.Material.SetVec2f( "Resolution", New Vec2f( width, height ) ) ' app width/heightCanvasLayer.Mask.Material.SetVec2f( "Offset", New Vec2f( App.MouseLocation.x, App.MouseLocation.y ) )which the shader will pick up and apply like this (simplified):
C++12345678910111213uniform vec2 m_Resolution;uniform sampler2D m_ImageTexture0;uniform sampler2D m_MaskTexture;uniform vec4 m_HighlightColor;uniform vec2 m_Offset;void main(){vec2 maskCoord = v_TexCoord0 - m_Offset / m_Resolution;vec4 maskColor = texture2D( m_MaskTexture, maskCoord );vec4 imageColor = texture2D( m_ImageTexture0, v_TexCoord0 );gl_FragColor.rgba = imageColor.rgba * m_HighlightColor.rgba;gl_FragColor.rgba *= ( maskColor.r + maskColor.g + maskColor.b ) / 3.0;#endifFor a full working example see this test on Github with a mask that moves based on mouse coordinates.
Here’s the shader code.
It’s not perfect but it shows how it works in principle.
-
AuthorPosts
You must be logged in to reply to this topic.