• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This post has been wikified, any user with enough reputation can edit it.
avatar image
1
Question by eviljack · Mar 10, 2016 at 05:27 PM · terrainshader programmingheightmapvertex shader

Displacing vertex with HeightMap texture in vertex shader

I'm trying to use a HeightMap texture in a vertex shader to morph a flat terrain to have hills/valleys, etc.

I'm using a quadtree structure, and each quad is it's own gameobject/mesh. I have a _HeightMap texture that that is passed to every quad using material.SetTexture. However, I see a repeated pattern, which I think means the texture is being scaled and then tiled on each quad, when I want the heightmap to 'stretch' over all quads. What's the proper way to do this?

Here is my shader code:

 Shader "Sagan/Proland" {
 
         SubShader{
            Pass {
              CGPROGRAM
 
              #include "Assets/Resources/Shaders/Sagan.cginc"
 
              #pragma vertex vert // vert function is the vertex shader
              #pragma fragment frag // frag function is the fragment shader
 
              float4x4 _TerrainMatrixWTL, _QuadPosition;
              sampler2D _HeightMap;
 
             // vertex shader
             saganVertexOutput vert(appdata_base v) {
                 saganVertexOutput v_out;
 
                 float4 vertexPos = v.vertex;
 
                 float textureHeightValue = tex2Dlod(_HeightMap, float4(vertexPos.xz, 0, 0)).r;
                 vertexPos.y += textureHeightValue;
 
                 v_out.position = mul(UNITY_MATRIX_MVP, vertexPos);
                 v_out.color = color(vertexPos);
 
                 return v_out;
             }
 
             // fragment shader
             float4 frag(saganVertexOutput input) : COLOR {
                return input.color;
                   // Here the fragment shader returns the "col" input
                   // parameter with semantic TEXCOORD0 as nameless
                   // output parameter with semantic COLOR.
             }
 
         ENDCG
       }
    }
 }
 



Here is what I'm seeing:

alt text

capture.png (404.3 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Eno-Khaon · Mar 10, 2016 at 06:21 PM

The key to this lies in line 21:

 float textureHeightValue = tex2Dlod(_HeightMap, float4(vertexPos.xz, 0, 0)).r;

Your texture position input is based on the object-space vertex position of your plane. The result is that you're taking a 0-1 texture space and requesting the texture at a position over a range of ~12 units. It's not terribly surprising that you would see numerous repeats.

Unfortunately, I haven't come across any way of retrieving object bounds data inside a shader without passing it through manually. Therefore, you'll want to pass one of the following into your shader:

A single scale value, applicable only to square planes - If the tile's origin is guaranteed to be centered on the plane, a single value can potentially determine the offsets required to scale your texture coordinate range down to a (center - scale) to (center + scale) range (which can then be converted into a 0-1 range for application of the texture).

A more versatile alternative would involve passing a Vector to the shader instead - Take data from the bounds of the mesh and pass it to the shader as something like (min.x, max.x, min.y, max.y). Then, in the shader, you can generate a range from each minimum to maximum and, again, scale the values to a 0-1 range to properly fit each texture.

As for actually rescaling the number, you won't have access to Mathf.InverseLerp, so you'll have to make due with writing a variant of your own instead.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image eviljack · Mar 16, 2016 at 11:54 PM 0
Share

Thanks for this, makes sense. The key was realizing that the texture space is 0-1 while my model space depends on the size of the model. I'm going to try the second option.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Problem with heightmap and terrain height maxing out at 10000, proportions *Solved* 0 Answers

There is no terrain tab in menu bar 1 Answer

Why does assigning heightmapResolution increase the size of my terrain? 2 Answers

import terrain from Photoshop 1 Answer

vertex and geometry shader change with distance 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges