Specular Shader

Posted By: Dooley

Specular Shader - 05/22/19 16:17

The specular shader I am using uses the alpha channel of the main diffuse texture for the specular map. I believe this is the default "mtl_specBump" that comes with game studio. I am using A7.

I'm wondering if there is another specular/bump material shader that might use, for instance, the alpha channel of the normal map, or maybe a separate skin for the specular map. That way, in theory, a transparent texture, like for grass or leaves, could also have a specular component.

Is that just the way the shaders were written, or is that some kind of limitation of the engine itself?
Posted By: txesmi

Re: Specular Shader - 05/23/19 15:22

That is just the way the shaders were written.
Posted By: Dooley

Re: Specular Shader - 05/23/19 17:36

Interesting! So in theory, a new shader could be written to allow specular mapping and transparency.
Posted By: txesmi

Re: Specular Shader - 05/23/19 17:41

Yes. Post your shader code and I will try to explain how to modify it.
Posted By: Dooley

Re: Specular Shader - 05/23/19 20:01

It is the standard specBump.fx that comes with A7

Code:
// Blinn / Phong bump mapping
// (c) oP group 2009  Version 2.2

#include <bump_vs>
#include <phong>

bool REQUIRE_NORMAL;

texture entSkin1;	// texture
texture entSkin2;	// normal map or lightmap
texture entSkin3;	// normal map on blocks

sampler sBaseTex = sampler_state { Texture = <entSkin1>; MipFilter = Linear;	};
sampler sSkin2 = sampler_state { Texture = <entSkin2>; MipFilter = None;	};
sampler sSkin3 = sampler_state { Texture = <entSkin3>; MipFilter = None;	};

float3 DoSpecular(bumpOut In,float3 Normal,float fSpecular)
{
#ifdef BLINN
	float3 viewDir = normalize(In.PosView);	
			
	float fLight = DoShine(In.Light1.xyz,Normal);
	float fHalfway = DoShine(In.Light1.xyz+viewDir,Normal);
	float3 Diffuse = DoPhong(In.Diffuse1,fLight,fHalfway,fSpecular);

	fLight = DoShine(In.Light2.xyz,Normal);
	fHalfway = DoShine(In.Light2.xyz+viewDir,Normal);
	Diffuse += DoPhong(In.Diffuse2,fLight,fHalfway,fSpecular);

	fLight = DoShine(In.Light3.xyz,Normal);
	fHalfway = DoShine(In.Light3.xyz+viewDir,Normal);
	Diffuse += DoPhong(In.Diffuse3,fLight,fHalfway,fSpecular);
#else // PHONG			
	float fLight = DoShine(In.Light1.xyz,Normal);
	float3 Diffuse = DoPhong(In.Diffuse1,fLight,fLight,fSpecular);		

	fLight = DoShine(In.Light2.xyz,Normal);
	Diffuse += DoPhong(In.Diffuse2,fLight,fLight,fSpecular);		

	fLight = DoShine(In.Light3.xyz,Normal);
	Diffuse += DoPhong(In.Diffuse3,fLight,fLight,fSpecular);
#endif

	return Diffuse;
}

float4 specBump_PS(bumpOut In): COLOR
{
	float4 Base = tex2D(sBaseTex,In.Tex12.xy);
	float3 Normalmap = tex2D(sSkin2,In.Tex12.xy)*2-1;
   float3 Diffuse = DoSpecular(In,Normalmap,Base.w);	
	return Base * DoColor(Diffuse,In.Ambient);
}

float4 specBumpLM_PS(bumpOut In): COLOR
{
	float4 Base = tex2D(sBaseTex,In.Tex12.xy);
	float4 Lightmap = tex2D(sSkin2,In.Tex12.zw);
	float3 Normalmap = tex2D(sSkin3,In.Tex12.xy)*2-1;
   float3 Diffuse = DoSpecular(In,Normalmap,Base.w);	
	return Base * DoLightmap(Diffuse,Lightmap,In.Ambient);
}


