mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-09 18:14:06 +09:00
gpu rendered light wip
This commit is contained in:
100
assets/raytracelight.frag
Normal file
100
assets/raytracelight.frag
Normal file
@@ -0,0 +1,100 @@
|
||||
#version 120
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texCoords;
|
||||
|
||||
// all 3 must have the same dimension!
|
||||
// the divisor of 2 input and an output must be the same. I.e. either divide all by 4, or not.
|
||||
uniform sampler2D shades;
|
||||
uniform sampler2D lights;
|
||||
uniform sampler2D u_texture;
|
||||
uniform vec2 outSize;
|
||||
uniform float multiplier = 4.0; // if divided by four, put 4.0 in there
|
||||
|
||||
#define TRAVERSE_SIZE 128 // should be good for screen size up to 1920 for tile size of 16
|
||||
|
||||
vec4 sampleFrom(sampler2D from, vec2 which) {
|
||||
return texture2D(from, which / outSize);
|
||||
}
|
||||
|
||||
int traceRayCount(vec2 delta) {
|
||||
vec2 absDelta = abs(delta);
|
||||
int arraySize = int(max(absDelta.x, absDelta.y));
|
||||
return arraySize + 1;
|
||||
}
|
||||
|
||||
vec2[TRAVERSE_SIZE] traceRay(int arraySize, vec2 from, vec2 to) {
|
||||
vec2 delta = to - from;
|
||||
vec2[TRAVERSE_SIZE] returnArray;
|
||||
int arri = 0;
|
||||
|
||||
// if the line is not vertical...
|
||||
if (delta.x != 0) {
|
||||
float deltaError = abs(delta.y / delta.x);
|
||||
float error = 0.0;
|
||||
float traceY = from.y;
|
||||
|
||||
for (float traceX = from.x; traceX <= to.x; traceX++) {
|
||||
// plot(traceX, traceY)
|
||||
returnArray[arri] = vec2(traceX, traceY);
|
||||
arri = arri + 1;
|
||||
|
||||
error = error + deltaError;
|
||||
if (error >= 0.5) {
|
||||
traceY = traceY + sign(delta.y);
|
||||
error = error - 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (float traceY = from.y; traceY <= to.y; traceY++) {
|
||||
returnArray[arri] = vec2(from.x, traceY);
|
||||
}
|
||||
}
|
||||
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 outColor = vec4(0.0,0.0,0.0,0.0);
|
||||
|
||||
// 1. pick a light source
|
||||
for (int y = 0; y < int(outSize.y); y++) {
|
||||
for (int x = 0; x < int(outSize.x); x++) {
|
||||
vec2 from = vec2(x, y);
|
||||
vec2 to = gl_FragCoord.xy;
|
||||
vec2 delta = to - from;
|
||||
int traceCount = traceRayCount(delta);
|
||||
vec4 light = sampleFrom(lights, from);
|
||||
|
||||
// 2. get a trace path
|
||||
vec2[TRAVERSE_SIZE] returnArray = traceRay(traceCount, from, to);
|
||||
|
||||
// 2.1 get angular darkening coefficient
|
||||
vec2 unitVec = delta / max(delta.x, delta.y);
|
||||
float angularDimming = sqrt(unitVec.x * unitVec.x + unitVec.y * unitVec.y);
|
||||
//float angularDimming = 1.0; // TODO depends on the angle of (lightPos, gl_FragCoord.x)
|
||||
|
||||
// 3. traverse the light path to dim the "light"
|
||||
// var "light" will be attenuated after this loop
|
||||
for (int i = 0; i < traceCount; i++) {
|
||||
vec4 shade = sampleFrom(shades, returnArray[i]) * angularDimming;
|
||||
|
||||
light = light - shade;
|
||||
}
|
||||
|
||||
// 4. mix the incoming light into the light buffer.
|
||||
outColor = max(outColor, light);
|
||||
}
|
||||
}
|
||||
|
||||
gl_FragColor = outColor * multiplier;
|
||||
gl_FragColor = vec4(0,1,0,1);
|
||||
|
||||
gl_FragColor = vec4(texture2D(lights, v_texCoords)) * multiplier;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user