Originally I was doing all terrain calculations in a vertex shader and simple modifying the positions of the vertices from there. I would now like to use normal maps and I cannot think of any way of using these with this current method. So my question is: how can one create a heightmap (as a texture) on the gpu in a pixel shader? Thanks for any replies/suggestions.

  • 1
    \$\begingroup\$ Could you clarify on what you mean by 'create a heightmap as a texture' - how is this heightmap created, for example? Also, you can use a compute shader for practically anything, or OpenCL if that floats your boat. Finally, OpenGL or DirectX? \$\endgroup\$
    – Polar
    Jul 21, 2013 at 10:17
  • \$\begingroup\$ The heightmap will be generated using multifractal noise. I would like to generate the heightmap as a texture image which I can then feed into another shader to create a normal map. And I am actually using java. \$\endgroup\$ Jul 21, 2013 at 19:19
  • \$\begingroup\$ If you're going to use multifractal noise to generate your heightmap, and you want to generate it on the GPU, then you need a Compute Shader / Equivalent to run first. If you merely want to use a pre-generated heightmap, then just represent it as a texture and pass it to the GPU. \$\endgroup\$
    – Polar
    Jul 21, 2013 at 19:39
  • \$\begingroup\$ Would it be possible to use a FBO with a pixel shader to generate it? The graphics library I am using does not support compute shaders...which is annoying at this point. \$\endgroup\$ Jul 21, 2013 at 23:09
  • \$\begingroup\$ I'd guess so, at least in principle - there may be practical issues with this in terms of position in the pipeline. At this point, my advice would be to use OpenCL to run it on the GPU yourself - your choice \$\endgroup\$
    – Polar
    Jul 22, 2013 at 5:15

1 Answer 1


Using the four adjacent heights to a position to compute its normal provides a nice balance between performance and accuracy. Use RGBA texture where RGB represents normal and alpha height.

vec3 ComputeNormals(vec3 position,sampler2D map)
   float left=texture(heightMap,position.xy - vec2(1.0,0.0)).w;
   float right=texture(heightMap,position.xy + vec2(1.0,0.0)).w;
   float bottom=texture(heightMap,position.xy - vec2(0.0,1.0)).w;
   float top=texture(heightMap,position.xy + vec2(0.0,1.0)).w;
   return vec3(left-right,bottom-top,2.0);
  • 1
    \$\begingroup\$ if this is too slow its actually enought if you only samle left and bottom \$\endgroup\$
    – Quonux
    Jul 21, 2013 at 13:50
  • \$\begingroup\$ Yea I actually was using a sobel filter to generate the maps. \$\endgroup\$ Jul 21, 2013 at 23:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .