diff --git a/src/main.rs b/src/main.rs index 9c2687d..c4170cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -113,21 +113,14 @@ impl Camera { } } - -pub struct SamplerBindGroups { - clamp: wgpu::BindGroup, - repeat: wgpu::BindGroup, -} - pub struct GraphicsBindGroups { camera: wgpu::BindGroup, skybox_texture: wgpu::BindGroup, - sampler: SamplerBindGroups, } pub struct GraphicsPipelines { skybox: wgpu::RenderPipeline, - entity: wgpu::RenderPipeline, + model: wgpu::RenderPipeline, } pub struct GraphicsData { @@ -290,7 +283,7 @@ impl strafe_client::framework::Example for GraphicsData { ], }); let skybox_texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: None, + label: Some("Skybox Texture Bind Group Layout"), entries: &[ wgpu::BindGroupLayoutEntry { binding: 0, @@ -302,13 +295,8 @@ impl strafe_client::framework::Example for GraphicsData { }, count: None, }, - ], - }); - let texture_filter_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: None, - entries: &[ wgpu::BindGroupLayoutEntry { - binding: 0, + binding: 1, visibility: wgpu::ShaderStages::FRAGMENT, ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), count: None, @@ -316,7 +304,7 @@ impl strafe_client::framework::Example for GraphicsData { ], }); let model_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: Some("Model"), + label: Some("Model Bind Group Layout"), entries: &[ wgpu::BindGroupLayoutEntry { binding: 0, @@ -328,9 +316,46 @@ impl strafe_client::framework::Example for GraphicsData { }, count: None, }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + multisampled: false, + view_dimension: wgpu::TextureViewDimension::D2, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, ], }); + let clamp_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("Clamp Sampler"), + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Linear, + ..Default::default() + }); + let repeat_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("Repeat Sampler"), + address_mode_u: wgpu::AddressMode::Repeat, + address_mode_v: wgpu::AddressMode::Repeat, + address_mode_w: wgpu::AddressMode::Repeat, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Linear, + ..Default::default() + }); + // Create the render pipeline let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: None, @@ -388,6 +413,14 @@ impl strafe_client::framework::Example for GraphicsData { binding: 0, resource: model_buf.as_entire_binding(), }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView(&squid_texture_view), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: wgpu::BindingResource::Sampler(&repeat_sampler), + }, ], label: Some(format!("ModelGraphics{}",i).as_str()), }); @@ -407,14 +440,13 @@ impl strafe_client::framework::Example for GraphicsData { &camera_bind_group_layout, &model_bind_group_layout, &skybox_texture_bind_group_layout, - &texture_filter_bind_group_layout, ], push_constant_ranges: &[], }); // Create the render pipelines let sky_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("Sky"), + label: Some("Sky Pipeline"), layout: Some(&pipeline_layout), vertex: wgpu::VertexState { module: &shader, @@ -440,8 +472,8 @@ impl strafe_client::framework::Example for GraphicsData { multisample: wgpu::MultisampleState::default(), multiview: None, }); - let entity_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("Entity"), + let model_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Model Pipeline"), layout: Some(&pipeline_layout), vertex: wgpu::VertexState { module: &shader, @@ -472,27 +504,6 @@ impl strafe_client::framework::Example for GraphicsData { multiview: None, }); - let clamp_sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: Some("Clamp Sampler"), - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Linear, - ..Default::default() - }); - let repeat_sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: Some("Repeat Sampler"), - address_mode_u: wgpu::AddressMode::Repeat, - address_mode_v: wgpu::AddressMode::Repeat, - address_mode_w: wgpu::AddressMode::Repeat, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Linear, - ..Default::default() - }); - let device_features = device.features(); let skybox_format = if device_features.contains(wgpu::Features::TEXTURE_COMPRESSION_ASTC) { @@ -583,29 +594,12 @@ impl strafe_client::framework::Example for GraphicsData { binding: 0, resource: wgpu::BindingResource::TextureView(&skybox_texture_view), }, - ], - label: Some("Sky Texture"), - }); - - let clamp_sampler_texture_filter_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &texture_filter_bind_group_layout, - entries: &[ wgpu::BindGroupEntry { - binding: 0, + binding: 1, resource: wgpu::BindingResource::Sampler(&clamp_sampler), }, ], - label: Some("Clamp Sampler Bind Group"), - }); - let repeat_sampler_texture_filter_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &texture_filter_bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Sampler(&repeat_sampler), - }, - ], - label: Some("Repeat Sampler Bind Group"), + label: Some("Sky Texture"), }); let depth_view = Self::create_depth_texture(config, device); @@ -616,15 +610,11 @@ impl strafe_client::framework::Example for GraphicsData { physics, pipelines:GraphicsPipelines{ skybox:sky_pipeline, - entity:entity_pipeline + model:model_pipeline }, bind_groups:GraphicsBindGroups{ camera:camera_bind_group, skybox_texture:skybox_texture_bind_group, - sampler:SamplerBindGroups{ - clamp:clamp_sampler_texture_filter_bind_group, - repeat:repeat_sampler_texture_filter_bind_group, - } }, camera_buf, models, @@ -798,9 +788,8 @@ impl strafe_client::framework::Example for GraphicsData { rpass.set_bind_group(0, &self.bind_groups.camera, &[]); rpass.set_bind_group(2, &self.bind_groups.skybox_texture, &[]); - rpass.set_bind_group(3, &self.bind_groups.sampler.repeat, &[]); - rpass.set_pipeline(&self.pipelines.entity); + rpass.set_pipeline(&self.pipelines.model); for model in self.models.iter() { rpass.set_bind_group(1, &model.bind_group, &[]); rpass.set_vertex_buffer(0, model.vertex_buf.slice(..)); @@ -812,8 +801,6 @@ impl strafe_client::framework::Example for GraphicsData { } rpass.set_pipeline(&self.pipelines.skybox); - rpass.set_bind_group(2, &self.bind_groups.skybox_texture, &[]); - rpass.set_bind_group(3, &self.bind_groups.sampler.clamp, &[]); rpass.draw(0..3, 0..1); } diff --git a/src/shader.wgsl b/src/shader.wgsl index a43b102..a2f1fe7 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -8,6 +8,8 @@ struct Camera { // camera position cam_pos: vec4, }; + +//group 0 is the camera @group(0) @binding(0) var camera: Camera; @@ -39,13 +41,8 @@ fn vs_sky(@builtin(vertex_index) vertex_index: u32) -> SkyOutput { return result; } -struct EntityOutputTexture { - @builtin(position) position: vec4, - @location(1) texture: vec2, - @location(2) normal: vec3, - @location(3) view: vec3, -}; const MAX_ENTITY_INSTANCES=1024; +//group 1 is the model @group(1) @binding(0) var entity_transforms: array,MAX_ENTITY_INSTANCES>; @@ -53,7 +50,19 @@ var entity_transforms: array,MAX_ENTITY_INSTANCES>; //my fancy idea is to create a megatexture for each model that includes all the textures each intance will need //the texture transform then maps the texture coordinates to the location of the specific texture //how to do no texture? +@group(1) +@binding(1) +var model_texture: texture_2d; +@group(1) +@binding(2) +var model_sampler: sampler; +struct EntityOutputTexture { + @builtin(position) position: vec4, + @location(1) texture: vec2, + @location(2) normal: vec3, + @location(3) view: vec3, +}; @vertex fn vs_entity_texture( @builtin(instance_index) instance: u32, @@ -70,19 +79,17 @@ fn vs_entity_texture( return result; } -//group 2 is texture bindings +//group 2 is the skybox texture @group(2) @binding(0) var cube_texture: texture_cube; - -//group 3 is texture sampler -@group(3) -@binding(0) -var texture_sampler: sampler; +@group(2) +@binding(1) +var cube_sampler: sampler; @fragment fn fs_sky(vertex: SkyOutput) -> @location(0) vec4 { - return textureSample(cube_texture, texture_sampler, vertex.sampledir); + return textureSample(cube_texture, model_sampler, vertex.sampledir); } @fragment @@ -92,8 +99,7 @@ fn fs_entity_texture(vertex: EntityOutputTexture) -> @location(0) vec4 { let d = dot(normal, incident); let reflected = incident - 2.0 * d * normal; - let dir = vec3(-1.0)+2.0*vec3(vertex.texture.x,0.0,vertex.texture.y); - let fragment_color = textureSample(cube_texture, texture_sampler, dir).rgb; - let reflected_color = textureSample(cube_texture, texture_sampler, reflected).rgb; + let fragment_color = textureSample(model_texture, model_sampler, vertex.texture).rgb; + let reflected_color = textureSample(cube_texture, cube_sampler, reflected).rgb; return vec4(mix(vec3(0.1) + 0.5 * reflected_color,fragment_color,1.0-pow(1.0-abs(d),2.0)), 1.0); }