technique spec
{
	pass one
	{		
      ZWriteEnable = True;
      AlphaBlendEnable = False;

		VertexShader = compile vs_2_0 bump_VS();
		PixelShader = compile ps_2_0 specBump_PS();
	}
}

technique spec_lm
{
	pass one
	{		
      ZWriteEnable = True;
      AlphaBlendEnable = False;

		VertexShader = compile vs_2_0 bump_VS();
		PixelShader = compile ps_2_0 specBumpLM_PS();
	}
}

technique fallback { pass one { } }

Posted By: txesmi

Re: Specular Shader - 05/24/19 12:58

Ok. I would start by setting up a new technique to draw alpha channeled entities. Copy the 'spec' techinque, rename it, change 'AlphaBlendEnable' state to 'True' and set a new function for the pixel shader.

Code:
technique spec_trans // a new name for the new shader 
{
	pass one
	{		
		ZWriteEnable = True;
		AlphaBlendEnable = True; // Enable alpha blending

		VertexShader = compile vs_2_0 bump_VS();
		PixelShader = compile ps_2_0 specBumpTrans_PS(); // A new pixel shader function
	}
}



I copied the 'spec' technique, renamed it, changed 'AlphaBlendEnable' state to 'True' and set a new function for pixel shading.

'AlphaBlendEnable' tells to the shader compiler how to threat the returned color of the pixel shader, it merges the computed color with the target pixel color when is set to true. This little change makes the shader far slower because it has to retrieve the render targets pixel color and merge it with the return of the pixel shader, so be sure of assigning this new technique to actual alpha channeled entities only. Rendering solid entities with activated alpha blending is a big waste of resources that can ruin the whole rendering. This new technique has to be especified inside a new MATERIAL* struct.

Code:
MATERIAL *mtlSpecBumpTrans = {
   effect = "specBump.fx"; // the shader file
   technique = "spec_trans"; // the new technique
   flags = TRANSLUCENT; // not neccesary but you can ensure the entity is rendered by the translucent pass
}



The only thing left is to write the new pixel shader specified inside the new technique.

Code:
float4 specBumpTrans_PS(bumpOut In): COLOR
{
	float4 Base = tex2D(sBaseTex,In.Tex12.xy);
	float4 Normalmap = tex2D(sSkin2,In.Tex12.xy);
	Normalmap.xyz = Normalmap.xyz*2-1;
	float3 Diffuse = DoSpecular(In,Normalmap.xyz,Normalmap.w);	
	Base.xyz *= DoColor(Diffuse,In.Ambient);
	return Base;
}



I copied the 'specBump_PS' function and renamed it. I converted the 'NormalMap' vector to a 4 members vector (float4) so it also holds the alpha channels value. Since the specular value saved into the normal maps alpha channel is not compressed, I needed to uncompress the other three channels in a separate line of code while the alpha channel remains unchanged.

Code:
Normalmap.xyz = Normalmap.xyz*2-1;



The next code line computes the specular term. 'DoSpecular' function spects a three member vector as second parameter, so it needs the channels of 'NormalMap' (previously transformed to a 4 members vector) be specified. The third parameter of 'DoSpecular' is the specular factor which I modified to be the alpha channel of the 'NormalMap' vector.

Code:
float3 Diffuse = DoSpecular(In,Normalmap.xyz,Normalmap.w);



If you want to use a different bitmap to hold the specular term, you will only need to set up a new 'texture' and its 'sampler_state', retrieve its value in a new code line, same as the other two textures, and use it inside 'DoSpecular' parameters.

And that's all.
Salud!
Posted By: Dooley

Re: Specular Shader - 05/24/19 14:12

Oh wow! I will try to implement this in the next couple days. Thank you so much laugh

I will report back here with results.
Posted By: DexLoomer

Re: Specular Shader - 05/25/19 09:34

Hey guys,
I've been sitting on a project for some time trying to use shaders. I urgently need objects with ColorMap, NormalMap and SpecularMap like 'Dooley'.

Since the standard shaders of mtlFX.c of 3DGS do not fulfill this to my knowledge, I have experimented with shade-c 0.91 and Shadec EVO.
With Shade-c I have big problems with shadows. With Shadec EVO, I get error messages such as "ìnvalid name: sc_lights_shadowmapBlur.fx" while loading the scene.

