POV-Ray : Newsgroups : povray.advanced-users : surface normal for use in pigment{function{...}} : Re: surface normal for use in pigment{function{...}} Server Time
29 Jul 2024 04:30:38 EDT (-0400)
  Re: surface normal for use in pigment{function{...}}  
From: Tor Olav Kristensen
Date: 4 Jan 2003 15:10:03
Message: <web.3e173eca48f7e074b417814a0@news.povray.org>
klk wrote:
>Is there any way to get and use surface normal in pigment{function{...}}?
>I read help, but found no one. But it seems to be usefull.

AFAIK there's no way to have a
function return a normal vector
for a surface.

This is, as Thorsten mentioned,
because functions (in POV-Ray v3.5)
can only return scalar values.

But you can use the
fn_Gradient_Directional() macro
in the "math.inc" include file
to find the component of a normal
(or a gradient vector) along a
given vector. The magnitude of
this component can then be used
to e.g. choose a pigment.

My code below shows how all this
can be done.

The SquashFn() function is used
to map the magnitude of the
vector component into the 0.0 to
1.0 range of the color maps.
(Try to vary the S value when
calling this function.)


Tor Olav


// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2003 by Tor Olav Kristensen
// Email: t o r _ o l a v _ k [ a t ] h o t m a i l . c o m
// http://home.no/t-o-k
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.5;

#include "colors.inc"
#include "functions.inc"
#include "math.inc"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare SquashFn = function(Fn, S) { 1/(1 + exp(-S*Fn)) }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare BozoFn = function { pattern { bozo turbulence 0.4 scale 4 } }
#declare NoiseFn = function { 4*BozoFn(x, y, z) }

//#declare NoiseFn = function { 4*f_noise3d(x/2, y/2, z/2) }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare pCamera = <2, 1, -4>/2;

camera {
  location pCamera
  look_at 0*y
}


#declare pLight = <-2, 2, -1>*100;

light_source {
  pLight
  color White*5
  shadowless
}

//  background { color Blue/2 }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare vC = vrotate(pCamera, -30);

#declare Grad1Fn = fn_Gradient_Directional(NoiseFn, y)
#declare Grad2Fn = fn_Gradient_Directional(NoiseFn, vC)
#declare Grad3Fn = fn_Gradient_Directional(NoiseFn, pCamera)
//#declare Grad3Fn = fn_Gradient_Directional(NoiseFn, pLight)

#declare PigmentY =
  pigment {
    function { SquashFn(Grad1Fn(x, y, z), 2) }
    color_map {
      [ 0 color White*0.6 ]
      [ 1 color Red*0.3 ]
    }
  }

#declare Smoothness = 1; // Also try 0.4 or 5.0

#declare R_Fn = function { SquashFn(Grad1Fn(x, y, z), Smoothness) }
#declare G_Fn = function { SquashFn(Grad2Fn(x, y, z), Smoothness) }
#declare B_Fn = function { SquashFn(Grad3Fn(x, y, z), Smoothness) }

#declare R_Map = color_map { [ 0 color Black ] [ 1 color Red   ] }
#declare G_Map = color_map { [ 0 color Black ] [ 1 color Green ] }
#declare B_Map = color_map { [ 0 color Black ] [ 1 color Blue  ] }

#declare PigmentMixed =
  pigment {
    average
    pigment_map {
      [ 1.4 function { R_Fn(x, y, z) } color_map { R_Map } ]
      [ 1.0 function { G_Fn(x, y, z) } color_map { G_Map } ]
      [ 1.0 function { B_Fn(x, y, z) } color_map { B_Map } ]
    }
  }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

isosurface {
  function { y + NoiseFn(x, y, z) }
  contained_by { box { -<20, 5, 20>, <20, 1, 20> } }
  max_gradient 8
  pigment { PigmentMixed }
//  pigment { PigmentY }
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.