Jump to content
  • Advertisement
Vivid3DDev

OpenGL Screen-Space-Reflections - OpenGL/Glsl - Any tips/help?

Recommended Posts

Hey,

I've got it working almost, but there are several morphing artifacts. it retains it's overall integrity as I move the camera around, so I assume the data is correct, but still these artifacts get worse or better depending on angle.

And also I removed any of the code that causes to mix well, so the reflection is just full bright, so the artifacts are more easily visible.

Any ideas what I could change to fix it? Here is the shader, mostly based on yours congard, but changed to work for my engine.

#version 330 core

//in vec2 UV;

out vec3 color;

uniform mat4 proj,view;




uniform sampler2D tFrame;
uniform sampler2D tNorm;
uniform sampler2D tPos;

in vec2 UV;

uniform vec3 ssr_skyColor = vec3(0.0);
uniform int ssr_binarySearchCount = 10;
uniform int ssr_rayMarchCount = 30; // 60
uniform float ssr_step = 0.05; // 0.025
uniform float ssr_LLimiter = 0.1;
uniform float ssr_minRayStep = 0.2;


#define getPosition(UV) texture(tPos, UV).xyz

vec2 binarySearch(inout vec3 dir, inout vec3 hitCoord, inout float dDepth) {
    float depth;

    vec4 projectedCoord;
 
    for(int i = 0; i < ssr_binarySearchCount; i++) {
        projectedCoord = proj * vec4(hitCoord, 1.0);
        projectedCoord.xy /= projectedCoord.w;
        projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
 
        depth = getPosition(projectedCoord.xy).z;
 
        dDepth = hitCoord.z - depth;

        dir *= 0.5;
        if(dDepth > 0.0)
            hitCoord += dir;
        else
            hitCoord -= dir;    
    }

    projectedCoord = proj * vec4(hitCoord, 1.0);
    projectedCoord.xy /= projectedCoord.w;
    projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
 
    return vec2(projectedCoord.xy);
}


vec2 rayCast(vec3 dir, inout vec3 hitCoord, out float dDepth) {
    dir *= ssr_step;
    
    for (int i = 0; i < ssr_rayMarchCount; i++) {
        hitCoord += dir;

        vec4 projectedCoord = proj * vec4(hitCoord, 1.0);
        projectedCoord.xy /= projectedCoord.w;
        projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5; 

        float depth = getPosition(projectedCoord.xy).z;
        dDepth = hitCoord.z - depth;

        if((dir.z - dDepth) < 1.2 && dDepth <= 0.0) return binarySearch(dir, hitCoord, dDepth);
    }

    return vec2(-1.0);
}

#define scale vec3(.8, .8, .8)
#define k 19.19

vec3 hash(vec3 a) {
    a = fract(a * scale);
    a += dot(a, a.yxz + k);
    return fract((a.xxy + a.yxx)*a.zyx);
}

#define fresnelExp 5.0

float fresnel(vec3 direction, vec3 normal) {
    vec3 halfDirection = normalize(normal + direction);
    
    float cosine = dot(halfDirection, direction);
    float product = max(cosine, 0.0);
    float factor = 1.0 - pow(product, fresnelExp);
    
    return factor;
}


void main(){

    float reflectionStrength = 0.7f;

    vec3 normal = texture(tNorm, UV).xyz;
    vec3 viewPos = getPosition(UV);

    vec3 worldPos = vec3(vec4(viewPos, 1.0) * inverse(view));
//    vec3 jitt = hash(worldPos) * texture(ssrValuesMap, texCoord).g;


    // Reflection vector
    vec3 reflected = normalize(reflect(normalize(viewPos), normalize(normal)));

    // Ray cast
    vec3 hitPos = viewPos;
    float dDepth; 
    vec2 coords = rayCast(reflected * max(-viewPos.z, ssr_minRayStep), hitPos, dDepth);

    float L = length(getPosition(coords) - viewPos);
    L = clamp(L * ssr_LLimiter, 0, 1);
    float error = 1 - L;

    float fresnel = fresnel(reflected, normal);
    
    vec3 fc = texture(tFrame, coords.xy).rgb;// * error * fresnel;

    // fragColor = vec3(fresnel);
    // return;

    if (coords.xy != vec2(-1.0)) {
        color = fc;
       return;
    }


    color = texture(tFrame,UV).rgb*2;



}

 

