Reflection problem.

Hi, I’m in the middle of reflection ‘trial and error’ using dynamic cube map.

I’m just curious, can we apply reflection as simple as defining the reflectivity level ?
When I use the Modulate mode, the result is too dark, and with the Add mode, the result is too bright.
I’ve tried to call setCombineRgb() and supply the possible sources and operands, but then all original (lower) textures lost.
Because I use dynamic cube map and it is rendered each frame, it is impossible to darken the reflected textures just like using the static cube map loaded from disk.

Any idea ?

regards,

JO

Have you thought about using shaders to render your relections? That way you can have absolute control over the color of every pixel you render. Panda makes it pretty simple to get up and running with your own custom stuff.

Well, CG reflectins also use CUBEmaps and I believe that you need to pass it from panda to your shader. I don’t know the details on this, but from the examples i have seen, that’s the way it works.

Miel

Right, using a shader will be the most elegant and effective way to control the reflectivity level. You can also do it to a lesser extent without using a shader, however, by using the texture combiner, but it will take an additional texture stage; and it may be a bit tricky to work out the exact combiner options you need to use. The Panda3D manual may be a little bit helpful here in pointing out the available combiner options, but it will take some trial and error to work out the details.

David

I’m totally new in Cg, so firstly I tried to desaturate the cubemap texture using a shader, but I got an error :

:display:gsg:glgsg(error): shader1.sha (23) : error C1102: incompatible type for parameter #2 (“s”)

This is the shader :


//Cg
//
//Cg profile arbvp1 arbfp1

void vshader(
  float3 vtx_position : POSITION,
  float2 vtx_texcoord0 : TEXCOORD0,
  out float4 out_position : POSITION,
  out float2 out_texcoord0 : TEXCOORD0,
  uniform float4x4 mat_modelproj)
{
  out_position=mul(mat_modelproj, float4(vtx_position,1));
  out_texcoord0=vtx_texcoord0;
}

void fshader(
  float4 out_position : POSITION,
  float2 out_texcoord0 : TEXCOORD0,
  samplerCUBE cubemap : TEXUNIT1,
  out float4 out_color : COLOR)
{
  float attenuate = saturate(0.1);
  float4 newcubemap = texCUBE(cubemap, out_texcoord0); --> erronous

  out_color=attenuate * newcubemap;
}

What did I miss ?
Thanks.

can you post the panda code? Maybe you didn’t pass the cubemap properly?

Miel

I’ve made some changes in the shader, especially in line 23:
from :

float4 newcubemap = texCUBE(cubemap, out_texcoord0);

to :

float3 newcubemap = texCUBE(cubemap, out_texcoord0);

This is the new shader :

//Cg
//
//Cg profile arbvp1 arbfp1

void vshader(
  float3 vtx_position : POSITION,
  float2 vtx_texcoord0 : TEXCOORD0,
  out float4 out_position : POSITION,
  out float2 out_texcoord0 : TEXCOORD0,
  uniform float4x4 mat_modelproj)
{
  out_position=mul(mat_modelproj, float4(vtx_position,1));
  out_texcoord0=vtx_texcoord0;
}

void fshader(
  float4 out_position : POSITION,
  float2 out_texcoord0,
  samplerCUBE cubemap,
  out float4 out_color : COLOR)
{
  float attenuate = saturate(0.1);
  float3 newcubemap = texCUBE(cubemap, out_texcoord0);

  out_color=newcubemap*attenuate;
}

There is no more error in line 23, but now the error is :

:display:gsg:glgsg(error): shader1.sha (25) : error C1035: assignment of incompatible types

in line 25:

out_color=newcubemap*attenuate;

Correct me if this is wrong :
the newcubemap is float3 and the attenuate is float, so the out_color if float3, but it’s expected to be float4.

How can I fix this, I’ve tried to cast it up to float4, but it didn’t work.

Here is the outline of the reflection and shader settings in the script :

    self.reflectionshader = Shader.load("shader1.sha")
    self.refleksimobiltexstage=TextureStage('refleksi')
    self.refleksimobiltex=self.setreflection(self.parent_of_object1,self.refleksimobiltexstage)
    self.applyreflection(self.object1)
    self.applyreflection(self.object2)
    self.applyreflection(self.object3)
    .
    .
    .(and so on)


