Trying to obtain Panda3ds synthesized shaders (or looks)

Hi everybody, I apologize for being back this soon, but I have been really trying for days to duplicate a certain shader created by panda3d;s shader generator, I would not normally do this since panda3d would give me the effect by setting setShaderAuto().

But in order to use glsl I had to set the GL version to 3.2 which broke the shader generator, at first I did not think it was problem since I thought it was basic normal mapping at play and I had glsl normal map shader at my disposal.

But as I tried it I learnt that was not the case, I did some research and it appears that it
is some kind of phong lighting shader with a grease look to it, I have provided a example of the shader generator and my glsl shader, the one on the left is my glsl one, and the one on the right is panda;s.


in the picture at the ramp in the background, the lighting is much more superior to my custom one as I used a simple dirctional light and ambient light for panda3d to generate this look, I tried this with a normalized vector of my camera position and vertex position and got a weak light.

oh and a extra request, the blending effect, I want to believe it is a simple mix pixel coloring process but judging by the image below, it seems like a much more complicated process at play.


now, I came here to ask because I read that panda3d synthesizes shaders to achieve these looks, if its possible to obtain these synthesized shaders and turn them into glsl shaders to use.

if not, I was wondering if anyone can explain what panda3d is doing to achieve these looks so I can try to make my own? Thank you to anyone wanting to help, and have a great day.

I believe that one can indeed export the shaders produced by the shader generator!

Based on the following (admittedly old) forum-post, it looks like it’s done via a configuration variable. See the post for details!

2 Likes

thanks, yes it produced 2 Cg shaders, though because its Cg and not glsl, I have to now try to translate them into useable glsl, this may take a vary long while, I will get back to you then with the result to see if they are them, once again thank you

Edit: alright, I almost got it, here is the original shader.

//Cg
/* Generated shader for render state:
  AlphaTestAttrib:greater,0
  ColorScaleAttrib:identity
  CullFaceAttrib:cull_clockwise
  DepthWriteAttrib:off
  LightAttrib:on
    render/directionalLight
    render/ambientLight
  MaterialAttrib:Material Floor a(1 1 1 1) d(0.64 0.64 0.64 1) s(0.5 0.5 0.5 1) e(0 0 0 1) s12.5 l0 t0
  RescaleNormalAttrib:none
  ShaderAttrib:auto
  TextureAttrib:on default:rm_1 tsnormal:rm_1_n
  TransparencyAttrib:alpha
*/
void vshader(
	 in float4 vtx_texcoord : ATTR8,
	 out float4 l_texcoord : TEXCOORD0,
	 in float4 vtx_tangent : ATTR9,
	 in float4 vtx_binormal : ATTR10,
	 out float4 l_tangent : TEXCOORD1,
	 out float4 l_binormal : TEXCOORD2,
	 in float4 vtx_color : ATTR3,
	 out float4 l_color : COLOR0,
	 uniform float4x4 trans_model_to_view,
	 out float4 l_eye_position : TEXCOORD3,
	 uniform float4x4 tpose_view_to_model,
	 in float3 vtx_normal : ATTR2,
	 uniform float4x4 mat_shadow_0,
	 out float4 l_lightcoord0 : TEXCOORD4,
	 in float4 vtx_position : ATTR0,
	 out float4 l_position : POSITION,
	 uniform float4x4 mat_modelproj
) {
	 l_position = mul(mat_modelproj, vtx_position);
	 l_eye_position = mul(trans_model_to_view, vtx_position);
	 l_texcoord = vtx_texcoord;
	 l_color = vtx_color;
	 l_tangent.xyz = normalize(mul((float3x3)trans_model_to_view, vtx_tangent.xyz));
	 l_tangent.w = 0;
	 l_binormal.xyz = normalize(mul((float3x3)trans_model_to_view, -vtx_binormal.xyz));
	 l_binormal.w = 0;
	 l_lightcoord0 = mul(mat_shadow_0, l_eye_position);
	 float3 eye_normal = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));
	 l_tangent.w = eye_normal.x;
	 l_binormal.w = eye_normal.y;
	 l_eye_position.w = eye_normal.z;
}