Therefore, I would also find it great if there is a solution to modify the standard shader of the mtlFX.c of 3DGS so that they represent everything necessary.

So I tried to follow the instructions of 'txesmi':
1. I inserted the part of the code with "technique spec_trans" and with "float4 specBumpTrans_PS" into the code of the file "specBump.fx".
2. I inserted the code with "MATERIAL * mtlSpecBumpTrans" in the "mtlFX.c" file.

When I start the scene but I get error messages:
"Malfunction W1550 Cant't compile effect: specBump.fx(20,30): errorX3018: invalid subscript'postView' .... "


Have I misunderstood some of the instructions from 'txesmi' or is there any other trick I overlooked?
Can someone tell me how I can make this whole to work?
Posted By: txesmi

Re: Specular Shader - 05/25/19 12:57

@DexLoomer
I has been a decade from last time I used the engines default shaders and I needed to test it. I had no error report when set the new technique. Anyway, there is nothing called 'postView' into 'specBump.fx'. I guess it has to come from anywhere else.

Moreover, it seems 'DoSpecular' does not compute the specular reflection. It looks flat for me. I don't know what happens.

Also, there is another state I missed to include into the pass states inside the technique description:

Code:
AlphaTestEnable = True;



This state makes the shader avoid witting into depth stencil map on transparent pixels.

Here goes a full diffuse+specular shader out of the 3dgs default shaders

Code:
float3x3 matTangent;

float4x4 matWorldViewProj;
float4x4 matWorld;
float4 vecViewDir;
float4 vecLight;

int iLights;
float4 vecLightPos[8];
float4 vecLightColor[8];

texture entSkin1;
sampler TexSampler = sampler_state { Texture = <entSkin1>; Mipfilter = Linear; Minfilter = Linear; Magfilter = Linear; };
texture entSkin2;
sampler TNSampler = sampler_state { Texture = <entSkin2>; Mipfilter = Linear; Minfilter = Linear; Magfilter = Linear; };

void VS (
	in float4 inPos: POSITION,
	in float3 inNormal: NORMAL,
	in float2 inTex: TEXCOORD0,
	in float3 inTangent: TEXCOORD2,
	out float4 outPos: POSITION,
	out float3 outNormal: TEXCOORD0,
	out float3 outWorld: TEXCOORD1,
	out float2 outTex: TEXCOORD2,
	out float3 outTangent: TEXCOORD3) {
		outPos = mul(inPos, matWorldViewProj);
		outNormal = mul(inNormal, (float3x3)matWorld);
		outWorld = mul(inPos, matWorld).xyz;
		outTex.xy = inTex.xy;
		outTangent = mul( inTangent.xyz, (float3x3)matWorld );
	}
	
float4 PS (
	in float3 inNormal: TEXCOORD0,
	in float3 inWorld: TEXCOORD1,
	in float2 inTex: TEXCOORD2,
	in float3 inTangent: TEXCOORD3) : COLOR0 {
		float4 Color = tex2D(TexSampler, inTex);
		float4 TNormalTex = tex2D(TNSampler, inTex);
		float3 bumpNormal = (TNormalTex.xyz * 2.0f) - 1.0f;
		inTangent = normalize(inTangent);
		inNormal = normalize(inNormal);
		float3 binormal = cross(inNormal, inTangent);
		float3 worldNormal = bumpNormal.x * inTangent + bumpNormal.y * binormal + bumpNormal.z * inNormal;
		
		float3 fDiffuse = vecLight.rgb;
		float3 fSpecular = 0;
		for(float i=0; i<iLights; i+=1) {
			float3 fDir = inWorld.xyz - vecLightPos[i].xyz;
			float3 fReflect = normalize((2.0f * dot(worldNormal, fDir) * worldNormal) - fDir);
			float fRadiance = saturate((vecLightPos[i].w - length(fDir)) / vecLightPos[i].w);
		   fSpecular += vecLightColor[i].rgb * pow(saturate(dot(fReflect, vecViewDir.xyz)), 8.0f) * TNormalTex.a;
			fDiffuse += vecLightColor[i].rgb * saturate(dot(normalize(-fDir), worldNormal.xyz)) * fRadiance;
		}
		
		float4 FinalColor;
		FinalColor.rgb = Color.rgb * fDiffuse;
		FinalColor.rgb += fSpecular;
		FinalColor.a = Color.a;
		
		return FinalColor;
	}

