Reflections and Shadows Based on Local Cubemaps Roberto Lopez Mendez Senior Engineer, ARM 1 Content Reflections based on local cubemaps Reflections with infinite cubemaps Local correction to reflections based on cubemaps Combining reflections based on local cubemaps with reflections rendered at runtime New shadows technique: dynamic soft shadows based on local cubemaps 2 The foundations of shadows based on local cubemaps Why dynamic? Why soft? Benefits and limitations of shadows based on local cubemaps Combining shadows based on local cubemaps with shadows rendered at runtime Wrap up Reflections with Infinite Cubemaps Normal N and view vector D are passed to fragment shader from the vertex shader. cubemap R N R In the fragment shader the texture colour is fetched from the cubemap using the reflected vector R: D float3 R = reflect(D, N); float4 col = texCUBE(Cubemap, R); Reflective surface 3 Incorrect Reflections Reflection generated using a cubemap without any local binding 4 Local Correction Using a Bounding Box as a Proxy Geometry cubemap C R’ float3 R = reflect(D, N); P N R D float4 col = texCUBE(Cubemap, R); Find intersection point P Find vector R’ = CP Float4 col = texCUBE(Cubemap, R’); Reflective surface Bounding Box GPU Gems. Chapter 19. Image-Based Lighting. Kevin Bjork, 2004. http://http.developer.nvidia.com/GPUGems/gpugems_ch19.html Cubemap Environment Mapping. 2010. http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/?&p=4637262 Image-based Lighting approaches and parallax-corrected cubemap. Sebastien Lagarde. SIGGRAPH 2012. http://seblagarde.wordpress.com/2012/09/29/image-based-lightingapproaches-and-parallax-corrected-cubemap/ 5 Correct Reflections Reflection generated after applying the “local correction” 6 Reflection generated with out “local correction” Infinite and Local Cubemaps Infinite Cubemaps • They are used to represent the lighting from a distant environment. • Cubemap position is not relevant. Local Cubemaps • They are used to represent the lighting from a finite local environment. • Cubemap position is relevant. • The lighting from these cubemaps is right only at the location where the cubemap was created. • Local correction must be applied to get the right local reflections. 7 Vertex Shader vertexOutput vert(vertexInput input) { vertexOutput output; output.tex = input.texcoord; // Transform vertex coordinates from local to world. float4 vertexWorld = mul(_Object2World, input.vertex); // Transform normal to world coordinates. float4 normalWorld = mul(float4(input.normal, 0.0), _World2Object); // Final vertex output position. output.pos = mul(UNITY_MATRIX_MVP, input.vertex); // ----------- Local correction -----------output.vertexInWorld = vertexWorld.xyz; output.viewDirInWorld = vertexWorld.xyz - _WorldSpaceCameraPos; output.normalInWorld = normalWorld.xyz; Passed as varyings to the fragment shader return output; } Source code in ARM Guide to Unity. 8 Fragment Shader float4 frag(vertexOutput input) : COLOR { float4 reflColor = float4(1, 1, 0, 0); // Find reflected vector in WS. float3 viewDirWS = normalize(input.viewDirInWorld); float3 normalWS = normalize(input.normalInWorld); float3 reflDirWS = reflect(viewDirWS, normalWS); Calculate reflected vector // Working in World Coordinate System. float3 localPosWS = input.vertexInWorld; float3 intersectMaxPointPlanes = (_BBoxMax - localPosWS) / reflDirWS; float3 intersectMinPointPlanes = (_BBoxMin - localPosWS) / reflDirWS; // Looking only for intersections in the forward direction of the ray. float3 largestRayParams = max(intersectMaxPointPlanes, intersectMinPointPlanes); // Smallest value of the ray parameters gives us the intersection. float distToIntersect = min(min(largestRayParams.x, largestRayParams.y), largestRayParams.z); // Find the position of the intersection point. float3 intersectPositionWS = localPosWS + reflDirWS * distToIntersect; // Get local corrected reflection vector. reflDirWS = intersectPositionWS - _EnviCubeMapPos; Ray-box intersection algorithm Local corrected reflected vector // Lookup the environment reflection texture with the right vector. reflColor = texCUBE(_Cube, reflDirWS); // Lookup the texture color. float4 texColor = tex2D(_MainTex, float2(input.tex)); return _AmbientColor + texColor * _ReflAmount * reflColor; Source code in ARM Guide to Unity. 9 } Filtering Cubemaps to Achieve Visual Effects Development Stage The cost of the process depends on filter complexity and cubemap resolution 10 Runtime Just use the filtered cubemap Reflections Based on Filtered Local Cubemap Reflection as rendered with frosty effect 11 Benefits and Limitations Benefits 1. Simple to implement. 2. Very realistic and physically correct. 1. Works fine only in open space with no geometry in the centre from where the cubemap will more likely be generated. 3. High quality of reflections. No pixel flickering/ instability when moving the camera. 2. Objects in the scene must be close to the proxy geometry when generating static texture for good results. 4. Cubemap texture can be compressed. 3. Does not reflect changes in dynamic objects unless we can afford to update the cubemap at runtime. 5. Offline filtering effects can be applied which could be very expensive at run time. 6. Resource saving technique compared with runtime generated reflections. 12 Limitations Handling Reflections From Different Types of Geometries Reflection from Skybox Reflection from Static Geometry Reflection from Dynamic Geometry Use Infinite Cubemap technique Use Local Cubemap technique Use Virtual Reflection Camera technique All Reflections Combine all types of reflections 13 Combined reflections 14 Combined Reflections Reflections on the chess piece using local cubemap Reflections from the sky using infinite cubemap Reflections from dynamic geometry using a mirrored camera Reflections from static geometry using local cubemap 15 Dynamic Soft Shadows 16 Dynamic Soft Shadows Based on Local Cubemaps Generation stage Top +Y Render the transparency of the scene in the alpha channel Y Left –X Front -Z Bottom -Y X Back +Z Opaque geometry is rendered with alpha = 1. We have a map of the zones where light rays can potentially come from and reach the geometry. Semi-transparent geometry is rendered with alpha different from 1. No light information is processed at this stage. Z Camera background alpha colour = 0. Fully transparent geometry is rendered with alpha 0. 17 Right +X Dynamic Soft Shadows Based on Local Cubemaps Runtime stage • Create a vertex to light source L vector in the vertex shader. • Pass this vector to the fragment shader to obtain the vector from the pixel to the light position piL. L Q P cubemap • Find the intersection of the vector piL with the bounding box. C shadowed pixel pk lit pixel pi • Build the vector CP from the cubemap position C to the intersection point P. • Use the new vector CP to fetch the texture from the cubemap. float texShadow = texCUBE(_CubeShadows, CP).a; Bounding Box Source code in the update of ARM Guide to Unity at Unite Europe 2015. 18 Dynamic Soft Shadows Based on Local Cubemaps Why dynamic? If the position of the light source changes the shadows are generated correctly using the same cubemap. 19 Dynamic Shadows 20 Dynamic Soft Shadows Based on Local Cubemaps Why soft? The further from the object the softer the shadows 21 Dynamic Soft Shadows Based on Local Cubemaps Why soft? float texShadow = texCUBE(_CubeShadows, CP).a; L Q P float4 newVec = float4(CP, factor * length(piP)) cubemap C float texShadow = texCUBElod(_CubeShadows, newVec ).a; shadowed pixel pk lit pixel pi Bounding Box Source code in the update of ARM Guide to Unity at Unite Europe 2015. 22 Soft shadows 23 Dynamic Soft Shadows Based on Local Cubemaps Benefits 1. Simple to implement. 2. Very realistic and physically correct. 3. High quality of shadows. 4. Cubemap texture can be compressed. 5. Offline filtering effects can be applied which could be very expensive at run time. 6. Resource saving technique compared with runtime generated reflections. 7. The static texture can be reused for shadow mapping when the light source is inside of the volume. 24 Limitations 1. Works fine in open space with no geometry in the centre from where the cubemap will more likely be generated. 2. Objects in the scene must be close to the proxy geometry when generating static texture for good results. This is more tolerant of deviations from the bounding box shape. 3. Does not reflect changes in dynamic objects unless we can afford to update the cubemap at runtime. Handling Shadows from Different Types of Geometries Shadows from Static Geometry Shadows from Dynamic Geometry Use Local Cubemap technique Use Shadow Mapping technique All Shadows Combine both types of shadows 25 Combined shadows 26 Combined Shadows Shadows from static geometry using local cubemap Shadows from the chess pieces using shadow mapping 27 Wrap Up Reflections and shadows based on local cubemaps are resource saving techniques that work great in mobile devices where available resources must be carefully balanced. These techniques can be effectively combined with runtime techniques to render static and dynamic objects together. Both techniques are currently used in the Ice Cave Demo together with other FX as fog, light shafts, procedural skybox, Enlighten in custom shaders, fireflies, dirty lens, etc. Source code in the update of ARM Guide to Unity at Unite Europe 2015. 28 29 Thank You The trademarks featured in this presentation are registered and/or unregistered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. Any other marks featured may be trademarks of their respective owners 30 To Find Out More…. ARM Booth #1624 on Expo Floor Live demos In-depth Q&A with ARM engineers More tech talks at the ARM Lecture Theatre http://malideveloper.arm.com/GDC2015 Revisit this talk in PDF and video format post GDC Download the tools and resources 31 More Talks from ARM at GDC 2015 Available post-show online at Mali Developer Center Unreal Engine 4 mobile graphics and the latest ARM CPU and GPU architecture - Weds 9:30AM; West Hall 3003 This talk introduces the latest advances in features and benefits of the ARMv8-A and tile-based Mali GPU architectures on Unreal Engine 4, allowing mobile game developers to move to 64-bit’s improved instruction set. Unleash the benefits of OpenGL ES 3.1 and Android Extension Pack (AEP) – Weds 2PM; West Hall 3003 OpenGL ES 3.1 provides a rich set of tools for creating stunning images. This talk will cover best practices for using advanced features of OpenGL ES 3.1 on ARM Mali GPUs using recently developed examples from the Mali SDK. Making dreams come true – global illumination made easy – Thurs 10AM; West Hall 3014 In this talk, we present an overview of the Enlighten feature set and show through workflow examples and gameplay demonstrations how it enables fast iteration and high visual quality on all gaming platforms. How to optimize your mobile game with ARM Tools and practical examples – Thurs 11:30AM; West Hall 3014 This talk introduces you to the tools and skills needed to profile and debug your application by showing you optimization examples from popular game titles. Enhancing your Unity mobile game – Thurs 4PM; West Hall 3014 32 Learn how to get the most out of Unity when developing under the unique challenges of mobile platforms.
© Copyright 2024