Commit da6debb7e20de8f1e01f652a7a175f8d8cf65fed
1 parent
3a81e76e
DALi ray marching / ray tracing example
Uses volumetric ray casting to draw a sphere with basic per-pixel lighting inside the fragment shader. Also modifies DALi demo make file to support shader files. Change-Id: I0645de8481fa75abb177ca76a5611a51350fc1b7 Todo: Create a separate folder for shaders?
Showing
18 changed files
with
450 additions
and
1 deletions
build/tizen/CMakeLists.txt
| ... | ... | @@ -33,6 +33,7 @@ SET(LOCAL_GAME_DIR ${RESOURCE_DIR}/game) |
| 33 | 33 | SET(LOCAL_VIDEOS_DIR ${RESOURCE_DIR}/videos) |
| 34 | 34 | SET(LOCAL_MODELS_DIR ${RESOURCE_DIR}/models) |
| 35 | 35 | SET(LOCAL_SCRIPTS_DIR ${RESOURCE_DIR}/scripts) |
| 36 | +SET(LOCAL_SHADERS_DIR ${RESOURCE_DIR}/shaders) | |
| 36 | 37 | IF(NOT DEFINED LOCAL_STYLE_DIR) |
| 37 | 38 | SET(LOCAL_STYLE_DIR ${RESOURCE_DIR}/style) |
| 38 | 39 | ENDIF() |
| ... | ... | @@ -42,6 +43,7 @@ SET(GAME_DIR ${APP_DATA_RES_DIR}/game/) |
| 42 | 43 | SET(VIDEOS_DIR ${APP_DATA_RES_DIR}/videos/) |
| 43 | 44 | SET(MODELS_DIR ${APP_DATA_RES_DIR}/models/) |
| 44 | 45 | SET(SCRIPTS_DIR ${APP_DATA_RES_DIR}/scripts/) |
| 46 | +SET(SHADERS_DIR ${APP_DATA_RES_DIR}/shaders/) | |
| 45 | 47 | SET(STYLE_DIR ${APP_DATA_RES_DIR}/style/) |
| 46 | 48 | |
| 47 | 49 | IF(NOT DEFINED LOCALE_DIR) |
| ... | ... | @@ -53,6 +55,7 @@ SET(DEMO_IMAGE_DIR \\"${IMAGES_DIR}\\") |
| 53 | 55 | SET(DEMO_VIDEO_DIR \\"${VIDEOS_DIR}\\") |
| 54 | 56 | SET(DEMO_MODEL_DIR \\"${MODELS_DIR}\\") |
| 55 | 57 | SET(DEMO_SCRIPT_DIR \\"${SCRIPTS_DIR}\\") |
| 58 | +SET(DEMO_SHADER_DIR \\"${SHADERS_DIR}\\") | |
| 56 | 59 | SET(DEMO_STYLE_DIR \\"${STYLE_DIR}\\") |
| 57 | 60 | SET(DEMO_THEME_PATH \\"${STYLE_DIR}demo-theme.json\\") |
| 58 | 61 | SET(DEMO_EXAMPLE_BIN \\"${BINDIR}/\\") |
| ... | ... | @@ -91,6 +94,11 @@ FOREACH(flag ${LOCAL_SCRIPTS_LIST}) |
| 91 | 94 | INSTALL(FILES ${LOCAL_SCRIPTS_DIR}/${flag} DESTINATION ${SCRIPTS_DIR}) |
| 92 | 95 | ENDFOREACH(flag) |
| 93 | 96 | |
| 97 | +FILE(GLOB LOCAL_SHADERS_LIST RELATIVE "${LOCAL_SHADERS_DIR}" "${LOCAL_SHADERS_DIR}/*") | |
| 98 | +FOREACH(flag ${LOCAL_SHADERS_LIST}) | |
| 99 | + INSTALL(FILES ${LOCAL_SHADERS_DIR}/${flag} DESTINATION ${SHADERS_DIR}) | |
| 100 | +ENDFOREACH(flag) | |
| 101 | + | |
| 94 | 102 | FILE(GLOB LOCAL_GAME_LIST RELATIVE "${LOCAL_GAME_DIR}" "${LOCAL_GAME_DIR}/*.*") |
| 95 | 103 | FOREACH(flag ${LOCAL_GAME_LIST}) |
| 96 | 104 | INSTALL(FILES ${LOCAL_GAME_DIR}/${flag} DESTINATION ${GAME_DIR}) |
| ... | ... | @@ -134,7 +142,7 @@ FOREACH(flag ${REQUIRED_PKGS_CFLAGS}) |
| 134 | 142 | SET(REQUIRED_CFLAGS "${REQUIRED_CFLAGS} ${flag}") |
| 135 | 143 | ENDFOREACH(flag) |
| 136 | 144 | |
| 137 | -SET(DALI_DEMO_CFLAGS "-DDEMO_GAME_DIR=${DEMO_GAME_DIR} -DDEMO_IMAGE_DIR=${DEMO_IMAGE_DIR} -DDEMO_VIDEO_DIR=${DEMO_VIDEO_DIR} -DDEMO_MODEL_DIR=${DEMO_MODEL_DIR} -DDEMO_SCRIPT_DIR=${DEMO_SCRIPT_DIR} -DDEMO_STYLE_DIR=${DEMO_STYLE_DIR} -DDEMO_THEME_PATH=${DEMO_THEME_PATH} -DDEMO_EXAMPLE_BIN=${DEMO_EXAMPLE_BIN} -DDEMO_LOCALE_DIR=${DEMO_LOCALE_DIR} -fvisibility=hidden -DHIDE_DALI_INTERNALS -DDEMO_LANG=${DEMO_LANG}") | |
| 145 | +SET(DALI_DEMO_CFLAGS "-DDEMO_GAME_DIR=${DEMO_GAME_DIR} -DDEMO_IMAGE_DIR=${DEMO_IMAGE_DIR} -DDEMO_VIDEO_DIR=${DEMO_VIDEO_DIR} -DDEMO_MODEL_DIR=${DEMO_MODEL_DIR} -DDEMO_SCRIPT_DIR=${DEMO_SCRIPT_DIR} -DDEMO_SHADER_DIR=${DEMO_SHADER_DIR} -DDEMO_STYLE_DIR=${DEMO_STYLE_DIR} -DDEMO_THEME_PATH=${DEMO_THEME_PATH} -DDEMO_EXAMPLE_BIN=${DEMO_EXAMPLE_BIN} -DDEMO_LOCALE_DIR=${DEMO_LOCALE_DIR} -fvisibility=hidden -DHIDE_DALI_INTERNALS -DDEMO_LANG=${DEMO_LANG}") | |
| 138 | 146 | |
| 139 | 147 | ########################################################################### |
| 140 | 148 | # Internationalization | ... | ... |
com.samsung.dali-demo.xml
| ... | ... | @@ -214,6 +214,8 @@ |
| 214 | 214 | </ui-application> |
| 215 | 215 | <ui-application appid="rendering-radial-progress.example" exec="/usr/apps/com.samsung.dali-demo/bin/rendering-radial-progress.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 216 | 216 | <label>Rendering Radial Progress</label> |
| 217 | + <ui-application appid="ray-marching.example" exec="/usr/apps/com.samsung.dali-demo/bin/ray-marching.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | |
| 218 | + <label>Ray Marching example</label> | |
| 217 | 219 | </ui-application> |
| 218 | 220 | <ui-application appid="rendering-basic-light.example" exec="/usr/apps/com.samsung.dali-demo/bin/rendering-basic-light.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 219 | 221 | <label>Basic Light</label> | ... | ... |
examples-reel/dali-examples-reel.cpp
| ... | ... | @@ -69,6 +69,7 @@ int DALI_EXPORT_API main(int argc, char **argv) |
| 69 | 69 | demo.AddExample(Example("rendering-cube.example", DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE)); |
| 70 | 70 | demo.AddExample(Example("rendering-textured-cube.example", DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE)); |
| 71 | 71 | demo.AddExample(Example("rendering-radial-progress.example", DALI_DEMO_STR_TITLE_RENDERING_RADIAL_PROGRESS)); |
| 72 | + demo.AddExample(Example("ray-marching.example", DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING)); | |
| 72 | 73 | demo.AddExample(Example("scroll-view.example", DALI_DEMO_STR_TITLE_SCROLL_VIEW)); |
| 73 | 74 | demo.AddExample(Example("size-negotiation.example", DALI_DEMO_STR_TITLE_NEGOTIATE_SIZE)); |
| 74 | 75 | demo.AddExample(Example("styling.example", DALI_DEMO_STR_TITLE_STYLING)); | ... | ... |
examples/ray-marching/ray-marching-example.cpp
0 → 100644
| 1 | +/* | |
| 2 | + * Copyright (c) 2017 Samsung Electronics Co., Ltd. | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#include <dali-toolkit/dali-toolkit.h> | |
| 19 | +#include <dali-toolkit/devel-api/controls/tool-bar/tool-bar.h> | |
| 20 | +#include "shared/view.h" | |
| 21 | +#include "shared/utility.h" | |
| 22 | +#include <stdio.h> | |
| 23 | + | |
| 24 | +using namespace Dali; | |
| 25 | +using Dali::Toolkit::TextLabel; | |
| 26 | +using Dali::Toolkit::Control; | |
| 27 | +using Dali::Toolkit::ToolBar; | |
| 28 | + | |
| 29 | +const char* BACKGROUND_IMAGE( "" ); | |
| 30 | +const char* TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" ); | |
| 31 | +const char* APPLICATION_TITLE( "Ray Marching" ); | |
| 32 | +const char* SHADER_NAME("raymarch_sphere_shaded"); | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * @brief LoadShaderCode | |
| 36 | + * @param filename | |
| 37 | + * @param output | |
| 38 | + * @return | |
| 39 | + */ | |
| 40 | +bool LoadShaderCode( const char* path, const char* filename, std::vector<char>& output ) | |
| 41 | +{ | |
| 42 | + std::string fullpath( path ); | |
| 43 | + fullpath += filename; | |
| 44 | + FILE* f = fopen( fullpath.c_str(), "rb" ); | |
| 45 | + if( !f ) | |
| 46 | + { | |
| 47 | + return false; | |
| 48 | + } | |
| 49 | + fseek( f, 0, SEEK_END ); | |
| 50 | + size_t size = ftell( f ); | |
| 51 | + fseek( f, 0, SEEK_SET ); | |
| 52 | + output.resize( size + 1 ); | |
| 53 | + std::fill( output.begin(), output.end(), 0 ); | |
| 54 | + ssize_t result = fread( output.data(), size, 1, f ); | |
| 55 | + fclose( f ); | |
| 56 | + | |
| 57 | + return ( result >= 0 ); | |
| 58 | +} | |
| 59 | + | |
| 60 | +/** | |
| 61 | + * @brief LoadShaders | |
| 62 | + * @param shaderName | |
| 63 | + * @return | |
| 64 | + */ | |
| 65 | +Shader LoadShaders( const std::string& shaderName ) | |
| 66 | +{ | |
| 67 | + std::vector<char> bufV, bufF; | |
| 68 | + std::string shaderVSH( shaderName ); | |
| 69 | + std::string shaderFSH( shaderName ); | |
| 70 | + shaderVSH += ".vsh"; | |
| 71 | + shaderFSH += ".fsh"; | |
| 72 | + LoadShaderCode( DEMO_SHADER_DIR, shaderVSH.c_str(), bufV ); | |
| 73 | + LoadShaderCode( DEMO_SHADER_DIR, shaderFSH.c_str(), bufF ); | |
| 74 | + Shader shader = Shader::New( bufV.data(), bufF.data() ); | |
| 75 | + return shader; | |
| 76 | +} | |
| 77 | + | |
| 78 | +// This example shows how to create a Ray Marching using a shader | |
| 79 | +// | |
| 80 | +class RayMarchingExample : public ConnectionTracker | |
| 81 | +{ | |
| 82 | +public: | |
| 83 | + | |
| 84 | + RayMarchingExample( Application& application ) | |
| 85 | + : mApplication( application ) | |
| 86 | + { | |
| 87 | + // Connect to the Application's Init signal | |
| 88 | + mApplication.InitSignal().Connect( this, &RayMarchingExample::Create ); | |
| 89 | + } | |
| 90 | + | |
| 91 | + ~RayMarchingExample() | |
| 92 | + { | |
| 93 | + // Nothing to do here; | |
| 94 | + } | |
| 95 | + | |
| 96 | + // The Init signal is received once (only) during the Application lifetime | |
| 97 | + void Create( Application& application ) | |
| 98 | + { | |
| 99 | + // Get a handle to the stage | |
| 100 | + Stage stage = Stage::GetCurrent(); | |
| 101 | + | |
| 102 | + stage.GetRootLayer().TouchSignal().Connect( this, &RayMarchingExample::OnTouch ); | |
| 103 | + | |
| 104 | + stage.KeyEventSignal().Connect(this, &RayMarchingExample::OnKeyEvent); | |
| 105 | + | |
| 106 | + stage.SetBackgroundColor( Color::YELLOW ); | |
| 107 | + | |
| 108 | + // Hide the indicator bar | |
| 109 | + application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE ); | |
| 110 | + | |
| 111 | + // Creates a default view with a default tool bar. | |
| 112 | + // The view is added to the stage. | |
| 113 | + mContentLayer = DemoHelper::CreateView( application, | |
| 114 | + mView, | |
| 115 | + mToolBar, | |
| 116 | + BACKGROUND_IMAGE, | |
| 117 | + TOOLBAR_IMAGE, | |
| 118 | + APPLICATION_TITLE ); | |
| 119 | + | |
| 120 | + // Add an extra space on the right to center the title text. | |
| 121 | + mToolBar.AddControl( Actor::New(), DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight ); | |
| 122 | + | |
| 123 | + AddContentLayer(); | |
| 124 | + | |
| 125 | + } | |
| 126 | + bool OnTouch( Actor actor, const TouchData& touch ) | |
| 127 | + { | |
| 128 | + // quit the application | |
| 129 | + mApplication.Quit(); | |
| 130 | + return true; | |
| 131 | + } | |
| 132 | + | |
| 133 | + /** | |
| 134 | + * Main key event handler | |
| 135 | + */ | |
| 136 | + void OnKeyEvent(const KeyEvent& event) | |
| 137 | + { | |
| 138 | + if(event.state == KeyEvent::Down) | |
| 139 | + { | |
| 140 | + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) ) | |
| 141 | + { | |
| 142 | + mApplication.Quit(); | |
| 143 | + } | |
| 144 | + } | |
| 145 | + } | |
| 146 | + | |
| 147 | + /** | |
| 148 | + * Creates quad renderer | |
| 149 | + */ | |
| 150 | + Renderer CreateQuadRenderer() | |
| 151 | + { | |
| 152 | + // Create shader & geometry needed by Renderer | |
| 153 | + Shader shader = LoadShaders( SHADER_NAME ); | |
| 154 | + | |
| 155 | + Property::Map vertexFormat; | |
| 156 | + vertexFormat["aPosition"] = Property::VECTOR2; | |
| 157 | + PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat ); | |
| 158 | + | |
| 159 | + const float P( 0.5f ); | |
| 160 | + const Vector2 vertices[] = { | |
| 161 | + Vector2( -P, -P ), | |
| 162 | + Vector2( +P, -P ), | |
| 163 | + Vector2( -P, +P ), | |
| 164 | + Vector2( +P, +P ) | |
| 165 | + }; | |
| 166 | + | |
| 167 | + vertexBuffer.SetData( vertices, 4 ); | |
| 168 | + | |
| 169 | + // Instantiate quad geometry | |
| 170 | + Geometry geometry = Geometry::New(); | |
| 171 | + geometry.AddVertexBuffer( vertexBuffer ); | |
| 172 | + geometry.SetType( Geometry::TRIANGLE_STRIP ); | |
| 173 | + | |
| 174 | + // Create renderer | |
| 175 | + Renderer renderer = Renderer::New( geometry, shader ); | |
| 176 | + | |
| 177 | + renderer.RegisterProperty("uRadius", 0.0f ); | |
| 178 | + renderer.RegisterProperty("uAdjuster", -4.0f ); | |
| 179 | + | |
| 180 | + // Animate the sphere radius uniform and a generic uAdjust uniform currently used to move the light around | |
| 181 | + Animation animation = Animation::New(8.0f); | |
| 182 | + animation.AnimateTo( Property(renderer,"uRadius"), 1.2f, AlphaFunction::BOUNCE); | |
| 183 | + animation.AnimateTo( Property(renderer,"uAdjuster"), 4.0f, AlphaFunction::BOUNCE); | |
| 184 | + animation.SetLooping( true ); | |
| 185 | + animation.Play(); | |
| 186 | + | |
| 187 | + return renderer; | |
| 188 | + } | |
| 189 | + | |
| 190 | + void AddContentLayer() | |
| 191 | + { | |
| 192 | + Stage stage = Stage::GetCurrent(); | |
| 193 | + | |
| 194 | + //Create all the renderers | |
| 195 | + Renderer renderer = CreateQuadRenderer(); | |
| 196 | + | |
| 197 | + Actor actor = Actor::New(); | |
| 198 | + actor.AddRenderer( renderer ); | |
| 199 | + | |
| 200 | + actor.SetAnchorPoint( Dali::AnchorPoint::CENTER ); | |
| 201 | + actor.SetParentOrigin( Dali::ParentOrigin::CENTER ); | |
| 202 | + actor.SetResizePolicy( Dali::ResizePolicy::FILL_TO_PARENT, Dali::Dimension::ALL_DIMENSIONS ); | |
| 203 | + | |
| 204 | + mContentLayer.Add( actor ); | |
| 205 | + } | |
| 206 | + | |
| 207 | +private: | |
| 208 | + Application& mApplication; | |
| 209 | + Control mView; | |
| 210 | + Layer mContentLayer; | |
| 211 | + ToolBar mToolBar; | |
| 212 | +}; | |
| 213 | + | |
| 214 | +void RunTest( Application& application ) | |
| 215 | +{ | |
| 216 | + RayMarchingExample test( application ); | |
| 217 | + | |
| 218 | + application.MainLoop(); | |
| 219 | +} | |
| 220 | + | |
| 221 | +// Entry point for Linux & Tizen applications | |
| 222 | +// | |
| 223 | +int DALI_EXPORT_API main( int argc, char **argv ) | |
| 224 | +{ | |
| 225 | + Application application = Application::New( &argc, &argv ); | |
| 226 | + | |
| 227 | + RunTest( application ); | |
| 228 | + | |
| 229 | + return 0; | |
| 230 | +} | ... | ... |
packaging/com.samsung.dali-demo.spec
| ... | ... | @@ -140,6 +140,7 @@ exit 0 |
| 140 | 140 | %{dali_app_res_dir}/videos/* |
| 141 | 141 | %{dali_app_res_dir}/models/* |
| 142 | 142 | %{dali_app_res_dir}/scripts/* |
| 143 | +%{dali_app_res_dir}/shaders/* | |
| 143 | 144 | %{dali_app_res_dir}/style/* |
| 144 | 145 | %{dali_app_res_dir}/style/images/* |
| 145 | 146 | %{dali_xml_file_dir}/%{name}.xml | ... | ... |
resources/po/as.po
resources/po/de.po
resources/po/en_GB.po
resources/po/en_US.po
resources/po/es.po
resources/po/fi.po
resources/po/ko.po
resources/po/ml.po
resources/po/ur.po
resources/po/zn_CH.po
resources/shaders/raymarch_sphere_shaded.fsh
0 → 100644
| 1 | +/* | |
| 2 | + * Fragment shader for textured quad | |
| 3 | + */ | |
| 4 | +varying mediump vec2 vTexCoord; | |
| 5 | +varying mediump vec2 vRayCastCoord; | |
| 6 | + | |
| 7 | +uniform mediump float uRadius; | |
| 8 | +uniform mediump float uAdjuster; | |
| 9 | + | |
| 10 | +#define CAMERA_Z_POSITION 1.0 // gives us a FOV of 90 degrees if Plane of projection is at Z = 0 with size 2x2 | |
| 11 | +#define SPHERE_Z_POSITION -1.0 // Sphere placed behind Plane of projection | |
| 12 | +#define SPHERE_RADIUS 0.5 | |
| 13 | + | |
| 14 | + | |
| 15 | +// signed distance function | |
| 16 | +// returns | |
| 17 | +// < 0 if inside sphere | |
| 18 | +// 0 == on sphere surface | |
| 19 | +// > 1 if outside sphere | |
| 20 | +mediump float distanceToSphere( mediump vec3 point, mediump vec3 sphereCenter, mediump float radius ) | |
| 21 | +{ | |
| 22 | + return distance( point, sphereCenter ) - radius; | |
| 23 | +} | |
| 24 | + | |
| 25 | +// Simulate a simple spot light ( there's no ambient light in this example) | |
| 26 | +mediump vec4 lightSphere( mediump vec3 point, mediump vec3 sphereCenter ) | |
| 27 | +{ | |
| 28 | + // the normal = direction of the vector from the sphere center to the point on the surface of the sphere | |
| 29 | + mediump vec3 normal = normalize( point - sphereCenter ); | |
| 30 | + | |
| 31 | + // Animate the light around the sphere in a circular motion | |
| 32 | + mediump vec3 lightDirection = vec3( sin(uAdjuster)+uRadius, cos ( uAdjuster )+uRadius, CAMERA_Z_POSITION ); | |
| 33 | + | |
| 34 | + // calculate the dot product to give us the intensity of the light bouncing off the surface | |
| 35 | + mediump float value = dot( normal , lightDirection); | |
| 36 | + | |
| 37 | + // add a purple tint to the final color by adjust green channel by 0.84 | |
| 38 | + return vec4( value, value * 0.843, value , 1.0); | |
| 39 | + | |
| 40 | +} | |
| 41 | + | |
| 42 | +void main() | |
| 43 | +{ | |
| 44 | + // The fragment shader is called for every pixel that is to be drawn for our | |
| 45 | + // quad geometry ( 2 triangles ). The size and number of pixels drawn is | |
| 46 | + // determined by the size / position of the quad and the DALi camera position. | |
| 47 | + // | |
| 48 | + // For this example the vRayCastCoord is currently set to the range -1 to 1 by the Vertex Shader | |
| 49 | + // | |
| 50 | + // (-1,-1) | |
| 51 | + // |--------------| | |
| 52 | + // | | | | |
| 53 | + // | | | | |
| 54 | + // |_____(0,0)____| | |
| 55 | + // | | | | |
| 56 | + // | | | | |
| 57 | + // |_______|______|(1,1) | |
| 58 | + | |
| 59 | + mediump vec3 pixelPosition = vec3( vRayCastCoord, 0.0 ); | |
| 60 | + | |
| 61 | + // uncomment line below to see red / green colors only visible when x > 0, or y > 0 | |
| 62 | + // gl_FragColor = vec4( pixelPosition, 1.0 ); return; | |
| 63 | + | |
| 64 | + // We are going to assume there is a virtual camera infront of the plane of projection | |
| 65 | + // Side view: | |
| 66 | + // projection | |
| 67 | + // plane (2x2) | |
| 68 | + // /| | |
| 69 | + // / | | |
| 70 | + // / | /----\ | |
| 71 | + // Camera---->| (SPHERE) | |
| 72 | + // \ | \----/ | |
| 73 | + // \ | | |
| 74 | + // \| | |
| 75 | + // z=1 z=0 z = -1 | |
| 76 | + // | |
| 77 | + // | |
| 78 | + // Why z=1 for camera? Our projection plane is at z = 0, with plane size 2x2 which gives a 90 degree FOV | |
| 79 | + // from the camera to the projection plane | |
| 80 | + // | |
| 81 | + mediump vec3 cameraPos = vec3( 0.0, 0.0, CAMERA_Z_POSITION ); | |
| 82 | + | |
| 83 | + // calculate the ray direction from the camera to the pixel on the quad | |
| 84 | + mediump vec3 rayDirection = normalize( pixelPosition - cameraPos ); | |
| 85 | + | |
| 86 | + // uncomment to visualize the normalized ray direction vector | |
| 87 | + // gl_FragColor = vec4( rayDirection, 1.0 ); return; | |
| 88 | + | |
| 89 | + // Setup the position on radius of our virtual sphere | |
| 90 | + mediump vec3 spherePosition = vec3( 0.0, 0.0, SPHERE_Z_POSITION ); | |
| 91 | + mediump float sphereRadius = SPHERE_RADIUS + uRadius ; // use uRadius to animate radius from small to large | |
| 92 | + | |
| 93 | + // We have the direction of the ray from the camera, now see if it | |
| 94 | + // hits our sphere using ray marching | |
| 95 | + // starting at a pixel position 0 on our projection plane, step in the direction | |
| 96 | + // of ray from the camera to see if it hits our sphere | |
| 97 | + // The concept of ray marching is the step size = minimum distance to an object | |
| 98 | + | |
| 99 | + mediump vec3 hitPoint = pixelPosition; | |
| 100 | + | |
| 101 | + int steps = 5; | |
| 102 | + | |
| 103 | + for( int i = 0; i < steps ; ++i ) | |
| 104 | + { | |
| 105 | + // calculate the shortest distance between our hitPoint and the sphere | |
| 106 | + mediump float distance = distanceToSphere( hitPoint, spherePosition, sphereRadius ); | |
| 107 | + | |
| 108 | + // if the distance < 0 then were inside the sphere | |
| 109 | + // if the distance > 0 then were outside the sphere | |
| 110 | + // if we're close to the edge of the sphere, then draw it | |
| 111 | + if( distance < 0.01 ) | |
| 112 | + { | |
| 113 | + gl_FragColor = lightSphere( hitPoint, spherePosition ); | |
| 114 | + return; | |
| 115 | + } | |
| 116 | + | |
| 117 | + // move the hit point along by the distance to the spin the direction of the ray | |
| 118 | + hitPoint += rayDirection * distance; | |
| 119 | + | |
| 120 | + } | |
| 121 | + // no hit, color the pixel based on it's x,y position | |
| 122 | + gl_FragColor = vec4(pixelPosition.x,pixelPosition.y,0.5,1); | |
| 123 | + | |
| 124 | +} | |
| 0 | 125 | \ No newline at end of file | ... | ... |
resources/shaders/raymarch_sphere_shaded.vsh
0 → 100644
| 1 | +attribute mediump vec2 aPosition; | |
| 2 | +uniform mediump mat4 uMvpMatrix; // DALi shader builtin | |
| 3 | +uniform mediump vec3 uSize; // DALi shader builtin | |
| 4 | + | |
| 5 | +varying mediump vec2 vTexCoord; | |
| 6 | +varying mediump vec2 vRayCastCoord; | |
| 7 | +void main() | |
| 8 | +{ | |
| 9 | + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0); | |
| 10 | + vertexPosition.xyz *= uSize; | |
| 11 | + | |
| 12 | + // In this ray march example we supply the fragment shader with 0..1 UV texture co-ordinates | |
| 13 | + // incase someone wants to extend the code and add texture mapping to it. | |
| 14 | + // DALi geometry typically ranges from -0.5 to 0.5, hence the +0.5 to make it 0..1 | |
| 15 | + | |
| 16 | + vTexCoord = aPosition + vec2(0.5); | |
| 17 | + | |
| 18 | + | |
| 19 | + // Our UV texture co-ordinates for the quad geometry should now range from 0..1 | |
| 20 | + // | |
| 21 | + // (0,0) | |
| 22 | + // |--------| | |
| 23 | + // | / | | |
| 24 | + // | / | | |
| 25 | + // | / | | |
| 26 | + // |/-------|(1,1) | |
| 27 | + // | |
| 28 | + // | |
| 29 | + // | |
| 30 | + // We're going to use the UV co-ordinates as our virtual screen / plane of projection on to our | |
| 31 | + // raycasted scene. | |
| 32 | + // | |
| 33 | + // We first modify the range to be from -1,-1 to 1,1 with 0,0 in the centre. Then | |
| 34 | + // pass this as a varying value to the fragment shader. | |
| 35 | + // | |
| 36 | + // | |
| 37 | + // (-1,-1) | |
| 38 | + // |--------------| | |
| 39 | + // | | | | |
| 40 | + // | | | | |
| 41 | + // |_____(0,0)____| | |
| 42 | + // | | | | |
| 43 | + // | | | | |
| 44 | + // |_______|______|(1,1) | |
| 45 | + // | |
| 46 | + // | |
| 47 | + | |
| 48 | + vRayCastCoord = (2.0 * vTexCoord ) - 1.0 ; | |
| 49 | + | |
| 50 | + gl_Position = uMvpMatrix * vertexPosition; | |
| 51 | +} | |
| 0 | 52 | \ No newline at end of file | ... | ... |
shared/dali-demo-strings.h
| ... | ... | @@ -75,6 +75,7 @@ extern "C" |
| 75 | 75 | #define DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE") |
| 76 | 76 | #define DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE") |
| 77 | 77 | #define DALI_DEMO_STR_TITLE_RENDERING_RADIAL_PROGRESS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_RADIAL_PROGRESS") |
| 78 | +#define DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING") | |
| 78 | 79 | #define DALI_DEMO_STR_TITLE_REFRACTION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_REFRACTION") |
| 79 | 80 | #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERER_STENCIL") |
| 80 | 81 | #define DALI_DEMO_STR_TITLE_SIMPLE_VISUALS_CONTROL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SIMPLE_VISUALS") |
| ... | ... | @@ -136,6 +137,7 @@ extern "C" |
| 136 | 137 | #define DALI_DEMO_STR_TITLE_RENDERING_DRAW_TRIANGLE "Draw Triangle" |
| 137 | 138 | #define DALI_DEMO_STR_TITLE_RENDERING_DRAW_CUBE "Draw Cube" |
| 138 | 139 | #define DALI_DEMO_STR_TITLE_RENDERING_TEXTURED_CUBE "Textured Cube" |
| 140 | +#define DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING "Ray Marching" | |
| 139 | 141 | #define DALI_DEMO_STR_TITLE_RENDERING_RADIAL_PROGRESS "Radial Progress" |
| 140 | 142 | #define DALI_DEMO_STR_TITLE_REFRACTION "Refract Effect" |
| 141 | 143 | #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL "Renderer Stencils" | ... | ... |