Hardware instancing, shaders and GLSL

I seems to have trouble passing arrays to shader, all I get is black model, and not a single instance is showing, and I don’t know where is the problem.

Python code:

import os
import direct.directbase.DirectStart

from pandac.PandaModules import *
from panda3d.core import *
from direct.actor.Actor import Actor


INST_NUM = 50
MODEL = os.path.abspath("../models/mod.egg")
TEXTURE = os.path.abspath("../textures/text.png")
SHA_V = "../shaders/inst-sha-v.sha"
SHA_F = "../shaders/inst-sha-f.sha"

position = PTAVecBase4.emptyArray(INST_NUM)

for x in xrange(0, INST_NUM):
	position[x] = Vec4(x*10, x*10, 0, 0)



model = Actor(MODEL)
model.setTexture(loader.loadTexture(TEXTURE))
model.setScale(5.0, 5.0, 5.0)
model.loop("idle01")
model.reparentTo(render)
shader = Shader.load(Shader.SLGLSL, SHA_V, SHA_F)
model.setShaderInput("upos", position)
model.setShader(shader)

model.setInstanceCount(INST_NUM)

run()

Shaders:

//GLSL

uniform sampler2D vtex;

varying vec3 vertex_light_position;
varying vec3 vertex_light_half_vector;
varying vec3 vertex_normal;

void main (void)
{
	vec4 ambient_color = gl_FrontMaterial.ambient * gl_LightSource[0].ambient + gl_LightModel.ambient * gl_FrontMaterial.ambient;
	
	vec4 diffuse_color = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
	vec4 specular_color = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(max(dot(vertex_normal, vertex_light_half_vector), 0.0) , gl_FrontMaterial.shininess);
	float diffuse_value = max(dot(vertex_normal, vertex_light_position), 0.0);

	gl_FragColor = texture(vtex, vec2(gl_TexCoord[0])) * (ambient_color + diffuse_color * diffuse_value + specular_color);
}
//GLSL

uniform vec4 upos;

varying vec3 vertex_light_position;
varying vec3 vertex_light_half_vector;
varying vec3 vertex_normal;

void main(void)
{
	vec4 vpos = gl_Vertex + upos[gl_InstanceID];
	gl_Position = gl_ModelViewProjectionMatrix * vpos;
	
	vertex_normal = normalize(gl_NormalMatrix * gl_Normal);
    vertex_light_position = normalize(gl_LightSource[0].position.xyz);
    vertex_light_half_vector = normalize(gl_LightSource[0].halfVector.xyz);
    gl_FrontColor = gl_Color;
	
	gl_TexCoord[0] = gl_MultiTexCoord0;
}

I can’t use cg shaders, because I have ATI card, and ATI doesn’t support cg shaders (only some basic functions, which instance isn’t).

Any help?

Passing arrays to shaders is not supported with GLSL.

You should not have a problem with using Cg, though. If you have “basic-shaders-only” set to “#f”, usually the shader is internally translated to GLSL anyway. So I advise using Cg instead.

we talked about it on the irc (nick battler), but I get InstaceID error with cgs (mostly since ATI doesnt support Cg anyways).

Here is the error:

:gobj(error): ../shaders/instance-shader.cg: (7) : error C5108: unknown semantics "INSTANCEID" specified for "l_id"
:gobj(error): Shader encountered an error.
:gobj(error): ../shaders/instance-shader.cg: (7) : error C5108: unknown semantics "INSTANCEID" specified for "l_id"

at this example,

//CG
//

void vshader(float4 vtx_position : POSITION,
//float vtx_othermodel : POSTION, //thats not working
float vtx_othermodel, //all values at zero
in uniform float4x4 mat_modelproj,
out float4 l_pos : POSITION)
{
l_pos = mul(mat_modelproj, vtx_position);
//l_pos1 = mul(mat_modelproj, vtx_othermodel); // 
}

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

is the entire vertex array (othermodel) on zero.

It is a common misconception that Cg is not supported on ATI cards. Cg is internally translated to other shader languages internally, so it should work on any card.

so you going to say, that the reason why the vertex array is on zero, is coming by amd? by translating the shader? i will ask at amd, if this is true.

I didn’t say that. There is either a bug in Panda3D, Cg or in your video card driver.

But first, make sure that “basic-shaders-only” is really set to “#f” and to be sure, put “//Cg profile glslv glslf” in your shader and set “notify-level-gobj debug” and give us the output.

oopsi, sorry maybe i miss interpreted your statement. :wink:

