For clarity, I start with my question:
Is it possible to use (in the shader code) the custom attribute name which I set for the TEXCOORD usage in the (OpenGL) stream mapping in RenderMonkey 1.82 or do I have to use gl_MultiTexCoord0?
(The question might be valid for the NORMAL usage too, i.e custom name or gl_Normal)
Background:
Using RenderMonkey version 1.82.
I have successfully used the stream mapping to map the general vertex attribute "position" (and maybe "normal"), but the texture coordinates does not seem to be forwarded correctly.
For the shader code, I use #version 330 and the "in" qualifier in GLSL, which should be OK since RM does not compile the shaders itself (the OpenGL driver do).
I have tried both .obj and .3ds files (exported from blender), and when checking the wavefront .obj-file, all texture coordinate information is there, as well as the vertex positions and normals.
If it is not possible, the stream mapping is broken and there is no point in naming the variables in the stream mapping editor (besides for the vertex position stream, which works), since one has to use the built-in variables anyway.
Update:
If using the deprecated built-in variables, one has to use compatibility mode in the shader e.g
#version 330 compatibility
out vec2 vTexCoord;
and, in the main function:
vTexCoord = vec2(gl_MultiTexCoord0);
(Now I'm not sure about the stream mapping of normals either. As soon as I got the texture coordinates working, I had normal problems and had to revert to gl_Normal.)
Here is a picture of a working solution, but with built-in variables (and yes, the commented texcoord variable in the picture does not have the same name as in the stream mapping dialog, but it had the same name when I tried to use it, so it's OK.):
You could try to use the generic vertices's attributes, see http://open.gl, it's a great tutorial ;)
(but I think it imply you'd have to rewrite the code to manual handle the transformations...)
#version 330
layout(location = 0) in vec3 bla_bla_bla_Vertex;
layout(location = 2) in vec3 bla_bla_bla_Normal;
layout(location = 8) in vec3 bla_bla_bla_TexCoord0;
This is a working solution for RM 1.82
Related
In vulkan, if under the lifetime of a single render pass you naively render to a framebuffer that contains multiple attachemnts with a pipeline that renders to all of them and then render again with a pipeline that only renders to one of them you will get an error.
Let me give an example.
Consider the following image, which is an intermediary step in a multi pass effect.
Which is obtained from writing a wireframe on top of an albedo:
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) out vec4 color_out;
layout(location = 1) out vec4 color_out1;
layout(location = 2) out vec4 color_out2;
layout(location = 3) out vec4 color_out3;
layout(location = 4) out vec4 color_out4;
void main()
{
color_out = vec4(1,1,1,1);
color_out1 = vec4(0,0,0,0);
color_out2 = vec4(0,0,0,0);
color_out3 = vec4(0,0,0,0);
color_out4 = vec4(0,0,0,0);
}
The 4 "noop" outputs are not really necessary, they exist merely to prevent vulkan errors.
Let's assume we instead do this (and we modify our pieline as well):
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) out vec4 color_out;
void main()
{
color_out = vec4(1,1,1,1);
}
Then we obtain the same image.
However a critical difference exists:
The second image produces multiple errors, one for each attachemnt, which look like this:
Message ID name: UNASSIGNED-CoreValidation-Shader-InputNotProduced
Message: Attachment 1 not written by fragment shader; undefined values will be written to attachment
Severity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
Why is not explicitely writing to the attachments of a framebuffer not valid as per the spec? i.e why isn't the spec that if you do not write to an attachment, the contents are preserved?
why isn't the spec that if you do not write to an attachment, the contents are preserved?
Because Vulkan is a low-level rendering API.
What gets written to has always, in OpenGL just as in Vulkan, been governed by the write mask state, not anything the fragment shader does. If you have some number of attachments, again in OpenGL as well as Vulkan, any rendering operation will write to all of them (assuming the various tests are passed) unless write masks (or blending) are employed to prevent those writes.
Note that this distinction may well be a hardware issue. If a GPU uses specialized hardware to interpret fragment data and perform blending/write masking/etc, it is hardly unreasonable to consider that there may be no mechanism for the shader to directly communicate which values in the fragment are valid and which are not.
It appears that some hardware does handle this as you would prefer. Or at least in some subset of cases. However, as we're looking at unspecified behavior, there's no way to know what triggers it or in which cases it may not function.
Now, one might say that, given that the Vulkan pipeline object includes all of this state, the code which builds the internal pipeline state data could just detect which values get written by the FS and write-mask out the rest. But that's kind of against the point of being a low-level API.
I always did my shaders in glsl 3 (with the #version 330 line) but it's starting to be pretty old, so I recently tried to make a shader in glsl 4, and use it with the SFML library for rendering, instead of pure openGL.
For now, my goal is to do a basic shader for a 2d game, which takes the color of each pixel of a texture and modify them. I always did that with gl_TexCoord[0].xy, but it seems to be depreciated now, so I searched and I heard that I must use the in and out variables with a vertex shader, so I tried.
Fragment shader
#version 400
in vec2 fragCoord;
out vec4 fragColor;
uniform sampler2D image;
void main(){
// Get the color
vec4 color = texture( image, fragCoord );
/*
* Do things with the color
*/
// Return the color
fragColor = color;
}
Vertex shader
#version 400
in vec3 position;
in vec2 textureCoord;
out vec2 fragCoord;
void main(){
// Set the position of the pixel and vertex (I guess)
fragCoord = textureCoord;
gl_Position = vec4( position, 1.0 );
}
I also seen that we could add the projection, model, and view matrices, but I don't know how to do that with SFML (I don't even think we can), and I don't want to learn some complex things about openGL or SFML just to change some colors on a 2d game, so here is my question:
Is there an easy way to just get the coordinates of the pixel we're working on? Maybe get rid of the vertex shader, or use it without using matrices?
Unless you really want to learn a lot of nasty OpenGl, writing your own shaders just for textures is a little overkill. SFML can handle textures and shaders for you behind the scenes (here is a good article on how to use them) so you don't need to worry about shaders at all. Also note that you can change the color of SFML sprites (which is, I believe, what you are trying to do), with sprite.setColor(sf::color(*whatever*));. Plus, there's no problem in using version 330. That's what I usually use, albeit with in and out stuff as well.
If you really want to use your own shaders for fancy effects, like pixellation, blurring, etc. I can't help you much since I've only ever worked with pure OpenGl, so I don't know how the vertex information is handled by SFML, but this is some interesting example code you can check out, here is a tutorial, and here is a reference.
To more directly answer your question. gl_FragCoord is a built-in variable with GLSL that keeps track of the fragments position, but you have to set gl_Position in the vertex shader. You can't get rid of the vertex shader if you are doing anything OpenGl related. You'd have to do fancy matrix stuff (this is a wonderful library) and probably buffer stuff (like this) to tell GLSL yourself where everything is.
Most GLSL shaders are using a attribute for the color in the vertex shader, which will be forwarded as varying to the fragment shader. Like this:
attribute vec4 position;
attribute vec4 color;
uniform mat4 mvp;
varying vec4 destinationColor;
void main(){
destinationColor = color;
gl_Position = mvp * position;
};
Setting the color can be done with glVertexAtribPointer() to pass one color per vertex or with glVertexAttrib4fv() to pass a global color for all vertexes. I try to understand the difference to the predefined variable gl_Color in the vertex shader (if there is any difference at all). i.e.
attribute vec4 position;
uniform mat4 mvp;
varying vec4 destinationColor;
void main(){
destinationColor = gl_Color;
gl_Position = mvp * position;
};
and using glColorPointer() to pass one color per vertex or glColor4fv() to use a global color for all vertexes. To me the second shader looks better (= more efficient?), because it uses less attributes. But all tutorials & online resources are using the first approach - so I wonder if I missed anything or if there is no difference at all.
What is better practice when writing GLSL shaders?
To me the second shader looks better (= more efficient?), because it uses less attributes.
It does not use fewer attributes. It just uses fewer explicit attribute declarations. All of the work needed to get that color value to OpenGL is still there. It's still being done. The hardware is still fetching data from a buffer object or getting it from the glColor context value or whatever.
You just don't see it in your shader's text. But just because you don't see it doesn't mean that it happens for free.
User-defined attributes are preferred for the following reasons:
User-defined attributes make it clear how many resources your shaders are using. If you want to know how many attributes you need to provide to a shader, just look at the global declarations. But with predefined attributes, you can't do this; you have to scan through the entire vertex shader for any gl_* names that name a predefined attribute.
User-defined attributes can do more things. If you want to pass integer values as integers to the vertex shader, you must use a user-defined attribute. If you need to pass a double-precision float to the vertex shader, again, a predefined attribute cannot help you.
Predefined attributes were removed from core OpenGL contexts. OSX, for example, does not allow the compatibility profile. You can still use OpenGL 2.1, but if you want to use any OpenGL version 3.2 or greater on OSX, you cannot use removed functionality. And the built-in vertex attributes were removed in OpenGL 3.1.
Predefined attributes were never a part of OpenGL ES 2.0+. So if you want to write shaders that can work in OpenGL ES, you again cannot use them.
So basically, there's no reason to use them these days.
if I remember correctly gl_Color is deprecated remnant from the old style API without VAO/VBO using glBegin() ... glEnd(). If you go to core profile there is no gl_Color anymore ... so I assume you use old OpenGL version or compatibility profile.
If you try to use gl_Color in core profile (for example 4.00) you got:
0(35) : error C7616: global variable gl_Color is removed after version 140
Which means gl_Color was removed from GLSL 1.4
It is not entirely matter of performance but the change in graphic rendering SW architecture or hierarchy of the GL calls if you want.
I've written plenty of
#version 330 core
GLSL shaders I'd like to reuse along with the OpenSceneGraph (OSG) 3.2.0 framework, and try to figure out how to get the state from the OSG I need to pass in by uniforms, and how to set them without having to change well-tested shader code, as well as how to populate arbitrarily named attributes.
This (version 140, OpenGL 3.1)
http://trac.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/examples/osgsimplegl3/osgsimplegl3.cpp
and this (version 400)
http://trac.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/examples/osgtessellationshaders/osgtessellationshaders.cpp
example give rise to a notion of aliasing certain attribute and uniform names to "osg_", but I'd like to use arbitrary names for the uniforms,
uniform mat4 uMVMatrix;
/*...*/
and to refer, or let the OSG refer, to the attributes by their numbers only, so sth like this
/*...*/
layout(location = 0) in vec4 aPosition;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aST;
as used in my legacy shaders, I'd like the OSG framework to populate with the vbo it already maintains for the "Drawables", or, at least, use an API call and do it myself.
I addition, I'd like to populate uniforms for lights and shawdowmaps by means of the scenegraph and the visitors; "somewhere" and "somehow" in the SG there must be light and esp shadow information be aggregated for default shading, so I'd like simply like to use this data and tailor it to fit to my custom shaders.
So the fundamental question is
How to populate arbitrary GLSL 330 shaders with data from within OSG without having to resent to redundant uniform assignment - providing my "u[..]Matrix" manually in addition to the "osg_[...]" uniform set by OSG - or changing attribute names in the shader sources?
I just stumbled upon this, turns out, you can just use your own names after all, if you just specify the layout location (so far I only tried it for the vertex position, so you might have to take care of using the correct layout location as osg would specify them, i.e. vertex position at 0, normal at 1 (which is not done the example of the link though))
layout (location = 0) in vec3 vertex;
this is enough to use the variable named vertex in the shader.
The link also provides an example to use custom names for matrices: you create an osg::Uniform::Callback class that uploads the matrix to the uniform.
when you create the osg::Uniform object, you specify the name of your choosing and add the callback.
I'm having some problem understanding one line in the most basic (flat) shader example while reading OpenGL SuperBible.
In chapter 6, Listing 6.4 and 6.5 it introduces the following two very basic shaders.
6.4 Vertex Shader:
// Flat Shader
// Vertex Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130
// Transformation Matrix
uniform mat4 mvpMatrix;
// Incoming per vertex
in vec4 vVertex;
void main(void)
{
// This is pretty much it, transform the geometry
gl_Position = mvpMatrix * vVertex;
}
6.5 Fragment Shader:
// Flat Shader
// Fragment Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130
// Make geometry solid
uniform vec4 vColorValue;
// Output fragment color
out vec4 vFragColor;
void main(void)
{
gl_FragColor = vColorValue;
}
My confusion is that it says vFragColor in the out declaration while saying gl_FragColor in main().
On the other hand, in code from the website, it has been corrected to 'vFragColor = vColorValue;' in the main loop.
What my question is that other then being a typo in the book, what is the rule for naming out values of shaders? Do they have to follow specific names?
On OpenGL.org I've found that gl_Position is required for the out of the vertex shader. Is there any such thing for the fragment shader? Or it is just that if there is only one output, then it will be the color in the buffer?
What happens when there is more then one out of a fragment shader? How does the GLSL compiler know which one to use in the buffer?
As stated in the GLSL specification for version 1.3, the use of gl_FragColor in the fragment shader is deprecated. Instead, you should use a user defined output variable like the
vFragColor variable described in your fragment shader. As you said, it's a typo.
What is the rule for naming out values of shaders?
The variable name can be anything you like, unless it collides with any existing names.
What happens when there is more then one out of a fragment shader? How does the GLSL compiler know which one to use in the buffer?
When there is more than one out in the fragment shader, you should assign slots to the fragment shader outputs by calling BindFragDataLocation. You can then say which slots will render to which render target by calling DrawBuffers.
The specification states that if you have one output variable in the fragment shader defined, it will be assigned to index 0 and output 0. For more information, I recommend you take a look at it yourself.
gl_FragColor was the original output variable in early versions of GLSL. This was the color of the fragment that was to be drawn.
Your initial confusion is justified, as there's no reason to declare that out variable and then write to glFragColor.
In later versions it became customizable, such that you could give arbitrary names to your output variables. You can map these arbitrary outputs to specific buffers with the command glBindFragDataLocation.
I'm not 100% positive, but I believe if you don't call this function before linking, then your output variables will be randomly assigned to buffers. If you only have one output, then it should always be assigned to buffer 0.