GLSL, CG, HLSL, FX, CGFX and CUDA

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

Implementing the power of GPU's in Irrlicht rendering.
GPU's are increasingly being called upon throughout the graphics world!
The aim of this topic is to examine the possibilities, share our experiences and share our code.
Irrlicht users could gain a lot from this subject if it is considered and maintained.
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by The_Glitch »

Well I know in shader pipeline you can harness the gpu for some things but I'm not to sure about a lot of the other things done on the gpu now.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

If you can write GPU Assembly through Irrlicht you can do everything with it, even Cuda..
Check out the CG Wrapper and example 10.. (don't worry it is HLSL friendly too)
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by The_Glitch »

I've only used it for hardware skinning.
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by devsh »

First you need to rewrite the Irrlicht Video driver to support a IGPUBuffer object, otherwise you'll have no way to pass and receive data from CUDA, OpenCL, Compute or even GS and Tessellation if you want the vertices back
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

Here is a good example of how the GPU can be used for non-render things
like Physics. I posted this because I'd like to try this in Irrlicht some time.
(should have been Vertex Program Physics?)

Image

It is GLSL, but can be ported to HLSL easily.
Much like HW Skinning it makes use of the GPU math capability
to do calculations much faster than the CPU. (no returning values though)

Here is the VC code etc: http://s000.tinyupload.com/?file_id=495 ... 4419514180
(old things are nice because most of our compilers can read them)


Devsh is quite right about Communincating with the GPU in his post.
I read up on it and found this little piece:
http://http.developer.nvidia.com/GPUGem ... _ch37.html
Last edited by Vectrotek on Sat Sep 26, 2015 12:48 pm, edited 2 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

This CG shader is very similar to Cone Step Mapping with added functionality namely "Specularity" and "Self Shadowing".
Now, I haven't seen too many of these before!

Image

It comes from a set of theoretical examples.
I've had to change a lot of things in the code to make it actually work though.
The Specularity Calculations were wrong (for my implementation) and there were some other fundamental issues.
The speed at which these calculations are done on the GPU is yet another example
of why GPU code (or anything to which it can be related) should not be forgotten.

Here is a small grab of the "Diffuse", "Normal", and "Z-Depth or Height Map" I made
to test it with:

Image

Believe it or not, the "Z Depth Map" is not a 32 bit grey scale image!
It is a plain vanilla 24 bit RGB Targa (might as well have been a 256 color PNG).
It is a misguided and common belief that for good parallax or relief mapping,
nothing less than 32 bit grey will do..
In this case the Information in the Normal Map is combined mathematically
with the Height Information to get a reasonably smooth height based curvature.
(the image was rendered in 'fast' real time with the old Nvidia's XP Composer)
Imagine what could be done in something like Z-Brush which incidentally,
exports cool Depth Maps and accompanying diffuse maps.
The actual GPU code is CG (could have been HLSL) embedded in CGFX..
Ill post it once I get it perfect.
Last edited by Vectrotek on Sat Sep 26, 2015 9:48 am, edited 4 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

GLSL to HLSL.. Matrices from "Irrlicht to GLSL" is interpreted Differently to Matrices from "Irrlicht to HLSL" by the looks of it.

Problems apparent right from the start:
Under D3D, there is no "gl_ModelViewProjectionMatrix" for the Vertex Program to depend on..
We need to know what the counterpart of this is in HLSL.. (could be complicated if Matrix Row Order etc isn't identical)

There will also be no "gl_Vertex.xyz" for the HLSL Vertex Program to use..
Again what is the counterpart in HLSL here..

Code: Select all

 
 // Pieces of code not necessarily in the right order..
 VNormal = vec3(mWorld * vec4(VNormal.xyz, 0 )).xyz; // Looks like we could lean on this.
 TheWorldMatrix = TheVideoDriver->getTransform(ETS_WORLD); // We could probably use this..
 PrivateServices->setVertexShaderConstant("mWorld", TheWorldMatrix.pointer(), 16); // Cool because of the previous line..
 

Code: Select all

 
 TheCameraPosition = TheSceneManager->getActiveCamera()->getPosition();  // O.K.
  PrivateServices->setPixelShaderConstant("CameraPos", &TheCameraPosition.X, 4); // Fragment, and not Vertex Program (could we do this in HLSL?)..
 
In GLSL the Vertex Program didn't even see the camera position! (good clue)

Also in GLSL there was pretty little from the matrices side fed to the Fragment Shader from the program..
Communication between the Vertex Program and the Fragment Shader was relied on..
Whats the story in HLSL..

In the Vertex Program we had :

Code: Select all

 
   gl_Position       = gl_ModelViewProjectionMatrix * gl_Vertex;    // "glModelview...." is mostly UNSEEN, and ensures that Object "ROTATION" is considered..
   VertexGLPosition  = vec3(mWorld * vec4(gl_Vertex.xyz,1)).xyz;
   // In the Fragment Shader we had:
   vec3 ViewDir     = normalize(CameraPos - VertexGLPosition);    // A light from the camera is always useful.
   vec3 LightDir001 = normalize(LightPos001 - VertexGLPosition); // We want a few lights right from the start..
   vec3 LightDir002 = normalize(LightPos002 - VertexGLPosition);
   vec3 LightDir003 = normalize(LightPos003 - VertexGLPosition);
   vec3 LightDir004 = normalize(LightPos004 - VertexGLPosition);
 
.. where Vertex Position became Fragment Position without any human intervention..
(whats the story here with HLSL?)

O.K. not much more we can do here..

Let's see what happens..
I'm looking for the simplest Irrlricht HLSL shader example out there as a basis to build on.
I've got a good animated Test Model complete with a Normal and Diffuse map to start with..
This is where I'd start looking at my old CG stuff and Composer examples..
What do we have to work with?
1. Irrlicht HLSL Examples.
2. Old CG Code (despite not quite understanding tangents at the time!).
3. Old Composer CG/HLSL Examples. (cool tangents but invisibly sent from appcode)
4. Forum code.
5.We now have a "pretty solid" basis for Irrlicht GLSL shaders which helps even if it is just moral support.

There are many seemingly correct physical based HLSL shaders out there but with closer scrutiny
it becomes apparent that we've got our work cut out for us!

Daunting stuff.. Help! Glitch!
Last edited by Vectrotek on Sat Sep 26, 2015 1:56 pm, edited 2 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

We'll be looking at these. thanks Alien.
You can distinguish shaders in low-level shaders and high-level shaders. Low-level shaders are basically assembler. But they are different for OpenGL and D3D. In Irrlicht those have been hardcoded into strings (see for example COpenGLNormalMapRender.cpp or C3D9NormapMapRender.cpp). But could also just as well be in text files (that was just a design decision).
Last edited by Vectrotek on Fri Sep 25, 2015 7:12 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

I was Corrected by Kojack on among others my "*.vert" & "*.frag" statement.
NVIDIA and Microsoft collaborated to develop the Cg language. Microsoft calls its implementation High-Level Shading Language, or HLSL for short. HLSL and Cg are the same language but reflect the different names each company uses to identify the language and its underlying technology. HLSL is a part of Microsoft's DirectX Graphics, a component of the DirectX 9 multimedia framework. Direct3D is the 3D component of Microsoft's DirectX Graphics. Cg is independent of the 3D programming interface and fully integrates with either Direct3D or OpenGL. A properly written Cg application can be written once and then work with either OpenGL or Direct3D.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

I don't think this is the right place for GLSL conversion to HLSL, so if anything useful gets done it will have to
be posted in "Bump Mapping for Animated Meshes".
Post your Irrlicht and GPU opinions here though.
Kojack
Posts: 67
Joined: Sun Jan 20, 2008 2:39 am

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Kojack »

Vectrotek wrote:This CG shader is very similar to Normal Parallax Mapping with two big differences
namely "Specularity" (in a primitive form) and "Self Shadowing" (also quite primitive)
rendered at remarkable speed.
One that I really like is Cone Step Mapping. It's like parallax occlusion mapping, but used to be faster (not sure if that's still the case).
It was never used much because there was a patent on it, but it's expired now.
For every texel in the cone step map, it stores an angle of the cone that can sit with it's tip touching the texel and it's sides not intersecting the height map. As the shader ray marches through the height map, it knows how far it can jump ahead without possible intersection based on the shape of the cone it's inside. A bit strange to get your head around at first, but it works well. The only program that I know of that can generate it's maps is XNormal. Luckily XNormal is awesome, so being stuck with it is fine. :)

Here's an old demo showing off Cone Step Mapping as well as a bunch of others (displacement, relief, parallax, etc). It's the "Detailed Surfaces Viewer" at http://www.brunoevangelista.com/projects
The performance is pretty even between most of them, but Cone Step Mapping puts the limited iteration count (16 by default in that demo) to much better use at steep glancing angles to avoid the layered slices look of other techniques.
This demo doesn't do it, but I've seen Cone Step Mapping doing self shadowing. (There's a demo that does it, but if you run it for more than a few minutes it will hard lock your pc. I'm playing soma and writing posts on another forum at the moment, so I don't want to find that demo and test it right now) :)
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

Your'e right it is based on Cone Step Mapping. My typo.
Kojack
Posts: 67
Joined: Sun Jan 20, 2008 2:39 am

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Kojack »

No, you were right. Cone Step is just another alternative that not many people use. I've never heard of a game using CSM (due to previous patent issues I'd guess) but a ton use Parallax Offset / Steep Parallax / Relief mapping.
Normal mapping distorts the surface normal to affect lighting.
Parallax does normal mapping plus distorts uv coordinates.
Parallax Occlusion / Steep Parallax / Relief do ray marching through the texture to allow occlusions.
Cone Step Mapping does the same but has an optimisation to use ray marching more efficiently.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: GLSL, CG, HLSL, FX, CGFX and CUDA

Post by Vectrotek »

I don't know the exact terminology, but here it is..
I pulled it from old Mental Mill stuff, changed it a bit and converted it for FX Composer in OpenGL Mode..
You'll make more sense of it than I could but it does work (in Composer at least).
I found that anything working in Composer worked in my old Win 32 OpenGL programs.
It would be great if one could get them working in Irrlicht.

Code: Select all

 
 
//            - RELIEF MAP - 
 
 // Values for the light_type parameter of light shaders
 #define LIGHT_POINT    0
 #define LIGHT_SPOT     1
 #define LIGHT_INFINITE 2
 #define LIGHT_PLANAR   3
 // The light iterator structure holds the return values resulting from
 // evaluating a light.
 struct Light_iterator 
  {float3  _point;
   float4  contribution;
   float4  raw_contribution;
   float   DotNLightDiffuse;
   float   DotNLightSpecular;
 
   float3  direction;
   float   distance;
   float4  shadow;
   int     count;
  };
 
struct Ray {
    float3 origin;
    float3 direction;
};
 
void CreateBasis(const float3 n, const float3 u, const float3 v,
        out float3 t, out float3 b)
{
    b = normalize(cross(u,n));
    t = cross(n,b);
    if(dot(b,v) < 0.0)  b = -b;
}
 
// float3 DividePerspective(float4 pt) { return pt.xyz/pt.w; }
 
//
// The state structure is used internally within the fragment shader to
// commonly used values.
//
struct State
{
    float4 tex_coord[4];
    float3 position;
    float3 normal;
    float3 direction;
    float3x3 tangent_space[1];
    float3 light_position;
    float3 light_to_surface;
    float light_distance;
    float light_dotnl;
};
 
//
// The following are free parameters of the shader that should be set by the
// application at runtime.
//
float4 __light0_Light_point_1_color
<
    string UIName = "Light0 Color";
    string UIWidget = "Color";
> = float4(1.000000, 1.000000, 1.000000, 1.000000);
float __light0_Light_point_1_intensity
<
    string UIName = "Light0 Intensity";
    float UIMin = 0.000000;
    float UIMax = 10.000000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 1.000000;
float __light0_Light_point_1_distance_falloff_exponent
<
    string UIName = "Light0 Distance Falloff Exponent";
    float UIMin = 0.000000;
    float UIMax = 4.000000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 1.000000;
float __light0_Light_point_1_distance_falloff_start
<
    string UIName = "Light0 Distance Falloff Start";
    float UIMin = 0.000000;
    float UIMax = 10.000000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 0.000000;
float __light0_Light_point_1_distance_falloff_limit
<
    string UIName = "Light0 Distance Falloff Limit";
    float UIMin = 0.000000;
    float UIMax = 1000.000000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 1000.000000;
 //-----------------------------------------------------------------------------
float __light0_Light_point_1_distance_scale
<
    string UIName = "Light0 Distance Scale";
    float UIMin = 0.001000;
    float UIMax = 100.000000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 1.000000;
 //-----------------------------------------------------------------------------
float3 __light0_position : Position 
<
    string Object = "PointLight0";
    string Space = "World";
    string UIName = "Light0 Light_position";
> = float3(0.000000, 1.000000, 0.000000);
 //-----------------------------------------------------------------------------
texture __Normals_relief_map_1_color_tex <
    string UIName = "Normals_relief_map_1_color_tex";
    string ResourceName = "CliffRock.dds";
    string ResourceType = "2D";
>;
 //-----------------------------------------------------------------------------
sampler2D Normals_relief_map_1_color_tex = sampler_state {
    Texture = <__Normals_relief_map_1_color_tex>;
    MinFilter = LinearMipMapLinear;
    MagFilter = Linear;
};
 //-----------------------------------------------------------------------------
texture __Normals_relief_map_1_height_tex <
    string UIName = "Normals_relief_map_1_height_tex";
    string ResourceName = "relief_map_1_height.dds";
    string ResourceType = "2D";
>;
 //-----------------------------------------------------------------------------
sampler2D Normals_relief_map_1_height_tex = sampler_state {
    Texture = <__Normals_relief_map_1_height_tex>;
    MinFilter = LinearMipMapLinear;
    MagFilter = Linear;
};
 //-----------------------------------------------------------------------------
texture __Normals_relief_map_1_norm_tex <
    string UIName = "Normals_relief_map_1_norm_tex";
    string ResourceName = "relief_map_1_normal.dds";
    string ResourceType = "2D";
>;
sampler2D Normals_relief_map_1_norm_tex = sampler_state {
    Texture = <__Normals_relief_map_1_norm_tex>;
    MinFilter = LinearMipMapLinear;
    MagFilter = Linear;
};
 //-----------------------------------------------------------------------------
 
float DiffuseMultiplier
<
    string UIName = "DIFFUSE_MULTIPLIER";
    float UIMin = 0.000000;
    float UIMax = 2.000000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 1.0;
 
 //-----------------------------------------------------------------------------
float Normals_relief_map_1_amount
<
    string UIName = "Amount";
    float UIMin = 0.000000;
    float UIMax = 0.500000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 0.050000;
 //-----------------------------------------------------------------------------
float4 SpecularColour
<
    string UIName = "Specular Color";
    float4 UIMin = float4(0.000000, 0.000000, 0.000000, 0.000000);
    float4 UIMax = float4(1.000000, 1.000000, 1.000000, 1.000000);
    float UIStep = 0.01;
    string UIWidget = "color";
> = float4(1.000000, 1.000000, 1.000000, 1.000000);
 //-----------------------------------------------------------------------------
float SpecularGloss
<
    string UIName = "Specular Shininess";
    float UIMin = 0.000000;
    float UIMax = 300.000000;
    float UIStep = 0.01;
    string UIWidget = "slider";
> = 100.000000;
 //-----------------------------------------------------------------------------
 int Normals_relief_map_1_steps
  <string UIName = "Steps";
   int UIMin = 1;
   int UIMax = 80;
   float UIStep = 0.01;
   string UIWidget = "slider";
  > = 10;
 //-----------------------------------------------------------------------------
 
 
// The following are parameters representing non-varying state variables 
// referenced by the shader. These should be set by the application at runtime.
// Note that vector parameters should be provided in camera space.
 
float4x4 __object_to_ndc : WorldViewProjection <string UIWidget = "none";>;
float4x4 __world_to_object : WorldInverse <string UIWidget = "none";>;
float4x4 __object_to_world : World <string UIWidget = "none";>;
float4x4 __camera_to_world : ViewInverse <string UIWidget = "none";>;
 
 
#ifndef PhongShade__Vector2__Scalar__Scalar__Scalar
 #define PhongShade__Vector2__Scalar__Scalar__Scalar 1
 
 float2 PhongShade(float n_dot_l, float n_dot_h, float e)
  {float2 res;
   res.x = (saturate(n_dot_l));
 
 
//   res.y = (((n_dot_l < 0) || (n_dot_h < 0)) ? 0 : (pow(n_dot_h, e)));  // WRONG!! (As in example)
 
   res.y = (((n_dot_l < 0) || (n_dot_h < 0)) ? 0 : (pow(n_dot_l, e)));   // RIGHT!!
 
  // AHA!! THIS WAS THE PROBLEM IN COMPOSER
  // (WHY DOES EXAMPLE GIVE US THIS?)
 
 
 
 
 
   return res;
  }
 
 #endif
 
 
//
// The App2vert structure defines the vertex attributes used by the vertex
// shader. The application should supply a vertex stream containing these 
// elements.
//
struct App2vert
{
    float3 position : POSITION;
    float3 normal : NORMAL;
    float4 texcoord0 : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    float4 texcoord2 : TEXCOORD2;
    float4 texcoord3 : TEXCOORD3;
    float3 tex_du : TANGENT;
    float3 tex_dv : BINORMAL;
};
 
//
// The Vert2frag structure defines values used by the fragment shader and
// supplied by the vertex shader.
//
struct Vert2frag
{
    float4 hpos : POSITION;
    float4 tex_coord[4] : TEXCOORD0;
    float3 tex_du : TEXCOORD4;
    float3 tex_dv : TEXCOORD5;
    float3 position : TEXCOORD6;
    float3 normal : TEXCOORD7;
};
 
//
// This function is the main method of the vertex shader.
//
Vert2frag VertexProgram(
    App2vert vs_in)
{
    Vert2frag vs_out;
    float4 position = float4(vs_in.position, 1);
    vs_out.hpos = mul(__object_to_ndc, position);
    vs_out.position = mul(__object_to_world, position).xyz;
    vs_out.normal = mul(vs_in.normal, (float3x3)__world_to_object);
    vs_out.tex_coord[0] = vs_in.texcoord0;
    vs_out.tex_coord[1] = vs_in.texcoord1;
    vs_out.tex_coord[2] = vs_in.texcoord2;
    vs_out.tex_coord[3] = vs_in.texcoord3;
    vs_out.tex_du = mul(vs_in.tex_du, (float3x3)__world_to_object);
    vs_out.tex_dv = mul(vs_in.tex_dv, (float3x3)__world_to_object);
    return vs_out;
}
 
//
// The following functions are generated from the MetaSL implementation of
// the shaders that are part of the compiled shader graph.
//
 
void Light_point_main(
    float4 color,
    float intensity,
    float distance_falloff_exponent,
    float distance_falloff_start,
    float distance_falloff_limit,
    float distance_scale,
    State state,
    out float4 result,
    out float4 light_shadow)
{
    {
        float d = saturate((((state.light_distance) / (distance_scale - distance_falloff_start)) / (distance_falloff_limit - distance_falloff_start)));
        float f = 1.0 / (1.0 + (pow(d, distance_falloff_exponent)));
        result = ((color * intensity) * f);
        light_shadow = (float4(1,1,1,1));
        result *= 3.14159265358979323846f;
    }
}
 
void LightCalculation(
    float4 Light_point_1_color,
    float Light_point_1_intensity,
    float Light_point_1_distance_falloff_exponent,
    float Light_point_1_distance_falloff_start,
    float Light_point_1_distance_falloff_limit,
    float Light_point_1_distance_scale,
    float3 __light_position,
    State state,
    out Light_iterator __light)
{
    {
        float4 light_shadow = float4(0.000000, 0.000000, 0.000000, 0.000000);
        float4 result = float4(0.000000, 0.000000, 0.000000, 0.000000);
        __light.direction = (__light_position - (state.position));
        __light.distance = (length(__light.direction));
        __light.direction /= __light.distance;
        __light.DotNLightDiffuse = (dot(__light.direction, (state.normal)));
        __light.contribution = 0.0;
        __light.raw_contribution = 0.0;
        __light.count = 0.0;
        __light.shadow = 0.0;
        __light._point = 0.0;
        (state.light_to_surface) = (-__light.direction);
        (state.light_distance) = __light.distance;
        (state.light_dotnl) = __light.DotNLightDiffuse;
        (state.light_position) = __light_position;
        Light_point_main(Light_point_1_color, Light_point_1_intensity, Light_point_1_distance_falloff_exponent, Light_point_1_distance_falloff_start, Light_point_1_distance_falloff_limit, Light_point_1_distance_scale, (state), result, light_shadow);
        __light._point = __light_position;
        __light.shadow = light_shadow;
        __light.count = 0;
        __light.raw_contribution = result;
        __light.contribution = (result * light_shadow);
    }
}
 
void ProcessRelief(
    sampler2D color_tex,
    sampler2D height_tex,
    sampler2D norm_tex,
    float amount,
    float4 specular_color,
    float specular_shininess,
    int steps,
    int texture_space,
    State state,
    out float4 result)
{
    {
        float3 vtan = mul((state.tangent_space)[0], (state.direction));
        float step_size = 1.0 / steps;
        float2 dt = ((-vtan.xy) * amount) / (steps * vtan.z);
        float height = 1.0;
        float2 t = (state.tex_coord)[texture_space].xy;
        float h = (tex2D(height_tex, t)).x;
        while (h < height)
        {
            height -= step_size;
            t += dt;
            h = (tex2D(height_tex, t)).x;
        }
        for (int i = 0; i < 8; i++)
        {
            if (h < height)
            {
                t += dt;
                height -= step_size;
            }
            else
            {
                t -= dt;
                height += step_size;
            }
            step_size *= 0.5;
            dt *= 0.5;
            h = (tex2D(height_tex, t)).y;
        }
        float3 n = ((tex2D(norm_tex, t)).xyz - 0.5) * 2.0;
        (state.normal) = (normalize(n));
        float4 color = tex2D(color_tex, t);
        float4 diffuse = float4(0, 0, 0, 0);
        float4 specular = float4(0, 0, 0, 0);
        step_size = (1.0 / steps);
        Light_iterator light;
        {
            {
                LightCalculation(__light0_Light_point_1_color, __light0_Light_point_1_intensity, __light0_Light_point_1_distance_falloff_exponent, __light0_Light_point_1_distance_falloff_start, __light0_Light_point_1_distance_falloff_limit, __light0_Light_point_1_distance_scale, __light0_position, (state), light);
 
                      float3 TanByLightDir = mul((state.tangent_space)[0], light.direction);
                float2 ti = t;
 
 
 
 
                       // float3 OrigNorm = state.normal;
                       // float TX = state.normal.x;
                       // float TY = state.normal.y;
                       // float TZ = state.normal.z;
 
                        // state.normal.y = TX;
 
 
 
 
                float DotNLightDiffuse = dot(TanByLightDir, (state.normal));
 
 
                        float3 TempStateNrml;
 
                        //TempStateNrml.x = state.normal.x; 
                        //TempStateNrml.y = state.normal.y;
                        //TempStateNrml.z = state.normal.z;
 
                        //float3  TanByLightDirTEMP ; 
 
                        //TanByLightDirTEMP.x = TanByLightDir.x;
                        //TanByLightDirTEMP.y = TanByLightDir.y;
                        //TanByLightDirTEMP.z = TanByLightDir.z;
 
                float DotNLightSpecular = dot(TanByLightDir, (state.normal));
 
 
                        // state.normal = OrigNorm;
                if (DotNLightDiffuse > 0.0)
                {               dt = ((TanByLightDir.xy * amount) / (steps * TanByLightDir.z));
                    h = (tex2D(height_tex, ti)).x;
                    height = (h + step_size);
                    ti += dt;
                    while ((h < height) && (height < 1))
                    {
                        height += step_size;
                        ti += dt;
                        h = (tex2D(height_tex, ti)).x;
                    }
                    if (h < height)
                    {
                        float3 vhalf = normalize((TanByLightDir - (state.direction)));
                        float2 illum = PhongShade(DotNLightDiffuse, (dot((state.normal), vhalf)), specular_shininess);
                        diffuse += (((illum.x * DotNLightDiffuse) * light.contribution) / 3.14159265358979323846f);
                                    // ======
                                    diffuse.xyz *= DiffuseMultiplier;
 
                        specular += ((((illum.y * DotNLightSpecular) * specular_color) * light.contribution) /  3.14159265358979323846f);
                    }
                }
            }
        }
        result = ((color * diffuse) + specular);
    }
}
 
//
// The following method is the root function of the shader graph
//
 float4 Evaluate(State state)
  {float4 result;
   ProcessRelief(Normals_relief_map_1_color_tex,
                                     Normals_relief_map_1_height_tex,
                                     Normals_relief_map_1_norm_tex,
                                     Normals_relief_map_1_amount,
                                     SpecularColour,
                                     SpecularGloss,
                                     Normals_relief_map_1_steps, 0, (state), result);
   return result;
  }
 
//
// This function is the main method of the fragment shader. It initializes the
// values in the state structure that are used by nodes in the shader graph
// and produces the final result of the shader.
//
float4 FragmentShader(
    Vert2frag fs_in) : COLOR
{
    State state;
    state.position = fs_in.position;
    state.normal = normalize(fs_in.normal);
    state.tex_coord = fs_in.tex_coord;
    float3 eye_to_pos = state.position - float3(__camera_to_world[0][3], __camera_to_world[1][3], __camera_to_world[2][3]);
    state.direction = normalize(eye_to_pos);
    float3 t_tex_tangent, t_tex_binormal;
    CreateBasis(state.normal, fs_in.tex_du, fs_in.tex_dv, t_tex_tangent, t_tex_binormal);
    state.tangent_space[0] = float3x3(
        t_tex_tangent,
        t_tex_binormal,
        state.normal);
    state.light_position = 0;
    state.light_to_surface = 0;
    state.light_distance = 0;
    state.light_dotnl = 0;
    return Evaluate(state);
}
 
 
// The following define the default technique and pass of the effect.
 
technique T0
{
    pass P0
    {
        DepthTestEnable = true;
        DepthMask       = true;
        CullFaceEnable  = false;
        VertexShader = compile vp40 VertexProgram();
        PixelShader  = compile fp40 FragmentShader();
    }
}
 
 
Last edited by Vectrotek on Sat Sep 26, 2015 12:55 pm, edited 1 time in total.
Post Reply