Commit 0d85c7ca authored by Johannes Braun's avatar Johannes Braun
Browse files

Better unified shaders. (OpenGL shading not yet working as expected)

parent 5b985c92
#version 430
in vec3 out_texcoord;
uniform samplerCube u_cube_map;
layout(location=0) out vec4 out_color;
layout(location = 1) out vec4 out_final_normal;
void main()
{
out_color = vec4(texture(u_cube_map, out_texcoord).rgb, 1);
out_final_normal = vec4(0,0,0,1);
}
\ No newline at end of file
#version 430
layout(location=0) in vec4 in_position;
layout(location=1) in vec4 in_normal;
layout(location=2) in vec2 in_texcoord;
uniform mat4 u_view_projection;
uniform mat4 u_model;
out vec3 out_texcoord;
void main()
{
gl_Position = (u_view_projection * u_model * in_position).xyzw;
out_texcoord = in_position.xyz;
}
\ No newline at end of file
...@@ -4,11 +4,18 @@ in vec3 out_texcoord; ...@@ -4,11 +4,18 @@ in vec3 out_texcoord;
uniform samplerCube u_cube_map; uniform samplerCube u_cube_map;
layout(location = 0) out vec4 out_color; // vec3 base color and float roughness
layout(location = 1) out vec4 out_final_normal; layout(location = 0) out vec4 output_base_ior;
// vec3 emission color and float metallic
layout(location = 1) out vec4 output_rough_metallic_transmit_emit;
layout(location = 2) out vec4 output_normal;
layout(location = 3) out vec4 output_modelview_position;
layout(location = 4) out vec4 output_world_position;
void main() void main()
{ {
out_color = vec4(texture(u_cube_map, out_texcoord).rgb, 1); output_base_ior = vec4(texture(u_cube_map, out_texcoord).rgb, 1);
out_final_normal = vec4(0, 0, 0, 1); output_rough_metallic_transmit_emit = vec4(0);
} output_normal = vec4(0, 0, 0, 1);
\ No newline at end of file }
#version 430 #version 430
layout(location = 6) out vec4 out_final_lighting; // vec3 base color and float roughness
layout(location = 0) out vec4 output_base_ior;
// vec3 emission color and float metallic
layout(location = 1) out vec4 output_rough_metallic_transmit_emit;
layout(location = 2) out vec4 output_normal;
layout(location = 3) out vec4 output_modelview_position;
layout(location = 4) out vec4 output_world_position;
uniform vec4 u_color; uniform vec4 u_color;
void main() void main()
{ {
out_final_lighting = u_color; output_base_ior.rgb = u_color.rgb;
output_rough_metallic_transmit_emit = vec4(0, 0, 0, 1);
} }
#ifndef __BSDF_DIFFUSE_GLH #ifndef INCLUDE_PATHTRACER_BSDF_GLSL
#define __BDSF_DIFFUSE_GLH #define INCLUDE_PATHTRACER_BSDF_GLSL
#include <raytracer/basic_structs.glsl> #include <util/math/random.glsl>
#include <raytracer/random.glsl> #include <util/math/geometry.glsl>
#include <raytracer/utilities.glsl> #include <util/math/ggx.glsl>
#include <raytracer/properties/ray_transform.glsl>
#include <raytracer/properties/fresnel.glsl>
#include <screenshader/gbuffer/cook_torrance.glsl> #include <util/scene/material.glsl>
#include <raytracer/properties/ggx.glsl>
// BSDF IDs // BSDF IDs
const uint eDiffuse = 0; const uint eDiffuse = 0;
...@@ -37,20 +34,14 @@ struct BSDFResult ...@@ -37,20 +34,14 @@ struct BSDFResult
struct SampledMaterial struct SampledMaterial
{ {
vec3 base; vec3 base;
vec3 ambient; float ior;
vec3 emission;
float emission;
float roughness; float roughness;
float metallic; float metallic;
float transmission; float transmission;
float ior;
}; };
vec3 reflectedDirection(vec3 local_hemi_sample, vec3 normal, vec3 reflected, float roughness)
{
return normalize(localToWorld(local_hemi_sample, normal, reflected));
}
/** /**
@brief Samples the material at the given vertex. In the process, all available textures will be sampled at the according texture coordinate. @brief Samples the material at the given vertex. In the process, all available textures will be sampled at the according texture coordinate.
So you will not only get the raw base colors, but also the textured ones. So you will not only get the raw base colors, but also the textured ones.
...@@ -59,9 +50,8 @@ SampledMaterial getMaterialParameters(const in Material material, const in Verte ...@@ -59,9 +50,8 @@ SampledMaterial getMaterialParameters(const in Material material, const in Verte
{ {
SampledMaterial sampled_material; SampledMaterial sampled_material;
sampled_material.base = material.getBase(vertex.texcoord); sampled_material.base = material.getBase(vertex.texcoord);
sampled_material.ambient = material.getAmbient(vertex.texcoord);
sampled_material.emission = material.getEmission(vertex.texcoord);
sampled_material.emission = material.getEmission(vertex.texcoord);
sampled_material.roughness = material.getRoughness(vertex.texcoord); sampled_material.roughness = material.getRoughness(vertex.texcoord);
sampled_material.metallic = material.getMetallic(vertex.texcoord); sampled_material.metallic = material.getMetallic(vertex.texcoord);
sampled_material.transmission = material.getTransmission(vertex.texcoord); sampled_material.transmission = material.getTransmission(vertex.texcoord);
...@@ -78,9 +68,9 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i ...@@ -78,9 +68,9 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i
//Use the pixel coordinates of the incoming ray. //Use the pixel coordinates of the incoming ray.
result.generated_ray = ray_in; result.generated_ray = ray_in;
if(sampled_material.emission.rgb != vec3(0)) if(sampled_material.emission != 0)
{ {
result.radiance = sampled_material.emission.rgb; result.radiance = sampled_material.emission * sampled_material.base;
result.bsdf_id = eEmit; result.bsdf_id = eEmit;
return result; return result;
} }
...@@ -101,7 +91,7 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i ...@@ -101,7 +91,7 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i
float eta = ior_in / ior_out; float eta = ior_in / ior_out;
// Transform the computed local microsurface normal to world space along the hit normal // Transform the computed local microsurface normal to world space along the hit normal
vec3 micro_normal = normalize(toWorld(hemisphere_sample.micro_normal, incoming, normal)); vec3 micro_normal = normalize(localToWorld(hemisphere_sample.micro_normal, incoming, normal));
// Schlick's fresnel approximation with the material's normal response // Schlick's fresnel approximation with the material's normal response
float normal_response = normalResponse(sampled_material.ior, sampled_material.metallic); float normal_response = normalResponse(sampled_material.ior, sampled_material.metallic);
...@@ -120,7 +110,7 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i ...@@ -120,7 +110,7 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i
{ {
// Sample lambertian diffuse // Sample lambertian diffuse
result.evaluation = (1-sampled_material.metallic)*sampled_material.base * ONE_OVER_PI; result.evaluation = (1-sampled_material.metallic)*sampled_material.base * ONE_OVER_PI;
result.generated_ray.direction = normalize(toWorld(randCosineHemisphere(random.x, random.y), incoming, normal)); result.generated_ray.direction = normalize(localToWorld(randCosineHemisphere(random.x, random.y), incoming, normal));
result.probability_density = abs(dot(vec4(result.generated_ray.direction, 0), vertex.normal)) * ONE_OVER_PI; result.probability_density = abs(dot(vec4(result.generated_ray.direction, 0), vertex.normal)) * ONE_OVER_PI;
result.radiance = (1-sampled_material.metallic)*sampled_material.base * ONE_OVER_PI; result.radiance = (1-sampled_material.metallic)*sampled_material.base * ONE_OVER_PI;
result.bsdf_id = eDiffuse; result.bsdf_id = eDiffuse;
...@@ -204,4 +194,4 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i ...@@ -204,4 +194,4 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i
return result; return result;
} }
#endif //!__BDSF_DIFFUSE_GLH #endif //!INCLUDE_PATHTRACER_BSDF_GLSL
#ifndef INCLUDE_PATHTRACER_BUFFERS_GLSL
#define INCLUDE_PATHTRACER_BUFFERS_GLSL
#include <util/scene/light.glsl>
#include <util/scene/mesh.glsl>
#include <util/scene/material.glsl>
#include <util/tracing/bvh_node.glsl>
#include <util/tracing/tracing.glsl>
layout(std430) restrict readonly buffer lights_buffer
{
Light lights_data[];
};
layout(std430) restrict readonly buffer mesh_buffer
{
Mesh meshes_data[];
};
layout(std430) restrict readonly buffer object_bvh_buffer
{
BVHNode global_bvh_nodes_data[];
};
layout(std430) restrict readonly buffer object_bvh_id_buffer
{
uint mesh_ids_data[];
};
layout(std430) restrict readonly buffer material_buffer
{
Material materials_data[];
};
layout(std430) buffer trace_buffer
{
Trace traces_data[];
};
#endif //!INCLUDE_PATHTRACER_BUFFERS_GLSL
#ifndef __GL_LINESPACE #ifndef INCLUDE_PATHTRACER_ANGULAR_LINESPACE_GLSL
#define __GL_LINESPACE #define INCLUDE_PATHTRACER_ANGULAR_LINESPACE_GLSL
#include <raytracer/basic_structs.glsl> #include <util/scene/mesh.glsl>
#include <raytracer/buffers.glsl> #include <util/tracing/intersections.glsl>
#include <raytracer/intersections.glsl> #include <util/tracing/tracing.glsl>
#include <raytracer/std.glsl>
#include <raytracer/utilities.glsl>
const uint face_width_axis[3] = {2, 2, 0}; #ifndef USE_ANGULAR_LS
const uint face_height_axis[3] = {1, 0, 1}; #define USE_ANGULAR_LS
//Include ls data structs with angular definition
#include <util/tracing/linespace.glsl>
#undef USE_ANGULAR_LS
#endif //!USE_ANGULAR_LS
uvec2 getPatch(const in Mesh mesh, vec3 at_position, int axis, int face){ uvec2 getPatch(const in Mesh mesh, vec3 at_position, int axis, int face){
bool flip_indices = face != axis; bool flip_indices = face != axis;
...@@ -18,22 +20,6 @@ uvec2 getPatch(const in Mesh mesh, vec3 at_position, int axis, int face){ ...@@ -18,22 +20,6 @@ uvec2 getPatch(const in Mesh mesh, vec3 at_position, int axis, int face){
uvec2(at_position[face_width_axis[axis]] / mesh.linespace.patch_size, at_position[face_height_axis[axis]] / mesh.linespace.patch_size)- 1; uvec2(at_position[face_width_axis[axis]] / mesh.linespace.patch_size, at_position[face_height_axis[axis]] / mesh.linespace.patch_size)- 1;
} }
float getDistance(const in Ray ray, const in Hit hit, inout uint dir_sign)
{
Mesh mesh = b_meshes[hit.mesh];
Triangle triangle = mesh.triangles[hit.triangle];
Vertex v1 = mesh.vertices[triangle.indices[1]];
Vertex v2 = mesh.vertices[triangle.indices[2]];
Vertex v3 = mesh.vertices[triangle.indices[0]];
vec3 vector = hit__getFromBarycentric(hit.barycentric, triangle, position).xyz - ray.origin;
dir_sign = uint(sign(dot(vector, ray.direction)));
return length(vector);
}
struct PatchInfo struct PatchInfo
{ {
int face; int face;
...@@ -167,4 +153,4 @@ bool traverseLineSpace(const in Mesh mesh, const in Ray local_ray, const in bool ...@@ -167,4 +153,4 @@ bool traverseLineSpace(const in Mesh mesh, const in Ray local_ray, const in bool
} }
#endif //__GL_LINESPACE #endif //INCLUDE_PATHTRACER_ANGULAR_LINESPACE_GLSL
#ifndef __GL_BVH #ifndef INCLUDE_PATHTRACER_BVH_GLSL
#define __GL_BVH #define INCLUDE_PATHTRACER_BVH_GLSL
#include <raytracer/basic_structs.glsl> #include <util/scene/mesh.glsl>
#include <raytracer/buffers.glsl> #include <util/tracing/intersections.glsl>
#include <raytracer/intersections.glsl> #include <util/tracing/bvh_node.glsl>
#include <raytracer/std.glsl> #include <util/tracing/tracing.glsl>
#include <raytracer/utilities.glsl>
Bounds getNodeBounds(int index, const in Mesh mesh) Bounds getNodeBounds(int index, const in Mesh mesh)
{ {
...@@ -122,4 +121,4 @@ bool traverseBVH(const in Mesh mesh, const in Ray local_ray, const in bool use_f ...@@ -122,4 +121,4 @@ bool traverseBVH(const in Mesh mesh, const in Ray local_ray, const in bool use_f
return hit_triangle; return hit_triangle;
} }
#endif //__GL_BVH #endif //INCLUDE_PATHTRACER_BVH_GLSL
#ifndef __GL_MESH_DATASTRUCTURE #ifndef INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL
#define __GL_MESH_DATASTRUCTURE #define INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL
#include <raytracer/datastructure/mesh_bvh.glsl> #include <pathtracer/buffers.glsl>
//#include <raytracer/datastructure/mesh_angular_linespace.glsl> #include <util/scene/mesh.glsl>
#include <raytracer/datastructure/mesh_linespace.glsl> #include <util/tracing/bvh_node.glsl>
uniform bool u_use_ls; #include <pathtracer/data/mesh_bvh.glsl>
#include <pathtracer/data/mesh_linespace.glsl>
//#include <raytracer/datastructure/mesh_angular_linespace.glsl>
#define USE_OBJECT_BVH true ||
//#define USE_OBJECT_BVH false &&
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false); bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false);
...@@ -25,17 +25,12 @@ bool intersectsAny(const in Ray ray, const in float max_distance, bool force_bvh ...@@ -25,17 +25,12 @@ bool intersectsAny(const in Ray ray, const in float max_distance, bool force_bvh
return traverseObjects(ray, true, max_distance, unused_hit, t_min, force_bvh); return traverseObjects(ray, true, max_distance, unused_hit, t_min, force_bvh);
} }
Bounds getObjectNodeBounds(int index)
{
return b_object_nodes[index].bounds;
}
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false) bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false)
{ {
float t = t_min; float t = t_min;
float max_dist = max_distance; float max_dist = max_distance;
// Check once the AABB for the whole scene // Check once the AABB for the whole scene
bool hit_scene = ray.intersectsBounds(getObjectNodeBounds(0), max_distance); bool hit_scene = ray.intersectsBounds(global_bvh_nodes_data[0].bounds, max_distance);
bool hit_triangle = false; bool hit_triangle = false;
int current_node = 0; int current_node = 0;
...@@ -45,13 +40,13 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m ...@@ -45,13 +40,13 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
while (hit_scene) while (hit_scene)
{ {
if (b_object_nodes[current_node].type == 0) //Inner node. if (global_bvh_nodes_data[current_node].type == 0) //Inner node.
{ {
int id_left = int(b_object_nodes[current_node].left_idx); int id_left = int(global_bvh_nodes_data[current_node].left_idx);
bool hit_left = ray.intersectsBounds(getObjectNodeBounds(id_left), max_distance); bool hit_left = ray.intersectsBounds(global_bvh_nodes_data[id_left].bounds, max_distance);
int id_right = int(b_object_nodes[current_node].right_idx); int id_right = int(global_bvh_nodes_data[current_node].right_idx);
bool hit_right = ray.intersectsBounds(getObjectNodeBounds(id_right), max_distance); bool hit_right = ray.intersectsBounds(global_bvh_nodes_data[id_right].bounds, max_distance);
//both hit //both hit
if (hit_left && hit_right) if (hit_left && hit_right)
...@@ -87,16 +82,16 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m ...@@ -87,16 +82,16 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
//shorten ray if closer intersection found. //shorten ray if closer intersection found.
//intersect triangles //intersect triangles
int start = int(b_object_nodes[current_node].left_idx); int start = int(global_bvh_nodes_data[current_node].left_idx);
int end = int(b_object_nodes[current_node].right_idx); int end = int(global_bvh_nodes_data[current_node].right_idx);
for (int i = start; i <= end; i++) for (int i = start; i <= end; i++)
{ {
float current_t = t_min; float current_t = t_min;
const Mesh mesh = b_meshes[i]; const Mesh mesh = meshes_data[i];
if(force_bvh) if(force_bvh)
{ {
if(mesh.traverseBVH(ray.makeMeshLocal(mesh), use_first, current_t, false, hit, unused, t_min)){ if(mesh.traverseBVH(ray.makeRelative(mesh), use_first, current_t, false, hit, unused, t_min)){
hit_triangle = true; hit_triangle = true;
if (use_first) if (use_first)
{ {
...@@ -106,7 +101,7 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m ...@@ -106,7 +101,7 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
} }
else else
{ {
if(mesh.traverseLineSpace(ray.makeMeshLocal(mesh), use_first, current_t, hit, t_min)){ if(mesh.traverseLineSpace(ray.makeRelative(mesh), use_first, current_t, hit, t_min)){
hit_triangle = true; hit_triangle = true;
if (use_first) if (use_first)
{ {
...@@ -127,16 +122,16 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m ...@@ -127,16 +122,16 @@ bool traverseObjects(const in Ray ray, const in bool use_first, const in float m
return hit_triangle; return hit_triangle;
} }
current_node = int(b_object_nodes[current_node].parent); current_node = int(global_bvh_nodes_data[current_node].parent);
bitstack = bitstack >> 1; bitstack = bitstack >> 1;
} }
//Use other (right) sibling from the left child of the branched tree node. //Use other (right) sibling from the left child of the branched tree node.
current_node = int(b_object_nodes[b_object_nodes[current_node].parent].right_idx); current_node = int(global_bvh_nodes_data[global_bvh_nodes_data[current_node].parent].right_idx);
bitstack = bitstack ^ 1; bitstack = bitstack ^ 1;
} }
return hit_triangle; return hit_triangle;
} }
#endif //__GL_MESH_DATASTRUCTURE #endif //INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL
#ifndef __GL_LINESPACE #ifndef INCLUDE_PATHTRACER_LINESPACE_GLSL
#define __GL_LINESPACE #define INCLUDE_PATHTRACER_LINESPACE_GLSL
#include <raytracer/basic_structs.glsl> #include <util/scene/mesh.glsl>
#include <raytracer/buffers.glsl> #include <util/tracing/intersections.glsl>
#include <raytracer/intersections.glsl> #include <util/tracing/linespace.glsl>
#include <raytracer/std.glsl> #include <util/tracing/tracing.glsl>
#include <raytracer/utilities.glsl>
uint ls__faceRangeIndex(uint in_face, uint out_face) uint configurationID(uint in_face, uint out_face)
{ {
return uint((((-0.5f * float(in_face)) + 4.5f)*float(in_face))) - 1u + out_face; return uint((((-0.5f * float(in_face)) + 4.5f)*float(in_face))) - 1u + out_face;
} }
const uint c_face_width_axis[3] = {2, 2, 0};
const uint c_face_height_axis[3] = {1, 0, 1};
uint linesBetweenFaces(const in Linespace linespace, uint inface, uint outface) uint linesBetweenFaces(const in Linespace linespace, uint inface, uint outface)
{ {
uint axis_in_width = linespace.resolution[c_face_width_axis[inface % 3]]; uint axis_in_width = linespace.resolution[face_width_axis[inface % 3]];
uint axis_in_height = linespace.resolution[c_face_height_axis[inface % 3]]; uint axis_in_height = linespace.resolution[face_height_axis[inface % 3]];
uint axis_out_width = linespace.resolution[c_face_width_axis[outface % 3]]; uint axis_out_width = linespace.resolution[face_width_axis[outface % 3]];
uint axis_out_height = linespace.resolution[c_face_height_axis[outface % 3]]; uint axis_out_height = linespace.resolution[face_height_axis[outface % 3]];
return axis_in_width * axis_in_height * axis_out_width * axis_out_height; return axis_in_width * axis_in_height * axis_out_width * axis_out_height;
} }
...@@ -31,7 +27,7 @@ uint offsetOf(const in Linespace linespace, uint inface, uint outface) ...@@ -31,7 +27,7 @@ uint offsetOf(const in Linespace linespace, uint inface, uint outface)
uint offset = 0; uint offset = 0;
// Caution! Fallthrough switch. Seemed to perform much better than a for-loop, usually even being faster than precalculated offsets in release builds. // Caution! Fallthrough switch. Seemed to perform much better than a for-loop, usually even being faster than precalculated offsets in release builds.
switch (ls__faceRangeIndex(inface, outface)) switch (configurationID(inface, outface))
{ {
case 15: case 15:
offset += linesBetweenFaces(linespace, 4, 5); offset += linesBetweenFaces(linespace, 4, 5);
...@@ -71,36 +67,12 @@ uint offsetOf(const in Linespace linespace, uint inface, uint outface) ...@@ -71,36 +67,12 @@ uint offsetOf(const in Linespace linespace, uint inface, uint outface)
return offset; return offset;
} }
uint getFaceWidth(uint axis){
return c_face_width_axis[axis];
}
uint getFaceHeight(uint axis){
return c_face_height_axis[axis];
}
uvec2 getPatch(const in Mesh mesh, vec3 at_position, int axis, int face){ uvec2 getPatch(const in Mesh mesh, vec3 at_position, int axis, int face){
bool flip_indices = face != axis; bool flip_indices = face != axis;
return !flip_indices return !flip_indices
? uvec2(at_position[getFaceWidth(axis)] / mesh.linespace.patch_size, at_position[getFaceHeight(axis)] / mesh.linespace.patch_size) ? uvec2(at_position[face_width_axis[axis]] / mesh.linespace.patch_size, at_position[face_height_axis[axis]] / mesh.linespace.patch_size)
: uvec2(mesh.linespace.resolution[getFaceWidth(axis)], mesh.linespace.resolution[getFaceHeight(axis)]) - : uvec2(mesh.linespace.resolution[face_width_axis[axis]], mesh.linespace.resolution[face_height_axis[axis]]) -
uvec2(at_position[getFaceWidth(axis)] / mesh.linespace.patch_size, at_position[getFaceHeight(axis)] / mesh.linespace.patch_size)- 1; uvec2(at_position[face_width_axis[axis]] / mesh.linespace.patch_size, at_position[face_height_axis[axis]] / mesh.linespace.patch_size)- 1;
}
float getDistance(const in Ray ray, const in Hit hit, inout uint dir_sign)
{
Mesh mesh = b_meshes[hit.mesh];
Triangle triangle = mesh.triangles[hit.triangle];
Vertex v1 = mesh.vertices[triangle.indices[1]];
Vertex v2 = mesh.vertices[triangle.indices[2]];
Vertex v3 = mesh.vertices[triangle.indices[0]];
vec3 vector = hit__getFromBarycentric(hit.barycentric, triangle, position).xyz - ray.origin;