materials, brick and nodes structure, preparing for world generation

This commit is contained in:
Piotrek
2021-04-24 17:06:44 +02:00
parent 829ae1ddb6
commit 97ece7a823
13 changed files with 311 additions and 244 deletions
+46 -3
View File
@@ -5,19 +5,62 @@ use winit::{
use std::sync::Arc;
mod camera_controller; use camera_controller::CameraController;
mod world_gen; use world_gen::WorldGen;
use crate::renderer::Renderer;
//use crate::renderer::BrickData;
pub struct App {
pub window: Window,
pub renderer: Renderer,
world_gen: WorldGen,
camera_controller: CameraController,
}
impl App {
pub fn new(window: Window, renderer: Renderer) -> Self {
pub fn new(window: Window) -> Self {
let mut renderer = futures::executor::block_on(Renderer::new(&window));
let camera_controller = CameraController::new();
Self { window, renderer, camera_controller }
let mut world_gen = WorldGen::new();
// let start = std::time::Instant::now();
// for x in 0..128 {
// for z in 0..128 {
// // Dirt
// for y in 0..31 {
// renderer.set_voxel(x, y, z, 1);
// }
// // Grass
// renderer.set_voxel(x, 31, z, 2);
// }
// }
// println!("Generated in {}ms", start.elapsed().as_millis());
let start = std::time::Instant::now();
for bx in 0..4 {
for bz in 0..4 {
let brick_id = renderer.brick_get_id(bx, 0, bz);
renderer.brick_mark_changed(brick_id);
for x in 0..32 {
for z in 0..32 {
// Dirt
for y in 0..31 {
renderer.brick_set_voxel(brick_id, x, y, z, 1);
}
// Grass
renderer.brick_set_voxel(brick_id, x, 31, z, 2);
}
}
}
}
println!("Generated in {}ms", start.elapsed().as_millis());
Self { window, renderer, camera_controller, world_gen }
}
pub fn input(&mut self, event: Arc<Event<()>>) {
+16
View File
@@ -0,0 +1,16 @@
use std::sync::Arc;
use crate::renderer::Renderer;
pub struct WorldGen {
}
impl WorldGen {
pub fn new() -> Self {
Self{}
}
pub fn generate(&mut self, renderer: Renderer) {
}
}
+1 -2
View File
@@ -20,8 +20,7 @@ fn main() {
.with_inner_size(LogicalSize::new(1280.0, 720.0))
.build(&events)
.expect("Failed to create window");
let _renderer = futures::executor::block_on(Renderer::new(&_window));
let mut app = App::new(_window, _renderer);
let mut app = App::new(_window);
// Stats
let mut fps_timer = std::time::Instant::now();
+23 -46
View File
@@ -1,42 +1,22 @@
use wgpu::util::DeviceExt;
use std::convert::TryInto;
use rand::prelude::*;
const BRICK_SIZE : usize = 32; // 32x32x32 brick size
const BRICK_NUM : usize = 10000; // x bricks in texture
const BRICK_LEN : usize = BRICK_SIZE*BRICK_SIZE*BRICK_SIZE;
use crate::renderer::buffers::{BRICK_SIZE, BRICK_NUM, BRICK_LEN};
const DATA_LEN : usize = BRICK_LEN * BRICK_NUM;
struct BrickData {
pub data: Box<[u8]>
}
impl BrickData {
pub fn new() -> Self {
let data = vec![0_u8; DATA_LEN].into_boxed_slice();
Self { data }
}
pub fn set(&mut self, brick: usize, x: usize, y: usize, z: usize, value: u8)
{
let local_idx = x + BRICK_SIZE * (y + BRICK_SIZE * z);
let offset = brick * BRICK_LEN;
self.data[offset + local_idx] = value;
}
}
pub struct BrickBuffer {
bricks: BrickData,
pub bricks: Box<[u8]>,
pub free_brick: usize,
texture: wgpu::Texture,
size: wgpu::Extent3d,
pub bind_layout: wgpu::BindGroupLayout,
pub bind_group: wgpu::BindGroup
}
impl BrickBuffer {
/*
* Create buffer in memory and gpu
*/
pub fn new(device: &wgpu::Device) -> Self {
// Create texture
@@ -93,36 +73,24 @@ impl BrickBuffer {
);
// Data
let mut bricks = BrickData::new();
let mut bricks = vec![0_u8; DATA_LEN].into_boxed_slice();
bricks[0] = 1;
println!("Brick buffer size: {} MB", DATA_LEN as f32 / 1024.0 / 1024.0);
let mut rng = rand::thread_rng();
for x in 0..32 {
for y in 0..32 {
for z in 0..32 {
let value = if rng.gen::<f32>()> 0.99 { 1 } else { 0 };
bricks.set(0, x, y, z, value);
bricks.set(1, x, 0, z, 1);
}
}
}
bricks.set(1, 20, 5, 16, 1);
// Done
Self { bricks, texture, size, bind_layout, bind_group }
Self { bricks, texture, bind_layout, bind_group, free_brick: 0 }
}
/*
Write brick data to gpu, should be called to apply changes
offset: Brick index to copy
*/
pub fn write(&mut self, queue: &wgpu::Queue, offset: usize)
{
pub fn write(&mut self, queue: &wgpu::Queue, brick: usize) {
// Get first brick
let brick_offset = offset*BRICK_LEN;
let brick_bytes : [u8;BRICK_LEN] = self.bricks.data[brick_offset..brick_offset+BRICK_LEN].try_into().unwrap();
let brick_offset = brick*BRICK_LEN;
let brick_bytes : [u8;BRICK_LEN] = self.bricks[brick_offset..brick_offset+BRICK_LEN].try_into().unwrap();
let brick_size = wgpu::Extent3d{ width: BRICK_SIZE as u32, height: BRICK_SIZE as u32, depth: BRICK_SIZE as u32 };
let brick_origin = wgpu::Origin3d{ x:0, y:0, z: (offset*BRICK_SIZE) as u32 };
let brick_origin = wgpu::Origin3d{ x:0, y:0, z: (brick*BRICK_SIZE) as u32 };
// Write
queue.write_texture(
@@ -132,4 +100,13 @@ impl BrickBuffer {
brick_size
);
}
pub fn next_brick(&mut self) -> usize {
if self.free_brick >= self.bricks.len() {
panic!("No more free bricks! we should consider reusing bricks...");
}
self.free_brick += 1;
self.free_brick
}
}
+74
View File
@@ -0,0 +1,74 @@
use wgpu::util::DeviceExt;
#[repr(C)]
#[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct Material {
pub albedo: [f32; 4],
}
impl Material {
pub fn set_albedo(&mut self, r: f32, g: f32, b:f32)
{
self.albedo[0] = r;
self.albedo[1] = g;
self.albedo[2] = b;
}
}
pub struct MaterialBuffer {
materials: [Material; 256],
pub buffer: wgpu::Buffer,
pub bind_layout: wgpu::BindGroupLayout,
pub bind_group: wgpu::BindGroup
}
impl MaterialBuffer {
pub fn new(device: &wgpu::Device) -> Self {
// Create values
let mut materials: [Material; 256] = [Default::default(); 256];
materials[0].set_albedo(0.41,0.33,0.20);
materials[1].set_albedo(0.49,0.74,0.00);
// Create buffer
let buffer = device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Materials buffer"),
contents: bytemuck::cast_slice(&materials),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
}
);
// Create bind group
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}
],
label: Some("Materials buffer layout"),
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: buffer.as_entire_binding(),
}
],
label: Some("Materials buffer group"),
});
// Done
MaterialBuffer { buffer, materials, bind_layout, bind_group }
}
}
+16 -2
View File
@@ -1,9 +1,20 @@
// Consts
pub const WORLD_SIZE: usize = 32;
pub const NUM_NODES: usize = (WORLD_SIZE*WORLD_SIZE*WORLD_SIZE) as usize;
pub const BRICK_SIZE : usize = 32; // 32x32x32 brick size
pub const BRICK_NUM : usize = 32768; // max bricks in texture
pub const BRICK_LEN : usize = BRICK_SIZE*BRICK_SIZE*BRICK_SIZE;
// Import names
mod node_buffer;
pub use node_buffer::NodeBuffer;
mod brick_buffer;
pub use brick_buffer::BrickBuffer;
pub use brick_buffer::{BrickBuffer};
mod uniform_buffer;
pub use uniform_buffer::UniformBuffer;
@@ -11,4 +22,7 @@ pub use uniform_buffer::UniformValues;
mod raster_buffer;
pub use raster_buffer::RasterBuffer;
pub use raster_buffer::Vertex;
pub use raster_buffer::Vertex;
mod material_buffer;
pub use material_buffer::MaterialBuffer;
+5 -41
View File
@@ -1,31 +1,10 @@
use byteorder::{ByteOrder, LittleEndian};
use rand::prelude::*;
// 4x4x4 nodes
const WORLD_SIZE: usize = 32;
const NUM_NODES: usize = (WORLD_SIZE*WORLD_SIZE*WORLD_SIZE) as usize;
struct NodeData {
pub data: Box<[u32]>
}
impl NodeData {
pub fn new() -> Self {
let data = vec![0_u32; NUM_NODES].into_boxed_slice();
Self { data }
}
pub fn set(&mut self, x: usize, y: usize, z: usize, value: u32)
{
let idx = x + WORLD_SIZE * (y + WORLD_SIZE * z);
self.data[idx] = value;
}
}
use crate::renderer::buffers::{WORLD_SIZE, NUM_NODES};
pub struct NodeBuffer {
nodes: NodeData,
pub nodes: Box<[u32]>,
texture: wgpu::Texture,
size: wgpu::Extent3d,
pub bind_layout: wgpu::BindGroupLayout,
@@ -90,23 +69,8 @@ impl NodeBuffer {
);
// Data
let mut nodes = NodeData::new();
// let mut rng = rand::thread_rng();
// for x in 0..WORLD_SIZE {
// for y in 0..WORLD_SIZE {
// for z in 0..WORLD_SIZE {
// let value = if rng.gen::<f32>()> 0.5 { 1 } else { 0 };
// nodes.set(x, y, z, value);
// }
// }
// }
for i in 0..WORLD_SIZE {
nodes.set(i, 0, 0, 1);
nodes.set(0, i, 0, 1);
nodes.set(0, 0, i, 1);
}
nodes.set(0, 0, 0, 2);
let nodes = vec![0_u32; NUM_NODES].into_boxed_slice();
println!("Node buffer size: {} MB", nodes.len() as f32 * 4.0 / 1024.0 / 1024.0);
// Done
Self { nodes, texture, size, bind_layout, bind_group }
@@ -115,7 +79,7 @@ impl NodeBuffer {
pub fn write(&mut self, queue: &wgpu::Queue) {
// Convert 32 bit values to 8 bit
let mut bytes = [0_u8; NUM_NODES*4];
LittleEndian::write_u32_into(&self.nodes.data, &mut bytes);
LittleEndian::write_u32_into(&self.nodes, &mut bytes);
// Write
queue.write_texture(
+86 -13
View File
@@ -1,6 +1,8 @@
use winit::{window::Window, dpi::PhysicalSize};
mod buffers; use buffers::{NodeBuffer, BrickBuffer, UniformBuffer, RasterBuffer, Vertex};
mod buffers;
use buffers::{NodeBuffer, BrickBuffer, UniformBuffer, RasterBuffer, Vertex, MaterialBuffer};
pub mod camera; use camera::Camera;
@@ -16,9 +18,11 @@ pub struct Renderer {
uniform_buffer: UniformBuffer,
node_buffer: NodeBuffer,
brick_buffer: BrickBuffer,
material_buffer: MaterialBuffer,
// Other
pub camera: Camera,
start: std::time::Instant
start: std::time::Instant,
changed_bricks: Vec<usize>,
}
impl Renderer {
@@ -82,6 +86,9 @@ impl Renderer {
})
}
/*
* Initializes renderer and all buffers
*/
pub async fn new(window: &Window) -> Self {
// Create surface and pick device
@@ -107,24 +114,29 @@ impl Renderer {
// Buffers
let uniform_buffer = UniformBuffer::new(&device);
let raster_buffer = RasterBuffer::new(&device);
let mut node_buffer = NodeBuffer::new(&device);
node_buffer.write(&queue);
let mut brick_buffer = BrickBuffer::new(&device);
brick_buffer.write(&queue, 0);
brick_buffer.write(&queue, 1);
let node_buffer = NodeBuffer::new(&device);
let brick_buffer = BrickBuffer::new(&device);
let material_buffer = MaterialBuffer::new(&device);
// Pipeline
let pipeline = Self::create_pipeline(&device, &swapchain_desc, &[&uniform_buffer.bind_layout, &node_buffer.bind_layout, &brick_buffer.bind_layout]);
let start = std::time::Instant::now();
let bind_layouts = [
&uniform_buffer.bind_layout,
&node_buffer.bind_layout,
&brick_buffer.bind_layout,
&material_buffer.bind_layout
];
let pipeline = Self::create_pipeline(&device, &swapchain_desc, &bind_layouts);
// Save values in app
println!("Initialized");
Self { surface, device, queue, swapchain_desc, swapchain, pipeline, raster_buffer, uniform_buffer, node_buffer, brick_buffer, camera, start }
let start = std::time::Instant::now();
let changed_bricks: Vec<usize> = Vec::new();
Self { surface, device, queue, swapchain_desc, swapchain, pipeline, raster_buffer, uniform_buffer, node_buffer, brick_buffer, material_buffer, camera, start, changed_bricks }
}
/*
* Recreates swapchain with new resolution
*/
pub fn resize(&mut self, new_size: Option<PhysicalSize<u32>>) {
if let Some(size) = new_size {
// Minimized or manually resized to 0
@@ -139,12 +151,24 @@ impl Renderer {
self.swapchain = self.device.create_swap_chain(&self.surface, &self.swapchain_desc);
}
/*
* Actually renders the frame
*/
pub fn render(&mut self) -> Result<(), wgpu::SwapChainError> {
// Update uniform buffer
self.uniform_buffer.values.update(&self.camera, self.start.elapsed().as_secs_f32());
self.queue.write_buffer(&self.uniform_buffer.buffer, 0, bytemuck::cast_slice(&[self.uniform_buffer.values]));
// Update changed nodes
if self.changed_bricks.len() > 0 {
self.node_buffer.write(&self.queue);
for node in &self.changed_bricks {
self.brick_buffer.write(&self.queue, *node);
}
self.changed_bricks.clear();
}
// Get next frame to render to
let frame = self.swapchain.get_current_frame()?.output;
@@ -171,6 +195,7 @@ impl Renderer {
render_pass.set_bind_group(0, &self.uniform_buffer.bind_group, &[]);
render_pass.set_bind_group(1, &self.node_buffer.bind_group, &[]);
render_pass.set_bind_group(2, &self.brick_buffer.bind_group, &[]);
render_pass.set_bind_group(3, &self.material_buffer.bind_group, &[]);
// Vertices and indices
render_pass.set_vertex_buffer(0, self.raster_buffer.vertex_buffer.slice(..));
render_pass.set_index_buffer(self.raster_buffer.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
@@ -183,4 +208,52 @@ impl Renderer {
// Return ok
Ok(())
}
/*
* Create or update brick at given location
*/
#[allow(dead_code)]
pub fn set_voxel(&mut self, x: usize, y: usize, z:usize, value: u8)
{
let brick_id = self.brick_get_id(x/32, y/32, z/32 );
self.brick_set_voxel(brick_id, x%32, y%32, z%32, value);
self.brick_mark_changed(brick_id);
}
/*
* Create or update brick at given location
*/
pub fn brick_set_voxel(&mut self, brick_id:usize, x: usize, y: usize, z:usize, value: u8)
{
let voxel_id = x + buffers::BRICK_SIZE * (y + buffers::BRICK_SIZE * z);
let brick_offset = brick_id * buffers::BRICK_LEN;
self.brick_buffer.bricks[brick_offset + voxel_id] = value;
}
/*
* Gets brick id
*/
pub fn brick_get_id(&mut self, x: usize, y: usize, z:usize) -> usize {
// Get node
let node_idx = x + buffers::WORLD_SIZE * (y + buffers::WORLD_SIZE * z);
let mut node_value = self.node_buffer.nodes[node_idx];
// Use new brick if neccesary
if node_value == 0 {
node_value = self.brick_buffer.next_brick() as u32;
self.node_buffer.nodes[node_idx] = node_value;
}
// Get brick id from node value
(node_value - 1) as usize
}
/*
* Marks brick as changed
*/
pub fn brick_mark_changed(&mut self, brick_id:usize) {
if !self.changed_bricks.contains(&brick_id) {
self.changed_bricks.push(brick_id);
}
}
}
Binary file not shown.
+6 -30
View File
@@ -1,28 +1,9 @@
/*
point: Hit point
view: View vector (camera ray)
normal: Normal vector
*/
vec3 solve(vec3 hitPoint, vec3 view, vec3 normal)
{
// Lighting
vec3 light_color = vec3(1.0, 1.0, 1.0);
vec3 light_dir = normalize(hitPoint-vec3(0.0, 1.5, 4.0));
vec3 ambient = light_color * 0.1;
vec3 diffuse = light_color * max(1.0-dot(normal, light_dir), 0.0);
vec3 specular = light_color * pow(max(dot(view, reflect(-light_dir, normal)), 0.0), 32);
// Combine colors
vec3 object_color = vec3(0.0, 0.1, 0.5);
return (ambient + diffuse + specular) * object_color;
}
/*
* origin: Point hit on the node
* dir: Camera view direction (ray direction)
* addr: Number given by node, afaik brick offset in brick array
* incAxis: Last axis that was used to increment position
* addr: Number given by node, brick offset in brick array
*/
vec4 castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr)
{
@@ -38,14 +19,12 @@ vec4 castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr)
vec3 rayInv = 1.0/dir;
vec3 raySign = sign(dir);
vec3 dist = (pos-origin+0.5 + raySign*0.5) * rayInv;
ivec3 offset = ivec3(0, 0, (addr-1)*32);
vec3 tmp = abs(raySign);
for(int i=0;i<110;i++)
{
// Get brick
uint brick = texelFetch(bricksTexture, offset+ivec3(pos), 0).r;
uint brick = texelFetch(_BricksTexture, offset+ivec3(pos), 0).r;
if(brick != 0)
{
// Hit point
@@ -55,7 +34,7 @@ vec4 castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr)
// Normal vector (negate previous increment axis and mult by sign)
vec3 normal = -incAxis * raySign;
return vec4(solve(hitPoint, dir, normal), 1.0);
return vec4(solve(hitPoint, dir, normal, brick-1), 1.0);
}
// Get new closest axis to increment
@@ -68,7 +47,7 @@ vec4 castBricks(vec3 origin, vec3 start, vec3 dir, vec3 incAxis, uint addr)
if(pos.x > 31 || pos.y > 31 || pos.z > 31) { break; }
}
return vec4(0.5,0.5,0.5, 0.0);
return vec4(1.0,0.0,0.5,0.0);
}
/*
@@ -93,16 +72,13 @@ vec3 castNodes(vec3 origin, vec3 dir)
for(int i=0;i<110;i++)
{
// Get node
uint node = texelFetch(nodesTexture, ivec3(pos), 0).r;
uint node = texelFetch(_NodesTexture, ivec3(pos), 0).r;
if(node != 0)
{
// Hit point
vec3 mini = (pos-origin+0.5 - raySign*0.5) * rayInv;
float len = max(0.0, max(mini.x, max(mini.y, mini.z)));
vec3 hitPoint = origin + dir * len;
// Normal vector (negate previous increment axis and mult by sign)
//vec3 normal = -incAxis * raySign;
//return solve(hitPoint, dir, normal);
// Cast brick
vec4 result = castBricks(pos, hitPoint, dir, incAxis, node);
-91
View File
@@ -1,91 +0,0 @@
// Returns nearest distance to and object id from given point
vec2 map(in vec3 pos)
{
vec2 d1 = vec2(sdPlane(pos), 1);
vec2 d2 = vec2(sdSphere(pos - vec3(0.0, 2.0, 5.0)), 2);
vec2 d3 = vec2(sdSphere(pos - vec3(0.0, 3.0, 3.0)), 3);
return sdUnion(sdUnion(d1, d2), d3);
}
// Returns distance to and object id that has been intersected by ray
vec2 intersect(in vec3 ro, in vec3 rd)
{
float depth = NEAR;
for(int i=0;i<MAX_STEPS;i++)
{
// Travel through map
vec2 dist = map(ro + rd * depth);
if(dist.x < EPSILON)
{
// Hit something
return vec2(depth, dist.y);
}
// Move further
depth += dist.x;
}
// Nothing found
return vec2(0);
}
vec3 estimateNormal(vec3 p)
{
return normalize(vec3(
map(vec3(p.x + EPSILON, p.y, p.z)).x - map(vec3(p.x - EPSILON, p.y, p.z)).x,
map(vec3(p.x, p.y + EPSILON, p.z)).x - map(vec3(p.x, p.y - EPSILON, p.z)).x,
map(vec3(p.x, p.y, p.z + EPSILON)).x - map(vec3(p.x, p.y, p.z - EPSILON)).x
));
}
vec3 raymarch(in vec3 ro, in vec3 rd)
{
// Light dir
vec3 ld = normalize(vec3(-0.5, 2.0, -0.2));
vec2 result = intersect(ro, rd);
if(result.y > 0.0)
{
// Calculate intersection point, normal vector and reflection vector
vec3 pos = ro + rd * result.x;
vec3 nor = estimateNormal(pos);
vec3 ref = reflect(rd, nor);
// Light
vec3 light = vec3(1);
float dif = clamp( dot( nor, ld ), 0.0, 1.0 );
light += 2.20*dif*vec3(1.30,1.00,0.70);
vec3 hal = normalize( ld-rd );
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0);
spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,ld),0.0,1.0),5.0);
light += 5.00*spe*vec3(1.30,1.00,0.70);
//float diffuse = max(dot(norm, -ld), 0);
//color *= diffuse;
//vec3 ldr = normalize(reflect(-ld, norm));
//float specular = max(dot(ldr, rd), 0.0);
//specular = pow(specular, 3);
//color += vec3(0.2) * specular;
//float scatter = pow(1.0-dot(rd, -norm), 2);
// Calculate color
vec3 color = vec3(0);
if(result.y == 1) color = vec3(0.0, 0.1, 0.01);
else if(result.y == 2) color = vec3(0.5, 0.7, 0.05);
else if(result.y == 3) color = vec3(0.0, 0.2, 0.7);
// Return
color *= light;
return color;
}
else
{
return vec3(0);
}
}
+19 -16
View File
@@ -1,38 +1,41 @@
// shader.frag
#version 450
struct Material {
vec4 albedo;
};
// Variables
layout(location=0) in vec2 vert_uv;
layout(location=0) out vec4 out_color;
layout(set=0, binding=0) uniform Uniforms
{
mat4 _viewMatrix;
mat4 _projMatrixInv;
layout(set=0,binding=0) uniform Uniforms {
mat4 _ViewMatrix;
mat4 _ProjMatrixInv;
vec3 _CamPos;
float _Time;
};
//layout(set = 1, binding = 0) uniform texture3D node_tex;
//layout(set = 1, binding = 1) uniform usampler3D node_sampl;
layout(set=1,binding=0) uniform usampler3D nodesTexture;
layout(set=2,binding=0) uniform usampler3D bricksTexture;
layout(set=1,binding=0) uniform usampler3D _NodesTexture;
layout(set=2,binding=0) uniform usampler3D _BricksTexture;
layout(set=3, binding=0) uniform Materials {
Material _Materials[256];
};
// Defines
#define PI 3.141592
#define EPSILON 0.01
#define NEAR 0.01
#define MAX_STEPS 200
// #define PI 3.141592
// #define EPSILON 0.01
// #define NEAR 0.01
// Include
#include "shapes.cginc"
#include "shading.cginc"
#include "raycasting.cginc"
void main()
{
// Calculate ray direction
vec3 view_dir = (_projMatrixInv * vec4(vert_uv, 0, 1)).xyz;
vec3 ray_dir = normalize(_viewMatrix * vec4(view_dir,0)).xyz;
vec3 view_dir = (_ProjMatrixInv * vec4(vert_uv, 0, 1)).xyz;
vec3 ray_dir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz;
// Raycast
out_color = vec4(castNodes(_CamPos, ray_dir), 1.0);
+19
View File
@@ -0,0 +1,19 @@
/*
point: Hit point
view: View vector (camera ray)
normal: Normal vector
*/
vec3 solve(vec3 hitPoint, vec3 view, vec3 normal, uint brick)
{
// Lighting
vec3 light_color = vec3(1.0, 1.0, 1.0);
vec3 light_dir = normalize(hitPoint-vec3(0.0, 1.5, 4.0));
vec3 ambient = light_color * 0.1;
vec3 diffuse = light_color * max(1.0-dot(normal, light_dir), 0.0);
vec3 specular = light_color * pow(max(dot(view, reflect(-light_dir, normal)), 0.0), 32);
// Combine colors
vec3 object_color = _Materials[brick].albedo.rgb;//vec3(0.0, 0.1, 0.5);
return (ambient + diffuse + specular) * object_color;
}