I have to make shaders in GLSL, I'm using OpenTK, and I'm writing in C# Windows Forms.
And i have some problems with using this shaders in my GLControl
this is my vertex shader
attribute vec3 tangent;
attribute vec3 binormal;
varying vec3 position;
varying vec3 lightvec;
void main()
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
position = gl_Vertex.xyz;
mat3 TBNMatrix = mat3(tangent, binormal, gl_Normal);
lightvec = gl_LightSource[0].position.xyz - position;
lightvec *= TBNMatrix;
}
and this is my fragment shader
uniform sampler2D base;
uniform sampler2D normalMap;
uniform vec3 CAMERA_POSITION;
varying vec3 position;
varying vec3 lightvec;
void main()
{
vec3 norm = texture2D(normalMap, gl_TexCoord[0].st).rgb * 2.0 - 1.0;
vec3 baseColor = texture2D(base, gl_TexCoord[0].st).rgb;
float dist = length(lightvec);
vec3 lightVector = normalize(lightvec);
float nxDir = max(0.0, dot(norm, lightVector));
vec4 diffuse = gl_LightSource[0].diffuse * nxDir;
float specularPower = 0.0;
if(nxDir != 0.0)
{
vec3 cameraVector = normalize(CAMERA_POSITION - position.xyz);
vec3 halfVector = normalize(lightVector + cameraVector);
float nxHalf = max(0.0,dot(norm, halfVector));
specularPower = pow(nxHalf, gl_FrontMaterial.shininess);
}
vec4 specular = gl_LightSource[0].specular * specularPower;
gl_FragColor = gl_LightSource[0].ambient +
(diffuse * vec4(baseColor.rgb,1.0)) +
specular;
}
Should i use GL.Uniform()? I don't know how to use this shaders...
Related
Ill try to rotate object in openGL (using OpenTK framework), but he rotate around zero point. Its logicly that object rotating around center, but i dont known how shoud hes rotating aroud itself center (or other point)
public static void Texture(Region region, float x, float y, float z, float rotateX, float rotateY, float rotateZ)
=> Texture(
region,
Matrix4.CreateTranslation(x, y, z),
Matrix4.CreateRotationX(rotateX) * Matrix4.CreateRotationY(rotateY) * Matrix4.CreateRotationZ(rotateZ),
TestGame.Camera.GetViewMatrix(),
TestGame.Camera.GetProjectionMatrix()
);
public static void Texture(Region region, Matrix4 translate, Matrix4 model, Matrix4 view, Matrix4 projection)
{
Shaders.TextureShader.Texture(TextureUnit.Texture0); //Bind texture as 0 in shader
region.Reference.Use(); //Bind texture as 0
Shaders.TextureShader.Matrix4("translate", translate);
Shaders.TextureShader.Matrix4("model", model);
Shaders.TextureShader.Matrix4("view", view);
Shaders.TextureShader.Matrix4("projection", projection);
Shaders.TextureShader.Draw();
}
#version 330 core
layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec2 aTexCoord;
out vec2 texCoord;
uniform mat4 translate;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(void)
{
texCoord = aTexCoord;
gl_Position = vec4(aPosition, 1) * translate * model * view * projection;
}
Matrix multiplications are not Commutative, the order mattes. Rotate the object before translating it:
gl_Position = vec4(aPosition, 1) * translate * model * view * projection;
gl_Position = vec4(aPosition, 1) * model * translate * view * projection;
You can find the shader code below. I did this as an "image effect shader" in Unity. Then I apply it to my camera along with the C# script (below the shader). Looks great on desktop but on Android it just makes the screen black. I'm probably using something that doesn't work on Android, maybe someone could point me in the right direction for fixing it?
//#<!--
//# CRT-simple shader
//#
//# Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader.
//#
//# Modified by fontmas: 2015-03-06
//#
//# This program is free software; you can redistribute it and/or modify it
//# under the terms of the GNU General Public License as published by the Free
//# Software Foundation; either version 2 of the License, or (at your option)
//# any later version.
//# -->
Shader "Custom/CRT"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
#define CURVATURE
#pragma target 3.0
#define PI 3.141592653589
uniform sampler2D _MainTex;
uniform float2 _InputSize;
uniform float2 _OutputSize;
uniform float2 _TextureSize;
uniform float2 _One;
uniform float2 _Texcoord;
uniform float _Factor;
uniform float _Distortion = 0.1f; // 0.1f
uniform float _Gamma = 1.0f; // 1.0f
uniform float _curvatureSet1 = 0.5f; // 0.5f
uniform float _curvatureSet2 = 0.5f; // 0.5f
uniform float _YExtra = 0.5f; // 0.5f;
uniform float _rgb1R = 1.0f; // 1.0f
uniform float _rgb1G = 1.0f; // 1.0f
uniform float _rgb1B = 1.0f; // 1.0f
uniform float _rgb2R = 1.0f; // 1.0f
uniform float _rgb2G = 1.0f; // 1.0f
uniform float _rgb2B = 1.0f; // 1.0f
uniform float _dotWeight = 2.0f; // 2.0f
float2 RadialDistortion(float2 coord)
{
coord *= _TextureSize / _InputSize;
float2 cc = coord - _curvatureSet1;
float dist = dot(cc, cc) * _Distortion;
return (coord + cc * (_curvatureSet2 + dist) * dist) * _InputSize / _TextureSize;
}
float4 ScanlineWeights(float distance, float4 color)
{
float4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f));
float4 weights = float4(distance / 0.5f, distance / 0.5f, distance / 0.5f, distance / 0.5f);
return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.3f + 0.2f * width);
}
float4 frag(v2f_img i) : COLOR
{
_Texcoord = i.uv;
_One = 1.0f / _TextureSize;
_OutputSize = _TextureSize;
_InputSize = _TextureSize;
_Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x;
//float4 ScreenGamma = pow(tex2D(_MainTex, _Texcoord), _Gamma);
#ifdef CURVATURE
float2 xy = RadialDistortion(_Texcoord);
#else
float2 xy = _Texcoord;
#endif
float2 ratio = xy * _TextureSize - float2(0.5f, 0.5f);
float2 uvratio = frac(ratio);
xy.y = (floor(ratio.y) + _YExtra) / _TextureSize;
float4 col = tex2D(_MainTex, xy);
float4 col2 = tex2D(_MainTex, xy + float2(0.0f, _One.y));
float4 weights = ScanlineWeights(uvratio.y, col);
float4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2);
float3 res = (col * weights + col2 * weights2).rgb;
float3 rgb1 = float3(_rgb1R, _rgb1G, _rgb1B);
float3 rgb2 = float3(_rgb2R, _rgb2G, _rgb2B);
float3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, _dotWeight)));
res *= dotMaskWeights;
return float4(pow(res, float3(1.0f / _Gamma, 1.0f / _Gamma, 1.0f / _Gamma)), 1.0f);
//return float4(pow(res, float3(1.0f / ScreenGamma.x, 1.0f / ScreenGamma.y, 1.0f / ScreenGamma.z)), 1.0f);
}
ENDCG
}
}
}
using UnityEngine;
using System.Collections;
public enum CRTScanLinesSizes { S32 = 32, S64 = 64, S128 = 128, S256 = 256, S512 = 512, S1024 = 1024 };
[ExecuteInEditMode]
public class CRT : MonoBehaviour
{
#region Variables
public Shader curShader;
public float Distortion = 0.1f;
public float Gamma = 1.0f;
public float YExtra = 0.5f;
public float CurvatureSet1 = 0.5f;
public float CurvatureSet2 = 1.0f;
public float DotWeight = 1.0f;
public CRTScanLinesSizes scanSize = CRTScanLinesSizes.S512;
public Color rgb1 = Color.white;
public Color rgb2 = Color.white;
private Material curMaterial;
#endregion
#region Properties
Material material
{
get
{
if (curMaterial == null)
{
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return curMaterial;
}
}
#endregion
// Use this for initialization
void Start()
{
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
}
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if (curShader != null)
{
material.SetFloat("_Distortion", Distortion);
material.SetFloat("_Gamma", Gamma);
material.SetFloat("_curvatureSet1", CurvatureSet1);
material.SetFloat("_curvatureSet2", CurvatureSet2);
material.SetFloat("_YExtra", YExtra);
material.SetFloat("_rgb1R", rgb1.r);
material.SetFloat("_rgb1G", rgb1.g);
material.SetFloat("_rgb1B", rgb1.b);
material.SetFloat("_rgb2R", rgb2.r);
material.SetFloat("_rgb2G", rgb2.g);
material.SetFloat("_rgb2B", rgb2.b);
material.SetFloat("_dotWeight", DotWeight);
material.SetVector("_TextureSize", new Vector2((float)scanSize, (float)scanSize));
Graphics.Blit(sourceTexture, destTexture, material);
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
// Update is called once per frame
void Update()
{
}
void OnDisable()
{
if (curMaterial)
{
DestroyImmediate(curMaterial);
}
}
}
Might be the RenderTexture, change the depth buffer to 0, if you create the RenderTexture in Unity do it like this:
rt = new RenderTexture(*width*, *height*, 0, RenderTextureFormat.ARGB32);
if you create the RenderTexture in Unity set "Depth Buffer" to "No depth buffer",
if changing the depth doesn't have any impact it could also be Graphics.Blit().
I want to show selected area from second half of an image (This is the range from 0.5 to 1.0) in my glcontrol. For that I have used two variables rightsliderStartval(any value between 0.5 and 1.0)
and rightsliderEndval(any value between 1.0 and 0.5). I want exactly the selected area between this rightsliderStartval and rightsliderEndval. When trying like below selected area is getting but it get stretched.
decimal RateOfResolution = (decimal)videoSource.VideoResolution.FrameSize.Width / (decimal)videoSource.VideoResolution.FrameSize.Height;
int openGLwidth = (this._Screenwidth / 3) - 40;
int openGLheight = Convert.ToInt32(screenWidthbyThree / RateOfResolution);
glControl.Width = openGLwidth;
glControl.Height = openGLheight;
GL.Viewport(new Rectangle(0, 0, glControl.Width, glControl.Height));
public void CreateShaders()
{
/***********Vert Shader********************/
vertShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertShader, #"attribute vec3 a_position;
varying vec2 vTexCoordIn;
void main() {
vTexCoordIn=( a_position.xy+1)/2 ;
gl_Position = vec4(a_position,1);
}");
GL.CompileShader(vertShader);
/***********Frag Shader ****************/
fragShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragShader, #"precision highp float;
uniform sampler2D sTexture;
varying vec2 vTexCoordIn;
void main ()
{
vec2 vTexCoord=vec2(vTexCoordIn.x,vTexCoordIn.y);
float rightsliderStartval=0.6;//0.5 to 1.0
float rightsliderEndval=0.8;//1.0 to 0.5
float rightsliderDelta=rightsliderEndval-rightsliderStartval;
if (vTexCoordIn.x < 0.5)
discard;
float u = mix(rightsliderStartval, rightsliderEndval, (vTexCoordIn.x-0.5) * 2.0);
vec4 color = texture2D(sTexture, vec2(u, vTexCoordIn.y));
gl_FragColor = color;
}");
GL.CompileShader(fragShader);
}
In Screenshot, White line represent center of image. I Want to show area between yellow and orange line.
If you want to skip a some parts of the texture, then you can use the discard keyword. This command causes the fragment's output values to be discarded and the fragments are not drawn at all.
If you've a rectangular area and you want to draw only in the 2nd half of the rectangular area, then you've to discard the fragments in the 1st half:
if (vTexCoordIn.x < 0.5)
discard;
If you want to draw the range from rightsliderStartval to rightsliderEndval in the 2nd half of the rectangular area, then you have to map the rang [0.5, 1.0] incoming texture coordinate vTexCoordIn.x to [rightsliderStartval, rightsliderEndval]:
float w = (vTexCoordIn.x-0.5) * 2.0; // [0.5, 1.0] -> [0.0, 1.0]
float u = mix(rightsliderStartval, rightsliderEndval, w); // [0.0, 1.0] -> [0.7, 0.9]
This leads to the fragment shader:
precision highp float;
uniform sampler2D sTexture;
varying vec2 vTexCoordIn;
void main ()
{
float rightsliderStartval = 0.7;
float rightsliderEndval = 0.9;
if (vTexCoordIn.x < 0.5)
discard;
float u = mix(rightsliderStartval, rightsliderEndval, (vTexCoordIn.x-0.5) * 2.0);
vec4 color = texture2D(sTexture, vec2(u, vTexCoordIn.y));
gl_FragColor = color;
}
If you don't want that the image is stretched then you've 2 possibilities.
Either discard the region from 0.0 to 0.7 and 0.9 to 1.0:
precision highp float;
uniform sampler2D sTexture;
varying vec2 vTexCoordIn;
void main ()
{
float rightsliderStartval = 0.7;
float rightsliderEndval = 0.9;
if (vTexCoordIn.x < 0.7 || vTexCoordIn.x > 0.9)
discard;
vec4 color = texture2D(sTexture, vTexCoordIn.xy));
gl_FragColor = color;
}
Or scale the image in the y direction, too:
precision highp float;
uniform sampler2D sTexture;
varying vec2 vTexCoordIn;
void main ()
{
float rightsliderStartval = 0.7;
float rightsliderEndval = 0.9;
if (vTexCoordIn.x < 0.5)
discard;
float u = mix(rightsliderStartval, rightsliderEndval, (vTexCoordIn.x-0.5) * 2.0);
float v_scale = (rightsliderEndval - rightsliderStartval) / 0.5;
float v = vTexCoordIn.y * v_scale + (1.0 - v_scale) / 2.0;;
vec4 color = texture2D(sTexture, vec2(u, v));
gl_FragColor = color;
}
I am currently building a test scene with shaders.
Here is my Vertext Shader code:
public const string VertexShaderText = #"
#version 130
in vec3 vertexPosition;
in vec3 vertexNormal;
in vec3 vertexTangent;
in vec2 vertexUV;
uniform vec3 light_direction;
out vec3 normal;
out vec2 uv;
out vec3 light;
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
uniform bool enable_mapping;
void main(void)
{
normal = normalize((model_matrix * vec4(floor(vertexNormal), 0)).xyz);
uv = vertexUV;
mat3 tbnMatrix = mat3(vertexTangent, cross(vertexTangent, normal), normal);
light = (enable_mapping ? light_direction * tbnMatrix : light_direction);
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";
Here is my Fragment Shader:
public const string FragmentShaderText = #"
#version 130
uniform sampler2D colorTexture;
uniform sampler2D normalTexture;
uniform bool enableToggleLighting;
uniform mat4 model_matrix;
uniform bool enable_mapping;
uniform float alpha;
uniform float ambi;
in vec3 normal;
in vec2 uv;
in vec3 light;
out vec4 fragment;
void main(void)
{
vec3 fragmentNormal = texture2D(normalTexture, uv).xyz * 2 - 1;
vec3 selectedNormal = (enable_mapping ? fragmentNormal : normal);
float diffuse = max(dot(selectedNormal, light), 0);
float ambient = ambi;
float lighting = (enableToggleLighting ? max(diffuse, ambient) : 1);
fragment = vec4(lighting * texture2D(colorTexture, uv).xyz, alpha);
}
";
My Project is initialized like this:
CanvasControlSettings.ShaderProgram.Use();
CanvasControlSettings.ShaderProgram["projection_matrix"].SetValue(mainSceneProj);
CanvasControlSettings.ShaderProgram["light_direction"].SetValue(new Vector3(0f, 0f, 1f));
CanvasControlSettings.ShaderProgram["enableToggleLighting"].SetValue(CanvasControlSettings.ToggleLighting);
CanvasControlSettings.ShaderProgram["normalTexture"].SetValue(1);
CanvasControlSettings.ShaderProgram["enable_mapping"].SetValue(CanvasControlSettings.ToggleNormalMapping);
My rotation moves the camera around the object. I want to move the light position along with the camera so that the shading is always visible.
How can I send the Camera Pos to the shader and implement this ?
From the front:
Rotated:
EDIT:
I Updated the Camera Position after rotate like this:
GL.Light(LightName.Light0, LightParameter.Position, new float[] { CanvasControlSettings.Camera.Position.X, CanvasControlSettings.Camera.Position.Y, CanvasControlSettings.Camera.Position.Z, 0.0f } );
And changed the light line to this
light = gl_LightSource[0].position.xyz;
This almost works perfectly accept that the material light color is now way to bright! I would show pictures but it seems I need more rep.
EDIT:
Ok, after following provided links, I found my way. I changed the Vertex Shader light code to:
vec4 lightPos4 = vec4(gl_LightSource[0].position.xyz, 1.0);
vec4 pos4 = model_matrix * vec4(vertexPosition, 1.0);
light = normalize((lightPos4 - pos4).xyz);
Works perfectly now. Thanks
You don't need to send the camera position to your shader. Just change your lights position to the camera position and send your light to your shader.
I am getting the error "Unable to find an entry point named 'glCreateShader' in DLL 'opengl32.dll'." Does anyone know what could be causing these errors? Here is the class that is causing the error
class PixelBlocks
{
private static ShaderProgram program;
public static void generateBlock(ref objStructs.Block Block)
{
Texture blockTex = Block.Texture;
VBO<Vector3> square;
VBO<int> elements;
float Scale = clientInfo.curScale;
Matrix4 trans;
Matrix4 SclFct;
program = new ShaderProgram(VertexShader, FragmentShader);
program.Use();
program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)Program.width / Program.height, 0.1f, 1000f));
program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 10), Vector3.Zero, Vector3.Up));
program["light_direction"].SetValue(new Vector3(0, 0, 1));
program["enable_lighting"].SetValue(Program.lighting);
square = new VBO<Vector3>(new Vector3[] {
new Vector3(-1, 1, 0),
new Vector3(1, 1, 0),
new Vector3(1, -1, 0),
new Vector3(-1, -1, 0) });
elements = new VBO<int>(new int[] { 0, 1, 2, 3 }, BufferTarget.ElementArrayBuffer);
trans = Matrix4.CreateTranslation(new Vector3(Block.Blk.x, Block.Blk.y, 0));
SclFct = Matrix4.CreateScaling(new Vector3(Scale, Scale, 0f));
Block.corners = square;
Block.elements = elements;
Block.trans = trans;
Block.Scale = SclFct;
}
public static bool drawBlocks(objStructs.Block[] Blocks)
{
for(int i = 0; i < Blocks.Length; i++)
{
try
{
Gl.UseProgram(program);
// set up the model matrix and draw the cube
program["model_matrix"].SetValue(Blocks[i].trans * Blocks[i].Scale);
Gl.BindBufferToShaderAttribute(Blocks[i].corners, program, "vertexPosition");
Gl.BindBuffer(Blocks[i].elements);
#pragma warning disable CS0618 // Type or member is obsolete
Gl.DrawElements(BeginMode.Quads, Blocks[i].elements.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
#pragma warning restore CS0618 // Type or member is obsolete
}
catch(Exception e)
{
Console.WriteLine(e);
return false;
}
}
return true;
}
public static string VertexShader = #"
#version 130
in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexUV;
out vec3 normal;
out vec2 uv;
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(void)
{
normal = normalize((model_matrix * vec4(floor(vertexNormal), 0)).xyz);
uv = vertexUV;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";
public static string FragmentShader = #"
#version 130
uniform sampler2D texture;
uniform vec3 light_direction;
uniform bool enable_lighting;
in vec3 normal;
in vec2 uv;
out vec4 fragment;
void main(void)
{
float diffuse = max(dot(normal, light_direction), 0);
float ambient = 0.3;
float lighting = (enable_lighting ? max(diffuse, ambient) : 1);
fragment = lighting * texture2D(texture, uv);
}
";
}
I know that's a lot of code but I don't what is causing this error.
I am using this library: https://github.com/giawa/opengl4csharp which is why it's not like any other questions
Graphics: Intel Iris Pro Graphics Experimental Version and Recommended Version both Tried
Processor: Intel i5
IDE: Visual Studio 2015 Community