reflectError1.jpg

Share this post


Link to post
Share on other sites
Advertisement

Do not forget that screen space effects are solid information lost. The artifacts are really strange. How exactly do you "set up" textures (ie, what format, GL_RGB16/32F or something else?)? Also try to increase ssr_rayMarchCount and ssr_binarySearchCount, reduce ssr_step. Experience shows that these values should change depending on the complexity of your scene. And in general, I think that cubemap reflections or planar reflections would be good for such a scene since there are a lot of "lower" parts

Share this post


Link to post
Share on other sites

Yeah I understand that but the engine is a part of a unity like ide, so it's just a nice feature that can be turned on/off(I.e not specific to the above scene)

And yeah here is a bunch of code that you might see the problem in?

This is the framebuffer(Rendertarget) and yeah I use RGB16f for both normal and position map. the color map is just normal rgb.

  public class FrameBufferColor
    {
        public int FBO = 0;
        public Texture2D BB;
        public TextureDepth DB;
        public int IW, IH;
        public int DRB = 0;

        public FrameBufferColor ( int w, int h,TextureFormat format = TextureFormat.Normal)
        {
            IW = w;
            IH = h;
            FBO = GL.GenFramebuffer ( );
            GL.BindFramebuffer ( FramebufferTarget.Framebuffer, FBO );
            BB = new Texture2D ( w, h, false,format );
            DB = new TextureDepth ( w, h );
            DRB = GL.GenRenderbuffer ( );
            GL.BindRenderbuffer ( RenderbufferTarget.Renderbuffer, DRB );
            GL.RenderbufferStorage ( RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent, w, h );
            GL.FramebufferRenderbuffer ( FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, DRB );
            GL.FramebufferTexture ( FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, BB.ID, 0 );
            DrawBuffersEnum db = DrawBuffersEnum.ColorAttachment0;
            GL.DrawBuffers ( 1, ref db );
            if ( GL.CheckFramebufferStatus ( FramebufferTarget.Framebuffer ) != FramebufferErrorCode.FramebufferComplete )
            {
                Console.WriteLine ( "Framebuffer failure." );
              
            }
            Console.WriteLine ( "Framebuffer success." );
            GL.BindFramebuffer ( FramebufferTarget.Framebuffer, 0 );
            GL.BindRenderbuffer ( RenderbufferTarget.Renderbuffer, 0 );
        }

        public void Bind ( )
        {
            GL.BindFramebuffer ( FramebufferTarget.Framebuffer, FBO );
            GL.Viewport ( 0, 0, IW, IH );
            AppInfo.RW = IW;
            AppInfo.RH = IH;
            GL.ClearColor ( 0, 0, 0, 0 );
            GL.Clear ( ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit );
        }
        public void BindFree()
        {
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO);
            GL.ClearColor(0, 0, 0, 0);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
        }
        public void ReleaseFree()
        {
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
        }
        public void Release ( )
        {
            GL.BindFramebuffer ( FramebufferTarget.Framebuffer, 0 );
            GL.Viewport ( 0, 0, AppInfo.W, AppInfo.H );
            AppInfo.RW = AppInfo.W;
            AppInfo.RH = AppInfo.H;
        }
    }

 