yes i did this already (without //cg just //profile…), its still using the default profile:

if the driver have a bug, then i do have really a problem. i think this was the latest release from amd. and this one is a bout a year old. so i dont think there will be a newer release coming.

…i will search for some alternative drivers today. (wish me luck…)

thanks anyhow for your answer…

oh one thing, is this correct how i try to receive the vertex coordinaten?

//Cg
//

void vshader(float4 vtx_position : POSITION,
//float vtx_othermodel : POSTION, //thats not working
float vtx_othermodel, //all values at zero
in uniform float4x4 mat_modelproj,
out float4 l_pos : POSITION)
{
l_pos = mul(mat_modelproj, vtx_position);
//l_pos1 = mul(mat_modelproj, vtx_othermodel); //
}

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

Sounds like you still have basic-shaders-only set to true. Also, it needs to be “//Cg profile” exactly.

basic-shaders are on false …
ok the to write //Cg profile was new to me, anyway it just seems not to work…

panda doesnt fit to the advanced stuff i have in mind. any suggestions about a more advanced engine?

whats about ogre or xna?

Without knowing what “advanced stuff” you want to do it is not possible to suggest anything.

Ogre is a rendering engine, not a game engine.
XNA is not an engine at all.

I agree with this poster.
I had my basic shaders set to false, and had profile in //Cg, yet it will still fail on InstanceID semantics with the error posted above.

And array passed to GLSL will be empty, for some weird reason.

i had in mind to do a realtime 3d motion blur. a nice lighting and some other cool stuff…

a graphics engine is exactly what i need. the other stuff like sound, collisions, pyhsics ,… are for sure already implemented or anybody already cared in ogre about.

xna isnt a engine i know, but lot of classes are already written to use it without much of work like a engine. and here the similar statement, someone already cared about the most things… (a friend of mine, is writting a engine on xna)

im only in need to work on something without getting everytime into a situation where i have to wait till it got fixed. or using workarounds which are mostly not that much smooth, like the basic way was.

Panda3D is advanced enough- it supports the feature you require. Just because you are having a difficulty with it (or there may be a bug), doesn’t mean the engine is not advanced enough. You misspelled “basic-shaders-only”, by the way.

Well there must be either bug or it is unsupported by the driver (which is very probable, because driver is made by AMD not NVIDIA).

Anyways, here is my code:

Python

import tests
import os
import math
import time

from pandac.PandaModules import ConfigVariableBool
shandle = ConfigVariableBool('basic-shaders-only', False)
shandle.setValue(True)

import direct.directbase.DirectStart

from pandac.PandaModules import *
from panda3d.core import *
from direct.actor.Actor import Actor

INST_NUM = 50
MODEL = os.path.abspath("../models/mod.egg")
TEXTURE = os.path.abspath("../textures/text.png")
SHA_V = "../shaders/inst-sha-v.sha"
SHA_F = "../shaders/inst-sha-f.sha"
SHA_NVIDIA = "../shaders/instance-shader.cg"

position = PTAVecBase4.emptyArray(INST_NUM)
rotation = PTAFloat.emptyArray(INST_NUM)

for x in xrange(0, INST_NUM):
	position[x] = Vec4(x*10.0, x*10.0, 0.0, 0.0)
	rotation[x] = float(math.radians(45))



model = Actor(MODEL)
model.setTexture(loader.loadTexture(TEXTURE))
model.setScale(5.0, 5.0, 5.0)
model.loop("idle01")
model.reparentTo(render)

shader = Shader.load(SHA_NVIDIA)
#shader = Shader.load(Shader.SLGLSL, SHA_V, SHA_F)

model.setShaderInput("offsets", position)
#model.setShaderInput("z_Position", position)
#model.setShaderInput("z_Rotation", rotation)
model.setShader(shader)

model.setInstanceCount(INST_NUM)

run()

Cg Shader

//Cg
//Cg profile glslv glslf

void vshader(float4 vtx_position: POSITION,
             float2 vtx_texcoord0: TEXCOORD0,
             uniform float4x4 mat_modelproj,
             int l_id: INSTANCEID,
             uniform float4 offsets[256],
             out float4 l_position : POSITION,
             out float2 l_texcoord0 : TEXCOORD0)
{
  l_position = mul(mat_modelproj, vtx_position + offsets[l_id]);
  l_texcoord0 = vtx_texcoord0;
}


void fshader(float2 l_texcoord0: TEXCOORD0,
             uniform sampler2D tex_0: TEXUNIT0,
             out float4 o_color: COLOR)
{
  o_color = tex2D(tex_0, l_texcoord0);
}

However, it will print this and do nothing:

DirectStart: Starting the game.
Known pipe types:
  glxGraphicsPipe
(all display modules loaded.)
:gobj(error): ../shaders/instance-shader.cg: (7) : error C5108: unknown semantics "INSTANCEID" specified for "l_id"
:gobj(error): Shader encountered an error.
:gobj(error): ../shaders/instance-shader.cg: (7) : error C5108: unknown semantics "INSTANCEID" specified for "l_id"

I wasn’t able to get the hardware instancing working on an ATI card with a CG shader either. Though if you don’t mind compiling your own build, you will find that the source code provided in this thread (8th post) will allow you to send array inputs to a GLSL shader, which works on an ATI card.

sorry i misspelled there nothing, i was just setting the existing call (basic-shader-only)or called short basic shaders, which is already in the config file, to false (#f i also tried it with zero (0)).

its not, just because i dont get this thing to run on a ati, means that it runs in regular on a nvidia card.

i only can say it doesnt work for me. so i cant do state of the art things with this engine, which means the engine is not advanced enough. (and this engine is not for free, if im going to download now any sources code, i have to spend money for the traffic, ok you dont receive any money. but it costs money for me)

peace

just get this pipe smoothly (without any workarounds) to work on ati graphics cards and i will be back.

so long then…

I tried to apply that patch, but unfortunately, only things that were different from recent cvs, is two lines. Which I added, but it did nothing.