void fshader(
	 in float4 l_eye_position : TEXCOORD3,
	 in float4 l_texcoord : TEXCOORD0,
	 uniform sampler2D tex_0,
	 uniform sampler2D tex_1,
	 in float4 l_tangent : TEXCOORD1,
	 in float4 l_binormal : TEXCOORD2,
	 uniform float4x4 attr_light0,
	 uniform sampler2DShadow shadow_0,
	 in float4 l_lightcoord0 : TEXCOORD4,
	 uniform float4x4 attr_material,
	 out float4 o_color : COLOR0,
	 in float4 l_color : COLOR0,
	 uniform float4 attr_ambient,
	 uniform float4 attr_colorscale
) {
	 float3 l_eye_normal = float3(l_tangent.w, l_binormal.w, l_eye_position.w);
	 float4 result;
	 float4 texcoord0 = l_texcoord;
	 float4 texcoord1 = l_texcoord;
	 // Fetch all textures.
	 float4 tex0 = tex2D(tex_0, texcoord0.xy);
	 float4 tex1 = tex2D(tex_1, texcoord1.xy);
	 // Correct the surface normal for interpolation effects
	 l_eye_normal = normalize(l_eye_normal);
	 // Translate tangent-space normal in map to view-space.
	 float3 tsnormal = normalize((tex1.xyz * 2) - 1);
	 l_eye_normal *= tsnormal.z;
	 l_eye_normal += normalize(l_tangent.xyz) * tsnormal.x;
	 l_eye_normal += normalize(l_binormal.xyz) * tsnormal.y;
	 l_eye_normal = normalize(l_eye_normal);
	 // Begin view-space light calculations
	 float ldist,lattenv,langle,lshad;
	 float4 lcolor,lspec,lpoint,latten,ldir,leye;
	 float3 lvec,lhalf;
	 float4 tot_ambient = float4(0,0,0,0);
	 float4 tot_diffuse = float4(0,0,0,0);
	 float4 tot_specular = float4(0,0,0,0);
	 float shininess = attr_material[3].w;
	 tot_ambient += attr_ambient;
	 // Directional Light 0
	 lcolor = attr_light0[0];
	 lspec  = lcolor;
	 lvec   = attr_light0[3].xyz;
	 lcolor *= saturate(dot(l_eye_normal, lvec.xyz));
	 lshad = shadow2DProj(shadow_0, l_lightcoord0).r;
	 lcolor *= lshad;
	 lspec *= lshad;
	 tot_diffuse += lcolor;
	 lhalf = normalize(lvec - float3(0, 1, 0));
	 lspec *= pow(saturate(dot(l_eye_normal, lhalf)), shininess);
	 tot_specular += lspec;
	 // Begin view-space light summation
	 result = attr_material[2];
	 result += tot_ambient * attr_material[0];
	 result += tot_diffuse * attr_material[1];
	 result = saturate(result);
	 // End view-space light calculations
	 result.a = attr_material[1].w;
	 result *= attr_colorscale;
	 result.rgba *= tex0.rgba;
	 tot_specular *= attr_material[3];
	 result.rgb = result.rgb + tot_specular.rgb;
	 o_color = result * 1.000001;
}

and here is my take, vertex shader.

# version 150 // vertex shader

uniform mat4 p3d_ModelViewProjectionMatrix;
uniform mat4 p3d_ModelMatrix;
uniform mat4 p3d_ViewMatirx;
uniform mat4 p3d_ViewProjectionMatrix;
uniform mat4 p3d_ModelViewMatrix;

in vec4 p3d_Vertex;
in vec2 p3d_MultiTexCoord0;
in vec3 p3d_Normal;
in vec4 p3d_Color;
in vec3 p3d_Tangent;
in vec3 p3d_Binormal;

out vec4 vEye;
out vec2 vUv;
out vec4 vTan;
out vec4 vBi;
out vec4 vView;