technique SpecTrans
{
	pass p0
	{
		ZWriteEnable = True;
		AlphaBlendEnable = True;
		AlphaTestEnable = True;
		
		VertexShader = compile vs_3_0 VS();
		PixelShader  = compile ps_3_0 PS();
	}
}



It computes the lights effect pixel side instead of vertex side as the defult 3dgs shader does. It looks much better but it is also much slower.

Salud!
Posted By: DexLoomer

Re: Specular Shader - 05/25/19 13:55

Hi,'txesmi' and thanks for the quick reply! I tried to install the code.
Unfortunately I have no idea about shader programming. I'm 3d graphic artist with little programming knowledge. wink

That's why I'm reaching my limits. In between I kept looking for a 'color_map + normal_map + specular_map ObjektShader' for 3DGS, but apart from shade-c and shadeC-EVO, I did not find anything. These did not go with me.

I am also afraid that with your tips my proficiency in programming will not be enough to modify the standard 3dgs shader. I do not know which files have to be changed at what point.
Posted By: txesmi

Re: Specular Shader - 05/25/19 18:19

Here goes my testbench. I hope it helps.
Posted By: Dooley

Re: Specular Shader - 05/25/19 20:03

That's awesome. It runs perfectly. I will have to see how much it slows down my game, since I have a lot of plants that would use it, but I will definitely add it, maybe make it an option for people with faster computers if it makes a big difference in framerate.
Posted By: DexLoomer

Re: Specular Shader - 05/26/19 12:27

Hello, first of all many thanks for the support!

The 'specTrans' Shader also looks great, as you can see on the picture:



But what is the ´specBumpTrans´ shader for? This does not seem to work (only color_Map + Tranparenz_Map).
Or am I doing something wrong? I commented it out in the main.c and assigned it to the cube in the WAD:



In addition, I came across yet another problem. The object with the 'specTrans' Sahder takes on no shadow.





The code is only extended by the shadow function:

Code:
///////////////////////////////
#include <acknex.h>
#include <default.c>
//#include <mtlFX.c>
#include <shadows.c>
///////////////////////////////
var shadow_flag = 1; 	// Einfacher Schatten



MATERIAL *mtlSpecTrans = {
   effect = "SpecTrans.fx";
}

MATERIAL *mtlSpecBumpTrans = {
   effect = "specBump.fx";
   technique = "spec_trans";
}


// Startet Schatten bei dem der Schatten einer Entity
// auch auf sich selber geworfen werden kann.
function setShadow() 
{
	if (shadow_flag == 1) // Schatten: Stancil mit Eigenschatten	
	{	
		//		stencil_blur(0);
		pssm_run(0);
		shadow_stencil = 1;
		
		for(you = ent_next(NULL); you; you = ent_next(you)) 
		{
			reset(you, CAST);
			set(you, SHADOW);
			you.shadow = NULL;
		}
	}
	
	if (shadow_flag == 2)
	{
		// Dieser Schatten kann nur aktiviert werden, wenn die
		// Grafikkarte Shadermodel 3 oder höher unterstützt.
		if (d3d_shaderversion >= 3)
		{			
			// Deaktivieren des PSSM um dessen Parameter ändern zu können.
			pssm_run(0);
			//			stencil_blur(0);
			for(you = ent_next(NULL); you; you = ent_next(you)) {
				reset(you, CAST);
				set(you, SHADOW);
				you.shadow = NULL;
			}
			shadow_stencil = 8;	
			// Clip-Werte so nah wie möglich zusammenlegen.
			camera.clip_near = 30;
			camera.clip_far = 3000;
			// Fehlerquotienten setzen, dieser Wert wird durch ausprobieren
			// optimiert.
			pssm_fbias = 0.0005;
			pssm_run(3);		
		}
		else
		{
			printf("Ihre Grafikkarte unterstützt Shader Model 3 nicht!");
		}		
	}	
}







