Skip to content

Commit

Permalink
Merge pull request #7 from nilspettersson/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
nilspettersson committed Nov 27, 2020
2 parents ca1fa24 + 3244be9 commit 18fba07
Show file tree
Hide file tree
Showing 26 changed files with 1,237 additions and 557 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
### 2.0.0
#### changed
* changed the game loop.
* added scene system. You can now create many scenes and switch between them. A scene has a load and update function. A scene will remove all its content when a different scene is loaded.
* improved ray marching api.
* changed how lights are added.

#### features
* added sdf shader to library for using ray marching distance functions.
* added shadows to ray marching.
* added ambient occlusion to ray marcher

#### bugfixes
* fixed memory leaks.
* ray marching now works with different window resolutions
* fixed issue when having no imports in shader

### 1.1.0
#### features
* added ray marching system. Raymarcher will go through scene of objects and calculate distance. float scene(vec3 point) needs to be created.
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# lwjgl_3D_library
Current version: **1.1.0**
Current version: **2.0.0**

## Core functionality
#### Game loop handling
* The Game class should be inherited, this will controll the flow of the application for you. The Game class contains all functionality for this library.
#### Scenes
* You can create many scenes and switch between them. Every scene has its own entites, ligths and camera.
#### Camera
* There is a Camera that can be moved and rotated using functions in Game class.
#### keybord Input
* Input from keybord is Posible using the Input class.
* Input from keybord is Possible using the Input class.
#### Mouse Input
* There is a Mouse class with static functions for changing Mouse location and visibility. It also contains x and y values that can be used to rotate camera.
#### Renderer
Expand All @@ -25,7 +27,7 @@ Current version: **1.1.0**
#### Post Processing
* You can create a post processing shader that add effects to the image.
#### Ray marcher
* You can add [distance functions](https://iquilezles.org/www/articles/distfunctions/distfunctions.htm) to a scene function and then use ray marcher to find closest objects.
* You can add [distance functions](https://iquilezles.org/www/articles/distfunctions/distfunctions.htm) to an sdf function and then use ray marcher to find closest objects. It can calculate diffuse, shadows and ambient occlusion.


## Setup for eclipse
Expand Down
410 changes: 410 additions & 0 deletions hs_err_pid7180.log

Large diffs are not rendered by default.

98 changes: 72 additions & 26 deletions shaders/lib/rayMarching.glsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
float scene(vec3 point);
float sdf(vec3 point);

struct Ray{
vec4 dir;
float length;
int steps;
};

vec4 multQuat(vec4 q1, vec4 q2){
return vec4(
Expand All @@ -18,68 +23,94 @@ vec4 rotate_vector( vec4 quat, vec4 vec )
return vec4(multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz, cosA);
}

vec4 getRay(){
Ray getRay(){
vec3 resolution = vec3(1.77, 1, 0.72);

vec2 uv = tex_coords;
uv.x = (uv.x * 2.0) - 1.0;
uv.y = (2.0 * uv.y) - 1.0;
vec2 uv2 = uv;
uv2.x = (uv2.x * 2.0) - 1.0;
uv2.y = (2.0 * uv2.y) - 1.0;
if(resolution.x >= resolution.y){
uv.x *= resolution.x/resolution.y;
uv2.x *= resolution.x/resolution.y;
}else{
uv.y *= resolution.y/resolution.x;
uv2.y *= resolution.y/resolution.x;
}
float tan_fov = tan(1.2217/2.0);
vec2 pxy = uv * tan_fov;
vec2 pxy = uv2 * tan_fov;
vec3 rayDir = normalize(vec3(pxy, 1));

vec4 dir = rotate_vector(cameraRotation, vec4(rayDir, rayDir.z));

return dir;
return Ray(dir, 0, 0);
}

//gets the distance to the closest object in the scene.
float rayMarch(vec4 rayDir, float maxDepth){
//gets the distance to the closest object in the sdf function.
Ray rayMarch(Ray ray){
vec3 rayOrigin = cameraPosition;
rayOrigin.z *=-1;

float cosA = rayDir.w;
float cosA = ray.dir.w;
float DistOrigin = 0;
for(int i = 0; i < 100; i++){
vec3 point = rayOrigin + rayDir.xyz * DistOrigin;
int steps = 0;
for(int i = 0; i < 200; i++){
vec3 point = rayOrigin + ray.dir.xyz * DistOrigin;

float dist = scene(point);
float dist = sdf(point);

DistOrigin += dist;
if(dist < 0.01 ){
break;
}
if(DistOrigin * cosA > maxDepth || DistOrigin > 10000){
if(DistOrigin * cosA > depth || DistOrigin > 10000){
DistOrigin = -1;
break;
}

steps++;
}

return Ray(ray.dir, DistOrigin, steps);
}

Ray rayMarch(Ray ray, vec3 origin, float length){

float cosA = ray.dir.w;
float DistOrigin = 0;
int steps = 0;
for(int i = 0; i < 200; i++){
vec3 point = origin + ray.dir.xyz * DistOrigin;

float dist = sdf(point);

DistOrigin += dist;
if(dist < 0.01 ){
break;
}
if(DistOrigin > length + 400 || DistOrigin > 10000){
DistOrigin = -1;
break;
}
steps++;
}

return DistOrigin;
return Ray(ray.dir, DistOrigin, steps);
}

//gets the normal for a pixel in ray marcher.
vec3 getNormal(vec3 point){
float dist = scene(point);
float dist = sdf(point);
vec2 e = vec2(0.01, 0);

vec3 normal = dist - vec3(scene(point - e.xyy),
scene(point - e.yxy),
scene(point - e.yyx));
vec3 normal = dist - vec3(sdf(point - e.xyy),
sdf(point - e.yxy),
sdf(point - e.yyx));
return normalize(normal);
}

vec4 rayMarchDiffuse(float rayOutput, vec4 rayDir, vec4 color){

vec4 rayMarchDiffuse(Ray ray, vec3 color){
//finding the point of the intersection.
vec3 rayOrigin = cameraPosition;
rayOrigin.z *= -1;
vec3 point = rayOrigin + rayDir.xyz * rayOutput;
vec3 point = rayOrigin + ray.dir.xyz * ray.length;
vec3 normal = getNormal(point);


Expand All @@ -88,9 +119,17 @@ vec4 rayMarchDiffuse(float rayOutput, vec4 rayDir, vec4 color){
vec3 pos = lightPositions[i];
pos.z *= -1;
vec3 toLight = pos - point;

float disToLight = length(toLight) / 8;


//if pixel is in shadow dont add current light.
Ray toLightRay = Ray(vec4(normalize(toLight), 0), length(toLight), 0);
vec3 point2 = rayOrigin + ray.dir.xyz * (ray.length - 0.02);
toLightRay = rayMarch(toLightRay, point2, disToLight);
if(toLightRay.length != -1){
continue;
}

float brightness = dot(normal, normalize(toLight));
brightness = max(brightness, 0);
float attenuation = lightIntensity[i] / (4.0 + 1 * disToLight + 1 * disToLight * disToLight);
Expand All @@ -100,8 +139,15 @@ vec4 rayMarchDiffuse(float rayOutput, vec4 rayDir, vec4 color){
allLight += light;
}

vec4 diffuse = color;
vec4 diffuse = vec4(color, 1);
diffuse.xyz *= max(allLight, 0);
return diffuse;
}


//ambient occlusion to give objects more depth.
vec4 rayMarchAmbient(Ray ray, vec3 ambientColor, float amount){
ambientColor /= max(ray.steps * amount, 4);
vec4 output = vec4(ambientColor, 1);
return output;
}
29 changes: 29 additions & 0 deletions shaders/lib/sdf.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
float sdSphere( vec3 p, float s )
{
return length(p)-s;
}

float sdplane( vec3 p, float y)
{
return p.y - y;
}

float sdBox( vec3 p, vec3 b )
{
vec3 q = abs(p) - b;
return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
}



vec3 opRepLim(vec3 p, float c, vec3 l)
{
p = p - c * clamp(round(p / c), -l, l);
return p;
}

vec3 opRep( vec3 p, float c )
{
p = mod( p + 0.5 * c, c) - 0.5 * c;
return p;
}
61 changes: 0 additions & 61 deletions shaders/postShader.glsl

This file was deleted.

12 changes: 6 additions & 6 deletions shaders/postShader2.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ float sdBox( vec3 p, vec3 b )
}


float scene(vec3 point){
float sdf(vec3 point){
vec4 ball = vec4(4, -7, 2, 1);
float ballDist = length(point - ball.xyz) - ball.w;

vec3 transform1 = vec3(0, -7.5, -2);
float box = sdBox(point - transform1, vec3(0.5, 0.5, 0.5));

return min(ballDist, box);
return ballDist;
}

fragment{
vec4 rayDir = getRay();
float rayOutput = rayMarch(rayDir, depth);
vec4 diffuse = rayMarchDiffuse(rayOutput, rayDir, vec4(1, 0, 0, 1));
Ray rayDir = getRay();
rayDir = rayMarch(rayDir);
vec4 diffuse = rayMarchDiffuse(rayDir, vec3(1));


vec4 output = texture;
if(rayOutput == -1){
if(rayDir.length == -1){
return vec4(output);
}
else{
Expand Down
30 changes: 30 additions & 0 deletions shaders/rayMarching.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include lib/rayMarching.glsl;
#include lib/sdf.glsl;

uniforms{
int x
}

float sdf(vec3 p){
float plane = sdplane(p, -1);

p = opRepLim(p, 4, vec3(500, 0, 500));
float box = sdBox(p - vec3(0, 0, 0), vec3(1, 1, 1) );

return min(box, plane);
}

fragment{

Ray ray = getRay();
ray = rayMarch(ray);

if(ray.length != -1){
return rayMarchDiffuse(ray, vec3(1)) + rayMarchAmbient(ray, vec3(0.2, 0.3, 0.4), 1);
}
else{
vec3 col = vec3(0.40, 0.46, 0.60) - ((1 - ray.dir.y) * 0.3);
return vec4(col, 1);
}

}
10 changes: 10 additions & 0 deletions src/niles/lwjgl/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,21 @@ public void addTexture(Texture texture) {
textures.add(texture);
}
public void bindTextures() {
if(textures.size() == 0) {
Texture.unbind();
}
for(int i = 0; i < textures.size(); i++) {
textures.get(i).bind(i);
}
}

//textures should be deleted when not used anymore.
public void DeleteTextures() {
for(int i = 0; i < textures.size(); i++) {
textures.get(i).delete();
}
}

public void bindGeometry() {
geometry.updateVertices();
geometry.updateIndices();
Expand Down
Loading

0 comments on commit 18fba07

Please sign in to comment.