Here is the class that is used to create the effect.

    public class SSRCompositer : Compositer
    {

        public SSRCompositer() : base(3)
        {

            Name = "SSRPP";

            InputFrame = new FrameTypes.FrameColor();

            Types[1] = new FrameTypes.FramePositionMap();



            Types[0] = new FrameTypes.FrameNormalMap();


            Types[2] = new FrameTypes.FrameEffect();

            dynamic f2 = Types[2];

            f2.FX = new VESSR();
            

            Types[2].TexBind.Add(InputFrame);
            Types[2].TexBind.Add(Types[0]);
            Types[2].TexBind.Add(Types[1]);

            OutputFrame = Types[2];
            Blend = FrameBlend.Solid;

        }
        
    }

    public class VESSR : Effect.Effect3D
    {
        public float Blur = 0.5f;

        public VESSR() : base("", "data/Shader/vsSSR.glsl", "data/Shader/fsSSR.glsl")
        {
        }

        public override void SetPars()
        {

            //          SetMat("pMatrix", Scene.SceneGraph3D.LastCam.ProjMat);
            //            SetMat("InvPMatrix", Scene.SceneGraph3D.LastCam.ProjMat.Inverted());
     
            SetMat("proj", Scene.SceneGraph3D.LastCam.ProjMat);

            SetMat("view", Scene.SceneGraph3D.LastCam.CamWorld);


            SetTex("tFrame", 0);
            SetTex("tNorm", 1);
            SetTex("tPos", 2);

        }
    }

As you can see, it renders the normal layer, then position, then color, then passes it to the SSR effect/shader. which has proj/view unjiforms, and the 3 textures.

Here is the normal shaders that generate the normal buffers.

-Vertex
#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTexCoords;
layout(location = 2) in vec3 aNormal;
layout(location = 3) in vec3 aBiTangent;
layout(location = 4) in vec3 aTangent;

// Values that stay constant for the whole mesh.
uniform mat4 view;
uniform mat4 model;
uniform mat4 proj;
uniform mat4 view2;



out vec3 fVert;
out vec3 fNorm;

void main(){

	
	fVert = vec3(model * vec4(aPos,1.0));


	mat4 normalMatrix = view * model;
    	vec3 N = vec3(normalize(normalMatrix * vec4(aNormal,0.0)));
    fNorm = N;


		gl_Position = proj * view * model* vec4(aPos,1.0);

	
}

-Fragment

#version 330 core

uniform mat4 model;
uniform vec3 camP;
uniform float minZ;
uniform float maxZ;




in vec3 fVert;
in vec3 fNorm;

// Ouput data
out vec3 color;

void main(){
 


    color = fNorm;
}

Here is the position map generator.

-vertex

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTexCoords;
layout(location = 2) in vec3 aNormal;
layout(location = 3) in vec3 aBiTangent;
layout(location = 4) in vec3 aTangent;

// Values that stay constant for the whole mesh.
uniform mat4 view;
uniform mat4 model;
uniform mat4 proj;



out vec3 fVert;
out vec3 fNorm;

void main(){

	
     mat4 tMat = view * model;

     vec3 fP = vec3(tMat * vec4(aPos,1.0));

    fVert = fP;


		gl_Position = proj * view * model* vec4(aPos,1.0);

	
}

-fragment

#version 330 core

uniform mat4 model;
uniform vec3 camP;
uniform float minZ;
uniform float maxZ;




in vec3 fVert;
in vec3 fNorm;

// Ouput data
out vec3 color;

void main(){
 
 

    color = fVert;
}

 

And here is the SSR shader. mostly based on yours with a few changes.

-vertex

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vP;

// Output data ; will be interpolated for each fragment.
out vec2 UV;

void main(){
	gl_Position =  vec4(vP,1);
	UV = (vP.xy+vec2(1,1))/2.0;
}

-fragment
  
#version 330 core

//in vec2 UV;

out vec3 color;

uniform mat4 proj,view;




uniform sampler2D tFrame;
uniform sampler2D tNorm;
uniform sampler2D tPos;

in vec2 UV;


uniform vec3 ssr_skyColor = vec3(0.0);
uniform int ssr_binarySearchCount = 10;
uniform int ssr_rayMarchCount = 30; // 60
uniform float ssr_step = 0.05; // 0.025
uniform float ssr_LLimiter = 0.1;
uniform float ssr_minRayStep = 0.2;

uniform vec3 bloom_vecThreshold = vec3(0.2126, 0.7152, 0.0722);
uniform float bloom_brightnessThreshold = 0.3;



#define getPosition(UV) texture(tPos, UV).xyz

