shader noobi question

hi,
due the fact,that im a very greenhorn to shaders (im learning shader programming since few hours), im coming along with a very noobish question. but all my efforts ended in nowhere.

so here my question, how to pass a dynamic value like time into a shader, or how to set a time value there?
i want just to test and to learn how shaders works. i know my try are completly wrong, its nonsense to use a endless loop in a shader for getting this value. a shader loops by it selfs, but i have no idea how to bring a dynamic value into a shader. of course i could animate a object in my application and pass this value for. but im looking for something like a time value.

thanks in forward for any solution.

//Cg
//

void vshader( 
    uniform float4x4 mat_modelproj, 
    in float4 vtx_position: POSITION, 
    in float2 vtx_texcoord : TEXCOORD, 
    out float4 l_position: POSITION, 
    out float4 l_pos) 
{ 
	//endless loop
	float time = 1.0;
	int x = 0;
	while (x < time) {
		time++;
		l_pos=vtx_position; 
		l_position.x=vtx_texcoord.x*.2-.2+sin(time); 
		l_position.y=vtx_texcoord.y*.2; 
		l_position.z=0.0; 
	}
	
} 

void fshader( 
    out float4 o_color: COLOR) 
{ 
    o_color=float4(1,0,0,0); 
}

You can pass values from your Panda code with something like this, for example, to pass a colour:

node.setShaderInput('mycolour', Vec4(1.0, 0.0, 0.0, 1.0))

Or if you wanted it to be based on time:

import time
thetime = time.time()
node.setShaderInput('mytime', thetime)

For that one you would need to have a task running to update with the new time each frame.

In your shader, the name you give it in Panda is prefixed with a “k_”:

void fshader(
  in float2 l_texcoord0: TEXCOORD0,
  in uniform sampler2D tex_0: TEXUNIT0,
  in uniform float4 k_mycolour,
  in uniform float k_mytime,
  out float4 o_color : COLOR)
{
  o_color = k_mycolour * k_mytime;
}

The Panda commands apply these values per-object, but I believe they trickle down to child objects; this way you could do setShaderInput on the top of a model or the whole scene to set the value on everything. You can even pass textures to the shader with this method.

yes, this is exactly im searching for. thank you 1000 times.

is there a way to print something out? like in cout or print?

Nope, there isn’t.

hmm, this makes it a bit more complicated for developing. then i need to abstract it into a slide-ruler. :unamused:

so, to get a value out of the shader for developing, i started with this ruler.

//Cg
//

void vshader( 
    uniform float4x4 mat_modelproj, 
    in uniform float4 k_Time,
    in float4 vtx_position: POSITION, 
    in float2 vtx_texcoord : TEXCOORD, 
    out float4 l_position: POSITION, 
    out float4 l_pos) 
{ 
	// xIN output value
	float xIN = k_Time[0];
	float sx = .01;
	float sy = .1;
	float x = -1+vtx_texcoord.x*sx+xIN;
	float y = vtx_texcoord.y*sy+.9;
	l_position = mul(mat_modelproj,vtx_position);
	l_position.x = x;
	l_position.y = y;
	l_position.z = 0.0;
} 

void fshader( 
	in uniform float4 k_Time,
    out float4 o_color: COLOR) 
{ 
    o_color=float4(k_Time[0]/2,0,0,0); 
}
#include "pandaFramework.h"
#include "pandaSystem.h"
#include "cardMaker.h"
#include "lineSegs.h"
#include "shader.h"
#include "string"
#include "stdio.h"


PandaFramework framework;
WindowFramework *window;
NodePath camera;
PT(Shader) myRuler;
PT(TextNode) text;
LineSegs lines("lines");
LineSegs lines1("lines1");
CardMaker cmNEEDLE("FSCard");
NodePath textNodePath[400];
NodePath vertLINE[400];
NodePath vertLINE1[400];
NodePath needle;
float relX = 0.0;
float time1 = 0.0;
float cp = 0.0;
float lp = 0.0;
float bl = 0.0;
int id =0;