void main() {
    vNormal = normalize(p3d_ViewMatrix * p3d_Nomral;
    vEye = p3d_ModelMatrix * p3d_Vertex;
    vEye.w = vNormal.z;
    vUv = p3d_MultiTexCoord0; // does not know if this is correct?
    vColor = p3d_Color;
    vTan = normalize(p3d_ModelViewMatrix * p3d_Tangent);
    vTan.w = vNomral.x;
    vBi = vec4(normalize(p3d_ModelViewMatrix * p3d_Binormal), vNormal.y);
    vView = inverse(p3d_ViewProjectionMatrix) * vec4(0, 0, 1.0, 1.0);
    vView.xyz /= vView.w;
    vLight = vec3(vView.xyz - p3d_Vertex.xyz)
    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;    
}

and the fragment shader.

#version 150 // fragment shader

uniform sampler2D p3d_Texture0;
uniform sampler2D p3d_Texture1;

in vec4 vEye;
in vec2 vUv;
in vec4 vTan;
in vec4 vBi;

out vec4 p3d_FragColor;

void main() {
    // Translate tangent-space normal in map to view-space.
    tang = vec3(normalize(texture(p3d_Texture1, vUv).xyz * 2) - 1);
    nrmMap = normalize(vEye * tang.z + (normalize(vTan.xyz) * tang.x) + (normalize(vBi.xyz) * tang.y));
    // Directional Light (Global)
    color = vec4(.0, .0, .0, .0);
    forward = normalize(attr_light0[3].xyz - vec3(0, 1, 0));
    ambient = vec4(.0, .0, .0, .0) * vec4(1, 1, 1, 1) // 1st is actual value.
    diffuse = vec4(0, 0, 0, 0) * vec4(0.64, 0.64, 0.64, 1) // 1st is actual value.
    specular = 50.0
    sheen = color * pow(clamp(dot(nrmMap, forward), 0.0, 1.0), specular) * vec4(0, 0, 0, 1);
    // Begin view-space light summation
    result = clamp(vec4(0.5 0.5 0.5 1) + ambient + diffuse, 0.0, 1.0) * Vec4(1.0, 1.0, 1.0, 1.0) * texture(p3d_Texture0, vUv).rgba;
    result.a = 1;
    // End view-space light calculations
    vec3 texel = result.rgb + sheen.rgb;
    p3d_FragColor = vec4(texel, 1.0);
}

I am only missing attr_light0[3], which I do not know what it is, from research it could be the half angle but I really don’t know.

1 Like

If you look at the name of the variable and the type of light source, that is, directional, then this is the direction vector.

1 Like

Ah, okay, I will try that calculation later tonight, thanks

Edit: okay back, a little late, though I tried your idea but I only got a quarter light, plus after looking more closely it is swizzling from a vec3 from a vec4 so I assume it is a matrix of some kind .

after a day of trying the closest I got was half light.
:removed to conserve bandwidth
plus if you notice, in the original picture, compared to this, the original had a sort of inverse specular to it which darked some areas to make it look greasy or wet, something I dont see here.

Here is my updated shader pair for you guys to see where I am at, maybe you can find where I went wrong, I will continue tomorrow though, the vertex shader.

# version 150 // vertex shader

uniform mat4 p3d_ModelViewMatrix;
uniform mat4 p3d_ModelViewProjectionMatrix;

in vec2 p3d_MultiTexCoord0;
in vec3 p3d_Normal;
in vec3 p3d_Binormal;
in vec3 p3d_Tangent;
in vec4 p3d_Vertex;

out vec2 vUv;
out vec4 vEye;
out mat3 tbnMatrix;

void main() {
    vUv = p3d_MultiTexCoord0;
    vEye = vec4(p3d_Vertex.x, p3d_Vertex.y, p3d_Vertex.z, 0);
    vec4 tan = normalize(p3d_ModelViewMatrix * vec4(p3d_Tangent, 0));
    vec4 bi = normalize(p3d_ModelViewMatrix * vec4(p3d_Binormal, 0));
    vec3 nrm = normalize(vec3(p3d_ModelViewMatrix * vec4(p3d_Normal, 0)));
    tbnMatrix = mat3(normalize(tan.xyz), normalize(bi.xyz), nrm);

    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
}

and the fragment shader.

# version 150 // fragment shader

uniform sampler2D p3d_Texture0;
uniform sampler2D p3d_Texture1;

in vec2 vUv;
in vec4 vEye;
in mat3 tbnMatrix;

out vec4 p3d_FragColor;

void main (){
    // Material (Global)
    vec4 bright = vec4(1, 1, 1, 1);
    vec4 sheen = vec4(0.64, 0.64, 0.64, 1);
    vec4 scale = vec4(1.0, 1.0, 1.0, 1.0); // colorscale
    vec4 reflect = vec4(0.5, 0.5, 0.5, 1);
    // Directional Light (Global)
    vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
    vec3 forward = vEye.xyz;
    vec4 ambient = vec4(0.5, 0.5, 0.5, 0.5) * bright;
    vec4 diffuse = vec4(0, 0, 0, 0) * sheen;
    float specular = 32.0;
    // Translate tangent-space normal in map to view-space.
    vec3 glaze = normalize(texture(p3d_Texture1, vUv).xyz * 2.0 - 1.0);
    vec3 glossMap = normalize(tbnMatrix * glaze);
    vec4 gloss = vec4(0, 0, 0, 0) + (color * pow(clamp(dot(glossMap, normalize(forward - vec3(0, 1, 0))), 0, 1.0), specular));
    // Begin view-space light summation
    vec4 shadow = diffuse + (color + clamp(dot(glossMap, forward), 0.0, 1.0));
    vec4 summation = clamp(reflect + (ambient * bright) + (shadow * sheen), 0.0, 1.0);
    summation.a = sheen.w;
    vec4 result = (summation * scale).rbga * texture(p3d_Texture0, vUv).rgba;
    // End view-space light calculations
    vec3 texel = result.rgb + gloss.rgb;
    p3d_FragColor = vec4(texel, 1.0);
}

once again thanks for your help
Edit: well it turns out you were right, after another day of tweaking I found out it was a light direction that was needed, it was just I was using the model matrix wrong, so here where I am so far, I am getting close.
:removed to conserve bandwidth
oh and the updated shader, vertex

# version 150 // vertex shader

uniform mat4 p3d_ModelViewMatrix;
uniform mat4 p3d_ModelViewProjectionMatrix;

in vec2 p3d_MultiTexCoord0;
in vec3 p3d_Normal;
in vec3 p3d_Binormal;
in vec3 p3d_Tangent;
in vec4 p3d_Vertex;

out vec2 vUv;
out vec4 vEye;
out mat3 tbnMatrix;

void main() {
    vUv = p3d_MultiTexCoord0;
    //vEye = vec4(p3d_Vertex.x, p3d_Vertex.y, p3d_Vertex.z, 0);
    //vEye = vec4(normalize(vec3(0, 0, 1) + 1), 0);
    vec3 view = -normalize((p3d_ModelViewMatrix * p3d_Vertex).xyz);
    vEye = vec4(view, 1.0);
    vec4 tan = normalize(p3d_ModelViewMatrix * vec4(p3d_Tangent, 0));
    vec4 bi = normalize(p3d_ModelViewMatrix * vec4(p3d_Binormal, 0));
    vec3 nrm = normalize(vec3(p3d_ModelViewMatrix * vec4(p3d_Normal, 0)));
    tbnMatrix = mat3(normalize(tan.xyz), normalize(bi.xyz), nrm);

    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
}

and the fragment

# version 150 // fragment shader

uniform sampler2D p3d_Texture0;
uniform sampler2D p3d_Texture1;

in vec2 vUv;
in vec4 vEye;
in mat3 tbnMatrix;

out vec4 p3d_FragColor;

void main (){
    // Material (Global)
    vec4 bright = vec4(0.5, 0.5, 0.5, 0.5);
    vec4 sheen = vec4(0.64, 0.64, 0.64, 1);
    vec4 scale = vec4(1.0, 1.0, 1.0, 1.0); // colorscale
    vec4 reflect = vec4(0, 0, 0, 1);
    // Directional Light (Global)
    vec4 color = vec4(0.33, 0.33, 0.33, 0.33);
    vec3 forward = vec3(0, 0, -1);
    vec4 ambient = vec4(0, 0, 0, 0) + bright;
    vec4 diffuse = vec4(0, 0, 0, 0) + sheen;
    float specular = 6.0;
    // Translate tangent-space normal in map to view-space.
    vec3 glaze = normalize(texture(p3d_Texture1, vUv).xyz * 2.0 - 1.0);
    vec3 glossMap = normalize(tbnMatrix * glaze);
    vec4 gloss = vec4(0, 0, 0, 0) + (color * pow(clamp(dot(glossMap, normalize(vEye.xyz + vec3(0, 1, 0))), 0.0, 1.0), specular));
    // Begin view-space light summation
    vec4 shadow = diffuse + (color * clamp(dot(glossMap, normalize(vEye.xyz + forward)), 0.0, 1.0));
    vec4 summation = clamp(reflect + (ambient * bright) + (shadow * sheen), 0.0, 1.0);
    summation.a = sheen.w;
    vec4 result = (summation * scale).rbga * texture(p3d_Texture0, vUv).rgba;
    // End view-space light calculations
    vec3 texel = mix(result.rgb, gloss.rgb, 0.45) * 1.9;
    p3d_FragColor = vec4(texel, 1.0);
}
1 Like

First of all, well done on how far you’ve gotten thus far! :slight_smile:

As to the remaining discrepancies, one that I note is that it looks to me like the light-direction is reversed–note the direction of the darker regions on the pattern on the ramp.

1 Like

There is another variant of this phenomenon. Perhaps the shader is written for Directx. Shaders for processing normal maps take direction into account in different ways, for example, the OpenGL shader requires direction inversion.

2 Likes

sorry about not posting yesterday, I was away, but, yeah, You guys are right, the Normals seem to be inside out, this something I have not been able to fix yet, it seems to be tied the matrixes or the way I calculate my half vector.

I still dont know how to calculate this half vector correctly and the reason the shader could be janked up, the sources which tried the explain it, explain normalizing the light vector + eye vector, but the light vector is a problem because I am trying to simulate a directional light so how would get the light vector from that?

another thing is the eye, does it want a position or the forward vector of the camera view, I actually tried to get the forward with the ModelViewMatrix then the reverse of it by ViewMatrix * ModelMatrix, then witth ModelViewMatrix * VertexPosition.

only by -(ModelViewMatrix * VertexPosition) did I get some result, but it was inside out as you have seen.


does this look okay?
:removed to conserve bandwidth
what about this?
:removed to conserve bandwidth
I know from this, that the floor is at least still inside out
:removed to conserve bandwidth
I have tried snce the past two days I cannot seem to flip the normals yet, I have provided a cleaner version of the shader so maybe someone can see something I missed, the vertex.

# version 150 // vertex shader

uniform mat4 p3d_ModelViewMatrix;
uniform mat4 p3d_ModelViewProjectionMatrix;

in vec2 p3d_MultiTexCoord0;
in vec3 p3d_Normal;
in vec3 p3d_Binormal;
in vec3 p3d_Tangent;
in vec4 p3d_Vertex;

out vec2 vUv;
out vec4 vEye;
out mat3 tbnMatrix;

void main() {
    vUv = p3d_MultiTexCoord0;
    vEye = -normalize(p3d_ModelViewMatrix * p3d_Vertex);
    vec4 tan = normalize(p3d_ModelViewMatrix * vec4(p3d_Tangent, 0));
    vec4 bi = normalize(p3d_ModelViewMatrix * vec4(-p3d_Binormal, 0));
    vec3 nrm = mat3(transpose(inverse(p3d_ModelViewMatrix))) * p3d_Normal;
    tbnMatrix = mat3(normalize(tan.xyz), normalize(bi.xyz), normalize(nrm));

    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
}

and the fragment.

# version 150 // fragment shader

uniform sampler2D p3d_Texture0;
uniform sampler2D p3d_Texture1;

in vec2 vUv;
in vec4 vEye;
in mat3 tbnMatrix;

out vec4 p3d_FragColor;

void main (){
    // Directional Light (Global)
    vec4 color = vec4(0.34, 0.34, 0.34, 0.34);
    vec3 forward = vec3(0, 1, 0);
    vec4 scale = vec4(1.0, 1.0, 1.0, 1.0); // colorscale
    vec4 ambient = vec4(0.5, 0.5, 0.5, 0.5);
    vec4 diffuse = vec4(0.64, 0.64, 0.64, 1);
    float specular = 8.0; // negative causes a rim light effect.
    // Translate tangent-space normal in map to view-space.
    vec3 tsNrm = normalize((texture(p3d_Texture1, vUv).xyz * 2) - 1);
    vec3 eyeNrm = normalize(tbnMatrix * tsNrm);
    vec3 halfvec = normalize(vEye.xyz + forward);
    vec4 gloss = color * pow(clamp(dot(eyeNrm, halfvec), 0.0, 1.0), specular);
    // Begin view-space light summation
    vec4 shadow = diffuse + (color * clamp(dot(eyeNrm, forward), 0.0, 1.0));
    vec4 summation = clamp((ambient * 0.4) + (shadow * diffuse), 0.0, 1.0);
    summation.a = diffuse.w;
    vec4 result = (summation * scale).rbga * texture(p3d_Texture0, vUv).rgba;
    // End view-space light calculations
    vec3 texel = result.rgb + gloss.rgb;
    p3d_FragColor = vec4(texel, 1.0);
}

I will try some more tomorrow, have a good one guys

It looks improved, at the least, I do think!

In particular, the ramps look pretty close–the purple one shows some differences in colouration, but nothing too huge.

It does look like the ground is lit differently, and the character-model too–unless you haven’t yet applied your changes to those…?

1 Like

I assume it could be color, but I have never seen the other side of the normal, though given that it looks like the original it could be assumed it is just the color, especially since the original is factoring in lighting and material color from the control program and I did mostly guess work to get to the coloring where I am at.

the floor though is wrong, and I am concerned because I have little to no options left, it seems I tried everything. he character model though is using a much different GLSL shader then the original that when I return to the original Cg setup there is no shading for it so t renders in the auto shader, that is how the character model looks in the auto shader.

To the former, ah, fair enough–it could well be that it’s a difference in material properties!

And likewise with regards to the model–that does explain the discrepancy there!

As to the floor, well, material properties might have at least some effect there, too–perhaps the specularity value is different to what you have, for example. I’m not sure that that’s all of the difference, but it may at least play a part…

sorry for the late reply, it seems to be a lighting issue if I had to guess, its attr_light0[3].xyz if only I knew what that exactly was, as my attempts so far have been guessing what that variable is, though it seems I may be onto something close as I got this far.

it could even just be a simple glsl quirk as this is my 3rd method of getting back to this result, maybe this is the real result, I say that because as I have seem this inversion before in the original on my published games.

some objects and faces are uncommonly inside out, but as you can see, the floor is not supposed to be one of those flips. but what if Cg and GLSL computing differ? then maybe the floor in GLSL is one of those uncommon flips, just a thought.

Since I’m noob to shaders, I took your task as my goal in search of an answer.

main.py

from panda3d.core import DirectionalLight, NodePath, Shader, Vec3, loadPrcFileData
loadPrcFileData("", "gl-coordinate-system default")
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        shader_light = Shader.load(Shader.SL_GLSL, "shaders/directional_light_vert.glsl", "shaders/directional_light_frag.glsl")
        render.set_shader(shader_light)
        #render.set_shader_auto()

        self.point_light = DirectionalLight('point_light')
        self.light_path = NodePath(self.point_light)
        render.set_light(self.light_path)

        self.test = loader.load_model('model/test')
        self.test.reparent_to(render)

        taskMgr.add(self.update, "update")

    def update (self, task):
        render.set_shader_input("attr_colorscale", self.test.get_color_scale())
        return task.cont

app = MyApp()
app.run()

directional_light_vert.glsl

#version 150

uniform mat4 p3d_ModelViewProjectionMatrix;
uniform mat4 p3d_ViewMatrixInverse;

uniform mat4 trans_model_to_view;
uniform mat4 tpose_view_to_model;

in vec2 p3d_MultiTexCoord0;
in vec4 p3d_Color;
in vec3 p3d_Normal;
in vec3 p3d_Binormal;
in vec3 p3d_Tangent;
in vec4 p3d_Vertex;

out vec4 l_eye_position;
out vec4 l_texcoord;
out vec4 l_color;
out vec4 l_tangent;
out vec3 l_eyevec;
out vec4 l_binormal;

void main() {
    l_eye_position = trans_model_to_view * p3d_Vertex;
    l_texcoord = vec4(p3d_MultiTexCoord0, 0, 0);
    l_color = p3d_Color;
    l_tangent.xyz = normalize(mat3(trans_model_to_view) * p3d_Tangent.xyz);
    l_tangent.w = 0;
    l_binormal.xyz = normalize(mat3(trans_model_to_view) * -p3d_Binormal.xyz);
    l_binormal.w = 0;
    vec3 eyedir = p3d_ViewMatrixInverse[3].xyz - p3d_Vertex.xyz;
    l_eyevec.x = dot(p3d_Tangent.xyz, eyedir);
    l_eyevec.y = dot(p3d_Binormal.xyz, eyedir);
    l_eyevec.z = dot(p3d_Normal, eyedir);
    l_eyevec = normalize(l_eyevec);
    vec3 eye_normal = normalize(mat3(tpose_view_to_model) * p3d_Normal);
    l_tangent.w = eye_normal.x;
    l_binormal.w = eye_normal.y;
    l_eye_position.w = eye_normal.z;
    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
}

directional_light_frag.glsl

#version 150

uniform sampler2D p3d_TextureNormal;
uniform sampler2D p3d_TextureModulate;
uniform vec4 attr_colorscale;

in vec4 l_eye_position;
in vec4 l_texcoord;
in vec4 l_color;
in vec4 l_tangent;
in vec3 l_eyevec;
in vec4 l_binormal;

uniform struct{ 
    vec4 ambient;
    vec4 diffuse;
    vec4 emission;
    vec3 specular;
    float shininess;
} p3d_Material;

uniform struct p3d_LightSourceParameters{
    vec4 color;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    vec4 position;
    vec3 spotDirection;
    float spotExponent;
    float spotCutoff;
    float spotCosCutoff;
    float constantAttenuation;
    float linearAttenuation;
    float quadraticAttenuation;
    vec3 attenuation;
    sampler2DShadow shadowMap;
    mat4 shadowViewMatrix;
} p3d_LightSource[1];

out vec4 p3d_FragColor;

void main(){
    vec3 l_eye_normal = vec3(l_tangent.w, l_binormal.w, l_eye_position.w);
    vec4 tex0 = texture(p3d_TextureNormal, l_texcoord.xy);
    vec3 parallax_offset = l_eyevec.xyz * (tex0.aaa * 2.0 - 1.0) * 0.1;
    parallax_offset = l_eyevec.xyz * (parallax_offset + (tex0.aaa * 2.0 - 1.0)) * 0.05;
    vec4 texcoord1 = l_texcoord;
    texcoord1.xyz -= parallax_offset;
    vec4 tex1 = texture(p3d_TextureModulate, texcoord1.xy);
    l_eye_normal = normalize(l_eye_normal);
    vec3 tsnormal = normalize((tex0.xyz * 2) - 1);
    l_eye_normal *= tsnormal.z;
    l_eye_normal += normalize(l_tangent.xyz) * tsnormal.x;
    l_eye_normal += normalize(l_binormal.xyz) * tsnormal.y;
    l_eye_normal = normalize(l_eye_normal);
    vec4 tot_diffuse = vec4(0, 0, 0, 0);
    vec4 lcolor = p3d_LightSource[0].color;
    lcolor *= clamp(dot(l_eye_normal, -p3d_LightSource[0].spotDirection), 0.0, 1.0);
    tot_diffuse += lcolor;
    vec4 result = vec4(0, 0, 0, 0);
    result += tot_diffuse * l_color * p3d_Material.diffuse;
    result = clamp(result, 0.0, 1.0);
    result *= attr_colorscale;
    result.rgb *= tex1.rgb;
    p3d_FragColor = result;
}

To compare, switch to shader_auto.

Sourse: BumpTest.zip (680.5 KB)

2 Likes

Interestingly, I just noticed that the auto shader uses parallax reception. However, it looks strange. It’s much better without him.

//texcoord1.xyz -= parallax_offset;

nice, I will take a more detailed look at this later today, in the meantime I made a bit of progress
:removed to conserve bandwidth
it actually turns out I was wrong, GLSL has no barring on the floor as I managed to replicate it somewhat here, the method I used was bad and betrays the original code as I had go off path a bit to achieve this, but I wanted to post this to correct myself. as always the code to this can be found below, vertex.

# version 150 // vertex shader

uniform mat4 p3d_ModelViewMatrix;
uniform mat4 p3d_ModelMatrix;
uniform mat4 p3d_ViewMatrix;
uniform mat4 p3d_ModelViewProjectionMatrix;

in vec2 p3d_MultiTexCoord0;
in vec3 p3d_Normal;
in vec3 p3d_Binormal;
in vec3 p3d_Tangent;
in vec4 p3d_Vertex;

out vec2 vUv;
out vec4 vEye;
out vec4 vLight;
out mat3 tbnMatrix;

void main() {
    vUv = p3d_MultiTexCoord0;
    vEye = -normalize(p3d_ModelViewMatrix * p3d_Vertex);
    vec4 tan = normalize(p3d_ModelViewMatrix * vec4(p3d_Tangent, 0));
    vec4 bi = normalize(p3d_ModelViewMatrix * vec4(-p3d_Binormal, 0));
    vec3 nrm = mat3(transpose(inverse(p3d_ModelViewMatrix))) * p3d_Normal;
    tbnMatrix = mat3(normalize(tan.xyz), normalize(bi.xyz), normalize(nrm));
    vLight = vec4(mat3(p3d_ModelViewMatrix) * vec3(0, 0, 1), 1.0);

    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
}

and fragment

# version 150 // fragment shader

uniform sampler2D p3d_Texture0;
uniform sampler2D p3d_Texture1;

in vec2 vUv;
in vec4 vEye;
in vec4 vLight;
in mat3 tbnMatrix;

out vec4 p3d_FragColor;

void main (){
    // Directional Light (Global)
    vec4 color = vec4(0.3, 0.3, 0.3, 0.3);
    vec3 forward = vec3(0, 1, 0);
    vec4 scale = vec4(1.0, 1.0, 1.0, 1.0); // colorscale
    vec4 ambient = vec4(0.5, 0.5, 0.5, 0.5);
    vec4 diffuse = vec4(0.64, 0.64, 0.64, 1);
    float specular = 8.0; // negative causes a rim light effect.
    // Translate tangent-space normal in map to view-space.
    vec3 tsNrm = normalize((texture(p3d_Texture1, vUv).xyz * 2) - 1);
    vec3 eyeNrm = normalize(tbnMatrix * tsNrm);
    vec3 halfvec = normalize(vLight.xyz + vEye.xyz);
    vec4 gloss = color * pow(clamp(dot(eyeNrm, halfvec), 0.0, 1.0), specular);
    // Begin view-space light summation
    vec4 shadow = diffuse + (color * clamp(dot(eyeNrm, vLight.xyz), 0.0, 1.0));
    vec4 summation = clamp((ambient * 0.3) + (shadow * diffuse), 0.0, 1.0);
    summation.a = diffuse.w;
    vec4 result = (summation * scale).rbga * texture(p3d_Texture0, vUv).rgba;
    // End view-space light calculations
    vec3 texel = result.rgb + gloss.rgb;
    p3d_FragColor = vec4(texel, 1.0);
}
1 Like

@jnpickee Please note that in order for the lighting to work properly, you need to switch the coordinate system.

from panda3d.core import  loadPrcFileData
loadPrcFileData("", "gl-coordinate-system default")

Perhaps this difference is caused by this.

sorry for the delay, I did try key parts of your code and while it did give off a cool water flowing on the surface effect as opposed to light reflection, I am looking to replicate the original rather then create a new shader.

I could post the cool water effect shader later today if you want.

Interestingly, I just noticed that the auto shader uses parallax reception. However, it looks strange. It’s much better without him.
//texcoord1.xyz -= parallax_offset

one thing I forgot to mention that may provide some clarification to this is that the shader generator seems to some times add unused variables for things mentioned for creating the graphics in the control program.

like the shadow map in my generated shader since I had shadowing in one of my game prototypes at one time, I have small traces of it that are picked up by the generator. and it reflects it but with blank information

I don’t understand you. I made such a scene, mind you.

from panda3d.core import DirectionalLight, NodePath, Shader, Vec3, loadPrcFileData
loadPrcFileData("", "dump-generated-shaders 1")
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        render.set_shader_auto()

        self.point_light = DirectionalLight('point_light')
        self.light_path = NodePath(self.point_light)
        render.set_light(self.light_path)

        self.test = loader.load_model('model/test')
        self.test.reparent_to(render)

app = MyApp()
app.run()

Took a copy of the shader dump.

//Cg
/* Generated shader for render state:
  CullFaceAttrib:cull_clockwise
  LightAttrib:on
    point_light
  MaterialAttrib:Material Material s0 l0 t0
  RescaleNormalAttrib:none
  ShaderAttrib:auto
  TextureAttrib:on Normal:layingrock-n Diffuse:layingrock-c
*/
void vshader(
	 in float4 vtx_texcoord : ATTR8,
	 out float4 l_texcoord : TEXCOORD0,
	 in float4 vtx_tangent : ATTR9,
	 in float4 vtx_binormal : ATTR10,
	 out float4 l_tangent : TEXCOORD1,
	 out float4 l_binormal : TEXCOORD2,
	 in float4 vtx_color : ATTR3,
	 out float4 l_color : COLOR0,
	 uniform float4x4 trans_model_to_view,
	 out float4 l_eye_position : TEXCOORD3,
	 uniform float4x4 tpose_view_to_model,
	 in float3 vtx_normal : ATTR2,
	 uniform float4 mspos_view,
	 out float3 l_eyevec,
	 in float4 vtx_position : ATTR0,
	 out float4 l_position : POSITION,
	 uniform float4x4 mat_modelproj
) {
	 l_position = mul(mat_modelproj, vtx_position);
	 l_eye_position = mul(trans_model_to_view, vtx_position);
	 l_texcoord = vtx_texcoord;
	 l_color = vtx_color;
	 l_tangent.xyz = normalize(mul((float3x3)trans_model_to_view, vtx_tangent.xyz));
	 l_tangent.w = 0;
	 l_binormal.xyz = normalize(mul((float3x3)trans_model_to_view, -vtx_binormal.xyz));
	 l_binormal.w = 0;
	 float3 eyedir = mspos_view.xyz - vtx_position.xyz;
	 l_eyevec.x = dot(vtx_tangent.xyz, eyedir);
	 l_eyevec.y = dot(vtx_binormal.xyz, eyedir);
	 l_eyevec.z = dot(vtx_normal, eyedir);
	 l_eyevec = normalize(l_eyevec);
	 float3 eye_normal = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));
	 l_tangent.w = eye_normal.x;
	 l_binormal.w = eye_normal.y;
	 l_eye_position.w = eye_normal.z;
}

