/// <summary> /// Constructor to create a new ShaderBuilder instance. /// </summary> /// <param name="type">The shader type to generate the source for</param> /// <param name="twoDimensional">If true, some helper code for two dimensional shaders will be included</param> /// <param name="parent">Previous shader in the pipeline (if any)</param> public ShaderBuilder(ShaderType type, bool twoDimensional, ShaderBuilder parent = null) { Type = type; _twoDimensional = twoDimensional; // Prepare an empty list of OpenGL extensions _extensions = new List<String>(); // Set up variable lists _uniforms = new List<ShaderVariable>(); _attribs = new List<ShaderVariable>(); _varyings = new List<ShaderVariable>(); if (type == ShaderType.VertexShader && twoDimensional) { AddUniform(ShaderVarType.Vec2, "screen_resolution"); } // If the builder is given a parent, copy any outputs // from that shader as inputs for this one if (parent != null) { foreach (var vary in parent._varyings) { AddVarying(vary.Type, vary.Identifier); } } Logic = ""; // Default fragment colour output variable identifier FragOutIdentifier = "out_colour"; }
public DepthClipShader() { ShaderBuilder vert = new ShaderBuilder(ShaderType.VertexShader, false); vert.AddUniform(ShaderVarType.Mat4, "vp_matrix"); vert.AddUniform(ShaderVarType.Mat4, "transform"); vert.AddAttribute(ShaderVarType.Vec3, "in_vertex"); vert.Logic = @" void main(void) { gl_Position = vp_matrix * (transform * vec4(in_vertex, 1.0)); } "; ShaderBuilder frag = new ShaderBuilder(ShaderType.FragmentShader, false, vert); frag.Logic = @" void main(void) { out_colour = vec4(0.0, 0.0, 0.0, 0.0); } "; VertexSource = vert.Generate(GL3); FragmentSource = frag.Generate(GL3); BeginMode = BeginMode.Triangles; Create(); }
protected override void OnAddShaderLogic(ShaderBuilder frag) { frag.Logic = @" float diff(float a, float b) { float d = b - a; if (d < -0.5) return d + 1.0; if (d >= 0.5) return d - 1.0; return d; } void main(void) { vec2 diff = vec2(diff(depression.x, tex_pos.x), diff(depression.y, tex_pos.y)); float dist = length(diff) * 128.0; if (dist < 1.0) { float scale = min(1.0, (1.0 - dist) * depression.z); float cur = texture2D(velocitymap, tex_pos).a; float mag = max(cur - scale, 0.5 - scale); out_colour = vec4(mag, mag, mag, mag); } else { discard; } } "; }
protected WaterEffectShader() { ShaderBuilder vert = new ShaderBuilder(ShaderType.VertexShader, true); vert.AddAttribute(ShaderVarType.Vec2, "in_position"); vert.AddVarying(ShaderVarType.Vec2, "tex_pos"); vert.AddUniform(ShaderVarType.Int, "resolution"); vert.Logic = @" void main( void ) { tex_pos = in_position.xy * vec2(1.0, -1.0) / resolution; gl_Position = in_position; } "; ShaderBuilder frag = new ShaderBuilder(ShaderType.FragmentShader, true, vert); OnAddShaderVariables(frag); OnAddShaderLogic(frag); VertexSource = vert.Generate(GL3); FragmentSource = frag.Generate(GL3); BeginMode = BeginMode.Quads; Create(); SetScreenSize(Water.Resolution, Water.Resolution); _bounds = new float[] { 0f, 0f, Water.Resolution, 0f, Water.Resolution, Water.Resolution, 0f, Water.Resolution }; }
public SkyShader() { ShaderBuilder vert = new ShaderBuilder(ShaderType.VertexShader, false); vert.AddUniform(ShaderVarType.Mat4, "vp_matrix"); vert.AddAttribute(ShaderVarType.Vec3, "in_vertex"); vert.AddVarying(ShaderVarType.Vec3, "var_texcoord"); vert.Logic = @" void main(void) { vec4 pos = vp_matrix * vec4(in_vertex, 0.0); gl_Position = pos.xyww; var_texcoord = in_vertex; } "; ShaderBuilder frag = new ShaderBuilder(ShaderType.FragmentShader, false, vert); frag.AddUniform(ShaderVarType.SamplerCube, "skybox"); frag.Logic = @" void main(void) { out_colour = textureCube(skybox, var_texcoord); out_colour += (vec4(0.0, 0.0, 0.0, 1.0) - out_colour) * max(0.0, -var_texcoord.y); } "; VertexSource = vert.Generate(GL3); FragmentSource = frag.Generate(GL3); BeginMode = BeginMode.Quads; Create(); }
protected override void OnAddShaderLogic(ShaderBuilder frag) { frag.Logic = @" void main(void) { const ivec2 offsets[] = ivec2[8] ( ivec2(-1, -1), ivec2( 0, -1), ivec2( 1, -1), ivec2(-1, 0), ivec2( 1, 0), ivec2(-1, 1), ivec2( 0, 1), ivec2( 1, 1) ); const float weights[] = float[8] ( 0.707, 1.0, 0.707, 1.0, 1.0, 0.707, 1.0, 0.707 ); float cur = texture2D(heightmap, tex_pos).a; float avg = (0.5 + textureOffset(heightmap, tex_pos, offsets[0]).a * weights[0] + textureOffset(heightmap, tex_pos, offsets[1]).a * weights[1] + textureOffset(heightmap, tex_pos, offsets[2]).a * weights[2] + textureOffset(heightmap, tex_pos, offsets[3]).a * weights[3] + textureOffset(heightmap, tex_pos, offsets[4]).a * weights[4] + textureOffset(heightmap, tex_pos, offsets[5]).a * weights[5] + textureOffset(heightmap, tex_pos, offsets[6]).a * weights[6] + textureOffset(heightmap, tex_pos, offsets[7]).a * weights[7]) / 7.828; float new = min(1.0, max(0.0, texture2D(velocitymap, tex_pos).a + (avg - cur) * 1.0)) * 0.996; out_colour = vec4(new, new, new, new); } "; }
protected override void OnAddShaderLogic(ShaderBuilder frag) { frag.Logic = @" void main(void) { float cur = texture2D(heightmap, tex_pos).a; float vel = (texture2D(velocitymap, tex_pos).a - 0.5) / 8.0; float new = cur + vel; out_colour = vec4(new, new, new, new); } "; }
protected override void OnAddShaderLogic(ShaderBuilder frag) { frag.Logic = @" void main(void) { const ivec2 offsets[] = ivec2[8] ( ivec2(-1, -1), ivec2( 0, -1), ivec2( 1, -1), ivec2(-1, 0), ivec2( 1, 0), ivec2(-1, 1), ivec2( 0, 1), ivec2( 1, 1) ); const float weights[] = float[8] ( 0.707, 1.0, 0.707, 1.0, 1.0, 0.707, 1.0, 0.707 ); float cur = texture2D(spraymap, tex_pos).a; float mx = max( max( max( textureOffset(spraymap, tex_pos, offsets[0]).a * weights[0], textureOffset(spraymap, tex_pos, offsets[1]).a * weights[1] ), max( textureOffset(spraymap, tex_pos, offsets[2]).a * weights[2], textureOffset(spraymap, tex_pos, offsets[3]).a * weights[3] ) ), max( max( textureOffset(spraymap, tex_pos, offsets[4]).a * weights[4], textureOffset(spraymap, tex_pos, offsets[5]).a * weights[5] ), max( textureOffset(spraymap, tex_pos, offsets[6]).a * weights[6], textureOffset(spraymap, tex_pos, offsets[7]).a * weights[7] ) ) ); float vel = pow(abs(texture2D(velocitymap, tex_pos).a - 0.5), 2.5); float new = min(1.0, cur + max((mx - cur) * 0.75, 0.0) + vel) * 0.99; out_colour = vec4(new, new, new, new); } "; }
public ModelShader() { ShaderBuilder vert = new ShaderBuilder(ShaderType.VertexShader, false); vert.AddUniform(ShaderVarType.Mat4, "vp_matrix"); vert.AddUniform(ShaderVarType.Mat4, "transform"); vert.AddAttribute(ShaderVarType.Vec3, "in_vertex"); vert.AddAttribute(ShaderVarType.Vec2, "in_textuv"); vert.AddAttribute(ShaderVarType.Vec3, "in_normal"); vert.AddVarying(ShaderVarType.Vec3, "var_normal"); vert.AddVarying(ShaderVarType.Vec2, "var_textuv"); vert.Logic = @" void main(void) { var_normal = (transform * vec4(in_normal, 0.0)).xyz; var_textuv = in_textuv; gl_Position = vp_matrix * (transform * vec4(in_vertex, 1.0)); } "; ShaderBuilder frag = new ShaderBuilder(ShaderType.FragmentShader, false, vert); frag.AddUniform(ShaderVarType.Vec4, "colour"); frag.AddUniform(ShaderVarType.Sampler2D, "tex"); frag.AddUniform(ShaderVarType.Vec3, "view_vector"); frag.AddUniform(ShaderVarType.Vec3, "light_vector"); frag.AddUniform(ShaderVarType.Float, "shinyness"); frag.Logic = @" void main(void) { out_colour = vec4(colour.rgb * texture2D(tex, var_textuv + vec2(0.5, 0.5)).rgb * (dot(-light_vector, var_normal) * 0.5 + 0.5), colour.a); if (shinyness > 0.0) { out_colour = vec4(out_colour.rgb + (vec3(1.0, 1.0, 1.0) - out_colour.rgb) * 0.5 * pow(max(0.0, dot(reflect(-light_vector, var_normal), view_vector)), shinyness), out_colour.a); } } "; VertexSource = vert.Generate(GL3); FragmentSource = frag.Generate(GL3); BeginMode = BeginMode.Triangles; Create(); }
protected override void OnAddShaderVariables(ShaderBuilder frag) { base.OnAddShaderVariables(frag); frag.AddUniform(ShaderVarType.Vec3, "depression"); }
public WaterShader() { ShaderBuilder vert = new ShaderBuilder(ShaderType.VertexShader, false); vert.AddUniform(ShaderVarType.Mat4, "vp_matrix"); vert.AddUniform(ShaderVarType.Vec3, "view_origin"); vert.AddUniform(ShaderVarType.Vec3, "view_vector"); vert.AddUniform(ShaderVarType.Sampler2D, "heightmap"); vert.AddAttribute(ShaderVarType.Vec2, "in_vertex"); vert.AddVarying(ShaderVarType.Float, "var_height"); vert.AddVarying(ShaderVarType.Float, "var_scale"); vert.AddVarying(ShaderVarType.Vec3, "var_position"); vert.AddVarying(ShaderVarType.Vec2, "var_texpos"); vert.Logic = @" void main(void) { const float size = 512.0; float rot = -atan(view_vector.z, view_vector.x); mat2 rmat = mat2(cos(rot), -sin(rot), sin(rot), cos(rot)); var_scale = max(0.0, 2.0 - max(1.0, length(in_vertex * size) / 48.0)); vec2 offset = rmat * (in_vertex * size) + view_origin.xz; var_texpos = offset / 128.0 + vec2(0.5, 0.5); var_height = texture2D(heightmap, var_texpos).a * 2.0 * var_scale; vec4 pos = vec4(offset.x, var_height - 1.0, offset.y, 1.0); var_position = pos.xyz; gl_Position = vp_matrix * pos; } "; ShaderBuilder frag = new ShaderBuilder(ShaderType.FragmentShader, false, vert); frag.AddUniform(ShaderVarType.Sampler2D, "heightmap"); frag.AddUniform(ShaderVarType.Sampler2D, "ripplemap"); frag.AddUniform(ShaderVarType.Sampler2D, "spraymap"); frag.AddUniform(ShaderVarType.SamplerCube, "skybox"); frag.AddUniform(ShaderVarType.Vec4, "colour"); frag.AddUniform(ShaderVarType.Vec3, "view_origin"); frag.AddUniform(ShaderVarType.Vec3, "light_vector"); frag.Logic = @" void main(void) { float l = textureOffset(heightmap, var_texpos, ivec2(-1, 0 )).a; float t = textureOffset(heightmap, var_texpos, ivec2( 0, -1 )).a; float r = textureOffset(heightmap, var_texpos, ivec2( 1, 0 )).a; float b = textureOffset(heightmap, var_texpos, ivec2( 0, 1 )).a; vec3 horz = normalize(vec3(0.0, (r - l) * 2.0 * var_scale, 1.0)); vec3 vert = normalize(vec3(1.0, (b - t) * 2.0 * var_scale, 0.0)); vec3 normal = cross(horz, vert); vec3 cam_dir = normalize(var_position - view_origin); vec3 reflected = normalize(reflect(cam_dir, normal)); out_colour = vec4(colour.rgb * max(0.0, dot(light_vector, normal)), colour.a); out_colour += vec4((textureCube(skybox, reflected).rgb - out_colour.rgb) * 0.5, 0.0); if (var_scale > 0.0) { float ripple = texture2D(ripplemap, (var_texpos * 8.0) + normal.xz * 0.125).a; float spray = texture2D(spraymap, var_texpos).a; if (ripple * pow(spray, 2.0) > 0.75) { out_colour += spray * 0.75 * (vec4(1.0, 1.0, 1.0, 1.0) - out_colour) * var_scale; } } } "; VertexSource = vert.Generate(GL3); FragmentSource = frag.Generate(GL3); BeginMode = BeginMode.Quads; Create(); }
protected virtual void OnAddShaderVariables(ShaderBuilder frag) { frag.AddUniform(ShaderVarType.Sampler2D, "heightmap"); frag.AddUniform(ShaderVarType.Sampler2D, "velocitymap"); frag.AddUniform(ShaderVarType.Sampler2D, "spraymap"); }
protected virtual void OnAddShaderLogic(ShaderBuilder frag) { frag.Logic = "void main(void) { discard; }"; }