void getWINDOW() {
	framework.set_window_title("My Shader Ruler");
	window = framework.open_window();
	window->get_graphics_window()->get_active_display_region(0)->set_clear_color(Colorf(1, 0, 0, 1));
}
void getCAM() {
	camera = window->get_camera_group();
}

void getSHADER() {
	myRuler = Shader::load(Shader::SL_GLSL,"myRuler.glsl","","");
}

void getRULER() {
	// paint the ruler
	char count[2];
	
	float winX = window->get_graphics_window()->get_fb_x_size();
	float winY = window->get_graphics_window()->get_fb_y_size();
	relX = winX/winY;
	cout << relX;
	for (int c=0;c<20;c++) {
		bl = -1+lp;
		_itoa( c, count, 10);
		text = new TextNode("node name");
		text->set_text(count);
		textNodePath[c] = window->get_aspect_2d().attach_new_node(text);
		textNodePath[c].set_scale(0.05);

		lines.get_current_position();
		lines.draw_to(0,0,.08);
		lines.set_thickness(2);
		vertLINE[c] =lines.create(); 
		vertLINE[c].reparent_to(window->get_render_2d());
		vertLINE[c].set_x(bl);
		vertLINE[c].set_z(.85);
		float sc = 0.0;
		for (int cc=0;cc<4;cc++) {
			sc += .02;
			lines1.get_current_position();
			lines1.draw_to(0,0,.05);
			vertLINE1[id] =lines1.create(); 
			vertLINE1[id].reparent_to(window->get_render_2d());
			vertLINE1[id].set_x(bl+sc);
			vertLINE1[id].set_z(.88);
			id += 1;
		}
		lp += .1;
		cp += relX/10;
	}
}
void getNEEDLE() {
	// geometry needle 
	needle=cmNEEDLE.generate();
	needle.set_shader_input("Plane",needle);
	needle.set_shader(myRuler);
	needle.set_scale(.1);
	needle.reparent_to(window->get_render_2d()); 
}
void getSHADERinput() {
	needle.set_shader_input("Time",LVector4f(time1,0,0,0));
}
void timer() {
	time1 +=.01;
	if (time1 >= 2) {
		time1 = 0.0;
	}
}
void relationFIX() {
	// relativate the textnode to the window size
	float winX = window->get_graphics_window()->get_fb_x_size();
	float winY = window->get_graphics_window()->get_fb_y_size();
	relX = winX/winY;
	float cp1 = 00;
	for (int c=0;c<20;c++) {
		textNodePath[c].set_pos(-relX+cp1,0,.85);
		cp1 += relX/10;
	}
}
void mainLOOP() {
	Thread *current_thread = Thread::get_current_thread(); 
	while (framework.do_frame(current_thread)) 
	{ 
		timer();
		getSHADERinput();
		relationFIX();
	}
}

int main(int argc, char *argv[]) {

    framework.open_framework(argc, argv);
    getWINDOW();
	getSHADER();
	getNEEDLE();
	getRULER();
	
	mainLOOP();
	
    framework.main_loop();
    framework.close_framework();
}

sorry for interrupting again! but i dont understand so many things about shaders. is there anywhere a good manual or tutorial for beginners which discribes the vertex shaders?

what im doing now wrong? i only wanna store a named geom vert array, like -> vtx_(geom) and going to multiply a modelprojetion 4x4 matrix with my float4 model. but nothing gets dispayed. :frowning: whats the best way for storing a def. vert array? i have to manipulate more then just one objekt and i wanna do this just in one shader.

thanks for help.

here is my test for touching a definite object:

//Cg
//

void vshader( 
    uniform float4x4 mat_modelproj, 
    in float4 vtx_Geo: POSITION,
    out float4 l_position: POSITION) 
{ 
	l_position = mul(mat_modelproj,vtx_Geo);
} 

void fshader( 
	in uniform float4 k_Time,
    out float4 o_color: COLOR) 
{ 
    o_color=float4(1,0,0,0); 
} 

neither this is working:

void vshader( 
    uniform float4x4 mat_modelproj, 
    in uniform float4x4 k_Geo, // also not with a POSITION def.
    out float4 l_position: POSITION) 
{ 
	l_position = mul(mat_modelproj,k_Geo);
} 

