material shader: Phong, fake reflect, bloom

Post your questions, suggestions and experiences regarding to Image manipulation, 3d modeling and level editing for the Irrlicht engine here.
TheMormegil
Posts: 3
Joined: Wed Mar 21, 2018 4:47 pm

Re: material shader: Phong, fake reflect, bloom

Post by TheMormegil »

Hi, I don't know if this is the right place to ask but I'm trying to convert one of these shaders to HLSL. It's working to some extent, but there are odd things going on. I'm very new to shaders so I'm probably doing stupid things :)
If anyone could help or point me to the right place to ask, that would be great.

Code: Select all

 
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
float4x4 mTransWorld;    // Transposed world matrix 
float4x4 mWorldViewProj; // World * View * Projection transformation
float4x4 mInvWorld;      // Inverted world matrix
float4x4 mInvWorldViewProj; // Inverted WorldViewProj
 
// Vertex shader output structure
struct VS_OUTPUT
{
    float4 fPosition : POSITION;  // fake position to satisfy compiler
    float3 Normal   : COLOR0;    // the Normal, store in COLOR0 semantic
    float2 TexCoord : TEXCOORD0; // tex coords
    float4 wPosition : TEXCOORD1;  // world position    
    float4 vPosition : TEXCOORD2;  // vertex position   
};
 
VS_OUTPUT vertexMain(   in float4 vPosition     : POSITION,
                        in float3 vNormal       : NORMAL,
                        float2 texCoord         : TEXCOORD0 )
{
    VS_OUTPUT Output;
 
    // transform position to clip space
    Output.vPosition = mul(vPosition, mWorldViewProj);
 
    // transform normal
    float3 normal = mul(float4(vNormal,0.0), mInvWorld);
 
    // renormalize normal
    Output.Normal = normalize(normal);
 
    // position in world coodinates
    Output.wPosition = mul(mTransWorld, vPosition);
    
    Output.TexCoord = texCoord;
    Output.fPosition = Output.vPosition;
 
    return Output;
}
 
// material attributes, because it doesn't work, to define it from the irrlicht API and to find it in gl_FrontMaterial
#define SHININESS 18
 
#define WITH_NORMALMAP_GREEN_UP
#define WITH_NORMALMAP
 
#define MAX_LIGHTS 8
 
// Pixel shader output structure
struct PS_OUTPUT
{
    float4 RGBColor : COLOR0; // Pixel color
};
 
struct LightSource
{
    float4 position;
    float4 diffuse;
    float4 specular;
};
 
sampler2D diffusemap;
sampler2D specularmap;
sampler2D normalmap;
sampler2D emitmap;
 
//float4 color;
 
float3x3 cotangent_frame(float3 N, float3 p, float2 uv)
{   
    // get edge vectors of the pixel triangle   
    float3 dp1 = ddx(p);    
    float3 dp2 = ddy(p);    
    float3 duv1 = ddx(float3(uv, 0));   
    float3 duv2 = ddy(float3(uv, 0));
 
    // solve the linear system  
    float3 dp2perp = cross(dp2, N); 
    float3 dp1perp = cross(N, dp1); 
    float3 T = dp2perp * duv1.x + dp1perp * duv2.x; 
    float3 B = dp2perp * duv1.y + dp1perp * duv2.y;
 
    // construct a scale-invariant frame    
    float invmax = rsqrt(max(dot(T,T), dot(B,B)));
    
    return float3x3(T * invmax, B * invmax, N);
}
// assume N, the interpolated vertex normal and V, the view vector (eye to vertex)
float3 perturb_normal(float3 N, float3 V, float2 texcoord)
{
    
// the normalmap pixels are in [0,1] interval, we needs [-1, 1]
    float3 map = tex2D(normalmap, texcoord).xyz*2 -1;
    #ifdef WITH_NORMALMAP_UNSIGNED
        map = map * 255./127. - 128./127.;
    #endif  
    #ifdef WITH_NORMALMAP_2CHANNEL
        map.z = sqrt(1. - dot(map.xy, map.xy));
    #endif
    #ifdef WITH_NORMALMAP_GREEN_UP
        map.y = -map.y;
    #endif
    float3x3 TBN = cotangent_frame(N, V, texcoord);
    
    //return normalize(TBN * map);
    return normalize(mul(map, TBN));
}
 
LightSource gl_LightSource[MAX_LIGHTS];
float LightCount;
 
float4 pixelMain(   float3 Normal  : COLOR0, 
                    float2 TexCoord : TEXCOORD0,
                    float4 wPosition : TEXCOORD1,
                    float4 vPosition : TEXCOORD2) :COLOR
{
    PS_OUTPUT Output;
    float4 diffuse = float4(0,0,0,0);
    float4 specular = float4(0,0,0,0);
    
    float4 color = float4(1.0, 1.0, 1.0, 1.0);
    
    #ifdef WITH_NORMALMAP
        float3 n = perturb_normal(Normal, wPosition, TexCoord);
        #define NORMAL n
    #else
        #define NORMAL Normal
    #endif
    float3 lv;
    float quadraticAttenuation;
    for (int i=0; i<LightCount; i++)
    {
        //Divide by 5 to give lights more range
        lv = (float3)((gl_LightSource[i].position - wPosition) / 5);
    
        quadraticAttenuation = 1 / pow(length(lv), 2);
        // max() is used to disallow negative values (that makes an other light at opposed direction)
        diffuse += max(0, dot(normalize(lv), NORMAL))
                   * quadraticAttenuation * gl_LightSource[i].diffuse;
        // changing 8 value changes the scale of the specular effect, there is currently a problem by replacing it by gl_FrontMaterial.shininess (shininess is to 0)
        specular += pow(max(0, dot(normalize(lv), normalize(reflect(wPosition, NORMAL)))), SHININESS) 
                    * quadraticAttenuation * gl_LightSource[i].specular;
    }
    Output.RGBColor = (
            diffuse  * tex2D(diffusemap,  TexCoord)
          + specular * tex2D(specularmap, TexCoord)
        ) + tex2D(emitmap, TexCoord) * color;
        
    return Output.RGBColor;
}
 
TheMormegil
Posts: 3
Joined: Wed Mar 21, 2018 4:47 pm

Re: material shader: Phong, fake reflect, bloom

Post by TheMormegil »

I'm very new to shaders so I'm probably doing stupid things
This was the problem, I have it working pretty well now. Thanks to OP for the original.
Post Reply