2020-11-24 06:49:43 +00:00
<!DOCTYPE html>
< html lang = "en-US" >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width,initial-scale=1" >
< title > Working with Lights | Learn Wgpu< / title >
< meta name = "description" content = "" >
< meta name = "generator" content = "VuePress 1.4.0" >
2021-08-09 20:59:53 +00:00
< meta property = "article:modified_time" content = "2021-08-04T13:06:53.000Z" > < meta property = "og:site_name" content = "Learn Wgpu" > < meta property = "og:title" content = "Working with Lights" > < meta property = "og:type" content = "website" > < meta property = "og:url" content = "/intermediate/tutorial10-lighting/" > < meta name = "twitter:title" content = "Working with Lights" > < meta name = "twitter:url" content = "/intermediate/tutorial10-lighting/" > < meta name = "twitter:card" content = "summary_large_image" > < meta name = "twitter:label1" content = "Written by" > < meta name = "twitter:data2" content = "Benjamin R Hansen" > < meta name = "twitter:creator" content = "https://twitter.com/sotrh760" >
2021-08-15 17:04:20 +00:00
< link rel = "preload" href = "/learn-wgpu/assets/css/0.styles.e2608c6d.css" as = "style" > < link rel = "preload" href = "/learn-wgpu/assets/js/app.7f3b47c3.js" as = "script" > < link rel = "preload" href = "/learn-wgpu/assets/js/2.da3fd46f.js" as = "script" > < link rel = "preload" href = "/learn-wgpu/assets/js/3.ee149516.js" as = "script" > < link rel = "preload" href = "/learn-wgpu/assets/js/22.2132e362.js" as = "script" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/10.de8cadfb.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/11.fdda3025.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/12.4285c323.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/13.2da6599a.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/14.3139647c.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/15.4800fa06.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/16.8cb7b62f.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/17.d3375cb5.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/18.83accaf9.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/19.bee0cfc3.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/20.17c44988.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/21.fed3f353.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/23.1a88f225.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/24.5e2c93e5.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/25.5c4d11d0.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/26.745a2634.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/27.04f788d9.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/28.a3ac06e2.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/29.281013fa.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/30.dc887be9.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/4.a1927191.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/5.5061acf7.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/6.a4165a76.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/7.88810c81.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/8.a23f98ec.js" > < link rel = "prefetch" href = "/learn-wgpu/assets/js/9.ecb6e79c.js" >
2021-07-10 16:25:11 +00:00
< link rel = "stylesheet" href = "/learn-wgpu/assets/css/0.styles.e2608c6d.css" >
2020-11-24 06:49:43 +00:00
< / head >
< body >
< div id = "app" data-server-rendered = "true" > < div class = "theme-container" > < header class = "navbar" > < div class = "inner" > < div class = "sidebar-button" > < svg xmlns = "http://www.w3.org/2000/svg" aria-hidden = "true" role = "img" viewBox = "0 0 448 512" class = "icon" > < path fill = "currentColor" d = "M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z" > < / path > < / svg > < / div > < a href = "/learn-wgpu/" class = "home-link router-link-active" > <!-- --> < span class = "site-name" > Learn Wgpu< / span > < / a > < div class = "links" > <!-- --> < div class = "search-box" > < input aria-label = "Search" autocomplete = "off" spellcheck = "false" value = "" > <!-- --> < / div > < / div > < / div > < / header > < div class = "sidebar-mask" > < / div > < div class = "docs-layout" > < aside class = "sidebar" > <!-- --> < ul class = "sidebar-links" > < li > < a href = "/learn-wgpu/" class = "sidebar-link" > Introduction< / a > < / li > < li > < section class = "sidebar-group depth-0" > < p class = "sidebar-heading" > < span > Beginner< / span > <!-- --> < / p > < ul class = "sidebar-links sidebar-group-items" > < li > < a href = "/learn-wgpu/beginner/tutorial1-window/" class = "sidebar-link" > Dependencies and the window< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial2-swapchain/" class = "sidebar-link" > The Swapchain< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial3-pipeline/" class = "sidebar-link" > The Pipeline< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial4-buffer/" class = "sidebar-link" > Buffers and Indices< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial5-textures/" class = "sidebar-link" > Textures and bind groups< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial6-uniforms/" class = "sidebar-link" > Uniform buffers and a 3d camera< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial7-instancing/" class = "sidebar-link" > Instancing< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial8-depth/" class = "sidebar-link" > The Depth Buffer< / a > < / li > < li > < a href = "/learn-wgpu/beginner/tutorial9-models/" class = "sidebar-link" > Model Loading< / a > < / li > < / ul > < / section > < / li > < li > < section class = "sidebar-group depth-0" > < p class = "sidebar-heading open" > < span > Intermediate< / span > <!-- --> < / p > < ul class = "sidebar-links sidebar-group-items" > < li > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/" class = "active sidebar-link" > Working with Lights< / a > < ul class = "sidebar-sub-headers" > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#ray-path-tracing" class = "sidebar-link" > Ray/Path Tracing< / a > < / li > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#the-blinn-phong-model" class = "sidebar-link" > The Blinn-Phong Model< / a > < / li > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#seeing-the-light" class = "sidebar-link" > Seeing the light< / a > < / li > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#ambient-lighting" class = "sidebar-link" > Ambient Lighting< / a > < / li > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#diffuse-lighting" class = "sidebar-link" > Diffuse Lighting< / a > < / li > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#the-normal-matrix" class = "sidebar-link" > The normal matrix< / a > < / li > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#specular-lighting" class = "sidebar-link" > Specular Lighting< / a > < / li > < li class = "sidebar-sub-header" > < a href = "/learn-wgpu/intermediate/tutorial10-lighting/#the-half-direction" class = "sidebar-link" > The half direction< / a > < / li > < / ul > < / li > < li > < a href = "/learn-wgpu/intermediate/tutorial11-normals/" class = "sidebar-link" > Normal Mapping< / a > < / li > < li > < a href = "/learn-wgpu/intermediate/tutorial12-camera/" class = "sidebar-link" > A Better Camera< / a > < / li > < li > < a href = "/learn-wgpu/intermediate/tutorial13-threading/" class = "sidebar-link" > Multi-threading with Wgpu and Rayon< / a > < / li > < / ul > < / section > < / li > < li > < section cl
< span class = "token attribute attr-name" > #[repr(C)]< / span >
< span class = "token attribute attr-name" > #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]< / span >
< span class = "token keyword" > struct< / span > < span class = "token type-definition class-name" > Light< / span > < span class = "token punctuation" > {< / span >
position< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 3< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // Due to uniforms requiring 16 byte (4 float) spacing, we need to use a padding field here< / span >
_padding< span class = "token punctuation" > :< / span > < span class = "token keyword" > u32< / span > < span class = "token punctuation" > ,< / span >
color< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 3< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span >
< / code > < / pre > < / div > < p > Our < code > Light< / code > represents a colored point in space. We're just going to use pure white light, but it's good to allow different colors of light.< / p > < p > We're going to create another buffer to store our light in.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > let< / span > light < span class = "token operator" > =< / span > < span class = "token class-name" > Light< / span > < span class = "token punctuation" > {< / span >
2021-03-29 15:01:03 +00:00
position< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token number" > 2.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 2.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 2.0< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
_padding< span class = "token punctuation" > :< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span >
2021-03-29 15:01:03 +00:00
color< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token number" > 1.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 1.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 1.0< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ;< / span >
< span class = "token comment" > // We'll want to update our lights position, so we use COPY_DST< / span >
< span class = "token keyword" > let< / span > light_buffer < span class = "token operator" > =< / span > device< span class = "token punctuation" > .< / span > < span class = "token function" > create_buffer_init< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > util< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferInitDescriptor< / span > < span class = "token punctuation" > {< / span >
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token string" > " Light VB" < / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
contents< span class = "token punctuation" > :< / span > < span class = "token namespace" > bytemuck< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > cast_slice< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > light< span class = "token punctuation" > ]< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
usage< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferUsage< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > UNIFORM< / span > < span class = "token operator" > |< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferUsage< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > COPY_DST< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< / code > < / pre > < / div > < p > Don't forget to add the < code > light< / code > and < code > light_buffer< / code > to < code > State< / code > . After that we need to create a bind group layout and bind group for our light.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > let< / span > light_bind_group_layout < span class = "token operator" > =< / span >
device< span class = "token punctuation" > .< / span > < span class = "token function" > create_bind_group_layout< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroupLayoutDescriptor< / span > < span class = "token punctuation" > {< / span >
entries< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroupLayoutEntry< / span > < span class = "token punctuation" > {< / span >
2021-03-29 15:01:03 +00:00
binding< span class = "token punctuation" > :< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
visibility< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderStage< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > VERTEX< / span > < span class = "token operator" > |< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderStage< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > FRAGMENT< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
ty< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindingType< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Buffer< / span > < span class = "token punctuation" > {< / span >
ty< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferBindingType< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Uniform< / span > < span class = "token punctuation" > ,< / span >
2021-03-29 15:01:03 +00:00
has_dynamic_offset< span class = "token punctuation" > :< / span > < span class = "token boolean" > false< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
min_binding_size< span class = "token punctuation" > :< / span > < span class = "token class-name" > None< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
count< span class = "token punctuation" > :< / span > < span class = "token class-name" > None< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > None< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > let< / span > light_bind_group < span class = "token operator" > =< / span > device< span class = "token punctuation" > .< / span > < span class = "token function" > create_bind_group< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroupDescriptor< / span > < span class = "token punctuation" > {< / span >
layout< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > light_bind_group_layout< span class = "token punctuation" > ,< / span >
2021-03-29 15:01:03 +00:00
entries< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroupEntry< / span > < span class = "token punctuation" > {< / span >
2020-11-24 06:49:43 +00:00
binding< span class = "token punctuation" > :< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span >
2021-03-29 15:01:03 +00:00
resource< span class = "token punctuation" > :< / span > light_buffer< span class = "token punctuation" > .< / span > < span class = "token function" > as_entire_binding< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > None< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< / code > < / pre > < / div > < p > Add those to < code > State< / code > , and also update the < code > render_pipeline_layout< / code > .< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > let< / span > render_pipeline_layout < span class = "token operator" > =< / span > device< span class = "token punctuation" > .< / span > < span class = "token function" > create_pipeline_layout< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > PipelineLayoutDescriptor< / span > < span class = "token punctuation" > {< / span >
bind_group_layouts< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span >
< span class = "token operator" > & < / span > texture_bind_group_layout< span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > uniform_bind_group_layout< span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > light_bind_group_layout< span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< / code > < / pre > < / div > < p > Let's also update the lights position in the < code > update()< / code > method, so we can see what our objects look like from different angles.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token comment" > // Update the light< / span >
< span class = "token keyword" > let< / span > old_position< span class = "token punctuation" > :< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Vector3< / span > < span class = "token operator" > < < / span > _< span class = "token operator" > > < / span > < span class = "token operator" > =< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > light< span class = "token punctuation" > .< / span > position< span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > light< span class = "token punctuation" > .< / span > position < span class = "token operator" > =< / span >
< span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Quaternion< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > from_axis_angle< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 1.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 0.0< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Deg< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 1.0< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > )< / span >
< span class = "token operator" > *< / span > old_position< span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > queue< span class = "token punctuation" > .< / span > < span class = "token function" > write_buffer< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > light_buffer< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > < span class = "token namespace" > bytemuck< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > cast_slice< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > light< span class = "token punctuation" > ]< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< / code > < / pre > < / div > < p > This will have the light rotate around the origin one degree every frame.< / p > < h2 id = "seeing-the-light" > < a href = "#seeing-the-light" class = "header-anchor" > #< / a > Seeing the light< / h2 > < p > For debugging purposes, it would be nice if we could see where the light is to make sure that the scene looks correct. We could adapt our existing render pipeline to draw the light, but it will likely get in the way. Instead we are going to extract our render pipeline creation code into a new function called < code > create_render_pipeline()< / code > .< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > fn< / span > < span class = "token function-definition function" > create_render_pipeline< / span > < span class = "token punctuation" > (< / span >
device< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Device< / span > < span class = "token punctuation" > ,< / span >
layout< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > PipelineLayout< / span > < span class = "token punctuation" > ,< / span >
color_format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > TextureFormat< / span > < span class = "token punctuation" > ,< / span >
depth_format< span class = "token punctuation" > :< / span > < span class = "token class-name" > Option< / span > < span class = "token operator" > < < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > TextureFormat< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
vertex_layouts< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexBufferLayout< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
2021-05-24 20:23:02 +00:00
shader< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderModuleDescriptor< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > -> < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > RenderPipeline< / span > < span class = "token punctuation" > {< / span >
2021-05-24 20:23:02 +00:00
< span class = "token keyword" > let< / span > shader < span class = "token operator" > =< / span > device< span class = "token punctuation" > .< / span > < span class = "token function" > create_shader_module< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > shader< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2020-11-24 06:49:43 +00:00
device< span class = "token punctuation" > .< / span > < span class = "token function" > create_render_pipeline< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > RenderPipelineDescriptor< / span > < span class = "token punctuation" > {< / span >
2021-03-03 17:40:00 +00:00
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token string" > " Render Pipeline" < / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
layout< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > layout< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
vertex< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexState< / span > < span class = "token punctuation" > {< / span >
2021-05-24 20:23:02 +00:00
module< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > shader< span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
entry_point< span class = "token punctuation" > :< / span > < span class = "token string" > " main" < / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
buffers< span class = "token punctuation" > :< / span > vertex_layouts< span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
fragment< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > FragmentState< / span > < span class = "token punctuation" > {< / span >
2021-05-24 20:23:02 +00:00
module< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > shader< span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
entry_point< span class = "token punctuation" > :< / span > < span class = "token string" > " main" < / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
targets< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ColorTargetState< / span > < span class = "token punctuation" > {< / span >
format< span class = "token punctuation" > :< / span > color_format< span class = "token punctuation" > ,< / span >
2021-05-24 20:23:02 +00:00
blend< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BlendState< / span > < span class = "token punctuation" > {< / span >
alpha< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BlendComponent< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > REPLACE< / span > < span class = "token punctuation" > ,< / span >
color< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BlendComponent< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > REPLACE< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
write_mask< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ColorWrite< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > ALL< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
primitive< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > PrimitiveState< / span > < span class = "token punctuation" > {< / span >
topology< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > PrimitiveTopology< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > TriangleList< / span > < span class = "token punctuation" > ,< / span >
strip_index_format< span class = "token punctuation" > :< / span > < span class = "token class-name" > None< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
front_face< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > FrontFace< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Ccw< / span > < span class = "token punctuation" > ,< / span >
2021-05-24 20:23:02 +00:00
cull_mode< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Face< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Back< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
< span class = "token comment" > // Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE< / span >
polygon_mode< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > PolygonMode< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Fill< / span > < span class = "token punctuation" > ,< / span >
2021-05-24 20:23:02 +00:00
< span class = "token comment" > // Requires Features::DEPTH_CLAMPING< / span >
clamp_depth< span class = "token punctuation" > :< / span > < span class = "token boolean" > false< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // Requires Features::CONSERVATIVE_RASTERIZATION< / span >
conservative< span class = "token punctuation" > :< / span > < span class = "token boolean" > false< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
depth_stencil< span class = "token punctuation" > :< / span > depth_format< span class = "token punctuation" > .< / span > < span class = "token function" > map< / span > < span class = "token punctuation" > (< / span > < span class = "token closure-params" > < span class = "token closure-punctuation punctuation" > |< / span > format< span class = "token closure-punctuation punctuation" > |< / span > < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > DepthStencilState< / span > < span class = "token punctuation" > {< / span >
format< span class = "token punctuation" > ,< / span >
depth_write_enabled< span class = "token punctuation" > :< / span > < span class = "token boolean" > true< / span > < span class = "token punctuation" > ,< / span >
depth_compare< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > CompareFunction< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Less< / span > < span class = "token punctuation" > ,< / span >
stencil< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > StencilState< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > default< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
bias< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > DepthBiasState< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > default< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2021-03-03 17:40:00 +00:00
multisample< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > MultisampleState< / span > < span class = "token punctuation" > {< / span >
count< span class = "token punctuation" > :< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span >
mask< span class = "token punctuation" > :< / span > < span class = "token operator" > !< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span >
alpha_to_coverage_enabled< span class = "token punctuation" > :< / span > < span class = "token boolean" > false< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span >
< span class = "token punctuation" > }< / span >
2021-05-24 20:23:02 +00:00
< / code > < / pre > < / div > < p > We also need to change < code > State::new()< / code > to use this function.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > let< / span > render_pipeline < span class = "token operator" > =< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > let< / span > shader < span class = "token operator" > =< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderModuleDescriptor< / span > < span class = "token punctuation" > {< / span >
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token string" > " Normal Shader" < / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
flags< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderFlags< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > all< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
source< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderSource< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Wgsl< / span > < span class = "token punctuation" > (< / span > < span class = "token macro property" > include_str!< / span > < span class = "token punctuation" > (< / span > < span class = "token string" > " shader.wgsl" < / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ;< / span >
< span class = "token function" > create_render_pipeline< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > device< span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > render_pipeline_layout< span class = "token punctuation" > ,< / span >
sc_desc< span class = "token punctuation" > .< / span > format< span class = "token punctuation" > ,< / span >
< span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token namespace" > texture< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Texture< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > DEPTH_FORMAT< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token namespace" > model< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ModelVertex< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > desc< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span > < span class = "token class-name" > InstanceRaw< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > desc< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
shader< span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ;< / span >
2021-08-09 20:59:53 +00:00
< / code > < / pre > < / div > < p > We're going to need to modify < code > model::DrawModel< / code > to use our < code > light_bind_group< / code > .< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > pub< / span > < span class = "token keyword" > trait< / span > < span class = "token class-name" > DrawModel< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > {< / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_mesh< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
material< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Material< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_mesh_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
material< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Material< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_model< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_model_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
2021-08-09 20:59:53 +00:00
< span class = "token keyword" > impl< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token punctuation" > ,< / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token operator" > > < / span > < span class = "token class-name" > DrawModel< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token operator" > > < / span > < span class = "token keyword" > for< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > RenderPass< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token operator" > > < / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > where< / span >
< span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token punctuation" > :< / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > {< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_mesh< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
material< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Material< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_mesh_instanced< / span > < span class = "token punctuation" > (< / span > mesh< span class = "token punctuation" > ,< / span > material< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ..< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_mesh_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
material< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Material< / span > < span class = "token punctuation" > ,< / span >
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_vertex_buffer< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > mesh< span class = "token punctuation" > .< / span > vertex_buffer< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_index_buffer< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > mesh< span class = "token punctuation" > .< / span > index_buffer< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_bind_group< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > material< span class = "token punctuation" > .< / span > bind_group< span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2021-08-09 20:59:53 +00:00
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_bind_group< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_bind_group< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 2< / span > < span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_indexed< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ..< / span > mesh< span class = "token punctuation" > .< / span > num_elements< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > instances< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_model< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_model_instanced< / span > < span class = "token punctuation" > (< / span > model< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ..< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_model_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > for< / span > mesh < span class = "token keyword" > in< / span > < span class = "token operator" > & < / span > model< span class = "token punctuation" > .< / span > meshes < span class = "token punctuation" > {< / span >
< span class = "token keyword" > let< / span > material < span class = "token operator" > =< / span > < span class = "token operator" > & < / span > model< span class = "token punctuation" > .< / span > materials< span class = "token punctuation" > [< / span > mesh< span class = "token punctuation" > .< / span > material< span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_mesh_instanced< / span > < span class = "token punctuation" > (< / span > mesh< span class = "token punctuation" > ,< / span > material< span class = "token punctuation" > ,< / span > instances< span class = "token punctuation" > .< / span > < span class = "token function" > clone< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
< / code > < / pre > < / div > < p > With that done we can create another render pipeline for our light.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > let< / span > light_render_pipeline < span class = "token operator" > =< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > let< / span > layout < span class = "token operator" > =< / span > device< span class = "token punctuation" > .< / span > < span class = "token function" > create_pipeline_layout< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > PipelineLayoutDescriptor< / span > < span class = "token punctuation" > {< / span >
2021-03-03 17:40:00 +00:00
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token string" > " Light Pipeline Layout" < / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
bind_group_layouts< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token operator" > & < / span > uniform_bind_group_layout< span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > light_bind_group_layout< span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
push_constant_ranges< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2021-05-24 20:23:02 +00:00
< span class = "token keyword" > let< / span > shader < span class = "token operator" > =< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderModuleDescriptor< / span > < span class = "token punctuation" > {< / span >
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token string" > " Light Shader" < / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
flags< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderFlags< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > all< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
source< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderSource< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Wgsl< / span > < span class = "token punctuation" > (< / span > < span class = "token macro property" > include_str!< / span > < span class = "token punctuation" > (< / span > < span class = "token string" > " light.wgsl" < / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ;< / span >
2020-11-24 06:49:43 +00:00
< span class = "token function" > create_render_pipeline< / span > < span class = "token punctuation" > (< / span >
2021-03-03 17:40:00 +00:00
< span class = "token operator" > & < / span > device< span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > layout< span class = "token punctuation" > ,< / span >
sc_desc< span class = "token punctuation" > .< / span > format< span class = "token punctuation" > ,< / span >
< span class = "token class-name" > Some< / span > < span class = "token punctuation" > (< / span > < span class = "token namespace" > texture< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Texture< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > DEPTH_FORMAT< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token namespace" > model< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ModelVertex< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > desc< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
2021-05-24 20:23:02 +00:00
shader< span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ;< / span >
2021-05-24 20:23:02 +00:00
< / code > < / pre > < / div > < p > I chose to create a seperate layout for the < code > light_render_pipeline< / code > , as it doesn't need all the resources that the regular < code > render_pipeline< / code > needs (main just the textures).< / p > < p > With that in place we need to write the actual shaders.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > // Vertex shader
[[block]]
struct Uniforms {
view_proj: mat4x4< f32> ;
};
[[group(0), binding(0)]]
var< uniform> uniforms: Uniforms;
[[block]]
struct Light {
position: vec3< f32> ;
color: vec3< f32> ;
};
[[group(1), binding(0)]]
var< uniform> light: Light;
struct VertexInput {
[[location(0)]] position: vec3< f32> ;
};
struct VertexOutput {
[[builtin(position)]] clip_position: vec4< f32> ;
[[location(0)]] color: vec3< f32> ;
};
[[stage(vertex)]]
fn main(
model: VertexInput,
) -> VertexOutput {
let scale = 0.25;
var out: VertexOutput;
out.clip_position = uniforms.view_proj * vec4< f32> (model.position * scale + light.position, 1.0);
out.color = light.color;
return out;
}
// Fragment shader
[[stage(fragment)]]
fn main(in: VertexOutput) -> [[location(0)]] vec4< f32> {
return vec4< f32> (in.color, 1.0);
}
2021-08-09 20:59:53 +00:00
< / code > < / pre > < / div > < p > Now we could manually implement the draw code for the light in < code > render()< / code > , but to keep with the pattern we developed, let's create a new trait called < code > DrawLight< / code > .< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > pub< / span > < span class = "token keyword" > trait< / span > < span class = "token class-name" > DrawLight< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > {< / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_mesh< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_mesh_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_model< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_model_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
2021-08-09 20:59:53 +00:00
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
2021-08-09 20:59:53 +00:00
< span class = "token keyword" > impl< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token punctuation" > ,< / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token operator" > > < / span > < span class = "token class-name" > DrawLight< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token operator" > > < / span > < span class = "token keyword" > for< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > RenderPass< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token operator" > > < / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > where< / span >
< span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token punctuation" > :< / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > {< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_mesh< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_light_mesh_instanced< / span > < span class = "token punctuation" > (< / span > mesh< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ..< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_mesh_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
mesh< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Mesh< / span > < span class = "token punctuation" > ,< / span >
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_vertex_buffer< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > mesh< span class = "token punctuation" > .< / span > vertex_buffer< span class = "token punctuation" > .< / span > < span class = "token function" > slice< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > ..< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2021-03-03 17:40:00 +00:00
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_index_buffer< / span > < span class = "token punctuation" > (< / span > mesh< span class = "token punctuation" > .< / span > index_buffer< span class = "token punctuation" > .< / span > < span class = "token function" > slice< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > ..< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > IndexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Uint32< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_bind_group< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > set_bind_group< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > ,< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_indexed< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ..< / span > mesh< span class = "token punctuation" > .< / span > num_elements< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span > instances< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_model< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_light_model_instanced< / span > < span class = "token punctuation" > (< / span > model< span class = "token punctuation" > ,< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ..< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > draw_light_model_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span >
model< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token class-name" > Model< / span > < span class = "token punctuation" > ,< / span >
instances< span class = "token punctuation" > :< / span > < span class = "token class-name" > Range< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
uniforms< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
light< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token lifetime-annotation symbol" > 'b< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroup< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > for< / span > mesh < span class = "token keyword" > in< / span > < span class = "token operator" > & < / span > model< span class = "token punctuation" > .< / span > meshes < span class = "token punctuation" > {< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > draw_light_mesh_instanced< / span > < span class = "token punctuation" > (< / span > mesh< span class = "token punctuation" > ,< / span > instances< span class = "token punctuation" > .< / span > < span class = "token function" > clone< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span > uniforms< span class = "token punctuation" > ,< / span > light< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
2021-03-29 15:01:03 +00:00
< / code > < / pre > < / div > < p > Finally we want to add Light rendering to our render passes.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > impl< / span > < span class = "token class-name" > State< / span > < span class = "token punctuation" > {< / span >
< span class = "token comment" > // ...< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > render< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > -> < / span > < span class = "token class-name" > Result< / span > < span class = "token operator" > < < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > SwapChainError< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > {< / span >
< span class = "token comment" > // ...< / span >
render_pass< span class = "token punctuation" > .< / span > < span class = "token function" > set_vertex_buffer< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ,< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > instance_buffer< span class = "token punctuation" > .< / span > < span class = "token function" > slice< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > ..< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > use< / span > < span class = "token keyword" > crate< / span > < span class = "token module-declaration namespace" > < span class = "token punctuation" > ::< / span > model< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > DrawLight< / span > < span class = "token punctuation" > ;< / span > < span class = "token comment" > // NEW!< / span >
render_pass< span class = "token punctuation" > .< / span > < span class = "token function" > set_pipeline< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > light_render_pipeline< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span > < span class = "token comment" > // NEW!< / span >
render_pass< span class = "token punctuation" > .< / span > < span class = "token function" > draw_light_model< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > obj_model< span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > uniform_bind_group< span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > light_bind_group< span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span > < span class = "token comment" > // NEW!< / span >
render_pass< span class = "token punctuation" > .< / span > < span class = "token function" > set_pipeline< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > render_pipeline< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
render_pass< span class = "token punctuation" > .< / span > < span class = "token function" > draw_model_instanced< / span > < span class = "token punctuation" > (< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > obj_model< span class = "token punctuation" > ,< / span >
< span class = "token number" > 0< / span > < span class = "token punctuation" > ..< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > instances< span class = "token punctuation" > .< / span > < span class = "token function" > len< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token keyword" > u32< / span > < span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > uniform_bind_group< span class = "token punctuation" > ,< / span >
< span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > light_bind_group< span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
2021-05-24 20:23:02 +00:00
< / code > < / pre > < / div > < p > With all that we'll end up with something like this.< / p > < p > < img src = "/learn-wgpu/assets/img/light-in-scene.7c329d72.png" alt = "./light-in-scene.png" > < / p > < h2 id = "ambient-lighting" > < a href = "#ambient-lighting" class = "header-anchor" > #< / a > Ambient Lighting< / h2 > < p > Light has a tendency to bounce around before entering our eyes. That's why you can see in areas that are in shadow. Actually modeling this interaction is computationally expensive, so we cheat. We define an ambient lighting value that stands in for the light bouncing of other parts of the scene to light our objects.< / p > < p > The ambient part is based on the light color as well as the object color. We've already added our < code > light_bind_group< / code > , so we just need to use it in our shader. In < code > shader.wgsl< / code > , add the following below the texture uniforms.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > [[block]]
struct Light {
position: vec3< f32> ;
color: vec3< f32> ;
};
[[group(2), binding(0)]]
var< uniform> light: Light;
< / code > < / pre > < / div > < p > Then we need to update our main shader code to calculate and use the ambient color value.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > [[stage(fragment)]]
fn main(in: VertexOutput) -> [[location(0)]] vec4< f32> {
let object_color: vec4< f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
// We don't need (or want) much ambient light, so 0.1 is fine
let ambient_strength = 0.1;
let ambient_color = light.color * ambient_strength;
let result = ambient_color * object_color.xyz;
return vec4< f32> (result, object_color.a);
}
2021-07-20 18:28:37 +00:00
< / code > < / pre > < / div > < p > With that we should get something like the this.< / p > < p > < img src = "/learn-wgpu/assets/img/ambient_lighting.8bece8d1.png" alt = "./ambient_lighting.png" > < / p > < h2 id = "diffuse-lighting" > < a href = "#diffuse-lighting" class = "header-anchor" > #< / a > Diffuse Lighting< / h2 > < p > Remember the normal vectors that were included with our model? We're finally going to use them. Normals represent the direction a surface is facing. By comparing the normal of a fragment with a vector pointing to a light source, we get a value of how light/dark that fragment should be. We compare the vector using the dot product to get the cosine of the angle between them.< / p > < p > < img src = "/learn-wgpu/assets/img/normal_diagram.dfa577f7.png" alt = "./normal_diagram.png" > < / p > < p > If the dot product of the normal and light vector is 1.0, that means that the current fragment is directly inline with the light source and will receive the lights full intensity. A value of 0.0 or lower means that the surface is perpendicular or facing away from the light, and therefore will be dark.< / p > < p > We're going to need to pull in the normal vector into our < code > shader.wgsl< / code > .< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > struct VertexInput {
2021-05-24 20:23:02 +00:00
[[location(0)]] position: vec3< f32> ;
[[location(1)]] tex_coords: vec2< f32> ;
[[location(2)]] normal: vec3< f32> ; // NEW!
};
< / code > < / pre > < / div > < p > We're also going to want to pass that value, as well as the vertex's position to the fragment shader.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > struct VertexOutput {
[[builtin(position)]] clip_position: vec4< f32> ;
[[location(0)]] tex_coords: vec2< f32> ;
[[location(1)]] world_normal: vec3< f32> ;
[[location(2)]] world_position: vec3< f32> ;
};
< / code > < / pre > < / div > < p > For now let's just pass the normal directly as is. This is wrong, but we'll fix it later.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > [[stage(vertex)]]
fn main(
model: VertexInput,
instance: InstanceInput,
) -> VertexOutput {
let model_matrix = mat4x4< f32> (
instance.model_matrix_0,
instance.model_matrix_1,
instance.model_matrix_2,
instance.model_matrix_3,
);
var out: VertexOutput;
out.tex_coords = model.tex_coords;
out.world_normal = model.normal;
var world_position: vec4< f32> = model_matrix * vec4< f32> (model.position, 1.0);
out.world_position = world_position.xyz;
out.clip_position = uniforms.view_proj * world_position;
return out;
}
< / code > < / pre > < / div > < p > With that we can do the actual calculation. Below the < code > ambient_color< / code > calculation, but above < code > result< / code > , add the following.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > let light_dir = normalize(light.position - in.world_position);
let diffuse_strength = max(dot(in.world_normal, light_dir), 0.0);
let diffuse_color = light.color * diffuse_strength;
< / code > < / pre > < / div > < p > Now we can include the < code > diffuse_color< / code > in the < code > result< / code > .< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > let result = (ambient_color + diffuse_color) * object_color.xyz;
< / code > < / pre > < / div > < p > With that we get something like this.< / p > < p > < img src = "/learn-wgpu/assets/img/ambient_diffuse_wrong.dab00d9a.png" alt = "./ambient_diffuse_wrong.png" > < / p > < h2 id = "the-normal-matrix" > < a href = "#the-normal-matrix" class = "header-anchor" > #< / a > The normal matrix< / h2 > < p > Remember when I said passing the vertex normal directly to the fragment shader was wrong? Let's explore that by removing all the cubes from the scene except one that will be rotated 180 degrees on the y-axis.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > const< / span > < span class = "token constant" > NUM_INSTANCES_PER_ROW< / span > < span class = "token punctuation" > :< / span > < span class = "token keyword" > u32< / span > < span class = "token operator" > =< / span > < span class = "token number" > 1< / span > < span class = "token punctuation" > ;< / span >
2020-11-24 06:49:43 +00:00
2021-05-24 20:23:02 +00:00
< span class = "token comment" > // In the loop we create the instances in< / span >
< span class = "token keyword" > let< / span > rotation < span class = "token operator" > =< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Quaternion< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > from_axis_angle< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 0.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 1.0< / span > < span class = "token punctuation" > ,< / span > < span class = "token number" > 0.0< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Deg< / span > < span class = "token punctuation" > (< / span > < span class = "token number" > 180.0< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< / code > < / pre > < / div > < p > We'll also remove the < code > ambient_color< / code > from our lighting < code > result< / code > .< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > let result = (diffuse_color) * object_color.xyz;
< / code > < / pre > < / div > < p > That should give us something that looks like this.< / p > < p > < img src = "/learn-wgpu/assets/img/diffuse_wrong.ce856a2c.png" alt = "./diffuse_wrong.png" > < / p > < p > This is clearly wrong as the light is illuminating the wrong side of the cube. This is because we aren't rotating our normals with our object, so no matter what direction the object faces, the normals will always face the same way.< / p > < p > < img src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV/TSkUqClYQcchQnSyIiuimVShChVIrtOpgcukXNGlIUlwcBdeCgx+LVQcXZ10dXAVB8APEydFJ0UVK/F9SaBHjwXE/3t173L0DhHqZqWZgDFA1y0jFY2ImuyoGXxFAL/oRxYzETH0umUzAc3zdw8fXuyjP8j735+hWciYDfCLxLNMNi3iDeGrT0jnvE4dZUVKIz4lHDbog8SPXZZffOBccFnhm2Ein5onDxGKhjeU2ZkVDJZ4kjiiqRvlCxmWF8xZntVxlzXvyF4Zy2soy12kOIY5FLCEJETKqKKEMi/oqQSPFRIr2Yx7+QcefJJdMrhIYORZQgQrJ8YP/we9uzfzEuJsUigEdL7b9MQwEd4FGzba/j227cQL4n4ErreWv1IHpT9JrLS1yBPRsAxfXLU3eAy53gIEnXTIkR/LTFPJ54P2MvikL9N0CXWtub819nD4AaeoqcQMcHAIjBcpe93h3Z3tv/55p9vcDzyByzFOETCsAAAAGYktHRAAAAJIA/yrWOGwAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfkBBAVMhAOsiflAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAHDVJREFUeNrt3XlcVPX+x/E3CMiiqJmAAkaS4IaIS3Uzs7TNfc/2bLlaVy9tlv1u2WJmt0wzui1m2b2llmZqqWXmtdLqqrhjpmi4L6CmQSo7vz9ME84ZnMFZzgyv5+PR45HfOTNz5jufw/t8zpwz46e0sjIBAOAgf6YAAECAAAAIEAAAAQIAIEAAACBAAAAECACAAAEAECAAAAIEAAACBABAgAAACBAAAAECACBAAAAgQAAABAgAgAABABAgAAACBAAAAgQAQIAAAAgQAAABAgAgQAAAIEAAAAQIAIAAAQAQIAAAAgQAAAIEAECAAAAIEAAAAQIAIEAAACBAAAAECACAAAEAECAAABAgAAACBABAgAAACBAAgG8KYAoc16fwuG7NWqlLdq5QvV2rVXP/T/I/mllumZeeP6BJdaKYLFCTIECcpVNxgWY9EnzO5UrrJai4/sXKr3+RjkU1196oRKU3StI/68V4dMKeObJT90wbqqBfvqZ64LC3d69Rn1fa27z9qReP6L2wC6hJECDnw/9opoKOZipouxQuqbGkKyQNvv5ZvXHNCL0bVt/t69SpuEBDZqayoaLKOmz6stLbe+5YqfdadXN5TW74fLQilowtN5Zz7VNK7v08bxLs/zvtbSsctfhZPfX+Hbrl5G9uf+5bDmxW8Jb5VA2q5O4TR9Vo0ehKl0laNU0xZWXUJOhAXKVm5pcatu5TfXTFPW593tije03HZ43aqA+jmml1jUAqCjb12LnqnMuErZ+hoYfH6OkG8dQkCBB7Fcd2VOxj35/5d4vSYl33+2HdvuIDxSwYZVg+ftnbSrj8LmX613DbOgYWnjCMlYXF6MHoJCoJlYooK1Ny+kd2LXvVtmWSnQFCTcKT/JTmQL/sBLY+RK8YIKd1LsrXjLHJhjNKJGnkS8c0PaROpc933/EjumH3WsXtXa+6+zIUnL1NKitRfqOWOtS4vX6Oa693YttqpY09tcm716r3K+0ceo0Huo1V225Pmt42PC9HXXavVdyedap7YLOCsrdKkgojE3WsYXPtjE3R0sbt9EbtiEqf46XsrbrzhWaG8Smjt+vpBvG688Qx9c/6QU23LFWtfRkK+uVrZQ6eos4d73PJPKFyzx3eoaFjmhjG93cfp0Zf/KPcWElUW93y+I9aHlDTqTV5IKq52r4/wOF1T793nnon93Fp3Ti7nlHNOhBbvgsM1vFLOql2ujFAalSSfb0KT2jUymmKnztSKs4z3F5rf7pqrf63LpZ0Tct+WtDzWaVGt3bZ6xiYn6dHf3xfcfMeNH8j9qcrdJ3USKdOFri9X5pevuJuza1Zy+HnStu3Uf1m/E0Be34ov7dQZv158lWdtn1nGDuRfLPSrrpf/6wQIDUOrtWdezdqeVwHy74ed9aNI/UM97L8h+idigsUtn25Ybz0whZaERJuYy//kF77zxDFfzLMtLgrCvlprga9lKyZW/7rktfw8G8HNH7qbTbDw0zc3FRNnHq7UnOzHXqu9ns3aOCk6wwb2x8HNyw9Tz4bHsWFavrdm4bxTZfepv+E1tOBG8cYbuuwaaFlX48768aRegYBckZCaYlG5GZrwrf/Mj18tbnbU8r0M65+j8ITemjOYwrJ+MTh57zqzWv16v6fnPo6+hf8rhGfPFSlM2WCf/5MqbMfUS+T49y2pLw/QH4FOeZv9lkdm9XmyZfdvm+jAvanG8a/jrtUkrSmxY2G2yIXP6f7jh+x3Gtxd93YW8/wDMscwgrY84MOpPrZtezRTg9pfJu+5ntHP32pWmv+YxjP63Cv5l43UgsubKISP+nmg1vUZ/ZIw/nz/eaO0sf3zz1zzHZY47YalnaqUL9a/bFaf3BL+X2gsBg1enGPzXUdlrFAoRtnGcZzLxuqudc+qs8vjFOJ/NTv8A71+/oVha+aUm65sPUz9EBKf81PcezY9YYhszS/6dX6JqyeUgqO6y9HdirmrDN2nD1PsK3DT8ZrP45c/Zj+9cfnXB9FJ6l7vQTDjlKPHSv1bqvuxpo6n5pMOXW/ql4H4qm6OVc9o5oHiL023vmRxrXpp+9MPmDsVFyg5Hn/MIwXR1+usQNe0Qehdc+M/RjdWicHp+nOcc3LLVtz60LdvytdK5tccd7r2rkoX63mGT9ML4q7WqMHjNes4D8Pwa2MTNCGAeP18oHNhnY9ed4/1Cmpl5YHBNn1vN+MWKpbE675s1sLqaPpMclSTLIl58mX3XXiqBouetowvq51rzP/vzQwWFldH9Ylsx8ot0zSqumKadlNe/38LPFaPFU356pncAjLbi2WTNTjm75Qi9Jiw229D2eZHu5a0/2pcsV92qioZjp6ZaphvOUvPzplXXsfzpJ/bpZhPKNLarnwOO2jkDra1PUh45t0NFM9j+yw6zlzLxuqx5tefe71stA8+bLeO1YaxspqRmhObEq5sZVNOxuWC1s/Q8MOZ1nntXigbuypZxAg9rdM+9PVdmp/TV2apoTSknK3XXR0n3n727CFzcc7ZHK+fMM1s1TbCesae2y/6fjPkc1s3iczyvy2xjYey/DYyb3PucdqtXnyVRFlZWqdPsMwvvuGUYaz696JTFDhJTcYlr0q81vLvB5P1I099QwP/j22yopUvA6kSVmpOhT8rmtytun6RS8qZNOn5Yv580f1bON2ujXhzz23WvnmX28ydEwTDXUwpDoU5WtpYPB5vSZb63PIxtljkpQTHO7QYxn+ONWLrfJ6eWqefNXwIztUa+2HhvHVzboadxz8a2hLx3vUevtX5cbjv0lT50tv03cWmGNP1I099QwCxCDLz19ZweGa2bidnh7wih6oECCS1C59hpTQ2SXP37jopOSBjdbvPE9NzAsMdev6emqevMFV25aZjg94uY3sPSWiRs5G3bFvo77744wtX2Fv3bi7nuEYrziE9Wr9OBXHdjSMh698R52L8s/8
< span class = "token attribute attr-name" > #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]< / span >
< span class = "token attribute attr-name" > #[allow(dead_code)]< / span >
< span class = "token keyword" > struct< / span > < span class = "token type-definition class-name" > InstanceRaw< / span > < span class = "token punctuation" > {< / span >
model< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 4< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 4< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
normal< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 3< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 3< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span >
2020-11-24 06:49:43 +00:00
2021-05-24 20:23:02 +00:00
< span class = "token keyword" > impl< / span > < span class = "token namespace" > model< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Vertex< / span > < span class = "token keyword" > for< / span > < span class = "token class-name" > InstanceRaw< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > desc< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > -> < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexBufferLayout< / span > < span class = "token operator" > < < / span > < span class = "token lifetime-annotation symbol" > 'a< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > use< / span > < span class = "token namespace" > std< span class = "token punctuation" > ::< / span > < / span > mem< span class = "token punctuation" > ;< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexBufferLayout< / span > < span class = "token punctuation" > {< / span >
array_stride< span class = "token punctuation" > :< / span > < span class = "token namespace" > mem< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > size_of< / span > < span class = "token punctuation" > ::< / span > < span class = "token operator" > < < / span > < span class = "token class-name" > InstanceRaw< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferAddress< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // We need to switch from using a step mode of Vertex to Instance< / span >
< span class = "token comment" > // This means that our shaders will only change to use the next< / span >
< span class = "token comment" > // instance when the shader starts processing a new instance< / span >
step_mode< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > InputStepMode< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Instance< / span > < span class = "token punctuation" > ,< / span >
attributes< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexAttribute< / span > < span class = "token punctuation" > {< / span >
offset< span class = "token punctuation" > :< / span > < span class = "token number" > 0< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // While our vertex shader only uses locations 0, and 1 now, in later tutorials we'll< / span >
< span class = "token comment" > // be using 2, 3, and 4, for Vertex. We'll start at slot 5 not conflict with them later< / span >
shader_location< span class = "token punctuation" > :< / span > < span class = "token number" > 5< / span > < span class = "token punctuation" > ,< / span >
format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Float32x4< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot< / span >
< span class = "token comment" > // for each vec4. We don't have to do this in code though.< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexAttribute< / span > < span class = "token punctuation" > {< / span >
offset< span class = "token punctuation" > :< / span > < span class = "token namespace" > mem< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > size_of< / span > < span class = "token punctuation" > ::< / span > < span class = "token operator" > < < / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 4< / span > < span class = "token punctuation" > ]< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferAddress< / span > < span class = "token punctuation" > ,< / span >
shader_location< span class = "token punctuation" > :< / span > < span class = "token number" > 6< / span > < span class = "token punctuation" > ,< / span >
format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Float32x4< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexAttribute< / span > < span class = "token punctuation" > {< / span >
offset< span class = "token punctuation" > :< / span > < span class = "token namespace" > mem< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > size_of< / span > < span class = "token punctuation" > ::< / span > < span class = "token operator" > < < / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 8< / span > < span class = "token punctuation" > ]< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferAddress< / span > < span class = "token punctuation" > ,< / span >
shader_location< span class = "token punctuation" > :< / span > < span class = "token number" > 7< / span > < span class = "token punctuation" > ,< / span >
format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Float32x4< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexAttribute< / span > < span class = "token punctuation" > {< / span >
offset< span class = "token punctuation" > :< / span > < span class = "token namespace" > mem< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > size_of< / span > < span class = "token punctuation" > ::< / span > < span class = "token operator" > < < / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 12< / span > < span class = "token punctuation" > ]< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferAddress< / span > < span class = "token punctuation" > ,< / span >
shader_location< span class = "token punctuation" > :< / span > < span class = "token number" > 8< / span > < span class = "token punctuation" > ,< / span >
format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Float32x4< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // NEW!< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexAttribute< / span > < span class = "token punctuation" > {< / span >
offset< span class = "token punctuation" > :< / span > < span class = "token namespace" > mem< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > size_of< / span > < span class = "token punctuation" > ::< / span > < span class = "token operator" > < < / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 16< / span > < span class = "token punctuation" > ]< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferAddress< / span > < span class = "token punctuation" > ,< / span >
shader_location< span class = "token punctuation" > :< / span > < span class = "token number" > 9< / span > < span class = "token punctuation" > ,< / span >
format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Float32x3< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexAttribute< / span > < span class = "token punctuation" > {< / span >
offset< span class = "token punctuation" > :< / span > < span class = "token namespace" > mem< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > size_of< / span > < span class = "token punctuation" > ::< / span > < span class = "token operator" > < < / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 19< / span > < span class = "token punctuation" > ]< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferAddress< / span > < span class = "token punctuation" > ,< / span >
shader_location< span class = "token punctuation" > :< / span > < span class = "token number" > 10< / span > < span class = "token punctuation" > ,< / span >
format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Float32x3< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexAttribute< / span > < span class = "token punctuation" > {< / span >
offset< span class = "token punctuation" > :< / span > < span class = "token namespace" > mem< span class = "token punctuation" > ::< / span > < / span > < span class = "token function" > size_of< / span > < span class = "token punctuation" > ::< / span > < span class = "token operator" > < < / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 22< / span > < span class = "token punctuation" > ]< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token keyword" > as< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BufferAddress< / span > < span class = "token punctuation" > ,< / span >
shader_location< span class = "token punctuation" > :< / span > < span class = "token number" > 11< / span > < span class = "token punctuation" > ,< / span >
format< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > VertexFormat< / span > < span class = "token punctuation" > ::< / span > < span class = "token class-name" > Float32x3< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span >
2021-05-24 20:23:02 +00:00
< / code > < / pre > < / div > < p > We need to modify < code > Instance< / code > to create the normal matrix.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token keyword" > struct< / span > < span class = "token type-definition class-name" > Instance< / span > < span class = "token punctuation" > {< / span >
position< span class = "token punctuation" > :< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Vector3< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > f32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
rotation< span class = "token punctuation" > :< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Quaternion< / span > < span class = "token operator" > < < / span > < span class = "token keyword" > f32< / span > < span class = "token operator" > > < / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span >
2021-05-24 20:23:02 +00:00
< span class = "token keyword" > impl< / span > < span class = "token class-name" > Instance< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > to_raw< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > -> < / span > < span class = "token class-name" > InstanceRaw< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > let< / span > model < span class = "token operator" > =< / span >
< span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Matrix4< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > from_translation< / span > < span class = "token punctuation" > (< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > position< span class = "token punctuation" > )< / span > < span class = "token operator" > *< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Matrix4< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > from< / span > < span class = "token punctuation" > (< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > rotation< span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token class-name" > InstanceRaw< / span > < span class = "token punctuation" > {< / span >
model< span class = "token punctuation" > :< / span > model< span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // NEW!< / span >
normal< span class = "token punctuation" > :< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Matrix3< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > from< / span > < span class = "token punctuation" > (< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > rotation< span class = "token punctuation" > )< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
< / code > < / pre > < / div > < p > Now we need to reconstruct the normal matrix in the vertex shader.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > struct InstanceInput {
[[location(5)]] model_matrix_0: vec4< f32> ;
[[location(6)]] model_matrix_1: vec4< f32> ;
[[location(7)]] model_matrix_2: vec4< f32> ;
[[location(8)]] model_matrix_3: vec4< f32> ;
// NEW!
[[location(9)]] normal_matrix_0: vec3< f32> ;
[[location(10)]] normal_matrix_1: vec3< f32> ;
[[location(11)]] normal_matrix_2: vec3< f32> ;
};
struct VertexOutput {
[[builtin(position)]] clip_position: vec4< f32> ;
[[location(0)]] tex_coords: vec2< f32> ;
[[location(1)]] world_normal: vec3< f32> ;
[[location(2)]] world_position: vec3< f32> ;
};
[[stage(vertex)]]
fn main(
model: VertexInput,
instance: InstanceInput,
) -> VertexOutput {
let model_matrix = mat4x4< f32> (
instance.model_matrix_0,
instance.model_matrix_1,
instance.model_matrix_2,
instance.model_matrix_3,
);
// NEW!
let normal_matrix = mat3x3< f32> (
instance.normal_matrix_0,
instance.normal_matrix_1,
instance.normal_matrix_2,
);
var out: VertexOutput;
out.tex_coords = model.tex_coords;
out.world_normal = normal_matrix * model.normal;
var world_position: vec4< f32> = model_matrix * vec4< f32> (model.position, 1.0);
out.world_position = world_position.xyz;
out.clip_position = uniforms.view_proj * world_position;
return out;
}
< / code > < / pre > < / div > < div class = "note" > < p > I'm currently doing things in < a href = "https://gamedev.stackexchange.com/questions/65783/what-are-world-space-and-eye-space-in-game-development" target = "_blank" rel = "noopener noreferrer" > world space< svg xmlns = "http://www.w3.org/2000/svg" aria-hidden = "true" x = "0px" y = "0px" viewBox = "0 0 100 100" width = "15" height = "15" class = "icon outbound" > < path fill = "currentColor" d = "M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z" > < / path > < polygon fill = "currentColor" points = "45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9" > < / polygon > < / svg > < / a > . Doing things in view-space also known as eye-space, is more standard as objects can have lighting issues when they are further away from the origin. If we wanted to use view-space, we would have include the rotation due to the view matrix as well. We'd also have to transform our light's position using something like < code > view_matrix * model_matrix * light_position< / code > to keep the calculation from getting messed up when the camera moves.< / p > < p > There are advantages to using view space. The main one is when you have massive worlds doing lighting and other calculations in model spacing can cause issues as floating point precision degrades when numbers get really large. View space keeps the camera at the origin meaning all calculations will be using smaller numbers. The actual lighting math ends up the same, but it does require a bit more setup.< / p > < / div > < p > With that change our lighting now looks correct.< / p > < p > < img src = "/learn-wgpu/assets/img/diffuse_right.e3a6b793.png" alt = "./diffuse_right.png" > < / p > < p > Bringing back our other objects, and adding the ambient lighting gives us this.< / p > < p > < img src = "/learn-wgpu/assets/img/ambient_diffuse_lighting.98735034.png" alt = "./ambient_diffuse_lighting.png" > ;< / p > < h2 id = "specular-lighting" > < a href = "#specular-lighting" class = "header-anchor" > #< / a > Specular Lighting< / h2 > < p > Specular lighting describes the highlights that appear on objects when viewed from certain angles. If you've ever looked at a car, it's the super bright parts. Basically, some of the light can reflect of the surface like a mirror. The location of the hightlight shifts depending on what angle you view it at.< / p > < p > < img src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV/TSkUqgnYQcchQnSyIVnHUKhShQqgVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi5Oik6CIl/q8ptIjx4Lgf7+497t4BQr3MNCswDmi6baYScTGTXRWDrwigHwKmEJOZZcxJUhKe4+sePr7eRXmW97k/R6+asxjgE4lnmWHaxBvE05u2wXmfOMyKskp8Tjxm0gWJH7muuPzGudBkgWeGzXRqnjhMLBY6WOlgVjQ14hhxRNV0yhcyLquctzhr5Spr3ZO/MJTTV5a5TnMYCSxiCRJEKKiihDJsRGnVSbGQov24h3+o6ZfIpZCrBEaOBVSgQW76wf/gd7dWfnLCTQrFga4Xx/kYAYK7QKPmON/HjtM4AfzPwJXe9lfqwMwn6bW2FjkC+raBi+u2puwBlzvA4JMhm3JT8tMU8nng/Yy+KQsM3AI9a25vrX2cPgBp6ip5AxwcAqMFyl73eHd3Z2//nmn19wOsGnK+VYnm+gAAAAZiS0dEAAAAkgD/KtY4bAAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+QEEgI7HGWmrfkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAgAElEQVR42u3deXhU5eG38e9MlskGSQwEggQEZBUDURAtsii4Ly1aUFyKtrX+3ABFq6i4UQuKtBp3alX01VC19VLbagVZSkFbRRQ1LCqKLAFCSAhJyDLJvH9EZjLZmGSWs8z9uS4vk1nPDJPnPs85c2YcyvN4BABAOzl5CgAABAQAQEAAAAQEAEBAAAAgIAAAAgIAICAAAAICACAgAAAQEAAAAQEAEBAAAAEBABAQAAAICACAgAAACAgAgIAAAAgIAAAEBABAQAAABAQAQEAAAFEmlqcAQEdlOqT7h0hj+0s9M6Qkl+TxSOVV0u5S6dNt0h2fSTvqea4ICAD8aHJnaeG5UnbX5uelpzT8N7in9PImaUclzxcBAQBJI+OlJ34qZaY1/F5dK73zqbRko/RDtTT6KGl4d2nsAKnew/NFQADgR/ed5IuHxyMtfF+6a6vv/I93S9ot6TPfaS/lSlee6n87tXVSabn05Xbp3g+l1VW+85aNlyYc3/DzV9ulZ9ZKs05r2FR28JD03gbpsnXSVUdJd4yX+nSTatzSt7ulOSukd8r97+uEOOmBk6QT+kgZnaQYp1RWKRXskBZ8KL3V6PL/GiudOcx330+skW4ZJ/XuKpVWSN1eav/jISAAIOmkfr6ft+7xj0d7xMVIXVOl01KlIT2lM/OlDe7ml0t2SfN/KiUnNPyeniJN/YmUECdNHCp1Smw4PT5WGnaM9Ni50juv+a5/TrL0wkVStzT/201PkUYPknJ6SzPflJ4vbvm+F/xMSvnxvh0heDx2wbuwALRLTqzUpbPv9693B3a9X6yXHI/7/hv2tDT7TanoQMP53dKk24e1fN1jMqWVG6UJz0mrN/pOnzRSKimXpr4k/f4fvtP7dJOuz/T9Pu90Xzy2F0nXL5HOfE5au7nhtE6J0pyJrd/3tr3Sr19tWO7Ml4J/PAQEQFQamOT/+8Hqjt3OBrc0f4f0v0azl+N6tHzZ0grp/P9Iyw9Jq771P2/xR9KSAw2zoNIK3+mDjmr4
struct Uniforms {
view_pos: vec4< f32> ;
view_proj: mat4x4< f32> ;
};
[[group(1), binding(0)]]
var< uniform> uniforms: Uniforms;
2021-06-09 18:56:44 +00:00
< / code > < / pre > < / div > < div class = "note" > < p > Don't forget to update the < code > Uniforms< / code > struct in < code > light.wgsl< / code > as well, as if it doesn't match the < code > Uniforms< / code > struct in rust, the light will render wrong.< / p > < / div > < p > We're going to need to update the < code > Uniforms< / code > struct as well.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token comment" > // main.rs< / span >
2020-11-24 06:49:43 +00:00
< span class = "token attribute attr-name" > #[repr(C)]< / span >
< span class = "token attribute attr-name" > #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]< / span >
< span class = "token keyword" > struct< / span > < span class = "token type-definition class-name" > Uniforms< / span > < span class = "token punctuation" > {< / span >
view_position< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 4< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
view_proj< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token punctuation" > [< / span > < span class = "token keyword" > f32< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 4< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 4< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > impl< / span > < span class = "token class-name" > Uniforms< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > new< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > -> < / span > < span class = "token keyword" > Self< / span > < span class = "token punctuation" > {< / span >
< span class = "token keyword" > Self< / span > < span class = "token punctuation" > {< / span >
2021-03-29 15:01:03 +00:00
view_position< span class = "token punctuation" > :< / span > < span class = "token punctuation" > [< / span > < span class = "token number" > 0.0< / span > < span class = "token punctuation" > ;< / span > < span class = "token number" > 4< / span > < span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
view_proj< span class = "token punctuation" > :< / span > < span class = "token namespace" > cgmath< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > Matrix4< / span > < span class = "token punctuation" > ::< / span > < span class = "token function" > identity< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > .< / span > < span class = "token function" > into< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ,< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
< span class = "token keyword" > fn< / span > < span class = "token function-definition function" > update_view_proj< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token keyword" > mut< / span > < span class = "token keyword" > self< / span > < span class = "token punctuation" > ,< / span > camera< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token class-name" > Camera< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > {< / span >
2021-05-24 20:23:02 +00:00
< span class = "token comment" > // We're using Vector4 because of the uniforms 16 byte spacing requirement< / span >
2020-11-24 06:49:43 +00:00
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > view_position < span class = "token operator" > =< / span > camera< span class = "token punctuation" > .< / span > eye< span class = "token punctuation" > .< / span > < span class = "token function" > to_homogeneous< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token keyword" > self< / span > < span class = "token punctuation" > .< / span > view_proj < span class = "token operator" > =< / span > < span class = "token constant" > OPENGL_TO_WGPU_MATRIX< / span > < span class = "token operator" > *< / span > camera< span class = "token punctuation" > .< / span > < span class = "token function" > build_view_projection_matrix< / span > < span class = "token punctuation" > (< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
< span class = "token punctuation" > }< / span >
< span class = "token punctuation" > }< / span >
< / code > < / pre > < / div > < p > Since we want to use our uniforms in the fragment shader now, we need to change it's visibility.< / p > < div class = "language-rust extra-class" > < pre class = "language-rust" > < code > < span class = "token comment" > // main.rs< / span >
< span class = "token keyword" > let< / span > uniform_bind_group_layout < span class = "token operator" > =< / span > device< span class = "token punctuation" > .< / span > < span class = "token function" > create_bind_group_layout< / span > < span class = "token punctuation" > (< / span > < span class = "token operator" > & < / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroupLayoutDescriptor< / span > < span class = "token punctuation" > {< / span >
2021-03-29 15:01:03 +00:00
entries< span class = "token punctuation" > :< / span > < span class = "token operator" > & < / span > < span class = "token punctuation" > [< / span >
2020-11-24 06:49:43 +00:00
< span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > BindGroupLayoutBinding< / span > < span class = "token punctuation" > {< / span >
2021-03-29 15:01:03 +00:00
< span class = "token comment" > // ...< / span >
2020-11-24 06:49:43 +00:00
visibility< span class = "token punctuation" > :< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderStage< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > VERTEX< / span > < span class = "token operator" > |< / span > < span class = "token namespace" > wgpu< span class = "token punctuation" > ::< / span > < / span > < span class = "token class-name" > ShaderStage< / span > < span class = "token punctuation" > ::< / span > < span class = "token constant" > FRAGMENT< / span > < span class = "token punctuation" > ,< / span > < span class = "token comment" > // Updated!< / span >
2021-03-29 15:01:03 +00:00
< span class = "token comment" > // ...< / span >
2020-11-24 06:49:43 +00:00
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > ,< / span >
< span class = "token comment" > // ...< / span >
< span class = "token punctuation" > ]< / span > < span class = "token punctuation" > ,< / span >
label< span class = "token punctuation" > :< / span > < span class = "token class-name" > None< / span > < span class = "token punctuation" > ,< / span >
< span class = "token punctuation" > }< / span > < span class = "token punctuation" > )< / span > < span class = "token punctuation" > ;< / span >
2021-05-24 20:23:02 +00:00
< / code > < / pre > < / div > < p > We're going to get the direction from the fragment's position to the camera, and use that with the normal to calculate the < code > reflect_dir< / code > .< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > // In the fragment shader...
let view_dir = normalize(uniforms.view_pos.xyz - in.world_position);
let reflect_dir = reflect(-light_dir, in.world_normal);
2021-07-20 18:28:37 +00:00
< / code > < / pre > < / div > < p > Then we use the dot product to calculate the < code > specular_strength< / code > and use that to compute the < code > specular_color< / code > .< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > let specular_strength = pow(max(dot(view_dir, reflect_dir), 0.0), 32.0);
let specular_color = specular_strength * light.color;
2021-05-24 20:23:02 +00:00
< / code > < / pre > < / div > < p > Finally we add that to the result.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > let result = (ambient_color + diffuse_color + specular_color) * object_color.xyz;
< / code > < / pre > < / div > < p > With that you should have something like this.< / p > < p > < img src = "/learn-wgpu/assets/img/ambient_diffuse_specular_lighting.76386148.png" alt = "./ambient_diffuse_specular_lighting.png" > < / p > < p > If we just look at the < code > specular_color< / code > on it's own we get this.< / p > < p > < img src = "/learn-wgpu/assets/img/specular_lighting.b3869eb1.png" alt = "./specular_lighting.png" > < / p > < h2 id = "the-half-direction" > < a href = "#the-half-direction" class = "header-anchor" > #< / a > The half direction< / h2 > < p > Up to this point we've actually only implemented the Phong part of Blinn-Phong. The Phong reflection model works well, but it can break down under < a href = "https://learnopengl.com/Advanced-Lighting/Advanced-Lighting" target = "_blank" rel = "noopener noreferrer" > certain circumstances< svg xmlns = "http://www.w3.org/2000/svg" aria-hidden = "true" x = "0px" y = "0px" viewBox = "0 0 100 100" width = "15" height = "15" class = "icon outbound" > < path fill = "currentColor" d = "M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z" > < / path > < polygon fill = "currentColor" points = "45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9" > < / polygon > < / svg > < / a > . The Blinn part of Blinn-Phong comes from the realization that if you add the < code > view_dir< / code > , and < code > light_dir< / code > together, normalize the result and use the dot product of that and the < code > normal< / code > , you get roughly the same results without the issues that using < code > reflect_dir< / code > had.< / p > < div class = "language-wgsl extra-class" > < pre class = "language-text" > < code > let view_dir = normalize(uniforms.view_pos.xyz - in.world_position);
let half_dir = normalize(view_dir + light_dir);
2021-07-20 18:28:37 +00:00
let specular_strength = pow(max(dot(in.world_normal, half_dir), 0.0), 32.0);
2021-08-09 20:59:53 +00:00
< / code > < / pre > < / div > < p > It's hard to tell the difference, but here's the results.< / p > < p > < img src = "/learn-wgpu/assets/img/half_dir.bbcc23b8.png" alt = "./half_dir.png" > < / p > < div class = "auto-github-link" > < a href = "https://github.com/sotrh/learn-wgpu/tree/master/code/intermediate/tutorial10-lighting/" target = "_blank" rel = "noopener noreferrer" > Check out the code!< / a > < svg xmlns = "http://www.w3.org/2000/svg" aria-hidden = "true" x = "0px" y = "0px" viewBox = "0 0 100 100" width = "15" height = "15" class = "icon outbound" > < path fill = "currentColor" d = "M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z" > < / path > < polygon fill = "currentColor" points = "45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9" > < / polygon > < / svg > < / div > < / div > < footer class = "page-edit" > <!-- --> < div class = "last-updated" > < span class = "prefix" > Last Updated: < / span > < span class = "time" > 8/4/2021, 1:06:53 PM< / span > < / div > < / footer > < div class = "page-nav" > < p class = "inner" > < span class = "prev" >
2020-11-24 06:49:43 +00:00
←
< a href = "/learn-wgpu/beginner/tutorial9-models/" class = "prev" >
Model Loading
< / a > < / span > < span class = "next" > < a href = "/learn-wgpu/intermediate/tutorial11-normals/" >
Normal Mapping
< / a >
→
< / span > < / p > < / div > < / main > < / div > < / div > < div class = "global-ui" > <!-- --> < / div > < / div >
2021-08-15 17:04:20 +00:00
< script src = "/learn-wgpu/assets/js/app.7f3b47c3.js" defer > < / script > < script src = "/learn-wgpu/assets/js/2.da3fd46f.js" defer > < / script > < script src = "/learn-wgpu/assets/js/3.ee149516.js" defer > < / script > < script src = "/learn-wgpu/assets/js/22.2132e362.js" defer > < / script >
2020-11-24 06:49:43 +00:00
< / body >
< / html >