| … | 120 unchanged lines hidden | ||
| 121 | 121 | Shader_Format :: enum { | |
| 122 | 122 | SPIRV, | |
| 123 | 123 | HLSL, | |
| 124 | + | GLSL, | |
| 124 | 125 | } | |
| 125 | 126 | ||
| 126 | 127 | Shader_Module_Desc :: struct { | |
| … | 348 unchanged lines hidden | ||
| … | 5 unchanged lines hidden | ||
| 6 | 6 | REQUIRED_SHADER_FORMAT :: Shader_Format.SPIRV | |
| 7 | 7 | } else when GPU_BACKEND == "d3d11" || GPU_BACKEND == "d3d12" { | |
| 8 | 8 | REQUIRED_SHADER_FORMAT :: Shader_Format.HLSL | |
| 9 | + | } else when GPU_BACKEND == "opengl" { | |
| 10 | + | REQUIRED_SHADER_FORMAT :: Shader_Format.GLSL | |
| 11 | + | } else { | |
| 12 | + | #assert(false, "unsupported GPU_BACKEND") | |
| 9 | 13 | } | |
Diff hidden because this file has more than 800 lines.
| … | 4 unchanged lines hidden | ||
| 5 | 5 | ||
| 6 | 6 | // GLSL 450 backend — emits from IR_Module | |
| 7 | 7 | ||
| 8 | + | Glsl_Flavor :: enum { | |
| 9 | + | Vulkan, | |
| 10 | + | OpenGL, | |
| 11 | + | } | |
| 12 | + | ||
| 13 | + | Glsl_Options :: struct { | |
| 14 | + | flavor: Glsl_Flavor, | |
| 15 | + | } | |
| 16 | + | ||
| 17 | + | GLSL_OPENGL_BINDINGS_PER_GROUP :: 16 | |
| 18 | + | GLSL_OPENGL_PUSH_CONSTANT_BINDING :: 15 | |
| 19 | + | ||
| 8 | 20 | Glsl_Emitter :: struct { | |
| 9 | 21 | w: Writer, | |
| 10 | 22 | module: ^IR_Module, | |
| 11 | 23 | current_fn: ^IR_Function, | |
| 12 | 24 | diagnostics: [dynamic]Diagnostic, | |
| 25 | + | flavor: Glsl_Flavor, | |
| 13 | 26 | } | |
| 14 | 27 | ||
| 15 | 28 | emit_glsl :: proc(module: ^IR_Module, allocator := context.allocator) -> (string, []Diagnostic) { | |
| 29 | + | return emit_glsl_with_options(module, {}, allocator) | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | emit_glsl_opengl :: proc(module: ^IR_Module, allocator := context.allocator) -> (string, []Diagnostic) { | |
| 33 | + | return emit_glsl_with_options(module, {flavor = .OpenGL}, allocator) | |
| 34 | + | } | |
| 35 | + | ||
| 36 | + | @(private = "file") | |
| 37 | + | emit_glsl_with_options :: proc(module: ^IR_Module, options: Glsl_Options, allocator := context.allocator) -> (string, []Diagnostic) { | |
| 16 | 38 | e := Glsl_Emitter{ | |
| 17 | 39 | w = writer_init(allocator), | |
| 18 | 40 | module = module, | |
| 19 | 41 | diagnostics = make([dynamic]Diagnostic, allocator), | |
| 42 | + | flavor = options.flavor, | |
| 20 | 43 | } | |
| 21 | 44 | ||
| 22 | 45 | write_line(&e.w, "#version 450") | |
| … | 1 unchanged lines hidden | ||
| 24 | 47 | ||
| 25 | 48 | // Specialization constants | |
| 26 | 49 | for &sc in module.spec_constants { | |
| 27 | - | // layout(constant_id = N) const type name = default; | |
| 28 | - | write_line(&e.w, "layout(constant_id = ", sc.spec_id, ") const ", resolved_type_to_glsl(sc.type), " ", sc.name, " = ", ir_const_value_to_string(sc.default_value), ";") | |
| 50 | + | if e.flavor == .OpenGL { | |
| 51 | + | write_line(&e.w, "const ", resolved_type_to_glsl(sc.type), " ", sc.name, " = ", ir_const_value_to_string(sc.default_value), ";") | |
| 52 | + | } else { | |
| 53 | + | // layout(constant_id = N) const type name = default; | |
| 54 | + | write_line(&e.w, "layout(constant_id = ", sc.spec_id, ") const ", resolved_type_to_glsl(sc.type), " ", sc.name, " = ", ir_const_value_to_string(sc.default_value), ";") | |
| 55 | + | } | |
| 29 | 56 | } | |
| 30 | 57 | if len(module.spec_constants) > 0 { | |
| 31 | 58 | write_line(&e.w, "") | |
| … | 31 unchanged lines hidden | ||
| 63 | 90 | emit_glsl_binding :: proc(e: ^Glsl_Emitter, b: ^IR_Binding) { | |
| 64 | 91 | switch b.kind { | |
| 65 | 92 | case .Texture: | |
| 66 | - | // GLSL 450 uses combined samplers — emit as sampler2D with the original name | |
| 67 | - | write_line(&e.w, "layout(set = ", b.group, ", binding = ", b.binding_num, ") uniform ", resolved_type_to_glsl(b.type), " ", b.combined_name, ";") | |
| 93 | + | if e.flavor == .OpenGL { | |
| 94 | + | binding := glsl_opengl_binding_point(b) | |
| 95 | + | write_line(&e.w, "layout(binding = ", binding, ") uniform ", resolved_type_to_glsl(b.type), " ", b.combined_name, ";") | |
| 96 | + | } else { | |
| 97 | + | // GLSL 450 uses combined samplers — emit as sampler2D with the original name | |
| 98 | + | write_line(&e.w, "layout(set = ", b.group, ", binding = ", b.binding_num, ") uniform ", resolved_type_to_glsl(b.type), " ", b.combined_name, ";") | |
| 99 | + | } | |
| 68 | 100 | case .Sampler: | |
| 69 | 101 | // Skip — already emitted by the Texture binding as a combined sampler | |
| 70 | 102 | return | |
| 71 | 103 | case .Uniform: | |
| 72 | - | write_line(&e.w, "layout(set = ", b.group, ", binding = ", b.binding_num, ") uniform ", b.name, "_Block {") | |
| 104 | + | if e.flavor == .OpenGL { | |
| 105 | + | binding := glsl_opengl_binding_point(b) | |
| 106 | + | if binding == GLSL_OPENGL_PUSH_CONSTANT_BINDING { | |
| 107 | + | append(&e.diagnostics, Diagnostic{level = .Error, message = fmt.aprintf("GLSL OpenGL: uniform binding for '%s' collides with reserved push-constant binding %d", b.name, GLSL_OPENGL_PUSH_CONSTANT_BINDING)}) | |
| 108 | + | } | |
| 109 | + | write_line(&e.w, "layout(std140, binding = ", binding, ") uniform ", b.name, "_Block {") | |
| 110 | + | } else { | |
| 111 | + | write_line(&e.w, "layout(set = ", b.group, ", binding = ", b.binding_num, ") uniform ", b.name, "_Block {") | |
| 112 | + | } | |
| 73 | 113 | indent(&e.w) | |
| 74 | 114 | if b.struct_ref != nil { | |
| 75 | 115 | for f in b.struct_ref.fields { | |
| … | 13 unchanged lines hidden | ||
| 89 | 129 | write_line(&e.w, "};") | |
| 90 | 130 | } | |
| 91 | 131 | case .Buffer: | |
| 92 | - | write_line(&e.w, "layout(set = ", b.group, ", binding = ", b.binding_num, ") buffer ", b.name, "_Block {") | |
| 132 | + | if e.flavor == .OpenGL { | |
| 133 | + | binding := glsl_opengl_binding_point(b) | |
| 134 | + | write_line(&e.w, "layout(std430, binding = ", binding, ") buffer ", b.name, "_Block {") | |
| 135 | + | } else { | |
| 136 | + | write_line(&e.w, "layout(set = ", b.group, ", binding = ", b.binding_num, ") buffer ", b.name, "_Block {") | |
| 137 | + | } | |
| 93 | 138 | if b.struct_ref != nil { | |
| 94 | 139 | indent(&e.w) | |
| 95 | 140 | for f in b.struct_ref.fields { | |
| … | 4 unchanged lines hidden | ||
| 100 | 145 | } | |
| 101 | 146 | write_line(&e.w, "} ", b.name, ";") | |
| 102 | 147 | case .Push_Constant: | |
| 103 | - | write_line(&e.w, "layout(push_constant) uniform ", b.name, "_Block {") | |
| 148 | + | if e.flavor == .OpenGL { | |
| 149 | + | write_line(&e.w, "layout(std140, binding = ", GLSL_OPENGL_PUSH_CONSTANT_BINDING, ") uniform ", b.name, "_Block {") | |
| 150 | + | } else { | |
| 151 | + | write_line(&e.w, "layout(push_constant) uniform ", b.name, "_Block {") | |
| 152 | + | } | |
| 104 | 153 | if b.struct_ref != nil { | |
| 105 | 154 | indent(&e.w) | |
| 106 | 155 | for f in b.struct_ref.fields { | |
| … | 118 unchanged lines hidden | ||
| 225 | 274 | io := fn.outputs[s.io_index] | |
| 226 | 275 | out_name: string | |
| 227 | 276 | if io.builtin != "" { | |
| 228 | - | out_name = builtin_to_glsl_variable(io.builtin, fn.stage, false) | |
| 277 | + | out_name = builtin_to_glsl_variable(io.builtin, fn.stage, false, e.flavor) | |
| 229 | 278 | } else { | |
| 230 | 279 | out_name = fmt.aprintf("out_%s", io.name) | |
| 231 | 280 | } | |
| … | 184 unchanged lines hidden | ||
| 416 | 465 | ||
| 417 | 466 | case ^IR_Builtin_Var: | |
| 418 | 467 | fn := e.current_fn | |
| 419 | - | write(&e.w, builtin_to_glsl_variable(d.name, fn != nil ? fn.stage : .None, d.is_input)) | |
| 468 | + | write(&e.w, builtin_to_glsl_variable(d.name, fn != nil ? fn.stage : .None, d.is_input, e.flavor)) | |
| 420 | 469 | ||
| 421 | 470 | case ^IR_Shared_Ref: | |
| 422 | 471 | write(&e.w, d.name) | |
| … | 33 unchanged lines hidden | ||
| 456 | 505 | return "?" | |
| 457 | 506 | } | |
| 458 | 507 | ||
| 459 | - | builtin_to_glsl_variable :: proc(name: string, stage: Shader_Stage, is_input: bool) -> string { | |
| 508 | + | builtin_to_glsl_variable :: proc(name: string, stage: Shader_Stage, is_input: bool, flavor: Glsl_Flavor = .Vulkan) -> string { | |
| 460 | 509 | switch name { | |
| 461 | 510 | case "position": | |
| 462 | 511 | if stage == .Vertex && !is_input do return "gl_Position" | |
| 463 | 512 | if stage == .Fragment && is_input do return "gl_FragCoord" | |
| 464 | 513 | return "gl_Position" | |
| 465 | 514 | case "vertex_id": | |
| 515 | + | if flavor == .OpenGL do return "gl_VertexID" | |
| 466 | 516 | return "gl_VertexIndex" | |
| 467 | 517 | case "instance_id": | |
| 518 | + | if flavor == .OpenGL do return "gl_InstanceID" | |
| 468 | 519 | return "gl_InstanceIndex" | |
| 469 | 520 | case "frag_coord": | |
| 470 | 521 | return "gl_FragCoord" | |
| … | 11 unchanged lines hidden | ||
| 482 | 533 | return name | |
| 483 | 534 | } | |
| 484 | 535 | ||
| 536 | + | glsl_opengl_binding_point :: proc(binding: ^IR_Binding) -> int { | |
| 537 | + | if binding == nil do return 0 | |
| 538 | + | return binding.group * GLSL_OPENGL_BINDINGS_PER_GROUP + binding.binding_num | |
| 539 | + | } | |
| 540 | + | ||
| 485 | 541 | builtin_to_glsl :: proc(name: string) -> string { | |
| 486 | 542 | switch name { | |
| 487 | 543 | case "sample": return "texture" | |
| … | 83 unchanged lines hidden | ||
| … | 6 unchanged lines hidden | ||
| 7 | 7 | ||
| 8 | 8 | Target :: enum { | |
| 9 | 9 | GLSL_450, | |
| 10 | + | GLSL_450_OPENGL, | |
| 10 | 11 | HLSL_SM6, | |
| 11 | 12 | MSL_2_4, | |
| 12 | 13 | WGSL, | |
| … | 173 unchanged lines hidden | ||
| 186 | 187 | str: string | |
| 187 | 188 | str, emit_diags = emit_glsl(&ir_module) | |
| 188 | 189 | output_bytes = transmute([]u8)str | |
| 190 | + | case .GLSL_450_OPENGL: | |
| 191 | + | str: string | |
| 192 | + | str, emit_diags = emit_glsl_opengl(&ir_module) | |
| 193 | + | output_bytes = transmute([]u8)str | |
| 189 | 194 | case .WGSL: | |
| 190 | 195 | str: string | |
| 191 | 196 | str, emit_diags = emit_wgsl(&ir_module) | |
| … | 302 unchanged lines hidden | ||
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(binding = 0) uniform sampler2D material_tex; | |
| 4 | + | ||
| 5 | + | layout(location = 0) in vec2 in_uv; | |
| 6 | + | layout(location = 1) in vec3 in_normal; | |
| 7 | + | layout(location = 0) out vec4 out__value; | |
| 8 | + | ||
| 9 | + | void main() { | |
| 10 | + | vec4 albedo = texture(material_tex, in_uv); | |
| 11 | + | vec3 n = normalize(in_normal); | |
| 12 | + | vec3 light_dir = normalize(vec3(1.0, 1.0, 0.5)); | |
| 13 | + | float light = max(dot(n, light_dir), 0.0); | |
| 14 | + | out__value = vec4((albedo.rgb * light), albedo.a); | |
| 15 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(std140, binding = 0) uniform uniforms_Block { | |
| 4 | + | mat4 model; | |
| 5 | + | mat4 view_proj; | |
| 6 | + | mat4 normal_mat; | |
| 7 | + | } uniforms; | |
| 8 | + | ||
| 9 | + | layout(location = 0) in vec3 in_position; | |
| 10 | + | layout(location = 1) in vec3 in_normal; | |
| 11 | + | layout(location = 2) in vec2 in_uv; | |
| 12 | + | layout(location = 0) out vec2 out_uv; | |
| 13 | + | layout(location = 1) out vec3 out_normal; | |
| 14 | + | ||
| 15 | + | void main() { | |
| 16 | + | vec3 pos = in_position; | |
| 17 | + | vec4 world_pos = (uniforms.model * vec4(pos, 1.0)); | |
| 18 | + | vec4 clip_pos = (uniforms.view_proj * world_pos); | |
| 19 | + | gl_Position = clip_pos; | |
| 20 | + | out_uv = in_uv; | |
| 21 | + | out_normal = normalize((uniforms.normal_mat * vec4(in_normal, 0.0)).xyz); | |
| 22 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | shared float scratch[64]; | |
| 4 | + | ||
| 5 | + | layout(std430, binding = 0) buffer params_Block { | |
| 6 | + | uint count; | |
| 7 | + | float scale; | |
| 8 | + | } params; | |
| 9 | + | layout(std430, binding = 1) buffer data_Block { | |
| 10 | + | float values[64]; | |
| 11 | + | } data; | |
| 12 | + | ||
| 13 | + | layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; | |
| 14 | + | ||
| 15 | + | void main() { | |
| 16 | + | uint idx = gl_LocalInvocationID.x; | |
| 17 | + | scratch[idx] = (data.values[idx] * params.scale); | |
| 18 | + | barrier(); | |
| 19 | + | if ((idx < 32)) { | |
| 20 | + | scratch[idx] = (scratch[idx] + scratch[(idx + 32)]); | |
| 21 | + | } | |
| 22 | + | barrier(); | |
| 23 | + | data.values[idx] = scratch[idx]; | |
| 24 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(binding = 0) uniform sampler2D albedo_tex; | |
| 4 | + | ||
| 5 | + | layout(location = 0) in vec2 in_uv; | |
| 6 | + | layout(location = 0) out vec4 out__value; | |
| 7 | + | ||
| 8 | + | void main() { | |
| 9 | + | vec4 color = texture(albedo_tex, in_uv); | |
| 10 | + | float dx = dFdx(color.r); | |
| 11 | + | float dy = dFdy(color.r); | |
| 12 | + | float fw = fwidth(color.r); | |
| 13 | + | float edge = step(0.1, fw); | |
| 14 | + | out__value = vec4((color.rgb * (1.0 - edge)), color.a); | |
| 15 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(binding = 0) uniform sampler2D albedo_tex; | |
| 4 | + | ||
| 5 | + | layout(location = 0) in vec2 in_uv; | |
| 6 | + | layout(location = 0) out vec4 out__value; | |
| 7 | + | ||
| 8 | + | void main() { | |
| 9 | + | vec4 color = texture(albedo_tex, in_uv); | |
| 10 | + | if ((color.a < 0.1)) { | |
| 11 | + | discard; | |
| 12 | + | } | |
| 13 | + | float bright = ((color.r > 0.5) ? 1.0 : 0.0); | |
| 14 | + | out__value = vec4((color.rgb * bright), color.a); | |
| 15 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(std140, binding = 0) uniform camera_Block { | |
| 4 | + | mat4 view_proj; | |
| 5 | + | vec3 position; | |
| 6 | + | } camera; | |
| 7 | + | layout(std140, binding = 1) uniform lighting_Block { | |
| 8 | + | vec3 direction; | |
| 9 | + | vec3 color; | |
| 10 | + | float intensity; | |
| 11 | + | } lighting; | |
| 12 | + | layout(binding = 16) uniform sampler2D diffuse_tex; | |
| 13 | + | layout(binding = 18) uniform sampler2D normal_tex; | |
| 14 | + | ||
| 15 | + | layout(location = 0) in vec2 in_uv; | |
| 16 | + | layout(location = 0) out vec4 out_color; | |
| 17 | + | ||
| 18 | + | void main() { | |
| 19 | + | vec4 diffuse = texture(diffuse_tex, in_uv); | |
| 20 | + | vec4 normal_sample = texture(normal_tex, in_uv); | |
| 21 | + | vec3 n = normalize(((normal_sample.xyz * 2.0) - vec3(1.0, 1.0, 1.0))); | |
| 22 | + | vec3 l = normalize(lighting.direction); | |
| 23 | + | float ndotl = max(dot(n, l), 0.0); | |
| 24 | + | vec3 lit = (((diffuse.rgb * lighting.color) * ndotl) * lighting.intensity); | |
| 25 | + | out_color = vec4(lit, diffuse.a); | |
| 26 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(binding = 0) uniform sampler2D material_tex; | |
| 4 | + | ||
| 5 | + | layout(location = 0) in vec2 in_uv; | |
| 6 | + | layout(location = 1) in vec3 in_normal; | |
| 7 | + | layout(location = 0) out vec4 out_color; | |
| 8 | + | ||
| 9 | + | void main() { | |
| 10 | + | vec4 albedo = texture(material_tex, in_uv); | |
| 11 | + | out_color = vec4(albedo.rgb, 1.0); | |
| 12 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(location = 0) in float in_value; | |
| 4 | + | layout(location = 0) out vec4 out__value; | |
| 5 | + | ||
| 6 | + | void main() { | |
| 7 | + | float result = 0.0; | |
| 8 | + | for (int i = 0; i <= 10; i++) { | |
| 9 | + | if (((i % 2) == 0)) { | |
| 10 | + | continue; | |
| 11 | + | } | |
| 12 | + | result = (result + float(i)); | |
| 13 | + | } | |
| 14 | + | float total = 0.0; | |
| 15 | + | for (int j = 0; j <= 100; j++) { | |
| 16 | + | if ((j > 5)) { | |
| 17 | + | break; | |
| 18 | + | } | |
| 19 | + | total = (total + 1.0); | |
| 20 | + | } | |
| 21 | + | int k = 0; | |
| 22 | + | while ((k < 100)) { | |
| 23 | + | if ((k > 10)) { | |
| 24 | + | break; | |
| 25 | + | } | |
| 26 | + | k = (k + 1); | |
| 27 | + | } | |
| 28 | + | float sum = 0.0; | |
| 29 | + | int m = 0; | |
| 30 | + | while ((m < 10)) { | |
| 31 | + | m = (m + 1); | |
| 32 | + | if ((m == 5)) { | |
| 33 | + | continue; | |
| 34 | + | } | |
| 35 | + | sum = (sum + 1.0); | |
| 36 | + | } | |
| 37 | + | out__value = vec4(((result + total) + sum), 0.0, 0.0, 1.0); | |
| 38 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(std140, binding = 0) uniform camera_Block { | |
| 4 | + | mat4 view_proj; | |
| 5 | + | vec3 position; | |
| 6 | + | } camera; | |
| 7 | + | layout(std140, binding = 1) uniform lighting_Block { | |
| 8 | + | vec3 direction; | |
| 9 | + | vec3 color; | |
| 10 | + | float intensity; | |
| 11 | + | } lighting; | |
| 12 | + | layout(binding = 16) uniform sampler2D diffuse_tex; | |
| 13 | + | layout(binding = 18) uniform sampler2D normal_tex; | |
| 14 | + | ||
| 15 | + | layout(location = 0) in vec2 in_uv; | |
| 16 | + | layout(location = 0) out vec4 out_color; | |
| 17 | + | ||
| 18 | + | void main() { | |
| 19 | + | vec4 diffuse = texture(diffuse_tex, in_uv); | |
| 20 | + | vec4 normal_sample = texture(normal_tex, in_uv); | |
| 21 | + | vec3 n = normalize(((normal_sample.xyz * 2.0) - vec3(1.0, 1.0, 1.0))); | |
| 22 | + | vec3 l = normalize(lighting.direction); | |
| 23 | + | float ndotl = max(dot(n, l), 0.0); | |
| 24 | + | vec3 lit = (((diffuse.rgb * lighting.color) * ndotl) * lighting.intensity); | |
| 25 | + | out_color = vec4(lit, diffuse.a); | |
| 26 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(std140, binding = 0) uniform material_Block { | |
| 4 | + | vec3 albedo; | |
| 5 | + | float metallic; | |
| 6 | + | float roughness; | |
| 7 | + | } material; | |
| 8 | + | layout(std140, binding = 1) uniform light_dir_Block { | |
| 9 | + | vec3 light_dir; | |
| 10 | + | }; | |
| 11 | + | layout(std140, binding = 2) uniform camera_pos_Block { | |
| 12 | + | vec3 camera_pos; | |
| 13 | + | }; | |
| 14 | + | layout(binding = 3) uniform sampler2D albedo_tex; | |
| 15 | + | ||
| 16 | + | vec3 fresnel_schlick(float cos_theta, vec3 f0) { | |
| 17 | + | return (f0 + ((vec3(1.0, 1.0, 1.0) - f0) * pow((1.0 - cos_theta), 5.0))); | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | vec3 compute_lighting(vec3 normal, vec3 view_dir, vec3 albedo) { | |
| 21 | + | vec3 n = normalize(normal); | |
| 22 | + | vec3 l = normalize(light_dir); | |
| 23 | + | vec3 h = normalize((l + view_dir)); | |
| 24 | + | float ndotl = max(dot(n, l), 0.0); | |
| 25 | + | float ndoth = max(dot(n, h), 0.0); | |
| 26 | + | vec3 f0 = mix(vec3(0.04, 0.04, 0.04), albedo, material.metallic); | |
| 27 | + | vec3 f = fresnel_schlick(max(dot(h, view_dir), 0.0), f0); | |
| 28 | + | vec3 specular = (f * pow(ndoth, ((1.0 - material.roughness) * 256.0))); | |
| 29 | + | vec3 diffuse = ((albedo * ndotl) * (vec3(1.0, 1.0, 1.0) - f)); | |
| 30 | + | return (diffuse + specular); | |
| 31 | + | } | |
| 32 | + | ||
| 33 | + | layout(location = 0) in vec2 in_uv; | |
| 34 | + | layout(location = 1) in vec3 in_normal; | |
| 35 | + | layout(location = 2) in vec3 in_world_pos; | |
| 36 | + | layout(location = 0) out vec4 out_color; | |
| 37 | + | ||
| 38 | + | void main() { | |
| 39 | + | vec4 tex_color = texture(albedo_tex, in_uv); | |
| 40 | + | vec3 albedo = (tex_color.rgb * material.albedo); | |
| 41 | + | vec3 view_dir = normalize((camera_pos - in_world_pos)); | |
| 42 | + | vec3 color = compute_lighting(in_normal, view_dir, albedo); | |
| 43 | + | out_color = vec4(color, tex_color.a); | |
| 44 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | const int NUM_LIGHTS = 4; | |
| 4 | + | const float BRIGHTNESS = 1.0; | |
| 5 | + | const bool USE_GAMMA = true; | |
| 6 | + | ||
| 7 | + | layout(std140, binding = 0) uniform uniforms_Block { | |
| 8 | + | vec3 base_color; | |
| 9 | + | float ambient; | |
| 10 | + | } uniforms; | |
| 11 | + | ||
| 12 | + | layout(location = 0) in vec3 in_position; | |
| 13 | + | ||
| 14 | + | void main() { | |
| 15 | + | gl_Position = vec4(in_position, 1.0); | |
| 16 | + | } | |
| 17 | + | ||
| 18 | + | layout(location = 0) in vec4 in_frag_coord; | |
| 19 | + | layout(location = 0) out vec4 out_color; | |
| 20 | + | ||
| 21 | + | void main() { | |
| 22 | + | vec3 color = (uniforms.base_color * uniforms.ambient); | |
| 23 | + | int i = 0; | |
| 24 | + | while ((i < NUM_LIGHTS)) { | |
| 25 | + | color = (color + vec3(0.1, 0.1, 0.1)); | |
| 26 | + | i = (i + 1); | |
| 27 | + | } | |
| 28 | + | color = (color * BRIGHTNESS); | |
| 29 | + | out_color = vec4(color, 1.0); | |
| 30 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(location = 0) in float in_value; | |
| 4 | + | layout(location = 0) out vec4 out__value; | |
| 5 | + | ||
| 6 | + | void main() { | |
| 7 | + | vec3 zero3 = vec3(0.0, 0.0, 0.0); | |
| 8 | + | vec4 one4 = vec4(1.0, 1.0, 1.0, 1.0); | |
| 9 | + | vec2 half2 = vec2(0.5, 0.5); | |
| 10 | + | vec3 full = vec3(1.0, 2.0, 3.0); | |
| 11 | + | float x = in_value; | |
| 12 | + | vec4 splatted = vec4(x, x, x, x); | |
| 13 | + | out__value = vec4(((((zero3.x + one4.x) + half2.x) + full.x) + splatted.x), 0.0, 0.0, 1.0); | |
| 14 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(std140, binding = 0) uniform params_Block { | |
| 4 | + | float bias; | |
| 5 | + | } params; | |
| 6 | + | layout(binding = 0) uniform sampler2D diffuse_tex; | |
| 7 | + | layout(binding = 2) uniform sampler2DShadow shadow_map; | |
| 8 | + | ||
| 9 | + | layout(location = 0) in vec2 in_uv; | |
| 10 | + | layout(location = 1) in vec2 in_shadow_uv; | |
| 11 | + | layout(location = 0) out vec4 out__value; | |
| 12 | + | ||
| 13 | + | void main() { | |
| 14 | + | vec4 mip_color = textureLod(diffuse_tex, in_uv, params.bias); | |
| 15 | + | float shadow = texture(shadow_map, vec3(in_shadow_uv, 0.5)); | |
| 16 | + | out__value = vec4((mip_color.rgb * shadow), mip_color.a); | |
| 17 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(std140, binding = 0) uniform uniforms_Block { | |
| 4 | + | mat4 mvp; | |
| 5 | + | } uniforms; | |
| 6 | + | ||
| 7 | + | layout(location = 0) in vec3 in_position; | |
| 8 | + | layout(location = 1) in vec2 in_uv; | |
| 9 | + | layout(location = 0) out vec2 out_uv; | |
| 10 | + | layout(location = 1) out vec3 out_normal; | |
| 11 | + | ||
| 12 | + | void main() { | |
| 13 | + | vec4 clip_pos = (uniforms.mvp * vec4(in_position, 1.0)); | |
| 14 | + | gl_Position = clip_pos; | |
| 15 | + | out_uv = in_uv; | |
| 16 | + | out_normal = vec3(0.0, 1.0, 0.0); | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | layout(location = 0) in vec2 in_uv; | |
| 20 | + | layout(location = 1) in vec3 in_normal; | |
| 21 | + | layout(location = 0) out vec4 out_color; | |
| 22 | + | ||
| 23 | + | void main() { | |
| 24 | + | out_color = vec4(in_uv, 0.0, 1.0); | |
| 25 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(location = 0) in vec2 in_uv; | |
| 4 | + | layout(location = 0) out vec4 out_color; | |
| 5 | + | ||
| 6 | + | void main() { | |
| 7 | + | if ((in_uv.x > 0.5)) { | |
| 8 | + | out_color = vec4(1.0, in_uv.y, 0.0, 1.0); | |
| 9 | + | } else { | |
| 10 | + | out_color = vec4(0.0, in_uv.y, 1.0, 1.0); | |
| 11 | + | } | |
| 12 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | shared float scratch[64]; | |
| 4 | + | ||
| 5 | + | layout(std430, binding = 0) buffer params_Block { | |
| 6 | + | uint count; | |
| 7 | + | float scale; | |
| 8 | + | } params; | |
| 9 | + | layout(std430, binding = 1) buffer data_Block { | |
| 10 | + | float values[64]; | |
| 11 | + | } data; | |
| 12 | + | ||
| 13 | + | layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; | |
| 14 | + | ||
| 15 | + | void main() { | |
| 16 | + | uint idx = gl_LocalInvocationIndex; | |
| 17 | + | uint gid = gl_GlobalInvocationID.x; | |
| 18 | + | uint lid = gl_LocalInvocationID.x; | |
| 19 | + | uint group_x = gl_WorkGroupID.x; | |
| 20 | + | if ((gid < params.count)) { | |
| 21 | + | scratch[idx] = (data.values[idx] * params.scale); | |
| 22 | + | barrier(); | |
| 23 | + | data.values[idx] = (scratch[idx] + float((lid + group_x))); | |
| 24 | + | } | |
| 25 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(location = 0) in float in_alpha; | |
| 4 | + | layout(location = 0) out vec4 out_color; | |
| 5 | + | ||
| 6 | + | void main() { | |
| 7 | + | if ((in_alpha < 0.01)) { | |
| 8 | + | discard; | |
| 9 | + | } else { | |
| 10 | + | out_color = vec4(in_alpha, in_alpha, in_alpha, 1.0); | |
| 11 | + | } | |
| 12 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(binding = 0) uniform sampler2D material_tex; | |
| 4 | + | ||
| 5 | + | layout(location = 0) in vec2 in_uv; | |
| 6 | + | layout(location = 1) in vec3 in_normal; | |
| 7 | + | layout(location = 0) out vec4 out_color; | |
| 8 | + | ||
| 9 | + | void main() { | |
| 10 | + | vec4 albedo = texture(material_tex, in_uv); | |
| 11 | + | out_color = vec4(albedo.rgb, 1.0); | |
| 12 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(location = 0) out vec4 out_color; | |
| 4 | + | ||
| 5 | + | void main() { | |
| 6 | + | vec2 coord = gl_FragCoord.xy; | |
| 7 | + | bool facing = gl_FrontFacing; | |
| 8 | + | float face = (facing ? 1.0 : 0.25); | |
| 9 | + | out_color = vec4((coord.x * 0.0), (coord.y * 0.0), face, 1.0); | |
| 10 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(location = 0) in vec2 in_uv; | |
| 4 | + | layout(location = 0) out vec4 out_color; | |
| 5 | + | ||
| 6 | + | void main() { | |
| 7 | + | out_color = vec4(in_uv, 0.0, 1.0); | |
| 8 | + | if ((in_uv.x > 0.5)) { | |
| 9 | + | out_color = vec4(1.0, in_uv.y, 0.0, 1.0); | |
| 10 | + | } | |
| 11 | + | } |
| 1 | + | #version 450 | |
| 2 | + | ||
| 3 | + | layout(std140, binding = 0) uniform uniforms_Block { | |
| 4 | + | mat4 model; | |
| 5 | + | mat4 view_proj; | |
| 6 | + | mat4 normal_mat; | |
| 7 | + | } uniforms; | |
| 8 | + | ||
| 9 | + | layout(location = 0) in vec3 in_position; | |
| 10 | + | layout(location = 1) in vec3 in_normal; | |
| 11 | + | layout(location = 2) in vec2 in_uv; | |
| 12 | + | layout(location = 0) out vec2 out_uv; | |
| 13 | + | layout(location = 1) out vec3 out_normal; | |
| 14 | + | ||
| 15 | + | void main() { | |
| 16 | + | vec3 pos = in_position; | |
| 17 | + | vec4 world_pos = (uniforms.model * vec4(pos, 1.0)); | |
| 18 | + | vec4 clip_pos = (uniforms.view_proj * world_pos); | |
| 19 | + | gl_Position = clip_pos; | |
| 20 | + | out_uv = in_uv; | |
| 21 | + | out_normal = normalize((uniforms.normal_mat * vec4(in_normal, 0.0)).xyz); | |
| 22 | + | } |
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.