vec2 binarySearch(inout vec3 dir, inout vec3 hitCoord, inout float dDepth) {
    float depth;

    vec4 projectedCoord;
 
    for(int i = 0; i < ssr_binarySearchCount; i++) {
        projectedCoord = proj * vec4(hitCoord, 1.0);
        projectedCoord.xy /= projectedCoord.w;
        projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
 
        depth = getPosition(projectedCoord.xy).z;
 
        dDepth = hitCoord.z - depth;

        dir *= 0.5;
        if(dDepth > 0.0)
            hitCoord += dir;
        else
            hitCoord -= dir;    
    }

    projectedCoord = proj * vec4(hitCoord, 1.0);
    projectedCoord.xy /= projectedCoord.w;
    projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
 
    return vec2(projectedCoord.xy);
}

vec2 rayCast(vec3 dir, inout vec3 hitCoord, out float dDepth) {
    dir *= ssr_step;
    
    for (int i = 0; i < ssr_rayMarchCount; i++) {
        hitCoord += dir;

        vec4 projectedCoord = proj* vec4(hitCoord, 1.0);
        projectedCoord.xy /= projectedCoord.w;
        projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5; 

        float depth = getPosition(projectedCoord.xy).z;
        dDepth = hitCoord.z - depth;

        if((dir.z - dDepth) < 1.2 && dDepth <= 0.0) return binarySearch(dir, hitCoord, dDepth);
    }

    return vec2(-1.0);
}

#define scale vec3(.8, .8, .8)
#define k 19.19

vec3 hash(vec3 a) {
    a = fract(a * scale);
    a += dot(a, a.yxz + k);
    return fract((a.xxy + a.yxx)*a.zyx);
}

// source: https://www.standardabweichung.de/code/javascript/webgl-glsl-fresnel-schlick-approximation
#define fresnelExp 5.0

float fresnel(vec3 direction, vec3 normal) {
    vec3 halfDirection = normalize(normal + direction);
    
    float cosine = dot(halfDirection, direction);
    float product = max(cosine, 0.0);
    float factor = 1.0 - pow(product, fresnelExp);
    
    return factor;
}




void main(){

    float reflectionStrength = 0.7f;

    vec3 normal = vec3(texture(tNorm, UV));
    vec3 viewPos = getPosition(UV);

    vec3 worldPos = vec3(vec4(viewPos, 1.0) * inverse(view));
//    vec3 jitt = hash(worldPos) * texture(ssrValuesMap, texCoord).g;


    // Reflection vector
    vec3 reflected = normalize(reflect(normalize(viewPos), normalize(normal)));

    float spec = 0.7;

   vec3 hitPos = viewPos;
    float dDepth; 
    vec2 coords = rayCast(reflected * max(-viewPos.z, ssr_minRayStep), hitPos, dDepth);

    float L = length(getPosition(coords) - viewPos);
    L = clamp(L * ssr_LLimiter, 0, 1);
    float error = 1 - L;

    float fresnel = fresnel(reflected, normal);
    
    vec3 c2 = texture(tFrame, coords.xy).rgb;// * error * fresnel;

    // fragColor = vec3(fresnel);
    // return;
    vec3 fragCol = vec3(0.0);

    if (coords.xy != vec2(-1.0)) {
        fragCol = c2;
        color = fragCol;
        return;
    }
    
    fragCol = mix(texture(tFrame, UV), vec4(ssr_skyColor, 1.0), reflectionStrength).rgb;



    color = texture(tFrame,UV).rgb;



}
  

