2 registered members (AndrewAMD, Nymphodora),
972
guests, and 8
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467721
08/24/17 17:16
08/24/17 17:16
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
Im assuming here is the correct line to add the multiplication?:
float Specular = pow(saturate(dot(R, normalize(InViewDir))), SpecularPower) * SpecularIntensity * shininess;
correct Do I have to define the entskin storing the alpha texture? Say I have it on entskin3. I put this on the top of the fx file?:
texture entSkin1; // diffuse texture entskin3; //shiny map
sampler ShinyMapSampler = sampler_state { Texture = <entSkin3>; AddressU = Clamp; AddressV = Clamp; }
correct. There are more parameter in a sampler_state that you can configure (linear interpolation and such). How then do I multiply each pixel of skin3 into that lighting equation?
shininess = texture2D(uSpecularMapSampler, vec2(vTextureCoord.s, vTextureCoord.t)).r * 255.0;
that doesnt work for me, I got that from a website trying to do it myself. that code line should be like this:
float shininess = tex2D ( ShinyMapSampler, inTex ).r;
Salud! edited____ late!
Last edited by txesmi; 08/24/17 17:17.
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467736
08/25/17 11:55
08/25/17 11:55
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
Hi, first of all I encourage you to take a look into directX documentation and HLSL tutorials before stain your hands with the task, pretty simple by the way. In the list of functions I linked above, there are two resolutive functions: texCUBE and reflect. texCUBE is a bmap sampler, cubemap specific, such skyboxes and enviroment reflections. Its first parameter is a sampler, cubemap specific too.
texture mtlSkin1; // or entSkin1<->4 or myGlobalBmap_bmap or whatever
samplerCUBE sEnvironment = sampler_state { Texture = <mtlSkin1>; MipFilter = Linear; };
And its second parameter is a three-dimensional vector that serves as texture coordinates. The transformation of the vector to the coordinates into a pixel of one of the faces of the cubemap is made by the sampler itself. Think a bit in a skycube. It certainly is a texCUBE sampler and the coordinates vector is the direction of the rendered pixel from the view point. As simple as that. This direction vector is alredy computed in the vertex shader of the tutorial and passed to the pixel shader, but inversed.
// PS
OutViewDir = vecViewPos - mul(InPos, matWorld);
// VS
in float4 InViewDir: TEXCOORD2
Try it yourself. Create a cubemap in liteC.
BMAP *bmpEnvMap = bmap_create ( "myEnvMap+6.tga" );
bmap_to_cubemap ( bmpEnvMap );
myEntMtl.skin1 = bmpEnvMap;
Declare the sampler in the shader.
texture mtlSkin1;
samplerCUBE sEnv = sampler_state { Texture = <mtlSkin1>; MipFilter = Linear; };
Sample and return it in the pixel shader.
float4 envColor = texCUBE ( sEnv, -InVierDir ); // inversed!
return envColor;
You will see that the entity is texturized as a skybox. Let's continue. reflect function is selfexplanatory. It returns the reflexion of a vector in reference to a surface normal and we have both passed from the pixel shader: view direction and surface normal.
float3 viewDirReflexion = reflect ( -InViewDir.xyz, InNormal ); // inversed!
float4 envSample = texCUBE ( sEnv, viewDirReflexion );
If you return this sample as texture color and set the same cubemap as skybox, you will see that the entity is texturized as a perfect skybox reflecting mirror. At this point you only need to mix this last color sample with the color you have already computed. As you may imagine you can do with those values all you want. I would simply replace the specular reflection computations by the texCUBE sample multiplied by specular term you got already. Simple and effective. Cubic real time reflections are managed same but with an unique difference: the cubemap is rendered each frame. That is an expensive task and it is not really advisable. Forget about using it into populated sceneries. Salud!
|
|
|
Re: Specular Shader with specular map
[Re: txesmi]
#467739
08/25/17 18:28
08/25/17 18:28
|
Joined: Apr 2002
Posts: 1,246 ny
jumpman
OP
Serious User
|
OP
Serious User
Joined: Apr 2002
Posts: 1,246
ny
|
Txesmi.....thank you! I was able to get the cubic environment mapping, as well as get it only reflecting on certain pixels of the model, using the model's skin2!! My next problem is trying to get the Envcube reflection to be more pronounced, with more of the cubemap color coming through, I think it has to do with the final color equation. Can you help me? Here is what I made so far: //-This line uses entity skin 2, to determine how much relfection is visible float enviness = 1.5 * tex2D(CubeMapSampler,InTex); //this line is me playing around: envSample*=(enviness*2)-(Diffuse*.8); //---cool envSample*=ShadColor; //Here is the final output return (envSample + Ambient + Diffuse + Specular) * Color; I can see the cubeMap reflection on where i put white in the skin2! However, the reflection itself is mainly white, and kind of loses strength when its normals are facing the sun. How can I add this reflection cubemap on top of the texture, with more of the color of the reflection map coming through? The sun is on the top left, shadow on the right. You can see the envmap on the shadow side. This is OK and kinda cool. This model also has a TGA/Transparency in the first skin. This double sided is important btw. If you look at the cubemap, it is very blue/green. Here is where I rendered just the cubemap as reflection:
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467740
08/25/17 20:57
08/25/17 20:57
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
glad of been helpful My next problem is trying to get the Envcube reflection to be more pronounced, with more of the cubemap color coming through, I think it has to do with the final color equation. Correct, the final color depends on the final color equation I am not sure of what you are looking for so I can only show you the master function of color mixing: lerp. I think I would do something like the following:
color *= ambient + diffuse + specular;
color = lerp ( color, envSample, envMask );
but maybe you like the specular term been persistent over reflections
color *= ambient + diffuse;
color = lerp ( color, envSample, envMask );
color *= 1.0f + specular; // or color += specular; in the case the specular term is a color vector instead of a color factor... Ancha es Castilla (Castilla is wide)
Salud!
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467743
08/25/17 21:33
08/25/17 21:33
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
Yes. lerp interpolates first two parameters by the third, a factor (0<->1). When the factor is 0 the return is the first parameter and the second parameter conversely. You will probably find a better description in the instrict function list I linked above.
Last edited by txesmi; 08/25/17 21:37.
|
|
|
Re: Specular Shader with specular map
[Re: txesmi]
#467744
08/25/17 23:27
08/25/17 23:27
|
Joined: Apr 2002
Posts: 1,246 ny
jumpman
OP
Serious User
|
OP
Serious User
Joined: Apr 2002
Posts: 1,246
ny
|
Here is the current shader! As you can see the cubemap is closer to its actual color: Facing the light: Darkside: However, the dark side is a little more interesting, and the cube map effect is a little more toned down when facing the sun. Here is the relevant code: //------------The cubemap strength is based on skin2 float enviness = 2.5 * tex2D(CubeMapSampler,InTex) ; /// based on skin 2 shinymap!! //-------The envSample is multiplied by the enviness value envSample*=enviness; ... Color *= Ambient + Diffuse + Specular; Color = lerp ( Color, envSample,.45); // I manually put .45 Color *= 1.0f + Specular; return Color; Lerp is better definitely, but how can I get it looking as defined as when it is in the shadow, all the while keeping it based on the envMap texture? (skin 2) BTW Im going to name this shader, "Txesmi and Jumpman's Hero Shader"
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467748
08/26/17 13:26
08/26/17 13:26
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
Hi, I did a try. Let's look how you do feel. Step by step. I love the diffuse term be a gradient vector between the brighter and the darker pixels, been both limits the sun color and the ambient color respectively. I usually compute the diffuse term as follows:
// Calculate the diffuse term:
float DiffuseFactor = pow ( ( 1.0f + dot(-vecSunDir.xyz, InNormal) ) * 0.5f, DiffuseGradient );
float3 texColor = texSample.rgb * lerp ( vecAmbient.rgb, vecSunColor.rgb, DiffuseFactor );
This way I take advantaje of the full range of the result of the dot product, scaling it to a 0<->1 range, so the back part of the mesh is slightly lightened instead of looking flat. DiffuseGradient controls the exponential of DiffuseFactor so you can displace the sun intensity to the back and the front. Then I multiply the texture sample by the interpolation between sun and ambient colors in reference to the computed DiffuseFactor. I like to compute the specular term as a factor of the resultant vector obtained from the subtraction of the previously computed diffuse color to the sun color so it can be added to the diffuse with no big worries of going out of color ranges and been the sun color the brightest color you will find into the scene.
// Calculate the speculate component:
float3 sunDirReflexion = reflect ( vecSunDir.xyz, InNormal );
float3 Specular = ( vecSunColor.rgb - texColor ) * pow(saturate(dot(sunDirReflexion, InViewDir)), SpecularPower ) * texSample.a;
texColor += Specular * SpecularIntensity;
SpecularIntensity can do the color go out of range, but it is a good looking 'burn' effect. I like it larger than one. I really do the enviroment reflexion implementation before computing the specular term.
// Calculate the enviroment reflection term
float3 viewDirReflexion = reflect ( -InViewDir.xyz, InNormal );
float3 envSample = texCUBE ( sEnv, viewDirReflexion ).rgb;
texColor = lerp ( texColor, texSample.rgb*envSample, texSample.a );
Notice that I multiplied the enviroment sample by the raw texture color. alltoghether
// Tweakables:
static const float DiffuseGradient = 1.5f;
static const float SpecularPower = 16.0f;
static const float SpecularIntensity = 2.5f;
// Application fed data:
const float4x4 matWorldViewProj; // World*view*projection matrix.
const float4x4 matWorld; // World matrix.
const float4 vecAmbient; // Ambient color.
const float4 vecSunDir; // The sun light direction vector.
const float4 vecSunColor; // The sun color
const float4 vecViewPos; // View position.
texture entSkin1;
sampler ColorMapSampler = sampler_state // Color map sampler.
{
Texture = <entSkin1>;
MipFilter = Linear; // required for mipmapping
};
texture mtlSkin1;
samplerCUBE sEnv = sampler_state { Texture = <mtlSkin1>; MipFilter = Linear; };
// Vertex Shader:
void SpecularVS(
in float4 InPos: POSITION,
in float3 InNormal: NORMAL,
in float2 InTex: TEXCOORD0,
out float4 OutPos: POSITION,
out float2 OutTex: TEXCOORD0,
out float3 OutNormal: TEXCOORD1,
out float3 OutViewDir: TEXCOORD2)
{
// Transform the vertex from object space to clip space:
OutPos = mul(InPos, matWorldViewProj);
// Transform the normal from object space to world space:
OutNormal = normalize(mul(InNormal, matWorld));;
// Pass the texture coordinate to the pixel shader:
OutTex = InTex;
// Calculate a vector from the vertex to the view:
OutViewDir = vecViewPos - mul(InPos, matWorld);
}
// Pixel Shader:
float4 SpecularPS(
in float2 InTex: TEXCOORD0,
in float3 InNormal: TEXCOORD1,
in float4 InViewDir: TEXCOORD2) : COLOR
{
// Incoming normals have to be normalized
InNormal = normalize(InNormal);
InViewDir = normalize(InViewDir);
// Fetch the pixel color from the color map:
float4 texSample = tex2D ( ColorMapSampler, InTex ); // texture alpha channel = specular map
// Calculate the diffuse term:
float DiffuseFactor = pow ( ( 1.0f + dot(-vecSunDir.xyz, InNormal) ) * 0.5f, DiffuseGradient );
float3 texColor = texSample.rgb * lerp ( vecAmbient.rgb, vecSunColor.rgb, DiffuseFactor );
// Calculate the enviroment reflection term
float3 viewDirReflexion = reflect ( -InViewDir.xyz, InNormal );
float3 envSample = texCUBE ( sEnv, viewDirReflexion ).rgb;
texColor = lerp ( texColor, texSample.rgb*envSample, texSample.a );
// Calculate the speculate component:
float3 sunDirReflexion = reflect ( vecSunDir.xyz, InNormal );
float3 Specular = ( vecSunColor.rgb - texColor ) * pow(saturate(dot(sunDirReflexion, InViewDir)), SpecularPower ) * texSample.a;
texColor += Specular * SpecularIntensity;
return float4 ( texColor, 1.0f );
}
// Technique:
technique SpecularTechnique
{
pass P0
{
ZEnable = True;
ZWriteEnable = True;
AlphaBlendEnable = False;
VertexShader = compile vs_3_0 SpecularVS();
PixelShader = compile ps_3_0 SpecularPS();
}
}
Salud!
|
|
|
Re: Specular Shader with specular map
[Re: txesmi]
#467764
08/28/17 13:12
08/28/17 13:12
|
Joined: Apr 2002
Posts: 1,246 ny
jumpman
OP
Serious User
|
OP
Serious User
Joined: Apr 2002
Posts: 1,246
ny
|
hi Txesmi! Here is what I added to the shader! I made a better test model with the appropriate skins on the far left. You can also see a pseudo/fake reflected light!!! The sun light is on the top left, but a fake reflected light on the bottom right!! All i did was copy the specular highlight lines, and did a negative on one of the view calculations!: The Cubemap relfection also takes into account the skin under it. I cant really put it on top of another texture and expect it to be obvious. I need to have the diffuse texture accomodate the cubemap reflection areas! I am very satisfied with the shader currently In a little bit, I am going to look at the shader workshop for Normal mapping....
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467768
08/29/17 12:57
08/29/17 12:57
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
Congratulations! I cant really put it on top of another texture and expect it to be obvious. I need to have the diffuse texture accomodate the cubemap reflection areas! Its true. RGB add & mul color treatment needs the base texture be neither too dark nor too light so there is space for specular addition on light colors and the dark parts of the texture are light enough to become a visible gradient when multiplied by the diffuse term. Maybe you want take a look to RGB<->HLS conversion. It is not really cheap but lets you modify the colors in a different way. While hue could remain unchanged you could use the diffuse and specular terms as lightness multipliers and the enviroment map as saturation modifier so both layers could have some presence in the final color. I remember a forum member publishing a shader which texturized the model with a simple image as enviroment map in screen space and a very cheap manner. The enviroment map was like a projection of an sphere and the shader computed its sample coordinates in base to the view direction vector so it gived the sense of an enviroment map but always aligned to the view, if i am not wrong. Does someone remember it? I can't find it
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467772
08/29/17 16:30
08/29/17 16:30
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
When a shader uses 4 entity skin textures within the model, that means the shader/engine does 4 passes or 4 calls to the images? More calls/passes mean more rendering time correct? mmm...hard to explain...there is an explanation of the D3D rendering pipeline into shader tutorials... The graphic card calls the vertex shader once per vertex and calls the pixel shader once per screen pixel contained by the triangles projected into the screen. Backfacing triangles are clipped away inbetween so there can be not shown computed vertex and there can be screen pixels computed more than once because of triangles overlapping. There is no such a texture rasterization I guess your are thinking about. Just image samples for each projected pixel. Linear interpolation on texture samples takes its time, yes. The more operations you perform the slower it will be, you know. You can speed up the samples by disabling the linear interpolation (MagFilter = Point;) but it shows the pixels. Should I just make a new material? Yes. A material for each rendering technique. You can define more than one technique inside the same effect file and share functions between techniques. For example:
float3 doDiffuse ( float3 inNormal )
{
float DiffuseFactor = pow ( ( 1.0f + dot(-vecSunDir.xyz, InNormal) ) * 0.5f, DiffuseGradient );
return lerp ( vecAmbient.rgb, vecSunColor.rgb, DiffuseFactor );
}
...
float3 texColor = texSample.rgb * doDiffuse ( inNormal );
|
|
|
Re: Specular Shader with specular map
[Re: txesmi]
#467774
08/29/17 23:13
08/29/17 23:13
|
Joined: Apr 2002
Posts: 1,246 ny
jumpman
OP
Serious User
|
OP
Serious User
Joined: Apr 2002
Posts: 1,246
ny
|
Hi txesmi! I am very close to the final outcome of the shader I need help figuring out what is happening to this portion of the Vertex Shader in regards to the cube map reflection. I currently have normal mapping+specular working! However, the cubemap reflection doesnt look correct when I have normal mapping and specular working. Here is the area Im having trouble with:
void SpecularVS(in float4 InPos : POSITION,
in float3 InNormal : NORMAL,
in float2 InTex : TEXCOORD0,
in float4 InTangent : TEXCOORD2,
out float4 OutPos : POSITION,
out float2 OutTex : TEXCOORD0,
out float3 OutNormal: TEXCOORD1,
out float3 OutViewDir: TEXCOORD2,
out float3 OutSunDir: TEXCOORD3,
out float3 OutViewDir2: TEXCOORD4)
{
OutPos = mul(InPos, matWorldViewProj); // Transform the vertex from object space to clip space:
//////////--------------------------- Having these 2 uncommented gives smooth cubemap reflections
// OutNormal = normalize(mul(InNormal,matWorld)); // Transform the normal from object space to world space:
// OutViewDir = vecViewPos - mul(InPos, matWorld); // Calculate a vector from the vertex to the view:
/////////////-----------------Normal Mapping segment
// Compute 3x3 matrix to transform from world space to tangent space:
matTangent[0] = mul(InTangent.xyz, matWorld);
matTangent[1] = mul(cross(InTangent.xyz,InNormal)*InTangent.w, matWorld);
matTangent[2] = mul(InNormal, matWorld);
/////////////-----------
// ---------------------------------------------------------------------------OutNormal = normalize(mul(matTangent,matWorld));
// OutNormal = normalize(mul(InNormal,matWorld))
OutViewDir = normalize(mul(matTangent, vecViewPos - mul(InPos, matWorld))); // Calculate the view direction vector in tangent space:
//////
OutSunDir = normalize(mul(matTangent, -vecSunDir)); // Calculate the light direction vector in tangent space:
//------------------
OutTex = InTex; // Pass the texture coordinate to the pixel shader:
}
Thats the vertex shader part. If I uncomment this line before the normal map segment, the cubemap reflection is correct: //Not considering normals OutViewDir = vecViewPos - mul(InPos, matWorld); But if I uncomment this line: //----Normal map OutViewDir OutViewDir = normalize(mul(matTangent, vecViewPos - mul(InPos, matWorld))); the normal mapping specular component works correctly, however the cubemap is reflected strangely....I can see the cubemap showing seams in the model's mesh where the UV seams are. What equation do I do, to get the cubemap reflecting correctly without showing seams? with the OutViewDir meant for normal maps uncommented. Below you can see the seams: OutViewDir = normalize(mul(matTangent, vecViewPos - mul(InPos, matWorld))); Below is the original OutViewDir not taking the normal map into account. This is the cubemap reflecting correctly: OutNormal = normalize(mul(InNormal,matWorld)); OutViewDir = vecViewPos - mul(InPos, matWorld);
|
|
|
Re: Specular Shader with specular map
[Re: jumpman]
#467777
08/30/17 09:48
08/30/17 09:48
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
I didn't remember the normal mapping tutorial uses tangent space in sun lighting. I am not sure if it helps or bothers As far as I understand there is no way of computing enviroment reflexion in tangent space because they need same coordinate system on every screen pixel. You will need to perform the tangent space to world space texture normal transformation pixel side so vertex shaders incoming tangent is needed for pixel shading.
void SpecularVS(
in float4 InPos: POSITION,
in float3 InNormal: NORMAL,
in float2 InTex: TEXCOORD0,
in float4 InTangent: TEXCOORD2,
out float4 OutPos: POSITION,
out float2 OutTex: TEXCOORD0,
out float3 OutNormal: TEXCOORD1,
out float3 OutTangent: TEXCOORD2,
out float3 OutViewDir: TEXCOORD3)
{
// Transform the vertex from object space to clip space:
OutPos = mul(InPos, matWorldViewProj);
// Transform the normal from object space to world space:
OutNormal = normalize(mul(InNormal, matWorld));
// Transform the tangent from object space to world space:
OutTangent = mul( InTangent.xyz, matWorld );
// Pass the texture coordinate to the pixel shader:
OutTex = InTex;
// Calculate a vector from the vertex to the view:
OutViewDir = vecViewPos - mul(InPos, matWorld);
}
then you can compute the world space normal into the pixel shader
// Read the normal from the normal map and convert from [0..1] to [-1..1] range
float3 TSNormal = normalize ( ( NormalSample.rgb * 2.0f ) - 1.0f );
// Transform tangent space normal to world space
InNormal = normalize(InNormal);
InTangent = normalize(InTangent);
float3 BumpNormal = TSNormal.z * inNormal + TSNormal.x * inTangent + TSNormal.y * cross ( InNormal, InTangent );
...
Then you will only need to sustitute 'inNormal' by 'BumpNormal' in next code lines of the shader that worked in world space, not this last version you showed that works in tangent space. Salud!
|
|
|
Re: Specular Shader with specular map
[Re: txesmi]
#467778
08/30/17 13:37
08/30/17 13:37
|
Joined: Jun 2009
Posts: 2,210 Bavaria, Germany
Kartoffel
Expert
|
Expert
Joined: Jun 2009
Posts: 2,210
Bavaria, Germany
|
for cubemap reflections you might wanna use this:
float3 vNormal = ... (normalized world-space normal with normalmapping applied)
float3 vViewPixel = PixelWorldCoord - ViewWorldCoord;
float3 vReflected = reflect(vViewPixel, vNormal);
float3 ReflectionColor = texCUBE(smpCube, vReflected).rgb;
POTATO-MAN saves the day! - Random
|
|
|
|