diff --git a/src/main.rs b/src/main.rs index 9902575..b843eae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,6 +56,7 @@ pub struct Skybox { camera: Camera, sky_pipeline: wgpu::RenderPipeline, entity_pipeline: wgpu::RenderPipeline, + ground_pipeline: wgpu::RenderPipeline, bind_group: wgpu::BindGroup, uniform_buf: wgpu::Buffer, entities: Vec, @@ -251,6 +252,33 @@ impl strafe_client::framework::Example for Skybox { multisample: wgpu::MultisampleState::default(), multiview: None, }); + let ground_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Ground"), + layout: Some(&pipeline_layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_ground", + buffers: &[], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_ground", + targets: &[Some(config.view_formats[0].into())], + }), + primitive: wgpu::PrimitiveState { + front_face: wgpu::FrontFace::Cw, + ..Default::default() + }, + depth_stencil: Some(wgpu::DepthStencilState { + format: Self::DEPTH_FORMAT, + depth_write_enabled: false, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + }), + multisample: wgpu::MultisampleState::default(), + multiview: None, + }); let sampler = device.create_sampler(&wgpu::SamplerDescriptor { label: None, @@ -360,6 +388,7 @@ impl strafe_client::framework::Example for Skybox { camera, sky_pipeline, entity_pipeline, + ground_pipeline, bind_group, uniform_buf, entities, @@ -449,6 +478,9 @@ impl strafe_client::framework::Example for Skybox { rpass.draw(0..entity.vertex_count, 0..1); } + rpass.set_pipeline(&self.ground_pipeline); + rpass.draw(0..3, 0..1); + rpass.set_pipeline(&self.sky_pipeline); rpass.draw(0..3, 0..1); } diff --git a/src/shader.wgsl b/src/shader.wgsl index deb6715..7ae2d05 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -39,6 +39,32 @@ fn vs_sky(@builtin(vertex_index) vertex_index: u32) -> SkyOutput { return result; } +struct GroundOutput { + @builtin(position) position: vec4, + @location(1) normal: vec3, + @location(3) view: vec3, + @location(4) pos: vec3, +}; + +@vertex +fn vs_ground(@builtin(vertex_index) vertex_index: u32) -> GroundOutput { + // hacky way to draw two triangles that make a square + let tmp1 = (i32(vertex_index)-i32(vertex_index)/3*2) / 2; + let tmp2 = (i32(vertex_index)-i32(vertex_index)/3*2) & 1; + let pos = vec3( + f32(tmp1) * 2.0 - 1.0, + 0.0, + f32(tmp2) * 2.0 - 1.0 + ) * 100.0; + + var result: GroundOutput; + result.normal = vec3(0.0,1.0,0.0); + result.pos = pos; + result.view = pos - r_data.cam_pos.xyz; + result.position = r_data.proj * r_data.view * vec4(pos, 1.0); + return result; +} + struct EntityOutput { @builtin(position) position: vec4, @location(1) normal: vec3, @@ -78,3 +104,15 @@ fn fs_entity(vertex: EntityOutput) -> @location(0) vec4 { let reflected_color = textureSample(r_texture, r_sampler, reflected).rgb; return vec4(vec3(0.1) + 0.5 * reflected_color, 1.0); } + +@fragment +fn fs_ground(vertex: GroundOutput) -> @location(0) vec4 { + //let incident = normalize(vertex.view); + //let normal = normalize(vertex.normal+vec3(cos(vertex.pos.x)/16.0,0.0,sin(vertex.pos.z)/16.0)); + //let reflected = incident - 2.0 * dot(normal, incident) * normal; + + //let reflected_color = textureSample(r_texture, r_sampler, reflected).rgb; + //return vec4(vec3(0.1) + 0.5 * reflected_color, 1.0); + let dir = vec3(-1.0)+vec3(vertex.pos.x/16.%1.0,0.0,vertex.pos.z/16.%1.0)*2.0; + return vec4(textureSample(r_texture, r_sampler, dir).rgb, 1.0); +}