void main () {
	video_mode = 10;
	wait(3);
	sun_light = 0;
	level_load("spec.wmb");
	
	setShadow();
	
	def_move();	
	
	while(!key_esc) {
		
		wait(1);
	}
	
	sys_exit(NULL);
}

Posted By: txesmi

Re: Specular Shader - 05/26/19 15:33

Originally Posted By: DexLoomer
But what is the ´specBumpTrans´ shader for? This does not seem to work (only color_Map + Tranparenz_Map).

It's the engine shader modification I explained before. I left it there for Dooley. He is working with A7. If the engines specBump works for him, it should work same.

Originally Posted By: DexLoomer
In addition, I came across yet another problem. The object with the 'specTrans' Sahder takes on no shadow.

Entities drawn by the translucent pass do not cast nor receive stencil shadows. Stencil shadows are geometry based, translucent entities are discarded.

I added a technique for solid rendering and fog, the only thing left, I guess.
download
Posted By: DexLoomer

Re: Specular Shader - 05/26/19 16:27

Hey, txesmi

So far, everything looks great! And you were right about the problem with the shadows. These are now working.

I have one more question: If I do not use fog, or this with ´camera-> fog_start = 0;´ disable, the boxes continue to have a foggy surface.



Is it possible to turn this on or off as well?
Posted By: txesmi

Re: Specular Shader - 05/26/19 19:34

Oh, it is true, I am sorry, forgot to multiply the fog term by 'vecFogColor.w' (68th code line of 'Spec.fx').

Code:
float fFog = saturate((camDist - vecFog.x) * vecFog.z) * vecFogColor.w;



Anyway, the fog is activated/deactivated by 'fog_color' variable in liteC.

Salud!
Posted By: DexLoomer

Re: Specular Shader - 05/26/19 19:55




Jap .. seems to go. Looks good! Thanks again. I will test it in the next few days and try to build in my project laugh

Posted By: Dooley

Re: Specular Shader - 05/26/19 20:08

@DexLoomer I am curious why you are using this shader instead of the standard mtl_specBump shader. On solid objects like boxes, it does not really serve its purpose.

So, the mtl_specBump does include a specular map, but it is in the alpha channel of the color map.

For me, since I was using the alpha channel to create transparent textures for plants and stuff, I could not use it for specular shading. This shader is specifically made to allow a transparent entity to also have a specular map.
Posted By: DexLoomer

Re: Specular Shader - 05/26/19 22:15

Hi Dooley, thanks for the hint, but I had some trouble with the mtl_specBump.

Also, I find the shader of 'txesmi' better in comparison.

Look ..on the left side ´mtl_specBump´ (with spec_map in the alpha channel of the color chart) and on the right side ´mtlSpecSolid´:

Posted By: Dooley

Re: Specular Shader - 05/26/19 23:25

@DexLoomer
That is strange. mtl_specBump works fine for me with solid objects. You may want to try that a bit more, since txesmi mentioned this would be a much slower way to render objects.

@txesmi The first version worked great, but for the second (specBump2) I can't run it with the "technique = "SpecTrans";" or "technique = "SpecSolid";" lines. It works fine if I comment out these lines, but my version of gamestudio does not recognize the "technique" command. At least not where you have placed them in the MATERIAL* definition.

When I comment out the lines, it does seem to work fine though, but I'm not sure if it's working as intended...
Posted By: txesmi

Re: Specular Shader - 05/27/19 14:46

@Dooley
Sorry, I didn't remember 'technique' is an A8 feature.

Here you go a version with each shader in a different file.

key_1 -> load 3dgs standard shaders + 'specBumpTrans'
key_2 -> load my shaders
Posted By: Dooley

Re: Specular Shader - 05/27/19 16:14

@txesmi You are a nice and helpful person. I did not expect you to actually write the shader I was imagining, but you did it anyway. I really do appreciate that.

Please let me know if I can return the favor some time.
Posted By: DexLoomer

Re: Specular Shader - 05/27/19 16:35

Hi txesmi, i can only join Dooley with my thanks. Maybe you need a return.
Posted By: txesmi

Re: Specular Shader - 05/27/19 19:56

You are welcome. Don't worry.
Posted By: DexLoomer

Re: Specular Shader - 06/12/19 19:47

Hi Guys,
In the last few days I have thought again about the comment of 'Dooley':

Quote
@DexLoomer I am curious why you are using this shader instead of the standard mtl_specBump shader. On solid objects like boxes, it does not really serve its purpose.

So, the mtl_specBump does include a specular map, but it is in the alpha channel of the color map.


I asked for a code from 'txesmi' for a shader combination of NomalMap and SpecularMap, because for me the 3DGS standard mtl_secBump shader does not show the SpecularMap.
To test this again, I created a file with normalMap and specularMap (..and put it online as a link) with the same result:

[Linked Image]

Link

NormalMap works, but no SpecularMap is visible!

Maybe someone can tell me why the SpecularMap is not displayed?
Posted By: Dooley

Re: Specular Shader - 06/14/19 06:14

I have checked it out. It actually is working, but maybe it's not noticeable with all those different colored lights.

[Linked Image]

Here I took out the dynamic lights, and the base tile (which was not compiling properly for me) so it is just the sun and the box.
You can see the shiny area on the edge of the box, but the triangular areas are not shiny. You can also see the word "test" as it appears in the alpha channel of the image.

So you do have it set up correctly. But I think either it can't handle the number of lights you are using, or maybe the specular material is set up differently in yours.

The mtl_specBump is in the mtlFX.c file, and mine looks like this:

Code
MATERIAL* mtl_specBump =
{
   effect = "specBump.fx";
   specular_blue = 255;
   specular_green = 255;
   specular_red = 255;
   power = 10;
   flags = PASS_SOLID;
}


I might have changed mine, but it should be similar to this anyway.


Posted By: DexLoomer

Re: Specular Shader - 06/14/19 18:05

Hi Dooley, thanks for the answer. But unfortunately it is different with me.

I have as you have written cleared the dynamic lights. In addition, the bottom plate deleted. In the mtlFX.c the values ​​are used as in your example. And yet, the box is apparently rendered without ScularMap:

[Linked Image]

I have also made various settings with the sun values. But all with the same result.
Posted By: Dooley

Re: Specular Shader - 06/14/19 20:33

No, I can see the specular happening there. It's not very obvious, but it is definitely shinier than the triangular sections in the middle.


Okay, I forgot to mention - I changed the sun color to 255,255,255
Also, you may want to increase the "power" of your mtl_specBump material. You can modify it in mtlFX.c, or create a new material, like the one I posted in your own script. Just make sure to assign the new material to that object in WED.

The manual mentions that power can be set between 1 and 10, but I think it can go up to 100 and it gives more shininess as you go higher.
Posted By: DexLoomer

Re: Specular Shader - 06/14/19 21:50

Ok, that's right! I have now also made the NormalMap monochrome and the SpecularMap is visible. However, this is much weaker than on your last screenshot. Although I set all the values ​​you said high.
I have no clue whats the cause of this..
Posted By: Dooley

Re: Specular Shader - 06/14/19 23:51

I'm using A7 engine, maybe the material works differently in A8?
Posted By: DexLoomer

Re: Specular Shader - 06/15/19 08:19

Jap .. maybe it's the Gamestudio versions. But I found out something interesting. If I make the 'power' value very small, the SpecularMap value gets much stronger. grin

Code
MATERIAL* mtl_specBump =
{
   effect = "specBump.fx";
   specular_blue = 255;
   specular_green = 255;
   specular_red = 255;
   power = 0.5;
   flags = PASS_SOLID;
}

[Linked Image]
I had not tried that before. I had always made the value higher.

Is still strange, right?

Posted By: Dooley

Re: Specular Shader - 06/15/19 18:54

That is strange ... I don't understand it, but if it works laugh use it!
© 2019 lite-C Forums