static public void SetupDisplacement(Material material, int layerCount = 1) { DisplacementMode displacementMode = GetFilteredDisplacementMode(material); for (int i = 0; i < layerCount; i++) { var heightAmplitude = layerCount > 1 ? kHeightAmplitude + i : kHeightAmplitude; var heightCenter = layerCount > 1 ? kHeightCenter + i : kHeightCenter; if (material.HasProperty(heightAmplitude) && material.HasProperty(heightCenter)) { var heightPoMAmplitude = layerCount > 1 ? kHeightPoMAmplitude + i : kHeightPoMAmplitude; var heightParametrization = layerCount > 1 ? kHeightParametrization + i : kHeightParametrization; var heightTessAmplitude = layerCount > 1 ? kHeightTessAmplitude + i : kHeightTessAmplitude; var heightTessCenter = layerCount > 1 ? kHeightTessCenter + i : kHeightTessCenter; var heightOffset = layerCount > 1 ? kHeightOffset + i : kHeightOffset; var heightMin = layerCount > 1 ? kHeightMin + i : kHeightMin; var heightMax = layerCount > 1 ? kHeightMax + i : kHeightMax; if (displacementMode == DisplacementMode.Pixel) { material.SetFloat(heightAmplitude, material.GetFloat(heightPoMAmplitude) * 0.01f); // Convert centimeters to meters. material.SetFloat(heightCenter, 1.0f); // PoM is always inward so base (0 height) is mapped to 1 in the texture } else { var parametrization = (HeightmapParametrization)material.GetFloat(heightParametrization); if (parametrization == HeightmapParametrization.MinMax) { float offset = material.GetFloat(heightOffset); float minHeight = material.GetFloat(heightMin); float amplitude = material.GetFloat(heightMax) - minHeight; material.SetFloat(heightAmplitude, amplitude * 0.01f); // Convert centimeters to meters. material.SetFloat(heightCenter, -(minHeight + offset) / Mathf.Max(1e-6f, amplitude)); } else { float offset = material.GetFloat(heightOffset); float center = material.GetFloat(heightTessCenter); float amplitude = material.GetFloat(heightTessAmplitude); material.SetFloat(heightAmplitude, amplitude * 0.01f); // Convert centimeters to meters. material.SetFloat(heightCenter, -offset / Mathf.Max(1e-6f, amplitude) + center); } } } } }
static DisplacementMode GetFilteredDisplacementMode(Material material, DisplacementMode displacementMode) { if (material.HasProperty(kTessellationMode)) { if (displacementMode == DisplacementMode.Pixel || displacementMode == DisplacementMode.Vertex) { return(DisplacementMode.None); } } else { if (displacementMode == DisplacementMode.Tessellation) { return(DisplacementMode.None); } } return(displacementMode); }
public WaterSample(Water water, DisplacementMode displacementMode = DisplacementMode.Height, float precision = 1.0f) { if (water == null) { throw new System.ArgumentException("Argument 'water' is null."); } if (precision <= 0.0f || precision > 1.0f) { throw new System.ArgumentException("Precision has to be between 0.0 and 1.0."); } this.precision = precision; this.horizontalThreshold = 0.045f / (precision * precision * precision); this.water = water; this.displacementMode = displacementMode; this.previousResult.x = float.NaN; }
void DrawSurfaceInputsGUI() { UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase[m_LayerIndex].floatValue; float X, Y, Z, W; materialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap[m_LayerIndex], baseColor[m_LayerIndex]); bool hasMetallic = materials.All(m => m.GetMaterialId() == MaterialId.LitStandard || m.GetMaterialId() == MaterialId.LitAniso || m.GetMaterialId() == MaterialId.LitIridescence); if (maskMap[m_LayerIndex].textureValue == null) { if (hasMetallic) materialEditor.ShaderProperty(metallic[m_LayerIndex], Styles.metallicText); materialEditor.ShaderProperty(smoothness[m_LayerIndex], Styles.smoothnessText); } else { if (hasMetallic) materialEditor.MinMaxShaderProperty(metallicRemapMin[m_LayerIndex], metallicRemapMax[m_LayerIndex], 0.0f, 1.0f, Styles.metallicRemappingText); materialEditor.MinMaxShaderProperty(smoothnessRemapMin[m_LayerIndex], smoothnessRemapMax[m_LayerIndex], 0.0f, 1.0f, Styles.smoothnessRemappingText); materialEditor.MinMaxShaderProperty(aoRemapMin[m_LayerIndex], aoRemapMax[m_LayerIndex], 0.0f, 1.0f, Styles.aoRemappingText); } materialEditor.TexturePropertySingleLine((materials.All(m => m.GetMaterialId() == MaterialId.LitSpecular)) ? Styles.maskMapSpecularText : Styles.maskMapSText, maskMap[m_LayerIndex]); materialEditor.ShaderProperty(normalMapSpace[m_LayerIndex], Styles.normalMapSpaceText); // Triplanar only work with tangent space normal if ((NormalMapSpace)normalMapSpace[m_LayerIndex].floatValue == NormalMapSpace.ObjectSpace && ((UVBaseMapping)UVBase[m_LayerIndex].floatValue == UVBaseMapping.Triplanar)) { EditorGUILayout.HelpBox(Styles.normalMapSpaceWarning.text, MessageType.Error); } // We have two different property for object space and tangent space normal map to allow // 1. to go back and forth // 2. to avoid the warning that ask to fix the object normal map texture (normalOS are just linear RGB texture if ((NormalMapSpace)normalMapSpace[m_LayerIndex].floatValue == NormalMapSpace.TangentSpace) { materialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap[m_LayerIndex], normalScale[m_LayerIndex]); materialEditor.TexturePropertySingleLine(Styles.bentNormalMapText, bentNormalMap[m_LayerIndex]); } else { // No scaling in object space materialEditor.TexturePropertySingleLine(Styles.normalMapOSText, normalMapOS[m_LayerIndex]); materialEditor.TexturePropertySingleLine(Styles.bentNormalMapOSText, bentNormalMapOS[m_LayerIndex]); } DisplacementMode displaceMode = (DisplacementMode)displacementMode.floatValue; if (displaceMode != DisplacementMode.None || (m_Features & Features.HeightMap) != 0) { EditorGUI.BeginChangeCheck(); materialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap[m_LayerIndex]); if (!heightMap[m_LayerIndex].hasMixedValue && heightMap[m_LayerIndex].textureValue != null && !displacementMode.hasMixedValue) { EditorGUI.indentLevel++; if (displaceMode == DisplacementMode.Pixel) { materialEditor.ShaderProperty(heightPoMAmplitude[m_LayerIndex], Styles.heightMapAmplitudeText); } else { materialEditor.ShaderProperty(heightParametrization[m_LayerIndex], Styles.heightMapParametrization); if (!heightParametrization[m_LayerIndex].hasMixedValue) { HeightmapParametrization parametrization = (HeightmapParametrization)heightParametrization[m_LayerIndex].floatValue; if (parametrization == HeightmapParametrization.MinMax) { EditorGUI.BeginChangeCheck(); materialEditor.ShaderProperty(heightMin[m_LayerIndex], Styles.heightMapMinText); if (EditorGUI.EndChangeCheck()) heightMin[m_LayerIndex].floatValue = Mathf.Min(heightMin[m_LayerIndex].floatValue, heightMax[m_LayerIndex].floatValue); EditorGUI.BeginChangeCheck(); materialEditor.ShaderProperty(heightMax[m_LayerIndex], Styles.heightMapMaxText); if (EditorGUI.EndChangeCheck()) heightMax[m_LayerIndex].floatValue = Mathf.Max(heightMin[m_LayerIndex].floatValue, heightMax[m_LayerIndex].floatValue); } else { EditorGUI.BeginChangeCheck(); materialEditor.ShaderProperty(heightTessAmplitude[m_LayerIndex], Styles.heightMapAmplitudeText); if (EditorGUI.EndChangeCheck()) heightTessAmplitude[m_LayerIndex].floatValue = Mathf.Max(0f, heightTessAmplitude[m_LayerIndex].floatValue); materialEditor.ShaderProperty(heightTessCenter[m_LayerIndex], Styles.heightMapCenterText); } materialEditor.ShaderProperty(heightOffset[m_LayerIndex], Styles.heightMapOffsetText); } } EditorGUI.indentLevel--; } // UI only updates intermediate values, this will update the values actually used by the shader. if (EditorGUI.EndChangeCheck()) { SurfaceOptionUIBlock surfaceOption; // Fetch the surface option block which contains the function to update the displacement datas if (m_LayerCount == 1) surfaceOption = parent.FetchUIBlock<SurfaceOptionUIBlock>(); else surfaceOption = parent.parent.FetchUIBlock<SurfaceOptionUIBlock>(); surfaceOption.UpdateDisplacement(m_LayerIndex); } } if (materials.All(m => m.GetMaterialId() == materials[0].GetMaterialId())) { // We can use materials[0] because all the material IDs have the same value switch (materials[0].GetMaterialId()) { case MaterialId.LitSSS: case MaterialId.LitTranslucent: ShaderSSSAndTransmissionInputGUI(); break; case MaterialId.LitStandard: // Nothing break; // Following mode are not supported by layered lit and will not be call by it // as the MaterialId enum don't define it case MaterialId.LitAniso: ShaderAnisoInputGUI(); break; case MaterialId.LitSpecular: ShaderSpecularColorInputGUI(); break; case MaterialId.LitIridescence: ShaderIridescenceInputGUI(); break; default: Debug.Assert(false, "Encountered an unsupported MaterialID."); break; } } if (!isLayeredLit) { ShaderClearCoatInputGUI(); } EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); materialEditor.ShaderProperty(UVBase[m_LayerIndex], Styles.UVBaseMappingText); uvBaseMapping = (UVBaseMapping)UVBase[m_LayerIndex].floatValue; X = (uvBaseMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f; Y = (uvBaseMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f; Z = (uvBaseMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f; W = (uvBaseMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f; UVMappingMask[m_LayerIndex].colorValue = new Color(X, Y, Z, W); if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar)) { materialEditor.ShaderProperty(TexWorldScale[m_LayerIndex], Styles.texWorldScaleText); } materialEditor.TextureScaleOffsetProperty(baseColorMap[m_LayerIndex]); if (EditorGUI.EndChangeCheck()) { // Precompute. InvTilingScale[m_LayerIndex].floatValue = 2.0f / (Mathf.Abs(baseColorMap[m_LayerIndex].textureScaleAndOffset.x) + Mathf.Abs(baseColorMap[m_LayerIndex].textureScaleAndOffset.y)); if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar)) { InvTilingScale[m_LayerIndex].floatValue = InvTilingScale[m_LayerIndex].floatValue / TexWorldScale[m_LayerIndex].floatValue; } } }