Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

New render function with support for material properties and multiple light sources #75

Merged
merged 1 commit into from
Jun 29, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 67 additions & 57 deletions libcurv/frag.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,69 +205,79 @@ void export_frag_3d(
//" */\n"
"}\n"

// Compute an ambient occlusion factor.
// pos: point on surface
// nor: normal of the surface at pos
// Yields a value clamped to [0,1] where 0 means no other surfaces
// around the point, and 1 means the point is occluded by other surfaces.
"float calcAO( in vec3 pos, in vec3 nor, float time )\n"
"{\n"
" float occ = 0.0;\n"
" float sca = 1.0;\n"
" for( int i=0; i<5; i++ )\n"
" {\n"
" float hr = 0.01 + 0.12*float(i)/4.0;\n"
" vec3 aopos = nor * hr + pos;\n"
" float dd = dist( vec4(aopos,time) );\n"
" occ += -(dd-hr)*sca;\n"
" sca *= 0.95;\n"
" }\n"
" return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ); \n"
"struct Light {\n"
" vec3 position;\n"
" // One component per color channel\n"
" vec3 specular_intensity;\n"
" vec3 diffuse_intensity;\n"
" vec3 ambient_intensity;\n"
"};\n"

"const Light lights[3] = Light[3](\n"
" Light(vec3(-10.0, -100.0, 100.0), vec3(1.5), vec3(1.5), vec3(0.25)),\n"
" Light(vec3( 0.0, 100.0, 100.0), vec3(2.0), vec3(2.0), vec3(0.25)),\n"
" Light(vec3( 20.0, 100.0, -100.0), vec3(1.5), vec3(1.5), vec3(0.5))\n"
");\n"

"struct Material {\n"
" // One component per color channel\n"
" vec3 specular_reflectivity;\n"
" vec3 diffuse_reflectivity;\n"
" vec3 ambient_reflectivity;\n"
" vec3 shininess;\n"
"};\n"

"Material material(vec3 point, float time) {\n"
" return Material(vec3(1.5), vec3(1.2), vec3(0.5), vec3(15.0));\n"
"}\n"

"// in ro: ray origin\n"
"// in rd: ray direction\n"
"// out: rgb colour\n"
"vec3 render( in vec3 ro, in vec3 rd, float time )\n"
"{ \n"
" //vec3 col = vec3(0.7, 0.9, 1.0) +rd.z*0.8;\n"
" vec3 col = background_colour;\n"
" vec4 res = castRay(ro,rd, time);\n"
" float t = res.x;\n"
" vec3 c = res.yzw;\n"
" if( c.x>=0.0 )\n"
" {\n"
" vec3 pos = ro + t*rd;\n"
" vec3 nor = calcNormal( pos, time );\n"
" vec3 ref = reflect( rd, nor );\n"
" \n"
" // material \n"
" col = c;\n"
"vec3 render(in vec3 ray_origin, in vec3 ray_direction, float time) {\n"
" vec4 result = castRay(ray_origin, ray_direction, time);\n"
" if (result.y < 0.0) {\n"
" return background_colour;\n"
" }\n"
"\n"
" float distance = result.x;\n"
" vec3 point = ray_origin + distance*ray_direction;\n"
" vec3 normal = calcNormal(point, time);\n"
" vec3 viewer_direction = -ray_direction;\n"
"\n"
" // lighting \n"
" float occ = calcAO( pos, nor, time );\n"
" vec3 lig = normalize( vec3(-0.4, 0.6, 0.7) );\n"
" float amb = clamp( 0.5+0.5*nor.z, 0.0, 1.0 );\n"
" float dif = clamp( dot( nor, lig ), 0.0, 1.0 );\n"
" float bac = clamp( dot( nor, normalize(vec3(-lig.x,lig.y,0.0))), 0.0, 1.0 )*clamp( 1.0-pos.z,0.0,1.0);\n"
" float dom = smoothstep( -0.1, 0.1, ref.z );\n"
" float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );\n"
" float spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0);\n"
" \n"
" vec3 lin = vec3(0.0);\n"
" lin += 1.30*dif*vec3(1.00,0.80,0.55);\n"
" lin += 2.00*spe*vec3(1.00,0.90,0.70)*dif;\n"
" lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ;\n"
" lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ;\n"
" lin += 0.50*bac*vec3(0.35,0.35,0.35)*occ;\n"
" lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ;\n"
" vec3 iqcol = col*lin;\n"
" vec3 color = result.yzw;\n"
" Material material = material(point, time);\n"
"\n"
" //col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );\n"
" col = mix(col,iqcol, 0.5);\n" // adjust contrast
" vec3 illumination = vec3(0.0);\n"
"\n"
" // Implementation follows https://en.wikipedia.org/wiki/Phong_reflection_model\n"
" for (int i = 0; i < lights.length(); i++) {\n"
" Light light = lights[i];\n"
"\n"
" illumination += material.ambient_reflectivity * light.ambient_intensity;\n"
"\n"
" vec3 light_direction = normalize(light.position - point);\n"
"\n"
" result = castRay(point, light_direction, time);\n"
" if (result.y < 0.0) {\n"
" // No part of the shape lies between the surface point\n"
" // and the light source, so directional light affects this point\n"
" vec3 reflection_direction = -reflect(light_direction, normal);\n"
"\n"
" float diffuse_term = dot(light_direction, normal);\n"
" if (diffuse_term > 0.0) {\n"
" illumination +=\n"
" material.diffuse_reflectivity * diffuse_term * light.diffuse_intensity;\n"
"\n"
" float specular_term = dot(reflection_direction, viewer_direction);\n"
" if (specular_term > 0.0) {\n"
" illumination +=\n"
" material.specular_reflectivity *\n"
" pow(vec3(specular_term), material.shininess) *\n"
" light.specular_intensity;\n"
" }\n"
" }\n"
" }\n"
" }\n"
"\n"
" return vec3( clamp(col,0.0,1.0) );\n"
" return mix(color, clamp(color*illumination, 0.0, 1.0), 0.5);\n"
"}\n"

"// Create a matrix to transform coordinates to look towards a given point.\n"
Expand Down