Jump to content

Make triangle via Surface and color it via shader


Lunarovich
 Share

Recommended Posts

Hello! As the title points out, I want to know how to color a simple triangle via my own shader. Basically, I want to achieve something like this:

 

61VOQdE.png

 

I'm trying to recreate, in LE, a tutorial 4 from this excellent resource. So, for the triangle itself, I do something like this:

 

    local model = Model:Create()
    model:SetColor(1.0,1.0,1.0)

    local surface = model:AddSurface()
    surface:AddVertex(-0.5,-0.5,0, 0,0,-1)
    surface:AddVertex(0.5,-0.5,0, 0,0,-1)
    surface:AddVertex(0.5,0.5,0, 0,0,-1)
    surface:AddTriangle(2,1,0)
    surface:Update()
    model:UpdateAABB(Entity.LocalAABB)
    model:UpdateAABB(Entity.GlobalAABB)
    return true

 

With camera and light added (light is probably not needed) and properly positioned, I get a white triangle.

 

I then proceed to create and add a material. Now comes the tricky part. My fragment shader looks like this:

 

#version 400
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

 

However, I have no idea what to do with the vertex shader. If I do nothing with it, nothing gets displayed on the screen in return. Now, I've tried with something like this

 

#version 400
uniform mat4 projectionmatrix;
uniform mat4 drawmatrix;
uniform vec2 position[3];
void main(void)
{
gl_Position = projectionmatrix * (drawmatrix * vec4(position[gl_VertexID], 0.0, 1.0));
}

 

but I cannot even get it working when the game starts, since I do not know how to send an array of floats via Lua. A side question: how does one sends an array of floats to a shader via Lua? Anyway, I see that there is no camera matrix transformation concatenated and I do not know how to do it. Any help would be appreciated.

 

Thank you!

Link to comment
Share on other sites

Ok. Thanx. What I really want is to create some procedural textures. I'm starting to learn how to do it (Perlin noise and such things) and would like to be able to use this knowledge with LE. So, for now, I have, basically, found three possible approaches:

  1. Texture::SetPixels. But this function is not exposed to Lua.
  2. By using Buffer:Create, Buffer:SetCurrent, drawing to the buffer via Context:Plot and than get a texture via Buffer:GetColorTexture(0)
  3. Via shaders.

In fact, I have had any success only by using the 2nd method thanks to your example found here. Now, I'd like to know if there is some LE specific way one should go about in order to make procedural textures.

 

Anyway, a default shader is a jungle I cannot get through - no docs, no comments, no nothing! On the contrary, those GLSL tutorials are excellent and simple, and I don't see why it should be so complicated in LE to paint a triangle, with a VBO defined, in red via shaders (btw, I know how to do it by coloring vertices, but that's not something that I want, just for the record).

Link to comment
Share on other sites

First, you should write your color values to fragData0. Leadwerks uses a deferred renderer - that means you don't set the fragment color yourself, but rather write your data to several buffers in the shaders, and afterwards the engine does the lighting computations and actually sets the fragment color. Unfortunately, most OpenGL tutorials that you find use a forward renderer, and you can't simply apply them 1:1 to Leadwerks, but rather have to understand the general concepts and adapt them to this engine.

 

Then, you don't need the position uniform in the vertex shader. You do create three vertices and add them to a triangle. When Leadwerks issues the draw call for your model, the vertex shader will be executed for every single vertex of your model, and its data like position and uv coordinates are automatically passed to the shader.

 

I actually haven't thought through if your code is equivalent to this, but the usual lines for the coordinate transformation are

 

vec4 modelvertexposition = entitymatrix_ * vec4(vertex_position,1.0);
gl_Position = projectioncameramatrix * modelvertexposition;

 

where the first line transform the vertex position from object space to world space, and the second line transform that to camera (eye) space and applies the perspective transformation.

  • Upvote 1
Link to comment
Share on other sites

Ok, here it is, an absolutely minimal model shader... It will output a green geometry...

 

Vertex shader:

 

#version 400
#define MAX_INSTANCES 256

//Uniforms
uniform instancematrices { mat4 matrix[MAX_INSTANCES];} entity;
uniform mat4 projectioncameramatrix;

//Attributes
in vec3 vertex_position;

void main()
{
mat4 entitymatrix = entity.matrix[gl_InstanceID];
mat4 entitymatrix_ =entitymatrix;
entitymatrix_[0][3]=0.0;
entitymatrix_[1][3]=0.0;
entitymatrix_[2][3]=0.0;
entitymatrix_[3][3]=1.0;

vec4 modelvertexposition = entitymatrix_ * vec4(vertex_position,1.0);

gl_Position = projectioncameramatrix * modelvertexposition;
}

 

Fragment shader:

#version 400

// Outputs
out vec4 fragData0;
out vec4 fragData2;

void main()
{
fragData0 = vec4(0.0, 1.0, 0.0, 0.0);
fragData2 = vec4(0.0, 0.0, 0.0, 0.0);
}

 

For the explanation of attribs, uniforms and inputs/outputs see this link.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...