void fshader( 
	in uniform float4 k_Time,
    out float4 o_color: COLOR) 
{ 
    o_color=float4(k_Time[0]/2,0,0,0); 
}

It can’t be uniform, it must be a varying. Otherwise it makes not much sense.

Do you really have a vertex column named Geo?

so i have to uniform if im doing a straigh vert input, but if im using the same column just by using the name i have only to varying? hmm, how makes this sense?
i dont have a vertex column named geo. i just used here a name which is related to.

but please explain me the first point.

anyway, thanks for the hint!

Uniform variables are the same for the whole geom. Varying variables differ per vertex. In this case, you are referencing a vertex column named Geo, which doesn’t exist according to you, and therefore it doesn’t work. Did you mean to use “vtx_position” instead?

my column name exist! but i use in my shader a other name for it! like i said i only used here this name for underline that im pointing on a geom!

so a other question, is there any good manual around for beginners?

OK, but vtx_cname is used to refer to a column called “cname”.

ok, whats about this HPOS? i got a error now, HPOS is not written.

Are you still using the same shader? If you write out a varying l_ parameter that is bound to POSITION, it should work fine.

i really have no idea! what i need is a beginner manual for vertex shader. with displaying some code lines.

//Cg
//

void vshader( 
    in varying float4 vtx_needle : POSITION,
    out varying float4 l_position: POSITION
    ) 
{ 
	l_position = vtx_needle;
} 

void fshader( 
	in uniform float4 k_Time,
    out float4 o_color: COLOR) 
{ 
    o_color=float4(1,0,0,0); 
}
//Cg
//

void vshader( 
    in float4 vtx_needle,
    varying float4 vtx_position: POSITION,
    out varying float4 l_position: POSITION
    ) 
{ 
	vtx_position = vtx_needle;
	l_position = vtx_position;
} 

void fshader( 
	in uniform float4 k_Time,
    out float4 o_color: COLOR) 
{ 
    o_color=float4(1,0,0,0); 
}

please say me whats wrong now.

Have you seen the shader tutorials here (as referenced in this thread?

David

thank you

yes, but this doesnt help me, this is what i already know. i need to store my verteces in a named column, that i can step over it.

here this is what i need to work:

something like this~ of course this isnt working. just for displaying what i wanna do.
->

...
CardMaker cmNEEDLE("FSCard");
	NodePath needle[10];
	for (int x=0;x<10;x++) {
		needle[x](cmNEEDLE.generate());
		needle[x].set_shader(myRuler);
		needle[x].reparent_to(window->get_render_2d()); 
needle[x].set_shader_input("Plane",needle[x]);
	}
	
//Cg
//

void vshader ( 
	uniform float4x4 mat_modelproj,
    in float4 vtx_needle : POSITION,
    out float4 l_my : POSITION,
    out float4 l_position: POSITION
    ) 
{ 
for (int x=0;x<10;x++) {
	vtx_position = vtx_Plane;
	l_position = mul(mat_modelproj, vtx_needle[x]);
    l_my = l_position;
l_my.x = (valueX);
l_my.y = (valueY);
l_my.z = (valueZ);

}
    
} 

or something like this:

//Cg
//

void vshader ( 
	uniform float4x4 mat_modelproj,
    in float4 vtx_needle : POSITION,
    out float4 l_my : POSITION,
    out float4 l_position: POSITION
    ) 
{ 
int id =0;
//if its not possible to touch a named object array
for (int x=0;x<10;x++) {
//looping over 4 verts
   for (xx= 0;xx<4;xx++) {
     vert[id].x = (valueX);
     vert[id].y = (valueY);
     vert[id].z = (valueZ); 
     id++;
     }
}
    
} 

As for your first shader, you have two outputs bound to POSITION. You can only have one output to represent the clip-space position.

Secondly, why the for loop that does the same thing anyways? A vertex shader is executed per vertex.

As for your second shader, it makes not much sense, as a vertex shader is executed for one single vertex. Maybe you mean to use a geometry shader there, that can loop over the vertices of a triangle (or other primitive kind).