Just in case, here is the texture code.

    public enum LoadMethod
    {
        Single, Multi
    }

    public enum TextureFormat
    {
        Normal,RGB16F,RGB32F
    }

    public class Texture2D : TextureBase
    {
        public static Dictionary<string, Texture2D> Lut = new Dictionary<string, Texture2D>();
        public static byte[] TmpStore = null;
        public bool Alpha = false;
        public bool Binded = false;
        public bool Loaded = false;
        public Mutex LoadMutex = new Mutex();
        public Thread LoadThread = null;
        public byte[] pixs = null;
        public byte[] RawData;
        public Bitmap TexData = null;
        private readonly bool PreLoaded = false;
        private FileStream nf;

        private BinaryReader nr;

        public Texture2D ( int w, int h, bool alpha = false )
        {
            GenTex ( w, h, alpha );
        }

        public Texture2D( int w,int h, bool alpha,TextureFormat format)
        {

            GenTex(w, h, alpha, format);

        }

        public Texture2D ( )
        {
        }

        public Texture2D ( int w, int h, byte [ ] dat, bool alpha = true )
        {
            GL.ActiveTexture ( TextureUnit.Texture0 );
            Alpha = alpha;
            W = w;
            H = h;
            ID = GL.GenTexture ( );
            GL.BindTexture ( TextureTarget.Texture2D, ID );
            if ( alpha )
            {
                GL.TexImage2D ( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, w, h, 0, PixelFormat.Rgba, PixelType.UnsignedByte, dat );
            }
            else
            {
                GL.TexImage2D ( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, w, h, 0, PixelFormat.Rgb, PixelType.UnsignedByte, dat );
            }
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ( int ) TextureWrapMode.Repeat );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ( int ) TextureWrapMode.Repeat );

            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ( int ) TextureMinFilter.LinearMipmapLinear );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ( int ) TextureMagFilter.Linear );
            GL.GenerateMipmap ( GenerateMipmapTarget.Texture2D );
            GL.PixelStore ( PixelStoreParameter.PackAlignment, 4 * 4 );
            pixs = dat;
        }
        public bool smallDone = false, bigDone = false;
        public static List<Texture2D> LoadingTexs = new List<Texture2D>();
        //public Thread LoadThread = null;
        //public Mutex LoadMutex = null;
        public int sW, sH;
        public int bW, bH;
        int wS = 0;
        public static void UpdateLoading()
        {
            foreach(var tex in LoadingTexs)
            {
                if (tex.smallDone)
                {
                    if (!tex.bigDone)
                    {
                        GL.Enable(EnableCap.Texture2D);
                        GL.BindTexture(TextureTarget.Texture2D, tex.ID);

                        if (tex.Alpha) 
                        {
                            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, tex.sW, tex.sH, 0, PixelFormat.Rgba, PixelType.UnsignedByte, tex.SmallRawData);
                        }
                        else
                        {
                            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, tex.sW, tex.sH, 0, PixelFormat.Rgb, PixelType.UnsignedByte, tex.SmallRawData);
                        }

                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                    //    GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

                        GL.BindTexture(TextureTarget.Texture2D, 0);
                    }
                    tex.smallDone = false;
                }
             
                if (tex.bigDone)
                {
                  

                    GL.Enable(EnableCap.Texture2D);
                    GL.BindTexture(TextureTarget.Texture2D, tex.ID);

                    if (tex.Alpha)
                    {
                        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, tex.bW, tex.bH, 0, PixelFormat.Rgba, PixelType.UnsignedByte, tex.RawData);
                    }
                    else
                    {
                        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, tex.bW, tex.bH, 0, PixelFormat.Rgb, PixelType.UnsignedByte, tex.RawData);
                    }

                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                    GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
                    tex.bigDone = true;
                    GL.BindTexture(TextureTarget.Texture2D, 0);
                    LoadingTexs.Remove(tex);
                    return;
                }

            }
        }
        public byte[] SmallRawData;
        public Texture2D ( string path, LoadMethod lm, bool alpha = true )
        {
            if ( File.Exists ( path ) == false )
            {
                return;
            }
            if ( path == string.Empty || path == "" || path == null )
            {
                return;
            }
            Path = path;

           


            GL.Enable ( EnableCap.Texture2D );
            ID = GL.GenTexture ( );

            GL.BindTexture ( TextureTarget.Texture2D, ID );

            if ( new FileInfo ( path + ".texDat" ).Exists )
            {


                void Load_Tex()
                {
                    SmallRawData = LoadTexData(path + ".texDatSmall");
                    sW = W;
                    sH = H;
                    smallDone = true;
                    RawData = LoadTexData(path + ".texDat");
                    bW = W;
                    bH = H;
                    bigDone = true;
                }

                LoadingTexs.Add(this);

                LoadThread = new Thread(new ThreadStart(Load_Tex));

                LoadThread.Start();

            }
            else
            {



                Bitmap img = null;
                try
                {
                    img = new Bitmap(path);
                    //System.Drawing.Imaging.BitmapData dat = img.LockBits( new Rectangle(0, 0, img.Width, img.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.);
                }
                catch
                {
                    img = new Bitmap(32, 32);
                }
                W = img.Width;
                H = img.Height;
                Alpha = alpha;

                int pc = 3;
                if (Alpha)
                {
                    pc = 4;
                }
                Bitmap small_img = new Bitmap(img, new Size(img.Width / 4, img.Height / 4));

                pc = WriteDat(path, alpha, small_img, pc, true, small_img.Width, small_img.Height);

                pc = WriteDat(path, alpha, img, pc, false,W, H);

                GL.BindTexture(TextureTarget.Texture2D,ID);

                if (Alpha)
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, W, H, 0, PixelFormat.Rgba, PixelType.UnsignedByte, RawData);
                }
                else
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, W, H, 0, PixelFormat.Rgb, PixelType.UnsignedByte, RawData);
                }

                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                //    GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

                GL.BindTexture(TextureTarget.Texture2D, 0);

            }

          
        }

        private byte[] LoadTexData(string lTex)
        {
            FileStream fs = new FileStream(lTex, FileMode.Open, FileAccess.Read);
            BinaryReader r = new BinaryReader(fs);
            Name = r.ReadString();
            Path = r.ReadString();
            W = r.ReadInt16();
            H = r.ReadInt16();
            Alpha = r.ReadBoolean();
            int pc = 3;
            if (Alpha)
            {
                pc = 4;
            }




            byte[] LData = new byte[W * H * (Alpha ? 4 : 3)];
            r.Read(LData, 0,W*H*(Alpha ? 4 : 3));

            

            fs.Close();
            fs = null;

            return LData;
        }

        private int WriteDat(string path, bool alpha, Bitmap img, int pc,bool small,int ow,int oh)
        {
            RawData = new byte[ow * oh * pc];

            //GL.TexImage2D(TextureTarget.Texture2D,0,PixelInternalFormat.)

            int pi = 0;
            for (int y = 0; y < img.Height; y++)
            {
                for (int x = 0; x < img.Width; x++)
                {
                    Color pix = img.GetPixel(x, y);
                    RawData[pi++] = pix.R;
                    RawData[pi++] = pix.G;
                    RawData[pi++] = pix.B;
                    if (alpha)
                    {
                        RawData[pi++] = pix.A;
                    }
                }
            }


            FileStream fs;
            if (small)
            {
                fs = new FileStream(path + ".texDatSmall", FileMode.Create, FileAccess.Write);
            }
            else
            {
                fs = new FileStream(path + ".texDat", FileMode.Create, FileAccess.Write);
            }

            BinaryWriter w = new BinaryWriter(fs);
            if (Name == null || Name == string.Empty)
            {
                Name = "Tex2D";
            }
            w.Write(Name);
            w.Write(Path);
            w.Write((short)ow);
            w.Write((short)oh);
            w.Write(Alpha);
            pc = 3;
            if (alpha)
            {
                pc = 4;
            }


            w.Write(RawData,0,RawData.Length);
            fs.Flush();
            fs.Close();
            fs = null;
            return pc;
        }

        ~Texture2D ( )
        {
            //NewMethod();
        }

        public string Name
        {
            get;
            set;
        }

        public string Path
        {
            get;
            set;
        }

        public override void Bind ( int texu )
        {
            GL.Enable ( EnableCap.Texture2D );
            GL.ActiveTexture ( ( TextureUnit ) ( ( int ) TextureUnit.Texture0 + texu ) );
            // GL.ClientActiveTexture((TextureUnit)((int)TextureUnit.Texture0 + texu));
            GL.BindTexture ( TextureTarget.Texture2D, ID );
        }

        public void BindData ( )
        {
            GL.Enable ( EnableCap.Texture2D );
            ID = GL.GenTexture ( );
            GL.BindTexture ( TextureTarget.Texture2D, ID );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ( int ) TextureWrapMode.Repeat );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ( int ) TextureWrapMode.Repeat );

            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ( int ) TextureMinFilter.LinearMipmapLinear );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ( int ) TextureMagFilter.Linear );
            GL.GenerateMipmap ( GenerateMipmapTarget.Texture2D );
            GL.PixelStore ( PixelStoreParameter.PackAlignment, 4 * 4 );
            GL.TexImage2D ( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, W, H, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixs );
            GL.Disable ( EnableCap.Texture2D );
        }

        public void CopyTex ( int x, int y )
        {
            GL.Enable ( EnableCap.Texture2D );
            GL.ActiveTexture ( TextureUnit.Texture0 );
            GL.BindTexture ( TextureTarget.Texture2D, ID );
            GL.CopyTexSubImage2D ( TextureTarget.Texture2D, 0, 0, 0, x, y, W, H );
            GL.BindTexture ( TextureTarget.Texture2D, 0 );
        }

        public void Delete ( )
        {
            GL.DeleteTexture ( ID );
        }

        public Texture2D ( TextureRaw raw )
        {
            RawData = raw.Data;
            Alpha = raw.Alpha;
            W = raw.W;
            H = raw.H;

            GL.Enable ( EnableCap.Texture2D );
            ID = GL.GenTexture ( );

            GL.BindTexture ( TextureTarget.Texture2D, ID );

            if ( Alpha )
            {
                GL.TexImage2D ( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, W, H, 0, PixelFormat.Rgba, PixelType.UnsignedByte, RawData );
            }
            else
            {
                GL.TexImage2D ( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, W, H, 0, PixelFormat.Rgb, PixelType.UnsignedByte, RawData );
            }

            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ( int ) TextureWrapMode.ClampToEdge );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ( int ) TextureWrapMode.ClampToEdge );

            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ( int ) TextureMinFilter.Linear );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ( int ) TextureMagFilter.Linear );
            // GL.GenerateMipmap ( GenerateMipmapTarget.Texture2D );

            GL.BindTexture ( TextureTarget.Texture2D, 0 );
        }

        public void Read ( )
        {
            W = Help.IOHelp.ReadInt ( );
            H = Help.IOHelp.ReadInt ( );
            Alpha = Help.IOHelp.ReadBool ( );
            RawData = Help.IOHelp.ReadBytes ( );
            // GL.ActiveTexture(TextureUnit.Texture0);

            GL.Enable ( EnableCap.Texture2D );
            ID = GL.GenTexture ( );

            GL.BindTexture ( TextureTarget.Texture2D, ID );

            if ( Alpha )
            {
                GL.TexImage2D ( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, W, H, 0, PixelFormat.Rgba, PixelType.UnsignedByte, RawData );
            }
            else
            {
                GL.TexImage2D ( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, W, H, 0, PixelFormat.Rgb, PixelType.UnsignedByte, RawData );
            }

            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ( int ) TextureWrapMode.Repeat );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ( int ) TextureWrapMode.Repeat );

            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ( int ) TextureMinFilter.LinearMipmapLinear );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ( int ) TextureMagFilter.Linear );
            GL.GenerateMipmap ( GenerateMipmapTarget.Texture2D );

            GL.BindTexture ( TextureTarget.Texture2D, 0 );
        }

        public void ReadBitmap ( BinaryReader r )
        {
            short bw = r.ReadInt16();
            short bh = r.ReadInt16();
            TexData = new Bitmap ( bw, bh );
            pixs = r.ReadBytes ( bw * bh * 4 );
            W = bw;
            H = bh;
            Alpha = true;
            return;
            for ( int y = 0; y < bh; y++ )
            {
                for ( int x = 0; x < bw; x++ )
                {
                    byte[] col = r.ReadBytes(4);
                    System.Drawing.Color nc = System.Drawing.Color.FromArgb(col[3], col[0], col[1], col[2]);
                    TexData.SetPixel ( x, y, nc );
                }
            }
            W = bw;
            H = bh;
        }

        public override void Release ( int texu )
        {
            GL.ActiveTexture ( ( TextureUnit ) ( ( int ) TextureUnit.Texture0 + texu ) );
            // GL.ClientActiveTexture((TextureUnit)((int)TextureUnit.Texture0 + texu));
            GL.BindTexture ( TextureTarget.Texture2D, 0 );
            GL.Disable ( EnableCap.Texture2D );
        }

        public void SaveTex ( string p )
        {
            if ( string.IsNullOrEmpty ( p ) )
            {
                return;
            }
            if ( File.Exists ( p ) )
            {
                return;
            }

            FileStream fs = new FileStream(p, FileMode.Create, FileAccess.Write);
            BinaryWriter w = new BinaryWriter(fs);

            Bitmap sd = new Bitmap(TexData, 32, 32);
            WriteBitmap ( sd, w );
            WriteBitmap ( TexData, w );

            fs.Flush ( );
            fs.Close ( );
        }

        public void SetPix ( )
        {
            pixs = new byte [ W * H * 4 ];
            int loc = 0;
            for ( int y = 0; y < H; y++ )
            {
                for ( int x = 0; x < W; x++ )
                {
                    Color p = TexData.GetPixel(x, y);
                    pixs [ loc++ ] = p.R;
                    pixs [ loc++ ] = p.G;
                    pixs [ loc++ ] = p.B;
                    pixs [ loc++ ] = p.A;
                }
            }
        }

        public void SkipBitmap ( BinaryReader r )
        {
            short bw = r.ReadInt16();
            short bh = r.ReadInt16();
            r.BaseStream.Seek ( bw * bh * 4, SeekOrigin.Current );
        }

        public void T_LoadTex ( )
        {
            TexData = new Bitmap ( Path );

            W = TexData.Width;
            H = TexData.Height;
            D = 1;
            Alpha = true;
            SetPix ( );
            SaveTex ( Path + ".vtex" );
            Loaded = true;
        }

        public void T_LoadVTex ( )
        {
            ReadBitmap ( nr );

            //W = TexData.Width;
            //H = TexData.Height;
            D = 1;
            Alpha = true;
            //SetPix();
            //SaveTex(Path + ".vtex");
            Loaded = true;
            nf.Close ( );
            nf = null;
            nr = null;
        }

        public void Write ( )
        {
            Help.IOHelp.WriteInt ( W );
            Help.IOHelp.WriteInt ( H );
            Help.IOHelp.WriteBool ( Alpha );
            Help.IOHelp.WriteBytes ( RawData );
        }

        public void WriteBitmap ( Bitmap b, BinaryWriter w )
        {
            w.Write ( ( short ) b.Width );
            w.Write ( ( short ) b.Height );
            for ( int y = 0; y < b.Height; y++ )
            {
                for ( int x = 0; x < b.Width; x++ )
                {
                    Color p = b.GetPixel(x, y);
                    w.Write ( p.R );
                    w.Write ( p.G );
                    w.Write ( p.B );
                    w.Write ( p.A );
                }
            }
        }

        private void GenTex(int w, int h, bool alpha, TextureFormat format = TextureFormat.Normal)
        {
            GL.ActiveTexture(TextureUnit.Texture0);
            Alpha = alpha;
            W = w;
            H = h;
            ID = GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, ID);
            if (alpha)
            {
                switch (format)
                {
                    case TextureFormat.Normal:
                        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, w, h, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
                        break;

                }
            }

            else
            {
                switch (format) {
                    case TextureFormat.Normal:
                        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, w, h, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
                        break;
                    case TextureFormat.RGB16F:
                        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb16f, w, h, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
                        break;
                }
            } 
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ( int ) TextureWrapMode.Repeat );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ( int ) TextureWrapMode.Repeat );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ( int ) TextureMinFilter.Nearest );
            GL.TexParameter ( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ( int ) TextureMagFilter.Nearest );
            GL.PixelStore ( PixelStoreParameter.PackAlignment, 4 * 4 );
        }
    }

Pls let me know if I've missed something. - 

 

And just to clarify I did try changing the constants in your shader, and it does help, but I can't quite get it working overall, i.e in any sort of scene. the more complex room like scenes I try on, have even more artifacts than above. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!