def setreflection(self,whichobject,texstage):
    .
    .
    .
    (setting the cameras and it's node)
    .
    .
    .
    return reflectionbuffer.getTexture()

def applyreflection(self,whichobject):
    self.whichobject=whichobject
    self.whichobject.setTexGen(self.refleksimobiltexstage, TexGenAttrib.MWorldCubeMap)
    self.whichobject.setTexture(self.refleksimobiltexstage,self.refleksimobiltex)
    ### set the shader ###
    self.whichobject.setShader(self.reflectionshader)

I didn’t pass the cubemap texture manually to the shader, because it will be done by Panda, or NOT ?

Thanks,

JO

for line 25.

I don’t know if setting your cubemap to float3 will do you any good but if that’s what works for you, try:


out_color.xyz = newcubemap * attenuate;
out color.w = 1.0;

I also don’t know if Panda is okay with the fact that you choose to name you cubemap “samplerCUBE cubemap” in your shader. I assume that the cubemap is stored into the second texture. So maybe you should try:


samplerCUBE tex_1

or


samplerCUBE tex_1   :   TEXUNIT1

maybe this’ll help.

I’ll do an in depth look this evening. I tried it myself a while ago. No sure if I had any succes though.

later,

Miel

I’ve tried everything (I think) possible, but still no progress.
I’m curious, the cubemap texcoord is not the same with the 2D texcoord.

Where can I find a complete reference about Cg ?

Thanks.

developer.nvidia.com/object/cg_toolkit.html

hth,
kaweh

Hey there,

as far as I know, the CG reference won’t help you much in this case because Panda has it’s own interface to CG. In other words: all of the things in the reference are related to c/c++ openGL or directX. You’ll have to figure out for yourself or through the forums how to revert it back to Panda “format”.

Miel

A CG or HLSL reference will work just fine for questions about the language, the only part panda really controls are the shader parameters that get passed in.

The texture coordinant for texCUBE is a float3, you can think of this as a ray from the center of the cube that shoots out and samples the texture.

Hope this helps. Don’t mind the noise textures, there for disrupting the reflections and refractions. This also has a fresnel term. It should work on nVidia 6 series as well as Radeon 9800s and above. Also, the calculations for reflection are in no way accurate, but they look good enough and is a pretty fast way of doing things.


//Cg

void vshader(float4 vtx_position : POSITION,
            float2 vtx_texcoord0 : TEXCOORD0,
            float3 vtx_normal : NORMAL,

          in uniform float4x4 mat_modelproj,
          in uniform float4 mspos_cam,
          in uniform float4 k_waterProperties,

          out float2 l_texcoord0 : TEXCOORD0,
          out float2 l_texcoord1 : TEXCOORD1,
          out float4 l_position : POSITION,
          out float3 l_ms_camvec,
          out float3 l_ms_position,
          out float3 l_ms_normal)
{
  //normal mapping stuff
  l_ms_normal = vtx_normal;

  l_ms_camvec = normalize(vtx_position.xyz - mspos_cam.xyz);
  l_ms_position = vtx_position.xyz;

  l_position = mul(mat_modelproj, vtx_position); //vertex position
  l_texcoord0 = vtx_texcoord0 * k_waterProperties.x + float2(k_waterProperties.z,0.0);
  l_texcoord1 = vtx_texcoord0 * k_waterProperties.y - float2(k_waterProperties.w,0.0);
  

  //l_texcoord0 = reflect(l_mscam_vec, vtx_normal.xyz) + vtx_position.xyz;
  //l_mscam_vec += vtx_position.xyz;
}

void fshader(float2 l_texcoord0: TEXCOORD0,
             float2 l_texcoord1 : TEXCOORD1,
             float3 l_ms_camvec,
             float3 l_ms_position,
             float3 l_ms_normal,
             uniform samplerCUBE tex_0:TEXUNIT0,
             uniform sampler2D k_noise1:TEXUNIT6,
             uniform sampler2D k_noise2:TEXUNIT7,


             out float4 o_color:COLOR)
{
  float4 noise1 = tex2D(k_noise1, l_texcoord0);
  float4 noise2 = tex2D(k_noise2, l_texcoord1);
  float4 noiseColor = 0.5 * (noise1 + noise2);

  float3 adjustedNormal = normalize((noiseColor.rgb - 0.5) * 2.0 + l_ms_normal);
  

  float3 reflectvec = reflect(l_ms_camvec, adjustedNormal) + l_ms_position.xyz;
  float3 refractvec = refract(l_ms_camvec, adjustedNormal, 1.3) + l_ms_position.xyz;
  //float3 refractvec = l_ms_camvec + l_ms_position.xyz;
  float4 reflectionColor =  texCUBE(tex_0, reflectvec);
  float4 transparencyColor = texCUBE(tex_0, refractvec);
  //transparencyColor *= float4(100.0/255.0, 109.0/255.0, 135.0/255.0, 1.0);
  float fresnelTerm = dot(adjustedNormal,reflectvec);
  o_color = lerp(reflectionColor, transparencyColor,fresnelTerm);
  //o_color.rgb = transparencyColor.rgb;
  o_color.a = 1.0;
}

Well, there you have it. This is really awesome.

Go Bei!

cheers,
Miel

Yes, awesome, Bei.

This means pedal to the metal.
Way to go !

Thanks alot.