ambiera logo

Ambiera Forum

Discussions, Help and Support.

folder icon Ambiera Forum > CopperCube > Announcements and Showcase
forum topic indicator Normal mapping without shader
person icon
Monks
Guest
Quote
2025-11-21 14:44:16

Great!!!

person icon
guest_Sam
Guest
Quote
2025-11-22 13:17:22

Any specular Robbo? , I just finished a shader and had 16 lights going, Until I figured that was i guess 4 passes? Ive been assuming its shader 2.0b ( since some non shader 2.0 stuff works, but some shader 3 stuff doesn't ( i had to manually unroll a loop) so not shader 3 I dont think. I cut back to 10 lights, 11 point + directional. I can still get 67 fps on a intel on board laptop. It let's you keep lightmaps if you want. Ive been trying to get access to lightviewproj. Which seems be there but only if real-time shadows are enabled so then I think cc uses some different vertex shaders? Because it seems to override mine. Ive been messing with a bunch. Also I went with non tangent space as well. And they seem right. Depending if its -y or +y ( but thats the normal map itself.
I think i can get projectors working, I can get it to project. But the uvs are wrong , im just looking up math so it might be far different from coppercubes co,ords. Just in case did it with his flash light in the last version of the point light shader so I know it can be done. I can use specular maps aswell. I also did some faked direction bent normal mapping , so that lightmaps update the normal maps, but it gets seams . I can do real bent directional normals but I dont have anything to create the lightmaps with direction stored aswell. Probably can do it in blender for smaller meshes. But a single lightmap won't work too well for a level mesh or terrain.
And I also got Parallax occlusion map shader to work.
(Maybe my maps were wrong) but even with 32 checks per pixel it seemed kinda fuzzy . I was making the maps as a normal map with a height map as the alpha channel. You can also store the specular maps in a alpha channel of the normal map saving a texture slot.

Sorry for the novel. Lol

But I've pretty excited that stuff actually works. Lol

But im gonna give this a try as it would be easier to use overall.

Thanks for the hard work.

Sam..

person icon
guest_Des
Guest
Quote
2025-11-22 18:36:08

Good job Robbo

umm, please is this Sammhnndy(to the guy who just posted)emoji icon_smileemoji icon_smile

person icon
guest_Des
Guest
Quote
2025-11-23 12:14:44

Oh I see, are you on the CopperCube discord server?emoji icon_smile

person icon
guest_Robbo
Guest
Quote
2025-11-25 11:54:36

Sound very impressive "guest_Sam" what you have going at the moment. I would like to see it myself and test it out if your interested..? did you want to post it on github or something ?

I dont have any specular lighting working as yet, no, not with fixed function pipeline - just standard specular which doesnt use specular maps...I was next going to see if I can add this actually....who knows...

I recently finished adding the bump mapping with the default terrain system and it works pretty good. Slight adjustment may be needed later where 2 textures blend together but its working.

I noticed very weird issue that when using 3d mesh along with the terrain system you have to reverse the direction of the light for those 3d mesh but leave unchanged for the terrain...else the 3d mesh will be too dark...

will do another update soon as some people complaining my videos and the attached files cant be understood.....very strange...

person icon
guest_Des
Guest
Quote
2025-11-26 16:15:04

that's nice that youve had it working, looking forward to your next video

person icon
guest_Robbo
Guest
Quote
2025-11-27 01:04:13

Just a quick update on terrain bump mapping now works also. (slight issues with the 2 texture blend sections but hard to see)

Just use the same API:
ccbSetBumpMap(node, mat index, dirX, dirY, dirZ, minLight (0-255)

Take note above about when using a terrain along with 3d mesh you have to reverse the direction of the directional light only for the 3d mesh to work correctly else leave as is.

I will do an update video on all additions since inception into one new video for the the uninitiated...

person icon
guest_Sam
Guest
Quote
2025-11-27 02:30:25

Sure thing Robbo

Ill clean up and post the lighting shader here later if someone wants to play around with it, hack it up whatever ya want. Ill post the 8 or 10 light. But its easy to add more lights or take them away as each have its own variables, just copy it and rename them to pointlight9 for example. ( haven't gotten it to use cc culling yet)

Not the best way to do it, but easiest ( i did it that way at first because I was having trouble getting coppercube light data ( color ext) I have since figured out it wasn't rgb, but xyz instead. Lol so at first I was setting the light data for color and range in the shader. But it picks it up from copper cube now. This one still has light maps in the second texture channel. Normal maps in the third. And should be specular in the alpha channel of the normal map ( i haven't actually tested this. But it should be calling nmap.a for the specular maps. Otherwise it just does spec without occlusion.

If not using lightmaps , I use a 64,64,64 color single pixel texture in that slot. I need to add a check and if they aren't there it will not multiply that second channel. So currently if there is no color there it is just dark and only spec kinda visible. ( so kinda is the ambient at the moment)

I got most my math from some old dx 9 shaders I found online, im pretty new to hlsl. So im surprised this even works.

We probably should get a new sub forum for community shaders. So we can build up a library.


Ill post it later.

Sam.

person icon
guest_Sam
Guest
Quote
2025-11-27 04:55:47

Alright cleaned it (still ,messy ,but should be readable)

Im using it in " Before drawing do something )

or When key pressed.

add the nodes to affect at the bottom

// Vertex shader
var VS =
"float4x4 mWorldViewProj;\n" +
"float4x4 mWorld;\n" +
"float4 CamPos;\n" +
"\n" +
"struct VS_OUTPUT {\n" +
" float4 Position : POSITION;\n" +
" float2 uv0 : TEXCOORD0;\n" +
" float2 uv1 : TEXCOORD1;\n" +
" float3 Nworld : TEXCOORD2;\n" +
" float4 WorldPos : TEXCOORD3;\n" +
"};\n" +
"\n" +
"VS_OUTPUT main(float4 pos : POSITION,\n" +
" float3 normal : NORMAL,\n" +
" float2 uv0 : TEXCOORD0,\n" +
" float2 uv1 : TEXCOORD1)\n" +
"{\n" +
" VS_OUTPUT o;\n" +
" o.Position = mul(pos, mWorldViewProj);\n" +
" o.WorldPos = mul(pos, mWorld);\n" +
" o.Nworld = normalize(mul(float4(normal,0.0), mWorld).xyz);\n" +
"\n" +
" o.uv0 = uv0;\n" +
" o.uv1 = uv1; // <-- Lightmap UVs\n" +
"\n" +
" return o;\n" +
"}";

person icon
guest_Sam
Guest
Quote
2025-11-27 04:56:53

// Fragment shader/
var FS =
"struct PS_OUTPUT { float4 Color : COLOR0; };\n" +
"\n" +
"sampler2D tex0; // Diffuse (UV0)\n" +
"sampler2D tex1; // Lightmap (UV1)\n" +
"sampler2D tex2; // Normal map + spec (UV0)\n" +
"\n" +

// Ambient color----
"float3 AmbientColor;\n" +
"float AmbBlend;\n" +
"\n" +

// Sky color------
"float3 SkyColor;\n" +
"float SkyStrength;\n" +
"\n" +

// Spec and intensity----
"float4 SpecColor;\n" +
"float Shininess;\n" +

// Camera position Var---
"float4 CamPos;\n" +
"\n" +

// Point Lights--------
"float4 Light1Pos;\n" +
"float4 Light2Pos;\n" +
"float4 Light3Pos;\n" +
"float4 Light4Pos;\n" +
"float4 Light5Pos;\n" +
"float4 Light6Pos;\n" +
"float4 Light7Pos;\n" +
"float4 Light8Pos;\n" +

"float3 Light1Color;\n" +
"float3 Light2Color;\n" +
"float3 Light3Color;\n" +
"float3 Light4Color;\n" +
"float3 Light5Color;\n" +
"float3 Light6Color;\n" +
"float3 Light7Color;\n" +
"float3 Light8Color;\n" +

"\n" +
// Directional Light--------
"float3 DirLightDir;\n" +
"float3 DirLightColor;\n" +
"\n" +


// main -------
"PS_OUTPUT main(\n" +
" float2 uv0 : TEXCOORD0,\n" +
" float2 uv1 : TEXCOORD1,\n" +
" float3 Nw : TEXCOORD2,\n" +
" float4 WorldPos : TEXCOORD3)\n" +
"{\n" +
" PS_OUTPUT o;\n" +
" float3 worldPos = WorldPos.xyz;\n" +
" float3 V = normalize(CamPos.xyz - worldPos);\n" +
"\n" +
" float3 albedo = tex2D(tex0, uv0).rgb;\n" +
" float3 lm = tex2D(tex1, uv1).rgb; // <-- Uses LM UV1\n" +
"\n" +
" float3 baseColor = albedo * (1.0 * lm*2);\n" +
"\n" +
" float4 ns = tex2D(tex2, uv0);\n" +
" float3 nTS = ns.rgb * 2.0 - 1.0;\n" +
" float specIntensity = ns.a;\n" +
"\n" +
// This assumes no tangents / --------- up is different pn openGL and DX style normal maps. Might have to flip it.

" float3 up = abs(Nw.y) < 0.999 ? float3(0,1,0) : float3(1,0,0);\n" +
" float3 T = normalize(cross(up, Nw));\n" +
" float3 B = normalize(cross(Nw, T));\n" +
" float3 N = normalize(T*nTS.x + B*nTS.y + Nw*nTS.z);\n" +
"\n" +
// Im not sure this is doing anything, lol --
" float3 ambient = lerp(AmbientColor.r, AmbientColor.g,AmbientColor.g)*AmbBlend;\n" +
" float3 color = baseColor * ambient;\n" +
"\n" +
//-------------------------------------------

" float3 L; float dist; float att; float ndl; float3 H;\n" +
"\n" +
// Calculate the pointLights-------
// LIGHT 1
" L = Light1Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light1Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light1Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light1Color * att;\n" +
"\n" +
// LIGHT 2
" L = Light2Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light2Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light2Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light2Color * att;\n" +
"\n" +
// LIGHT 3
" L = Light3Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light3Pos.w);\n" +
" ndl = saturate

person icon
guest_Sam
Guest
Quote
2025-11-27 04:58:23

(dot(N, L));\n" +
" color += baseColor * Light2Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light2Color * att;\n" +
"\n" +
// LIGHT 3
" L = Light3Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light3Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light3Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light3Color * att;\n" +
"\n" +
// LIGHT 4
" L = Light4Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light4Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light4Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light4Color * att;\n" +
"\n" +
// LIGHT 5
" L = Light5Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light5Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light5Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light5Color * att;\n" +
"\n" +
// LIGHT 6
" L = Light6Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light6Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light6Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light6Color * att;\n" +
"\n" +
// LIGHT 7
" L = Light7Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light7Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light7Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light7Color * att;\n" +
"\n" +
// LIGHT 8
" L = Light8Pos.xyz - worldPos; dist = length(L); L /= dist;\n" +
" att = saturate(1.0 - dist / Light8Pos.w);\n" +
" ndl = saturate(dot(N, L));\n" +
" color += baseColor * Light8Color * ndl * att;\n" +
" H = normalize(L + V);\n" +
" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * Light8Color * att;\n" +
"\n" +


// DIRECTIONAL LIGHT----------------------
" float3 Ld = normalize(DirLightDir);\n" +
" float ndld = saturate(dot(N, Ld));\n" +
" color += baseColor * DirLightColor * ndld;\n" +
" H = normalize(Ld + V);\n" +

" color += pow(saturate(dot(N,H)), Shininess * specIntensity) * SpecColor.rgb * DirLightColor * att;\n" +
"\n" +
// SKY
" float sky = saturate(N.y * 0.5 + 0.5);\n" +
" color += SkyColor * sky * SkyStrength;\n" +
"\n" +
" o.Color = float4(color,1);\n" +
" return o;\n" +
"}";

person icon
guest_Sam
Guest
Quote
2025-11-27 04:59:30

myShaderCallback = function()
{
var cam = ccbGetActiveCamera();
var CamPos = ccbGetSceneNodeProperty(cam, "Position");
var cx = CamPos.x ;
var cy = CamPos.y ;
var cz = CamPos.z ;
ccbSetShaderConstant(2, "CamPos", cx, cy,cz, 0);

// === POINT LIGHTS ===
// Mul will multiply the brightness. 4 seems pretty close to CC brightness level, since they were either multi X2 or X4 since cc5 i think, whichever they are brighter than CC4 now.
function setPointLight(name, constName, colorConst,Mul)
{
var L = ccbGetSceneNodeFromName(name);
if (!L) return;
var lpos = ccbGetSceneNodeProperty(L, "Position");
var px = lpos.x ;
var py = lpos.y ;
var pz = lpos.z ;
var r = ccbGetSceneNodeProperty(L, "Radius"); // used for attenuation

ccbSetShaderConstant(2, constName, px, py, pz, r);
var LC = ccbGetSceneNodeProperty(L, "Color");
var rC = LC.x;
var gC =LC.y;
var bC = LC.z;
ccbSetShaderConstant(2, colorConst, rC*Mul, gC*Mul, bC*Mul, 0);
}

// set the pointlight, Position,color,Radius -------------
setPointLight("Light1", "Light1Pos", "Light1Color",4);
setPointLight("Light2", "Light2Pos", "Light2Color",4);
setPointLight("Light3", "Light3Pos", "Light3Color",4);
setPointLight("Light4", "Light4Pos", "Light4Color",4);
setPointLight("Light5", "Light5Pos", "Light5Color",4);
setPointLight("Light6", "Light6Pos", "Light6Color",4);
setPointLight("Light7", "Light7Pos", "Light7Color",4);
setPointLight("Light8", "Light8Pos", "Light8Color",4);

// === DIRECTIONAL LIGHT ===
var DL = ccbGetSceneNodeFromName("DirectionalLight");
if (DL) {
var dpos = ccbGetSceneNodeProperty(DL, "Position");
var x = dpos.x ;
var y = dpos.y ;
var z = dpos.z;

var Ldir =ccbGetSceneNodeProperty(DL, 'Direction');
var lx = Ldir.x;
var ly = Ldir.y;
var lz = Ldir.z;

var dx = lx +x;
var dy = ly + y;
var dz = lz +z;

ccbSetShaderConstant(2, "DirLightDir", dx, dy, dz, 0);
// Probably should multiply this as well to be accurate//
var LC = ccbGetSceneNodeProperty(DL, "Color");
var rC = LC.x;
var gC =LC.y;
var bC = LC.z;
ccbSetShaderConstant(2, "DirLightColor", rC, gC,bC, 0);
}

// Light Var's---
ccbSetShaderConstant(2, "AmbientColor", 0.6,0.6,0.6,0);

ccbSetShaderConstant(2, "AmbBlend", 0.4,0,4,0.4);

ccbSetShaderConstant(2, "SkyColor", 0.4,0.4,0.2,0);
ccbSetShaderConstant(2, "SkyStrength", 0.1,0,0,0);

ccbSetShaderConstant(2, "SpecColor", 0.2,0.2,0.1,0);
ccbSetShaderConstant(2, "Shininess", 10.5,0,0,0);
};

var mat = ccbCreateMaterial(VS, FS, 0, myShaderCallback);

// Put your Mesh's here

var node = ccbGetSceneNodeFromName("cubeMesh1");
var n = ccbGetSceneNodeMaterialCount(node);
for (var i=0; i<n; ++i)
{
ccbSetSceneNodeMaterialProperty(node, i, "Type", mat);
}

person icon
guest_Sam
Guest
Quote
2025-11-27 05:17:21

hopefully you can put that back together as it took 3 posts , or i can email it to you.


Robbo , if you can add the D3D dot product Color
D3DTOP_DOTPRODUCT3 which i think is 24

22 and 23 should be
D3DTOP_BUMPENVMAP and
D3DTOP_BUMPENVMAPLUMINANCE

which with RTT should give good bumped reflective surfaces like stained glass , dirty mirror, water (like CC current water) ect.

if you can add that blending stage. Ive only ever done it back in DX 7 , but looks like it still exist in DX9 for compatibility.


im working on cube map shader that can do all that. but would be better without a shader having to be called.


Sam

person icon
guest_Robbo
Guest
Quote
2025-11-27 06:03:33

Interesting Sam - so you created your own Action/Behavior HLSL shader to do your own lighting with 8 lights plus directional.

Just interested to see how you went about it...I thought you might have been updating the source code for that so was wondering about that..

Yes, maybe someday I might update the source code for DX9 shader code so that it has more lights than 4 and ignores shadows (bad performance anyway). For now the standard non shader approachs seems to working good enough...and yes, I notice that there are the other two FFP functions that might be enabled like you mentioned:
D3DTOP_BUMPENVMAP
D3DTOP_BUMPENVMAPLUMINANCE

maybe the luminance one can be used for specular highlights....not sure as yet...

nice work, cheers!

person icon
guest_Robbo
Guest
Quote
2025-11-28 01:53:41

The D3DTOP_BUMPENVMAPLUMINANCE fixed function pipeline can adjust specularity per pixel but its based on old technology and special texture formats and types not done much anymore.
It would take some time just to create the textures not to mention the new material to use those textures. Its different to a standard normal map texture format so wont work with that.

It also uses a 2nd cubemap texture so its quite involved to get all that working and so Im not going to worry about that. The Normal mapping (bumpmap) material I made does work though so thats an improvement.


Create reply:










 

  

Possible Codes


Feature Code
Link [url] www.example.com [/url]
Bold [b]bold text[/b]
Image [img]http://www.example.com/image.jpg[/img]
Quote [quote]quoted text[/quote]
Code [code]source code[/code]

Emoticons


icon_holyicon_cryicon_devilicon_lookicon_grinicon_kissicon_monkeyicon_hmpf
icon_sadicon_happyicon_smileicon_uhicon_blink   






Copyright© Ambiera e.U. all rights reserved.
Contact | Imprint | Products | Privacy Policy | Terms and Conditions |