void fshader(
	 in float4 l_eye_position : TEXCOORD3,
	 in float4 l_texcoord : TEXCOORD0,
	 uniform sampler2D tex_0,
	 uniform sampler2D tex_1,
	 in float4 l_tangent : TEXCOORD1,
	 in float4 l_binormal : TEXCOORD2,
	 uniform float4x4 attr_light0,
	 float3 l_eyevec,
	 out float4 o_color : COLOR0,
	 in float4 l_color : COLOR0,
	 uniform float4 attr_ambient,
	 uniform float4 attr_colorscale
) {
	 float3 l_eye_normal = float3(l_tangent.w, l_binormal.w, l_eye_position.w);
	 float4 result;
	 float4 texcoord0 = l_texcoord;
	 float4 texcoord1 = l_texcoord;
	 // Fetch all textures.
	 float4 tex0 = tex2D(tex_0, texcoord0.xy);
	 float3 parallax_offset = l_eyevec.xyz * (tex0.aaa * 2.0 - 1.0) * 0.1;
	 parallax_offset = l_eyevec.xyz * (parallax_offset + (tex0.aaa * 2.0 - 1.0)) * 0.05;
	 parallax_offset = l_eyevec.xyz * (parallax_offset + (tex0.aaa * 2.0 - 1.0)) * 0.05;
	 texcoord1.xyz -= parallax_offset;
	 float4 tex1 = tex2D(tex_1, texcoord1.xy);
	 // Correct the surface normal for interpolation effects
	 l_eye_normal = normalize(l_eye_normal);
	 // Translate tangent-space normal in map to view-space.
	 float3 tsnormal = normalize((tex0.xyz * 2) - 1);
	 l_eye_normal *= tsnormal.z;
	 l_eye_normal += normalize(l_tangent.xyz) * tsnormal.x;
	 l_eye_normal += normalize(l_binormal.xyz) * tsnormal.y;
	 l_eye_normal = normalize(l_eye_normal);
	 // Begin view-space light calculations
	 float ldist,lattenv,langle,lshad;
	 float4 lcolor,lspec,lpoint,latten,ldir,leye;
	 float3 lvec,lhalf;
	 float4 tot_diffuse = float4(0,0,0,0);
	 tot_diffuse += attr_ambient;
	 // Directional Light 0
	 lcolor = attr_light0[0];
	 lspec  = lcolor;
	 lvec   = attr_light0[3].xyz;
	 lcolor *= saturate(dot(l_eye_normal, lvec.xyz));
	 tot_diffuse += lcolor;
	 // Begin view-space light summation
	 result = float4(0,0,0,0);
	 result += tot_diffuse * l_color;
	 result = saturate(result);
	 // End view-space light calculations
	 result *= attr_colorscale;
	 result.rgb *= tex1.rgb;
	 o_color = result * 1.000001;
}

And I translated it to glsl, now you claim that I wrote a new shader??? Can I get an explanation of what I added in your opinion?

my apologies, what I meant was I toke parts of your code that I thought would work out for my situation and implemented them into my shader and it gave a untended effect, I had thought you were giving me a example which I can use as a syntax guide, but it seems like you were giving me a whole new shader to use, and I am thankful for that.

but it seems from the photos you provided that the shader has a much different shading effect then the one I need, once again my apologies for the mix up and confusion.

Edit: I did end up downloading your bump test zip and found the shaders there, I tried it and got a gray screen
:removed to conserve bandwidth
I thought it was maybe a issue with the program, so I ran the shader though my game and the world became invisible.
:removed to conserve bandwidth: