webgl - Calculating color values in vertex shader? -


so i'm using noise functions create procedural terrain. how understand it, can use noise function takes in 2d vector , returns float. can interpret float "height" of point in space. can interpret float color corresponding fragment. result, end mountains white on top , black on bottom.

right now, i'm doing same calculation in vertex , fragment shaders same value:

vertex shader:

uniform sampler2d texture; uniform float time; uniform float speed;  varying vec3 pos; varying vec2 vuv;  float random (in vec2 st) {      return fract(sin(dot(st.xy,                          vec2(12.9898,78.233)))*          43758.5453123); }  // based on morgan mcguire @morgan3d // https://www.shadertoy.com/view/4ds3wd float noise (in vec2 st) {     vec2 = floor(st);     vec2 f = fract(st);      // 4 corners in 2d of tile     float = random(i);     float b = random(i + vec2(1.0, 0.0));     float c = random(i + vec2(0.0, 1.0));     float d = random(i + vec2(1.0, 1.0));      vec2 u = f * f * (3.0 - 2.0 * f);      return mix(a, b, u.x) +              (c - a)* u.y * (1.0 - u.x) +              (d - b) * u.x * u.y; }  #define octaves 8 float fbm ( vec2 st) {     // initial values     float value = 0.;     float amplitud = .5;     float frequency = 0.;     //     // loop of octaves     (int = 0; < octaves; i++) {         value += amplitud * noise(st);         st *= 2.1;         amplitud *= .6;     }     return value; }  float pattern( in vec2 p )   {       vec2 q = vec2( fbm( p + vec2(0.0,0.0) ),                      fbm( p + vec2(5.2,1.3) ) );        vec2 r = vec2( fbm( p + 4.0*q + vec2(1.7,9.2) ),                      fbm( p + 4.0*q + vec2(8.3,2.8) ) );        return fbm( p + 4.0*r );   }  void main(){     vuv = uv + time;     pos = position;      float n = pattern(pos.xy);      gl_position = projectionmatrix * modelviewmatrix * vec4(position +      normal*n*.035, 1.); } 

fragment shader:

uniform sampler2d texture; uniform float time;  varying vec2 vuv; varying vec3 pos;  float random (in vec2 st) {      return fract(sin(dot(st.xy,                          vec2(12.9898,78.233)))*          43758.5453123); }  // based on morgan mcguire @morgan3d // https://www.shadertoy.com/view/4ds3wd float noise (in vec2 st) {     vec2 = floor(st);     vec2 f = fract(st);      // 4 corners in 2d of tile     float = random(i);     float b = random(i + vec2(1.0, 0.0));     float c = random(i + vec2(0.0, 1.0));     float d = random(i + vec2(1.0, 1.0));      vec2 u = f * f * (3.0 - 2.0 * f);      return mix(a, b, u.x) +              (c - a)* u.y * (1.0 - u.x) +              (d - b) * u.x * u.y; }  #define octaves 8 float fbm ( vec2 st) {     // initial values     float value = 0.;     float amplitud = .5;     float frequency = 0.;     //     // loop of octaves     (int = 0; < octaves; i++) {         value += amplitud * noise(st);         st *= 2.1;         amplitud *= .6;     }     return value; }  float pattern( in vec2 p )   {       vec2 q = vec2( fbm( p + vec2(0.0,0.0) ),                      fbm( p + vec2(5.2,1.3) ) );        vec2 r = vec2( fbm( p + 4.0*q + vec2(1.7,9.2) ),                      fbm( p + 4.0*q + vec2(8.3,2.8) ) );        return fbm( p + 4.0*r );   }  void main(){     vec2 q;      vec2 r;     vec2 j = vec2(0., 1.);     float p = pattern(pos.xy);      vec4 color = texture2d(texture, vuv + p/5.);      // gl_fragcolor = vec4(color.rgb, p);     gl_fragcolor = vec4(p); } 

both vertex , fragment shaders call pattern(pos.xy), yields same value. figured make code more efficient calculating value once each vertex , passing fragment shader using varying float:

//vertex shader varying float noise;  void main(){     noise = pattern(position.xy);     //rest of code }  //fragment shader varying float noise; void main(){     //do noise value } 

however, when try this, value gets passed doesn't seem same. height map disappears completely. i'm guessing has fact fragment shader calculates color each fragment, not each vertex? going on? ways can optimize code? feel shouldn't necessary repeat code.

while vertex shader executed each vertex of vertices of mesh buffer, fragment shader executed @ least once each fragment drawn. output variables vertex shader passed next stage of pipeline.
if next stage fragment shader (which case in webgl) output varibales of vertex shader interpolated according there barycentric coordinates on rendered primitive, , passed input veribales of fragment shader.

note, while gl_position calculated once per vertex, gl_fragcolor calculated once per fragment. causes, vertex shader defines geometry , fragment shader defines color of fragment.

for reason of optimization, can calculate height of height map once per vertex, , let graphics pipeline job interpolate height coloring of fragments between vertices.

your code should somehow this:

vertex shader

attribute vec3 position; attribute vec3 normal; attribute vec2 uv;  uniform float time; uniform float speed;  varying vec3  pos; varying vec2  vuv; varying float maph;  float pattern( in vec2 p );  void main() {     vuv         = uv + time;     pos         = position;     maph        = pattern(pos.xy);     gl_position = projectionmatrix * modelviewmatrix * vec4(position + normal*maph*.035, 1.0); } 

frgament shader

varying vec2  vuv; varying vec3  pos; varying float maph;  vec3 heighttorgb(in float h) {     float b = abs(h * 5.0 - 3.0) - 1.0;     float g = 2.0 - abs(h * 5.0 - 2.0);     float r = 2.0 - abs(h * 5.0 - 4.0);     return clamp( vec3(r,g,b), 0.0, 1.0 ); }  void main() {     vec3 color = heighttorgb( clamp(maph, 0.0, 1.0) );     gl_fragcolor = vec4( color, 1.0 ); } 

note, added function, colors height map similar rainbow.


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -